diff --git a/renderdoc/driver/shaders/spirv/spirv_debug.cpp b/renderdoc/driver/shaders/spirv/spirv_debug.cpp index 358a045e6..44d33eae5 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug.cpp @@ -536,6 +536,73 @@ void ThreadState::StepNext(ShaderDebugState *state, break; } + case Op::CompositeInsert: + { + OpCompositeInsert insert(it); + + ShaderVariable var = GetSrc(insert.composite); + ShaderVariable obj = GetSrc(insert.object); + + // walk any struct member indices + ShaderVariable *mod = &var; + size_t i = 0; + while(i < insert.indexes.size() && !mod->members.empty()) + { + mod = &mod->members[insert.indexes[i]]; + i++; + } + + if(i == insert.indexes.size()) + { + // if there are no more indices, replace the object here + mod->value = obj.value; + } + else if(i + 1 == insert.indexes.size()) + { + // one more index + uint32_t idx = insert.indexes[i]; + + // if it's a matrix, replace a whole (column) vector + if(mod->rows > 1) + { + uint32_t column = idx; + + RDCASSERTEQUAL(mod->rows, obj.columns); + + for(uint32_t row = 0; row < mod->rows; row++) + { + if(VarTypeByteSize(mod->type) == 8) + mod->value.u64v[row * mod->columns + column] = obj.value.u64v[row]; + else + mod->value.uv[row * mod->columns + column] = obj.value.uv[row]; + } + } + else + { + // if it's a vector, replace one scalar + if(VarTypeByteSize(mod->type) == 8) + mod->value.u64v[idx] = obj.value.u64v[0]; + else + mod->value.uv[idx] = obj.value.uv[0]; + } + } + else if(i + 2 == insert.indexes.size()) + { + // two more indices, selecting column then scalar in a matrix + uint32_t column = insert.indexes[i]; + uint32_t row = insert.indexes[i + 1]; + + if(VarTypeByteSize(mod->type) == 8) + mod->value.u64v[row * mod->columns + column] = obj.value.u64v[0]; + else + mod->value.uv[row * mod->columns + column] = obj.value.uv[0]; + } + + // then evaluate it, to get the extracted value + SetDst(state, insert.result, var); + + break; + } case Op::CompositeConstruct: { OpCompositeConstruct construct(it); diff --git a/util/test/demos/vk/vk_shader_debug_zoo.cpp b/util/test/demos/vk/vk_shader_debug_zoo.cpp index fa547d9d8..256640346 100644 --- a/util/test/demos/vk/vk_shader_debug_zoo.cpp +++ b/util/test/demos/vk/vk_shader_debug_zoo.cpp @@ -310,6 +310,9 @@ void main() %v2f = OpTypeStruct %float2 %float2 %float2 %float %float %float %flatv2f = OpTypeStruct %uint %uint + %child = OpTypeStruct %float4 %float3 %float + %parent = OpTypeStruct %float4 %child %float4x4 + %_ptr_Input_v2f = OpTypePointer Input %v2f %_ptr_Input_flatv2f = OpTypePointer Input %flatv2f %_ptr_Input_uint = OpTypePointer Input %uint @@ -341,6 +344,8 @@ void main() %uint_4 = OpConstant %uint 4 %uint_15 = OpConstant %uint 15 +%empty_parent = OpConstantNull %parent + %uint_flt_1_234 = OpConstant %uint 0x3f9df3b6 %uint_0x1234 = OpConstant %uint 0x1234 %uint_0xb9c5 = OpConstant %uint 0xb9c5 @@ -578,15 +583,51 @@ void main() OpBranch %break %test_12 = OpLabel - ; once was a test of mod/rem with negative parameters, which is undefined. - ; This test is kept as a no-op to avoid needing to renumber everything below. - OpStore %Color %float_0000 + %a_12 = OpFAdd %float %zerof %float_15 + %b_12 = OpFAdd %float %zerof %float_4 + %c_12 = OpFAdd %float %zerof %float_neg4 + %d_12 = OpFAdd %float %zerof %float_1_234 + %vec0_12 = OpCompositeConstruct %float4 %zerof %zerof %zerof %zerof + %vec1_12 = OpCompositeInsert %float4 %a_12 %vec0_12 2 + %vec2_12 = OpCompositeInsert %float4 %b_12 %vec1_12 1 + %vec3_12 = OpCompositeInsert %float4 %c_12 %vec2_12 3 + %vec4_12 = OpCompositeInsert %float4 %d_12 %vec3_12 0 + OpStore %Color %vec4_12 OpBranch %break %test_13 = OpLabel - ; once was a test of mod/rem with negative parameters, which is undefined. - ; This test is kept as a no-op to avoid needing to renumber everything below. - OpStore %Color %float_0000 + %a_13 = OpFAdd %float %zerof %float_15 + %b_13 = OpFAdd %float %zerof %float_4 + %c_13 = OpFAdd %float %zerof %float_neg4 + %d_13 = OpFAdd %float %zerof %float_1_234 + + %vec4a_13 = OpCompositeConstruct %float4 %b_13 %d_13 %a_13 %c_13 + %vec3a_13 = OpCompositeConstruct %float3 %d_13 %c_13 %a_13 + + %vec4b_13 = OpVectorShuffle %float4 %vec4a_13 %vec4a_13 3 2 0 1 + %vec4c_13 = OpVectorShuffle %float4 %vec4a_13 %vec4a_13 0 1 3 2 + %vec4d_13 = OpVectorShuffle %float4 %vec4a_13 %vec4a_13 2 0 1 3 + %vec4e_13 = OpVectorShuffle %float4 %vec4a_13 %vec4a_13 3 1 2 0 + %vec4f_13 = OpVectorShuffle %float4 %vec4a_13 %vec4a_13 1 3 0 2 + + %parent1_13 = OpCompositeInsert %parent %vec4a_13 %empty_parent 0 + + %parent2_13 = OpCompositeInsert %parent %vec4b_13 %parent1_13 1 0 + %parent3_13 = OpCompositeInsert %parent %vec3a_13 %parent2_13 1 1 + %parent4_13 = OpCompositeInsert %parent %d_13 %parent3_13 1 2 + + %parent5_13 = OpCompositeInsert %parent %vec4c_13 %parent4_13 2 0 + %parent6_13 = OpCompositeInsert %parent %vec4d_13 %parent5_13 2 1 + %parent7_13 = OpCompositeInsert %parent %vec4e_13 %parent6_13 2 2 + %parent8_13 = OpCompositeInsert %parent %vec4f_13 %parent7_13 2 3 + + %x_13 = OpCompositeExtract %float %parent8_13 0 2 + %y_13 = OpCompositeExtract %float %parent8_13 2 1 3 + %z_13 = OpCompositeExtract %float %parent8_13 1 1 1 + %w_13 = OpCompositeExtract %float %parent8_13 1 0 2 + + %Color_13 = OpCompositeConstruct %float4 %x_13 %y_13 %z_13 %w_13 + OpStore %Color %Color_13 OpBranch %break ; test mod/rem with zeros