2017-08-08 52 views
0

我正在研究引擎的紋理類,並且遇到了一個問題。DX12,如何實現標準的紋理類?

我們的API支持不同的動作,例如更新紋理的紋理元素以及從紋理讀取數據。

該紋理可以作爲無人機或可能作爲SRV綁定到管道。它也可以創建爲RTV或DSV。

我應該如何處理紋理的創建和更新?我應該只是創建所有紋理作爲UPLOAD堆?這將是最標準的解決方案,因爲我可以輕鬆讀寫數據,但也意味着更少的GPU帶寬。

我也可以檢測是否從文件或程序紋理創建紋理,在第一種情況下,我會將紋理上傳到DEFAULT堆。

您認爲如何?

謝謝!

+0

您可能想看看[DirectX Tool Kit for DX12](https://github.com/Microsoft/DirectXTK12),特別是「DescriptorHeap」和「ResourceUploadBatch」類 –

+0

Hi @ ChuckWalbourn,是的,你的代碼對於理解一些東西會很有幫助,謝謝! – Nacho

回答

0

您將無法在上傳堆中創建紋理,在嘗試解決它時您將面臨驗證錯誤的永久循環。這是因爲紋理在內存中不使用線性表示。但至少對你來說,複製和更新操作是你最關心的問題。

當您想要在CPU和GPU之間執行傳輸時,您需要在上傳或回讀堆中創建一個緩衝區,使用GetCopyableFootprints來知道如何存儲/讀取其中的圖像並呼叫CopyTextureRegion執行實際複製。如果你想支持部分更新和讀取,這是幾頁代碼,但這個操作很簡單。

之後,許多考慮因素會影響你的紋理類,你想如何在描述符堆中抽象視圖,你是否希望支持保留紋理,部分駐留,你想支持內存別名,你如何管理在更新/銷燬它們的過程中,gpu使用的紋理生命週期,流媒體等等。沒有完美的解決方案,它完全取決於您的需求。

+0

Hi @ galop1n,可以說我想實現一個_ReadTexel()_方法,我的想法是創建一個_READBACK_資源,並從_DEFAULT_資源複製數據。但是,_ID3D12GraphicsCommandList :: CopyTextureRegion()_將在ReadTexel()返回後執行很多,我該如何處理?也許我應該有一個_CopyCommandList_,我應該發送這個命令,所以我可以在_ReadTexel()_方法中執行它? 謝謝! – Nacho

+0

@Nacho''ReadTexel'不是一個推薦的操作,除非真的有必要,不應該同步GPU和CPU!如果它位於CPU內存創建的資源上,那麼只需標記圖像即可不丟棄內存並支付額外的存儲費用。如果它是一個GPU生成曲面的「ReadTexel」,那麼你必須將其視爲一個'std :: future'。然後以異步方式觸發複製,等待操作完成後再讀回。在執行「CopyTextureRegion」後插入'ID3D12Fence'並等待它達到合適的值。 – galop1n

+0

是的我發現它必須是一個非常昂貴的操作!很有趣,因爲在Dx11中,你可以做到沒有太多複雜因素,所以我猜想內部驅動程序會做很多事情。我喜歡你對未來的態度,但這意味着我將在一段時間內沒有結果。你有什麼想法有一個單獨的CopyCmdList? – Nacho