diff --git a/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp b/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp index b8ab3e8ec..555a88659 100644 --- a/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp +++ b/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp @@ -286,9 +286,15 @@ cbuffer consts : register(b0) float4 test; // {536, 537, 538, 539} }; +cbuffer packed_consts : register(b1) +{ + float col1z : packoffset(c1.z); // 4+2 + float col2w : packoffset(c2.w); // 8+3 +}; + float4 main() : SV_Target0 { - return test + float4(0.1f, 0.0f, 0.0f, 0.0f); + return test + col1z + float4(0.1f, 0.0f, 0.0f, 0.0f); } )EOSHADER"; @@ -312,8 +318,13 @@ float4 main() : SV_Target0 for(int i = 0; i < 512; i++) cbufferdata[i] = Vec4f(float(i * 4 + 0), float(i * 4 + 1), float(i * 4 + 2), float(i * 4 + 3)); + float packed_consts[12]; + for(int i = 0; i < 12; i++) + packed_consts[i] = (float)i; + ID3D11BufferPtr vb = MakeBuffer().Vertex().Data(DefaultTri); ID3D11BufferPtr cb = MakeBuffer().Constant().Data(cbufferdata); + ID3D11BufferPtr cb1 = MakeBuffer().Constant().Data(packed_consts); ID3D11Texture2DPtr fltTex = MakeTexture(DXGI_FORMAT_R32G32B32A32_FLOAT, screenWidth, screenHeight).RTV().SRV(); @@ -331,6 +342,7 @@ float4 main() : SV_Target0 ctx->PSSetShader(ps, NULL, 0); ctx->PSSetConstantBuffers(0, 1, &cb.GetInterfacePtr()); + ctx->PSSetConstantBuffers(1, 1, &cb1.GetInterfacePtr()); RSSetViewport({0.0f, 0.0f, (float)screenWidth, (float)screenHeight, 0.0f, 1.0f}); diff --git a/util/test/demos/d3d11/d3d11_shader_debug_zoo.cpp b/util/test/demos/d3d11/d3d11_shader_debug_zoo.cpp index 27095e568..e2a455f61 100644 --- a/util/test/demos/d3d11/d3d11_shader_debug_zoo.cpp +++ b/util/test/demos/d3d11/d3d11_shader_debug_zoo.cpp @@ -46,6 +46,12 @@ struct consts float negoneVal : NEGONE; }; +cbuffer packed_consts : register(b1) +{ + uint col1z : packoffset(c1.z); + uint col2w : packoffset(c2.w); +}; + struct v2f { float4 pos : SV_POSITION; @@ -816,6 +822,10 @@ float4 main(v2f IN) : SV_Target0 return structrwtest[z2+5].b; } + if(IN.tri == 98) + { + return float4(col1z, col2w, 1.0, 2.0); + } return float4(0.4f, 0.4f, 0.4f, 0.4f); } @@ -1139,6 +1149,13 @@ float4 main(v2f IN, uint samp : SV_SampleIndex) : SV_Target0 ctx->PSSetShaderResources(102, 1, &rgbsrv.GetInterfacePtr()); + float packed_consts[12]; + for(int i = 0; i < 12; i++) + packed_consts[i] = (float)i; + + ID3D11BufferPtr cb = MakeBuffer().Constant().Data(packed_consts); + ctx->PSSetConstantBuffers(1, 1, &cb.GetInterfacePtr()); + // Create resources for MSAA draw ID3DBlobPtr vsmsaablob = Compile(D3DDefaultVertex, "main", "vs_5_0"); ID3DBlobPtr psmsaablob = Compile(msaaPixel, "main", "ps_5_0"); diff --git a/util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp b/util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp index 2c1206aa7..b77958f3a 100644 --- a/util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp +++ b/util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp @@ -295,6 +295,19 @@ cbuffer rootconsts : register(b1) float3_1 root_d; }; +cbuffer packed_consts : register(b2) +{ + float col1z : packoffset(c1.z); // 4+2 + float col2w : packoffset(c2.w); // 8+3 +}; + +struct ArrayStruct +{ + float4 a; +}; + +ConstantBuffer array_consts[2] : register(b3); + cbuffer hugespace : register(b0, space999999999) { float4 huge_val; @@ -302,7 +315,7 @@ cbuffer hugespace : register(b0, space999999999) float4 main() : SV_Target0 { - return test + root_zero + huge_val * 1e-30f + float4(0.1f, 0.0f, 0.0f, 0.0f); + return test + root_zero + huge_val * 1e-30f + col1z + array_consts[0].a + array_consts[1].a + float4(0.1f, 0.0f, 0.0f, 0.0f); } )EOSHADER"; @@ -349,6 +362,21 @@ float4 main() : SV_Target0 cbufferdata[bindOffset + i] = Vec4f(float(i * 4 + 0), float(i * 4 + 1), float(i * 4 + 2), float(i * 4 + 3)); + float packed_consts[12]; + for(int i = 0; i < 12; i++) + packed_consts[i] = (float)i; + + struct AlignedCB + { + Vec4f col; + Vec4f padding[15]; + }; + static_assert(sizeof(AlignedCB) == 256, "Invalid alignment for CB data"); + + AlignedCB array_consts[2]; + for(uint32_t i = 0; i < 2; ++i) + array_consts[i].col = Vec4f(i / 1.0f, i + 1 / 1.0f, 0.5f, 0.5f); + RootData rootData = {}; rootData.root_a[0] = 10.0f; @@ -373,12 +401,18 @@ float4 main() : SV_Target0 ID3D12ResourcePtr vb = MakeBuffer().Data(DefaultTri); ID3D12ResourcePtr cb = MakeBuffer().Data(cbufferdata); + ID3D12ResourcePtr cbPacked = MakeBuffer().Data(packed_consts); + ID3D12ResourcePtr cbArray = MakeBuffer().Data(array_consts).Size(sizeof(AlignedCB) * 2); + for(uint32_t i = 0; i < 2; ++i) + MakeCBV(cbArray).SizeBytes(256).Offset(i * sizeof(AlignedCB)).CreateGPU(i); ID3D12RootSignaturePtr sig = MakeSig({ cbvParam(D3D12_SHADER_VISIBILITY_PIXEL, 0, 7), constParam(D3D12_SHADER_VISIBILITY_VERTEX, 0, 1, sizeof(rootData) / sizeof(uint32_t)), constParam(D3D12_SHADER_VISIBILITY_PIXEL, 0, 1, sizeof(rootData) / sizeof(uint32_t)), constParam(D3D12_SHADER_VISIBILITY_GEOMETRY, 0, 1, sizeof(rootData) / sizeof(uint32_t)), + cbvParam(D3D12_SHADER_VISIBILITY_PIXEL, 0, 2), + tableParam(D3D12_SHADER_VISIBILITY_PIXEL, D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 0, 3, 2, 0), cbvParam(D3D12_SHADER_VISIBILITY_PIXEL, 999999999, 0), }); @@ -400,6 +434,10 @@ float4 main() : SV_Target0 ResourceBarrier(vb, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER); ResourceBarrier(cb, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER); + ResourceBarrier(cbPacked, D3D12_RESOURCE_STATE_COMMON, + D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER); + ResourceBarrier(cbArray, D3D12_RESOURCE_STATE_COMMON, + D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER); ID3D12ResourcePtr rtvtex = MakeTexture(DXGI_FORMAT_R32G32B32A32_FLOAT, screenWidth, screenHeight) .RTV() @@ -427,13 +465,16 @@ float4 main() : SV_Target0 IASetVertexBuffer(cmd, vb, sizeof(DefaultA2V), 0); cmd->SetPipelineState(dxbcpso); cmd->SetGraphicsRootSignature(sig); + cmd->SetDescriptorHeaps(1, &m_CBVUAVSRV.GetInterfacePtr()); cmd->SetGraphicsRootConstantBufferView( 0, cb->GetGPUVirtualAddress() + bindOffset * sizeof(Vec4f)); cmd->SetGraphicsRoot32BitConstants(1, sizeof(emptyRoot) / sizeof(uint32_t), &emptyRoot, 0); cmd->SetGraphicsRoot32BitConstants(2, sizeof(rootData) / sizeof(uint32_t), &rootData, 0); cmd->SetGraphicsRoot32BitConstants(3, sizeof(emptyRoot) / sizeof(uint32_t), &emptyRoot, 0); + cmd->SetGraphicsRootConstantBufferView(4, cbPacked->GetGPUVirtualAddress()); + cmd->SetGraphicsRootDescriptorTable(5, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart()); cmd->SetGraphicsRootConstantBufferView( - 4, cb->GetGPUVirtualAddress() + bindOffset * sizeof(Vec4f) + 256); + 6, cb->GetGPUVirtualAddress() + bindOffset * sizeof(Vec4f) + 256); RSSetViewport(cmd, {0.0f, 0.0f, (float)screenWidth, (float)screenHeight, 0.0f, 1.0f}); RSSetScissorRect(cmd, {0, 0, screenWidth, screenHeight}); diff --git a/util/test/demos/d3d12/d3d12_shader_debug_zoo.cpp b/util/test/demos/d3d12/d3d12_shader_debug_zoo.cpp index 222106ea0..5814b0cbc 100644 --- a/util/test/demos/d3d12/d3d12_shader_debug_zoo.cpp +++ b/util/test/demos/d3d12/d3d12_shader_debug_zoo.cpp @@ -1104,6 +1104,12 @@ cbuffer consts : register(b0) double doubleX; }; +cbuffer packed_consts : register(b1) +{ + uint col1z : packoffset(c1.z); + uint col2w : packoffset(c2.w); +}; + RWStructuredBuffer bufIn : register(u0); RWStructuredBuffer bufOut : register(u1); @@ -1152,6 +1158,12 @@ void main(int3 inTestIndex : SV_GroupID) testResult.z = gsmStruct[gsmInt * 4].a.y; testResult.w = gsmInt2DArray[ZERO][idx] + gsmInt2DArray[ONE][idx]; } + else if (testIndex == 2) + { + testResult = bufOut[0]; + testResult.x += bufIn[0].x * (uint)col1z; + testResult.y += bufIn[0].y * (uint)col2w; + } else { testResult.x = inTestIndex.x; @@ -1890,6 +1902,7 @@ void main(int3 inTestIndex : SV_GroupID) uavParam(D3D12_SHADER_VISIBILITY_ALL, 0, 0), uavParam(D3D12_SHADER_VISIBILITY_ALL, 0, 1), constParam(D3D12_SHADER_VISIBILITY_ALL, 0, 0, 4), + constParam(D3D12_SHADER_VISIBILITY_ALL, 0, 1, 12), tableParam(D3D12_SHADER_VISIBILITY_ALL, D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 0, 2, 1, 3), }); @@ -2123,7 +2136,9 @@ void main(int3 inTestIndex : SV_GroupID) cmd->SetComputeRoot32BitConstant(2, 6, 1); cmd->SetComputeRoot32BitConstant(2, 7, 2); cmd->SetComputeRoot32BitConstant(2, 8, 3); - cmd->SetComputeRootDescriptorTable(3, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart()); + cmd->SetComputeRoot32BitConstant(3, 10, 4 + 2); // col1z + cmd->SetComputeRoot32BitConstant(3, 11, 8 + 3); // col2w + cmd->SetComputeRootDescriptorTable(4, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart()); cmd->SetPipelineState(computePSOs[i]); setMarker(cmd, computeSMs[i]); diff --git a/util/test/tests/D3D11/D3D11_CBuffer_Zoo.py b/util/test/tests/D3D11/D3D11_CBuffer_Zoo.py index 4f1b8862b..5893198f3 100644 --- a/util/test/tests/D3D11/D3D11_CBuffer_Zoo.py +++ b/util/test/tests/D3D11/D3D11_CBuffer_Zoo.py @@ -23,7 +23,12 @@ class D3D11_CBuffer_Zoo(rdtest.TestCase): pipe.GetShaderEntryPoint(stage), 0, cbuf.resource, cbuf.byteOffset, cbuf.byteSize)) - self.check_cbuffer(var_check) + packed_check = rdtest.ConstantBufferChecker( + self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(), + pipe.GetShader(stage), stage, + pipe.GetShaderEntryPoint(stage), 1, + cbuf.resource, cbuf.byteOffset, cbuf.byteSize)) + self.check_cbuffer(var_check, packed_check) rdtest.log.success("CBuffer variables are as expected") @@ -52,12 +57,12 @@ class D3D11_CBuffer_Zoo(rdtest.TestCase): cbufferVars = self.combine_source_vars(cbufferVars) - self.check(len(cbufferVars) == 1) + self.check(len(cbufferVars) == 2) self.check(cbufferVars[0].name == 'consts') - + self.check(cbufferVars[1].name == 'packed_consts') var_check = rdtest.ConstantBufferChecker(cbufferVars[0].members) - - self.check_cbuffer(var_check) + packed_check = rdtest.ConstantBufferChecker(cbufferVars[1].members) + self.check_cbuffer(var_check, packed_check) rdtest.log.success("Debugged CBuffer variables are as expected") @@ -67,20 +72,20 @@ class D3D11_CBuffer_Zoo(rdtest.TestCase): debugged = self.evaluate_source_var(output, variables) - if not rdtest.util.value_compare(debugged.value.f32v[0:4], [536.1, 537.0, 538.0, 539.0]): + if not rdtest.util.value_compare(debugged.value.f32v[0:4], [542.1, 543.0, 544.0, 545.0]): raise rdtest.TestFailureException( "Debugged output {} did not match expected {}".format( - debugged.value.f32v[0:4], [536.1, 537.0, 538.0, 539.0])) + debugged.value.f32v[0:4], [542.1, 543.0, 544.0, 545.0])) rdtest.log.success("Debugged output matched as expected") self.controller.FreeTrace(trace) - self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 0.5, 0.5, [536.1, 537.0, 538.0, 539.0]) + self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 0.5, 0.5, [542.1, 543.0, 544.0, 545.0]) rdtest.log.success("Picked value is as expected") - def check_cbuffer(self, var_check): + def check_cbuffer(self, var_check, packed_check): # For more detailed reference for the below checks, see the commented definition of the cbuffer # in the shader source code in the demo itself @@ -441,3 +446,7 @@ class D3D11_CBuffer_Zoo(rdtest.TestCase): var_check.check('test').rows(1).cols(4).value([536.0, 537.0, 538.0, 539.0]) var_check.done() + + packed_check.check('col1z').rows(1).cols(1).value([6.0]) + packed_check.check('col2w').rows(1).cols(1).value([11.0]) + packed_check.done() diff --git a/util/test/tests/D3D12/D3D12_CBuffer_Zoo.py b/util/test/tests/D3D12/D3D12_CBuffer_Zoo.py index f194e1b7d..f16744273 100644 --- a/util/test/tests/D3D12/D3D12_CBuffer_Zoo.py +++ b/util/test/tests/D3D12/D3D12_CBuffer_Zoo.py @@ -73,10 +73,12 @@ class D3D12_CBuffer_Zoo(rdtest.TestCase): refl: rd.ShaderReflection = pipe.GetShaderReflection(stage) - # Make sure we have three constant buffers - b7 normal, b1 root constants, and space9999999:b0 + # Make sure we have five constant buffers - b7 normal, b1 root constants, b2, b3 and space9999999:b0 binds = [ (0, 7), (0, 1), + (0, 2), + (0, 3), (999999999, 0), ] @@ -106,18 +108,47 @@ class D3D12_CBuffer_Zoo(rdtest.TestCase): pipe.GetShaderEntryPoint(stage), 1, cbuf.resource, cbuf.byteOffset, cbuf.byteSize)) - cbuf = pipe.GetConstantBlock(stage, 2, 0).descriptor + cbuf = pipe.GetConstantBlock(stage, 4, 0).descriptor huge_check = rdtest.ConstantBufferChecker( + self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(), + pipe.GetShader(stage), stage, + pipe.GetShaderEntryPoint(stage), 4, + cbuf.resource, cbuf.byteOffset, cbuf.byteSize)) + + cbuf = pipe.GetConstantBlock(stage, 2, 0).descriptor + + packed_check = rdtest.ConstantBufferChecker( self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(), pipe.GetShader(stage), stage, pipe.GetShaderEntryPoint(stage), 2, cbuf.resource, cbuf.byteOffset, cbuf.byteSize)) - self.check_cbuffers(var_check, root_check, huge_check) - + self.check_cbuffers(var_check, root_check, huge_check, packed_check) rdtest.log.success("CBuffer variables are as expected") + cbuf = pipe.GetConstantBlock(stage, 3, 0).descriptor + arrays_check = rdtest.ConstantBufferChecker( + self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(), + pipe.GetShader(stage), stage, + pipe.GetShaderEntryPoint(stage), 3, + cbuf.resource, cbuf.byteOffset, cbuf.byteSize)) + arrays_check.check('array_consts').rows(0).cols(0).structSize(1).members({ + 'a' : lambda y : y.rows(1).cols(4).value([0.0, 1.0, 0.5, 0.5])}) + arrays_check.done() + + cbuf = pipe.GetConstantBlock(stage, 3, 1).descriptor + arrays_check = rdtest.ConstantBufferChecker( + self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(), + pipe.GetShader(stage), stage, + pipe.GetShaderEntryPoint(stage), 3, + cbuf.resource, cbuf.byteOffset, cbuf.byteSize)) + arrays_check.check('array_consts').rows(0).cols(0).structSize(1).members({ + 'a' : lambda y : y.rows(1).cols(4).value([1.0, 2.0, 0.5, 0.5])}) + arrays_check.done() + + rdtest.log.success("Array cbuffer variables are as expected") + if self.controller.GetAPIProperties().shaderDebugging and pipe.GetShaderReflection( rd.ShaderStage.Pixel).debugInfo.debuggable: trace: rd.ShaderDebugTrace = self.controller.DebugPixel(int(pipe.GetViewport(0).width / 2.0), @@ -143,39 +174,49 @@ class D3D12_CBuffer_Zoo(rdtest.TestCase): cbufferVars = self.combine_source_vars(cbufferVars) - self.check(len(cbufferVars) == 3) + self.check(len(cbufferVars) == 5) self.check(cbufferVars[0].name == 'consts') self.check(cbufferVars[1].name == 'rootconsts') - self.check(cbufferVars[2].name == 'hugespace') + self.check(cbufferVars[2].name == 'packed_consts') + self.check(cbufferVars[3].name == 'array_consts') + self.check(cbufferVars[4].name == 'hugespace') var_check = rdtest.ConstantBufferChecker(cbufferVars[0].members) root_check = rdtest.ConstantBufferChecker(cbufferVars[1].members) - huge_check = rdtest.ConstantBufferChecker(cbufferVars[2].members) - - self.check_cbuffers(var_check, root_check, huge_check) + packed_check = rdtest.ConstantBufferChecker(cbufferVars[2].members) + arrays_check = rdtest.ConstantBufferChecker(cbufferVars[3].members) + huge_check = rdtest.ConstantBufferChecker(cbufferVars[4].members) + self.check_cbuffers(var_check, root_check, huge_check, packed_check) rdtest.log.success("Debugged CBuffer variables are as expected") + arrays_check.check('[0]').rows(0).cols(0).members({ + 'a' : lambda y : y.rows(1).cols(4).value([0.0, 1.0, 0.5, 0.5])}) + arrays_check.check('[1]').rows(0).cols(0).members({ + 'a' : lambda y : y.rows(1).cols(4).value([1.0, 2.0, 0.5, 0.5])}) + arrays_check.done() + rdtest.log.success("Array cbuffer variables are as expected") + cycles, variables = self.process_trace(trace) output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0) debugged = self.evaluate_source_var(output, variables) - if not rdtest.util.value_compare(debugged.value.f32v[0:4], [536.1, 537.0, 538.0, 539.0]): + if not rdtest.util.value_compare(debugged.value.f32v[0:4], [543.1, 546.0, 545.0, 546.0]): raise rdtest.TestFailureException( "Debugged output {} did not match expected {}".format( - debugged.value.f32v[0:4], [536.1, 537.0, 538.0, 539.0])) + debugged.value.f32v[0:4], [543.1, 546.0, 545.0, 546.0])) rdtest.log.success("Debugged output matched as expected") self.controller.FreeTrace(trace) - self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 0.5, 0.5, [536.1, 537.0, 538.0, 539.0]) + self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 0.5, 0.5, [543.1, 546.0, 545.0, 546.0]) rdtest.log.success("Picked value is as expected") - def check_cbuffers(self, var_check, root_check, huge_check): + def check_cbuffers(self, var_check, root_check, huge_check, packed_check): # For more detailed reference for the below checks, see the commented definition of the cbuffer # in the shader source code in the demo itself @@ -565,5 +606,13 @@ class D3D12_CBuffer_Zoo(rdtest.TestCase): # float4 huge_val; huge_check.check('huge_val').rows(1).cols(4).value([64.0, 65.0, 66.0, 67.0]) + huge_check.done() rdtest.log.success("Huge space variables are as expected") + + packed_check.check('col1z').rows(1).cols(1).value([6.0]) + packed_check.check('col2w').rows(1).cols(1).value([11.0]) + packed_check.done() + + rdtest.log.success("Packed cbuffer variables are as expected") +