diff --git a/util/test/rdtest/testcase.py b/util/test/rdtest/testcase.py index 9fe263632..adfaf9604 100644 --- a/util/test/rdtest/testcase.py +++ b/util/test/rdtest/testcase.py @@ -495,16 +495,84 @@ class TestCase: def evalute_source_var(self, sourceVar: rd.SourceVariableMapping, debugVars): debugged = rd.ShaderVariable() debugged.name = sourceVar.name - debugged.rowMajor = True debugged.type = sourceVar.type debugged.rows = sourceVar.rows debugged.columns = sourceVar.columns fv = [0.0] * 16 for i, debugVar in enumerate(sourceVar.variables): + debugged.rowMajor = debugVars[debugVar.name].rowMajor fv[i] = debugVars[debugVar.name].value.fv[debugVar.component] debugged.value.fv = fv return debugged + def combine_source_vars(self, vars): + NOT_FOUND = 100000 + + processed = [] + + # Keep looping until we're done + while len(vars) > 0: + # find the first member that contains a . or [ character in its name + base = '' + bare_array = False + first_var = len(vars) + for i,v in enumerate(vars): + idx = NOT_FOUND + if '.' in v.name: + idx = v.name.index('.') + if '[' in v.name: + idx2 = v.name.index('[') + if idx2 < idx: + if idx == NOT_FOUND: + bare_array = True + idx = idx2 + if idx2 == 0: + idx = v.name.index(']')+1 + + if idx == NOT_FOUND: + processed.append(v) + else: + first_var = i + base = v.name[:idx] + break + + del vars[0:first_var] + + # If no vars are found, we're done + if base == '': + continue + + members = [] + + combined = rd.ShaderVariable() + combined.name = base + + last_var = -1 + for i in range(len(vars)): + check = vars[i].name[:len(base)+1] + if check == base + '.' or check == base + '[': + last_var = i + v = vars[i] + v.name = v.name[len(base):] + if v.name[0] == '.': + v.name = v.name[1:] + combined.isStruct = True + if check == base + '.': + combined.isStruct = True + members.append(vars[i]) + + if not bare_array: + members = self.combine_source_vars(members) + combined.members = members + + del vars[0:last_var+1] + processed.append(combined) + + # Continue and combine the next set of vars (there could be multiple structs/arrays on the same level, + # and we only combined the first set) + + return processed + def check_export(self, capture_filename): recomp_path = util.get_tmp_path('recompressed.rdc') conv_zipxml_path = util.get_tmp_path('conv.zip.xml') diff --git a/util/test/tests/D3D11/D3D11_CBuffer_Zoo.py b/util/test/tests/D3D11/D3D11_CBuffer_Zoo.py index c26ce512b..b2c5ab099 100644 --- a/util/test/tests/D3D11/D3D11_CBuffer_Zoo.py +++ b/util/test/tests/D3D11/D3D11_CBuffer_Zoo.py @@ -23,6 +23,53 @@ class D3D11_CBuffer_Zoo(rdtest.TestCase): pipe.GetShaderEntryPoint(stage), 0, cbuf.resourceId, cbuf.byteOffset, cbuf.byteSize)) + self.check_cbuffer(var_check) + + rdtest.log.success("CBuffer variables are as expected") + + props: rd.APIProperties = self.controller.GetAPIProperties() + + if props.shaderDebugging: + trace: rd.ShaderDebugTrace = self.controller.DebugPixel(int(pipe.GetViewport(0).width / 2.0), + int(pipe.GetViewport(0).height / 2.0), + rd.ReplayController.NoPreference, + rd.ReplayController.NoPreference) + + debugVars = dict() + + for base in trace.constantBlocks: + for var in base.members: + debugVars[base.name + var.name] = var + + cbufferVars = [] + + for sourceVar in trace.sourceVars: + sourceVar: rd.SourceVariableMapping + + if sourceVar.variables[0].name not in debugVars.keys(): + continue + + eval: rd.ShaderVariable = self.evalute_source_var(sourceVar, debugVars) + cbufferVars.append(eval) + + cbufferVars = self.combine_source_vars(cbufferVars) + + self.check(len(cbufferVars) == 1) + self.check(cbufferVars[0].name == 'consts') + + var_check = rdtest.ConstantBufferChecker(cbufferVars[0].members) + + self.check_cbuffer(var_check) + + rdtest.log.success("Debugged CBuffer variables are as expected") + + self.controller.FreeTrace(trace) + + self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [512.1, 513.0, 514.0, 515.0]) + + rdtest.log.success("Picked value is as expected") + + def check_cbuffer(self, var_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 @@ -361,9 +408,3 @@ class D3D11_CBuffer_Zoo(rdtest.TestCase): var_check.check('test').rows(1).cols(4).value([512.0, 513.0, 514.0, 515.0]) var_check.done() - - rdtest.log.success("CBuffer variables are as expected") - - self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [512.1, 513.0, 514.0, 515.0]) - - rdtest.log.success("Picked value is as expected") diff --git a/util/test/tests/D3D12/D3D12_CBuffer_Zoo.py b/util/test/tests/D3D12/D3D12_CBuffer_Zoo.py index a2493fd84..34664aa07 100644 --- a/util/test/tests/D3D12/D3D12_CBuffer_Zoo.py +++ b/util/test/tests/D3D12/D3D12_CBuffer_Zoo.py @@ -45,6 +45,73 @@ class D3D12_CBuffer_Zoo(rdtest.TestCase): pipe.GetShaderEntryPoint(stage), 0, cbuf.resourceId, cbuf.byteOffset, cbuf.byteSize)) + cbuf: rd.BoundCBuffer = pipe.GetConstantBuffer(stage, 1, 0) + + root_check = rdtest.ConstantBufferChecker( + self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(), + pipe.GetShader(stage), + pipe.GetShaderEntryPoint(stage), 1, + cbuf.resourceId, cbuf.byteOffset, cbuf.byteSize)) + + cbuf: rd.BoundCBuffer = pipe.GetConstantBuffer(stage, 2, 0) + + huge_check = rdtest.ConstantBufferChecker( + self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(), + pipe.GetShader(stage), + pipe.GetShaderEntryPoint(stage), 2, + cbuf.resourceId, cbuf.byteOffset, cbuf.byteSize)) + + self.check_cbuffers(var_check, root_check, huge_check) + + rdtest.log.success("CBuffer variables are as expected") + + props: rd.APIProperties = self.controller.GetAPIProperties() + + if props.shaderDebugging: + trace: rd.ShaderDebugTrace = self.controller.DebugPixel(int(pipe.GetViewport(0).width / 2.0), + int(pipe.GetViewport(0).height / 2.0), + rd.ReplayController.NoPreference, + rd.ReplayController.NoPreference) + + debugVars = dict() + + for base in trace.constantBlocks: + for var in base.members: + debugVars[base.name + var.name] = var + + cbufferVars = [] + + for sourceVar in trace.sourceVars: + sourceVar: rd.SourceVariableMapping + + if sourceVar.variables[0].name not in debugVars.keys(): + continue + + eval: rd.ShaderVariable = self.evalute_source_var(sourceVar, debugVars) + cbufferVars.append(eval) + + cbufferVars = self.combine_source_vars(cbufferVars) + + self.check(len(cbufferVars) == 3) + self.check(cbufferVars[0].name == 'consts') + self.check(cbufferVars[1].name == 'rootconsts') + self.check(cbufferVars[2].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) + + rdtest.log.success("Debugged CBuffer variables are as expected") + + self.controller.FreeTrace(trace) + + self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [512.1, 513.0, 514.0, 515.0]) + + rdtest.log.success("Picked value is as expected") + + def check_cbuffers(self, var_check, root_check, huge_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 @@ -384,49 +451,31 @@ class D3D12_CBuffer_Zoo(rdtest.TestCase): var_check.done() - rdtest.log.success("CBuffer variables are as expected") - - self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [512.1, 513.0, 514.0, 515.0]) - - rdtest.log.success("Picked value is as expected") - - cbuf: rd.BoundCBuffer = pipe.GetConstantBuffer(stage, 1, 0) - - var_check = rdtest.ConstantBufferChecker( - self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(), - pipe.GetShader(stage), - pipe.GetShaderEntryPoint(stage), 1, - cbuf.resourceId, cbuf.byteOffset, cbuf.byteSize)) + rdtest.log.success("Base variables are as expected") # float4 zero; - var_check.check('root_zero').rows(1).cols(4).value([0.0, 0.0, 0.0, 0.0]) + root_check.check('root_zero').rows(1).cols(4).value([0.0, 0.0, 0.0, 0.0]) # float4 a; - var_check.check('root_a').rows(1).cols(4).value([10.0, 20.0, 30.0, 40.0]) + root_check.check('root_a').rows(1).cols(4).value([10.0, 20.0, 30.0, 40.0]) # float2 b; - var_check.check('root_b').rows(1).cols(2).value([50.0, 60.0]) + root_check.check('root_b').rows(1).cols(2).value([50.0, 60.0]) # float2 c; - var_check.check('root_c').rows(1).cols(2).value([70.0, 80.0]) + root_check.check('root_c').rows(1).cols(2).value([70.0, 80.0]) # float3_1 d; - var_check.check('root_d').rows(0).cols(0).structSize(2).members({ + root_check.check('root_d').rows(0).cols(0).structSize(2).members({ 'a': lambda y: y.rows(1).cols(3).value([90.0, 100.0, 110.0]), 'b': lambda y: y.rows(1).cols(1).value([120.0]), }) - var_check.done() + root_check.done() rdtest.log.success("Root signature variables are as expected") - cbuf: rd.BoundCBuffer = pipe.GetConstantBuffer(stage, 2, 0) - - var_check = rdtest.ConstantBufferChecker( - self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(), - pipe.GetShader(stage), - pipe.GetShaderEntryPoint(stage), 2, - cbuf.resourceId, cbuf.byteOffset, cbuf.byteSize)) - # float4 huge_val; - var_check.check('huge_val').rows(1).cols(4).value([64.0, 65.0, 66.0, 67.0]) + huge_check.check('huge_val').rows(1).cols(4).value([64.0, 65.0, 66.0, 67.0]) + + rdtest.log.success("Huge space variables are as expected")