diff --git a/util/test/demos/d3d12/d3d12_execute_indirect.cpp b/util/test/demos/d3d12/d3d12_execute_indirect.cpp index 6085e7135..2a63c9fe2 100644 --- a/util/test/demos/d3d12/d3d12_execute_indirect.cpp +++ b/util/test/demos/d3d12/d3d12_execute_indirect.cpp @@ -48,14 +48,23 @@ cbuffer test : register(b0) float4 cbtest[5]; } +cbuffer rootConsts : register(b1) +{ + float4 rootConsts; +} + StructuredBuffer srvtest : register(t0); RWStructuredBuffer uavtest : register(u0); +RWStructuredBuffer uavarray[2] : register(u1); + v2f main(vertin IN, uint vid : SV_VertexID) { v2f OUT = (v2f)0; + int ZERO = floor(vid/(vid+1.0e-6f)); + if(vid < 3) { OUT.pos = float4(IN.pos.xyz, 1); @@ -69,6 +78,20 @@ v2f main(vertin IN, uint vid : SV_VertexID) if(uavtest[1].w != 1.234f) OUT.col.r += 0.5f; + + if (rootConsts.x == 0.0f) + OUT.col.b += 0.2f; + if (rootConsts.y == 0.0f) + OUT.col.b += 0.2f; + if (rootConsts.z == 0.0f) + OUT.col.b += 0.2f; + if (rootConsts.w == 0.0f) + OUT.col.b += 0.2f; + + if (rootConsts.w != 0.0f) + uavarray[ZERO][10] = 10.0; + else + uavarray[ZERO+1][10] = 20.0; } else { @@ -230,7 +253,7 @@ void main(uint3 gid : SV_GroupID) if(!Init()) return 3; - ID3DBlobPtr vsblob = Compile(vert, "main", "vs_5_0"); + ID3DBlobPtr vsblob = Compile(vert, "main", "vs_5_1"); ID3DBlobPtr vs2blob = Compile(vert2, "main", "vs_5_0"); ID3DBlobPtr psblob = Compile(pixel, "main", "ps_4_0"); @@ -260,14 +283,15 @@ void main(uint3 gid : SV_GroupID) ID3D12ResourcePtr srv = MakeBuffer().Data(checkdata); ID3D12ResourcePtr uav = MakeBuffer().UAV().Data(checkdata); - ID3D12RootSignaturePtr patchsig = MakeSig({ - cbvParam(D3D12_SHADER_VISIBILITY_VERTEX, 0, 0), - srvParam(D3D12_SHADER_VISIBILITY_VERTEX, 0, 0), - uavParam(D3D12_SHADER_VISIBILITY_VERTEX, 0, 0), - }); + ID3D12RootSignaturePtr patchsig = MakeSig( + {cbvParam(D3D12_SHADER_VISIBILITY_VERTEX, 0, 0), + srvParam(D3D12_SHADER_VISIBILITY_VERTEX, 0, 0), + uavParam(D3D12_SHADER_VISIBILITY_VERTEX, 0, 0), + constParam(D3D12_SHADER_VISIBILITY_VERTEX, 0, 1, 4), + tableParam(D3D12_SHADER_VISIBILITY_ALL, D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 0, 1, 2, 0)}); - ID3D12CommandSignaturePtr patchArgSig = - MakeCommandSig(patchsig, {vbArg(0), cbvArg(0), srvArg(1), uavArg(2), drawArg()}); + ID3D12CommandSignaturePtr patchArgSig = MakeCommandSig( + patchsig, {vbArg(0), cbvArg(0), srvArg(1), uavArg(2), constArg(3, 0, 1), drawArg()}); struct PatchArgs { @@ -275,6 +299,7 @@ void main(uint3 gid : SV_GroupID) D3D12_GPU_VIRTUAL_ADDRESS cbv; D3D12_GPU_VIRTUAL_ADDRESS srv; D3D12_GPU_VIRTUAL_ADDRESS uav; + float constData; D3D12_DRAW_ARGUMENTS draw; } patchargs; @@ -288,8 +313,29 @@ void main(uint3 gid : SV_GroupID) patchargs.draw.InstanceCount = 1; patchargs.draw.StartInstanceLocation = 0; patchargs.draw.StartVertexLocation = 0; + patchargs.constData = 123.0f; - ID3D12ResourcePtr patchArgBuf = MakeBuffer().Upload().Size(sizeof(patchargs)).Data(&patchargs); + std::vector patchArgsData; + patchArgsData.resize(sizeof(PatchArgs)); + + char *ptr = patchArgsData.data(); + memcpy(ptr, &patchargs.vb, sizeof(D3D12_VERTEX_BUFFER_VIEW)); + ptr += sizeof(D3D12_VERTEX_BUFFER_VIEW); + memcpy(ptr, &patchargs.cbv, sizeof(D3D12_GPU_VIRTUAL_ADDRESS)); + ptr += sizeof(D3D12_GPU_VIRTUAL_ADDRESS); + memcpy(ptr, &patchargs.srv, sizeof(D3D12_GPU_VIRTUAL_ADDRESS)); + ptr += sizeof(D3D12_GPU_VIRTUAL_ADDRESS); + memcpy(ptr, &patchargs.uav, sizeof(D3D12_GPU_VIRTUAL_ADDRESS)); + ptr += sizeof(D3D12_GPU_VIRTUAL_ADDRESS); + memcpy(ptr, &patchargs.constData, sizeof(float)); + ptr += sizeof(float); + memcpy(ptr, &patchargs.draw, sizeof(D3D12_DRAW_ARGUMENTS)); + ptr += sizeof(D3D12_DRAW_ARGUMENTS); + + size_t patchArgsDataSize = ptrdiff_t(ptr - patchArgsData.data()); + + ID3D12ResourcePtr patchArgBuf = + MakeBuffer().Upload().Size((UINT)patchArgsData.size()).Data(patchArgsData.data()); ID3D12PipelineStatePtr patchpso = MakePSO().RootSig(patchsig).InputLayout(layout).VS(vsblob).PS(psblob); @@ -312,6 +358,10 @@ void main(uint3 gid : SV_GroupID) .NumElements(256000) .CreateGPU(1); + MakeUAV(compuav).Format(DXGI_FORMAT_R32_FLOAT).FirstElement(0).NumElements(1024).CreateGPU(2); + + MakeUAV(compuav).Format(DXGI_FORMAT_R32_FLOAT).FirstElement(1024).NumElements(1024).CreateGPU(3); + ID3D12RootSignaturePtr compsig = MakeSig({ tableParam(D3D12_SHADER_VISIBILITY_ALL, D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 0, 0, 1, 0), tableParam(D3D12_SHADER_VISIBILITY_ALL, D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 0, 1, 1, 1), @@ -326,12 +376,17 @@ void main(uint3 gid : SV_GroupID) ID3D12ResourcePtr fullargsDrawBuf = MakeBuffer().Size(countDrawsInFullBuffer * sizeof(D3D12_INDIRECT_ARGUMENT_DESC)); - PatchArgs fullargsStateDraw[countDrawsInFullBuffer]; + std::vector fullargsData; + fullargsData.resize(countDrawsInFullBuffer * sizeof(PatchArgs)); + char *fullargsPtr = fullargsData.data(); for(uint32_t i = 0; i < countDrawsInFullBuffer; ++i) - fullargsStateDraw[i] = patchargs; + { + memcpy(fullargsPtr, patchArgsData.data(), patchArgsDataSize); + fullargsPtr += patchArgsDataSize; + } ID3D12ResourcePtr fullargsStateDrawBuf = - MakeBuffer().Upload().Size(countDrawsInFullBuffer * sizeof(patchargs)).Data(fullargsStateDraw); + MakeBuffer().Upload().Size((UINT)fullargsData.size()).Data(fullargsData.data()); ID3D12RootSignaturePtr plainsig = MakeSig({}); ID3D12PipelineStatePtr plainpso = @@ -344,6 +399,8 @@ void main(uint3 gid : SV_GroupID) customvbargs, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER | D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT); + float baseConstData[4] = {10.0f, 9.0f, 8.0f, 7.0f}; + while(Running()) { std::vector cmds; @@ -352,6 +409,8 @@ void main(uint3 gid : SV_GroupID) Reset(cmd); cmds.push_back(cmd); + cmd->SetDescriptorHeaps(1, &m_CBVUAVSRV.GetInterfacePtr()); + uint32_t zero[4] = {}; cmd->ClearUnorderedAccessViewUint( MakeUAV(compuav).Format(DXGI_FORMAT_R32G32B32A32_UINT).CreateGPU(0), @@ -372,12 +431,16 @@ void main(uint3 gid : SV_GroupID) cmd->SetPipelineState(patchpso); cmd->SetGraphicsRootSignature(patchsig); + cmd->SetDescriptorHeaps(1, &m_CBVUAVSRV.GetInterfacePtr()); + cmd->SetGraphicsRootDescriptorTable(4, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart()); RSSetViewport(cmd, {0.0f, 0.0f, (float)screenWidth, (float)screenHeight, 0.0f, 1.0f}); RSSetScissorRect(cmd, {0, 0, screenWidth, screenHeight}); OMSetRenderTargets(cmd, {rtv}, {}); + cmd->SetGraphicsRoot32BitConstants(3, 4, baseConstData, 0); + cmd->ExecuteIndirect(patchArgSig, 1, patchArgBuf, 0, NULL, 0); } popMarker(cmd); @@ -485,11 +548,14 @@ void main(uint3 gid : SV_GroupID) cmd->SetPipelineState(patchpso); cmd->SetGraphicsRootSignature(patchsig); + cmd->SetDescriptorHeaps(1, &m_CBVUAVSRV.GetInterfacePtr()); + cmd->SetGraphicsRootDescriptorTable(4, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart()); RSSetViewport(cmd, {0.0f, 0.0f, (float)screenWidth, (float)screenHeight, 0.0f, 1.0f}); RSSetScissorRect(cmd, {0, 0, screenWidth, screenHeight}); OMSetRenderTargets(cmd, {rtv}, {}); + cmd->SetGraphicsRoot32BitConstants(3, 4, baseConstData, 0); cmd->ExecuteIndirect(patchArgSig, countDrawsInFullBuffer, fullargsStateDrawBuf, 0, NULL, 0); } popMarker(cmd); diff --git a/util/test/tests/D3D12/D3D12_Execute_Indirect.py b/util/test/tests/D3D12/D3D12_Execute_Indirect.py index 790ada0a7..c63246baf 100644 --- a/util/test/tests/D3D12/D3D12_Execute_Indirect.py +++ b/util/test/tests/D3D12/D3D12_Execute_Indirect.py @@ -18,11 +18,28 @@ class D3D12_Execute_Indirect(rdtest.TestCase): raise rdtest.TestFailureException("No pixel history found") rdtest.log.success("Pixel History Worked") + def check_root_consts(self, expected: List[float]): + pipe: rd.PipeState = self.controller.GetPipelineState() + root_consts = pipe.GetConstantBlock(rd.ShaderStage.Vertex, 1, 0) + if root_consts is None: + raise rdtest.TestFailureException('rootConsts not found in pipeline state') + bytes = self.controller.GetBufferData(root_consts.descriptor.resource, 0, root_consts.descriptor.byteSize) + self.check(len(bytes) == 16) # 4 floats + data = struct.unpack("ffff", bytes) + for i in range(len(expected)): + if not rdtest.value_compare(expected[i], data[i]): + raise rdtest.TestFailureException(f'rootConsts[i] does not match expected:{expected[i]} got:{data[i]}') + rdtest.log.success("rootConsts is as expected") + def check_capture(self): from_eid = self.find_action("Multiple draws").eventId + ei_eid = self.find_action("ExecuteIndirect", from_eid).eventId + self.controller.SetFrameEvent(ei_eid - 1, False) + self.check_root_consts([10.0, 9.0, 8.0, 7.0]) for i in range(8): action = self.find_action("IndirectDraw", from_eid) self.controller.SetFrameEvent(action.eventId, False) + self.check_root_consts([123.0, 9.0, 8.0, 7.0]) self.check_triangle(back=[0.0, 0.0, 0.0, 1.0])