2017-04-03 27 views
0

我有一個輸出緩衝區的格式如下:如何在計算着色器完成後使用數據?

D3D11_BUFFER_DESC rgbaGPUBuffer; 

rgbaGPUBuffer.ByteWidth    = width * height * 16; // 4 * 4 floats (RGBA) 
rgbaGPUBuffer.Usage     = D3D11_USAGE_DEFAULT; 
rgbaGPUBuffer.BindFlags    = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE; 
rgbaGPUBuffer.CPUAccessFlags  = 0; 
rgbaGPUBuffer.MiscFlags    = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; 
rgbaGPUBuffer.StructureByteStride = 4; // shader will output one rgba component by one 

我有一個無序訪問視圖:

D3D11_UNORDERED_ACCESS_VIEW_DESC descView; 
descView.Format      = DXGI_FORMAT_UNKNOWN; 
descView.ViewDimension    = D3D11_UAV_DIMENSION_BUFFER; 
descView.Buffer.FirstElement  = 0; 
descView.Buffer.NumElements   = rgbaGPUBuffer.ByteWidth/rgbaGPUBuffer.StructureByteStride; 
descView.Buffer.Flags    = 0; 

緩衝區的使用必須D3D11_USAGE_DEFAULT和CPUAccessFlags不能設置。因此,訪問的視圖格式必須是DXGI_FORMAT_UNKNOWN。具有諷刺意味的是,一旦計算着色器完成,輸出緩衝區實際上就保存了格式DXGI_FORMAT_R8G8B8A8_UNORM。我的渲染目標交換鏈是這種格式,我不能對數據做任何事情。

  1. 我無法訪問它,因爲無法設置CPUFlags。
  2. 我無法複製,因爲CopyResource在源和目標不是相同資源類型時不起作用。

那麼,問題是,如何使用這些數據?

回答

0

它們是GPU可以寫入的資源和CPU可以讀取的資源之間的障礙。

如果您需要回讀(並打破並行性,除非添加一些從GPU工作到CPU工作的延遲幀),唯一的方法是通過在D3D11_USAGE_STAGING池中創建一個沒有GPU綁定的獨立資源和運行CopyResource將您的GPU工作轉移到CPU可訪問的資源。

+0

如果我的最終目標是將該數據傳輸到後臺緩衝區並調用Present(),這種情況是否適用?如果是,那麼我將不得不將數據從GPU移動到CPU,然後再找到一種方法將其移回到後臺緩衝區。這讓我想知道人們如何使用GPU來進行顏色轉換等愚笨的操作...... – moose

+0

當然不是,如果工作對CPU沒有興趣,那麼不會。您可以創建交換鏈,以便後臺緩衝區爲無人機,並且可以讓計算機直接使用'RWTexture2D'寫入它們。如果更方便,您仍然可以分離計算輸出並使用另一個計算或繪圖將其複製回後緩衝區。我建議你不要像目標一樣使用緩衝區,因爲它們對於紋理讀取或寫入的內存效率較低。 – galop1n

+0

我通常理解你在說什麼,但將其轉換爲DirectX代碼是一場噩夢,因爲我對DirectX一無所知。我會嘗試按照你的建議創建一個交換鏈,但我真的不知道如何在HLSL中使用'RWTexture2D'(或'Texture2D')。我可以問一個新問題,這樣你就可以贏得你的聲望。其實我甚至不知道如何創建交換鏈,因爲當前交換鏈的用法是'DXGI_USAGE_RENDER_TARGET_OUTPUT'。如果我將它轉換爲'DXGI_USAGE_UNORDERED_ACCESS',我可以用它來呈現嗎? – moose