2017-07-31 93 views
0

在DirectX12,渲染使用世界單一統一緩存相當於在不同位置的多個對象的變換,如:Vulkan:有沒有辦法在DirectX12中的不同位置繪製多個對象?

// Basic simplified pseudocode 
SetRootSignature(); 
SetPrimitiveTopology(); 
SetPipelineState(); 
SetDepthStencilTarget(); 
SetViewportAndScissor(); 

for (auto object : objects) 
{ 
    SetIndexBuffer(); 
    SetVertexBuffer(); 

    struct VSConstants 
    { 
     QEDx12::Math::Matrix4 modelToProjection; 
    } vsConstants; 
    vsConstants.modelToProjection = ViewProjMat * object->GetWorldProj(); 
    SetDynamicConstantBufferView(0, sizeof(vsConstants), &vsConstants); 

    DrawIndexed(); 
} 

然而,福爾康,如果你做一個單一的統一的緩存類似的東西全部,

for (auto object : objects) 
{ 
    SetIndexBuffer(); 
    SetVertexBuffer(); 

    UploadUniformBuffer(object->GetWorldProj()); 

    DrawIndexed(); 
} 

有沒有一種方法來繪製多個對象,在福爾康一個統一的緩存,就像在DirectX12:對象在過去的世界矩陣的位置呈現?

我知道Sascha Willem的動態統一緩衝區示例(https://github.com/SaschaWillems/Vulkan/tree/master/dynamicuniformbuffer),他將許多矩陣包裝在一個大的統一緩衝區中,雖然有用,但並不完全符合我的要求。

在此先感謝您的幫助。

回答

1

您必須使用Push常量或爲每個位置使用單獨的統一緩衝區。這些可以與每個動態偏移位置的描述符綁定。

在薩沙的例子中,你可以不僅僅是制服內的一個矩陣。

這意味着在UploadUniformBuffer中,您將新矩陣附加到緩衝區並綁定新位置。

1

我在D3D 12 API中找不到一個叫SetDynamicConstantBufferView的函數。我認爲這是你發明的一些功能,但不知道它的作用,我只能猜測。

它看起來像你正在上傳數據到緩衝區對象而渲染。如果是這種情況,那麼Vulkan不能那樣做。這是一個好東西。上傳到您正在閱讀的內存需要同步。您必須在讀取要覆蓋的數據的最後一個渲染命令與下一個渲染命令之間發出障礙。如果你喜歡錶演,這不是一個好主意。

但是我再也不確定這個功能到底在做什麼,所以我的理解可能是錯誤的。


在Vulkan中,描述符一般不會在渲染幀的過程中發生變化。然而,Vulkan的製造商意識到用戶有時想使用同一個VkBuffer對象的不同子集。這是動態統一/存儲緩衝區的用途。

您在技術上沒有多個統一緩衝區;你只有一個。但是您可以使用提供給vkCmdBindDescriptorSets的偏移量來移動下一個渲染命令將從其緩衝區獲取數據的位置。因此,以不同的數據提供不同的渲染命令是一種輕量級的方式。

基本上,您重新綁定了描述符集,但使用了不同的pDynamicOffset數組值。爲了使這些工作,你需要提前計劃。您的管道佈局必須將這些描述符顯式聲明爲動態描述符。每次你綁定這個集合,你都需要在這個描述符所使用的緩衝區中提供偏移量。這就是說,使統一緩衝區存儲更大的矩陣陣列,使用動態偏移量從一個矩陣塊跳到另一個矩陣塊可能會更好。你需要的是,你要提供的統一數據(取決於硬件)將保留在着色器內存中,除非你做了一些改變偏移量或着色器的內容。上傳這些數據有一些小的成本,所以最大限度地減少這種上傳的需求可能不是一個壞主意。

所以你應該去上傳全部你的對象緩衝數據在一個DMA操作中。然後你發出一個障礙,並進行渲染,使用動態偏移等來告訴每個偏移量在哪裏。

相關問題