diff --git a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp index 4e7d484cd..c9902782f 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp @@ -120,6 +120,11 @@ void Debugger::MakeSignatureNames(const rdcarray &sigList, name += StringFormat::Fmt("._child%u", chain); type = &dataTypes[type->children[chain].type]; } + else if(type->type == DataType::MatrixType) + { + name += StringFormat::Fmt(".col%u", chain); + type = &dataTypes[type->InnerType()]; + } else { RDCERR("Got access chain with non-aggregate type in interface."); @@ -1649,6 +1654,10 @@ uint32_t Debugger::AllocateVariable(const Decorations &varDecorations, const Decorations &typeDecorations = decorations[inType.id]; uint32_t location = 0; + // if this is a top-level array, don't pass the decorations down and let each child get an + // explicit offset, otherwise each child will consume the same location + const Decorations &childDecorations = + curDecorations.flags & Decorations::HasLocation ? Decorations() : curDecorations; ShaderVariable len = GetActiveLane().ids[inType.length]; for(uint32_t i = 0; i < len.value.u.x; i++) @@ -1656,8 +1665,9 @@ uint32_t Debugger::AllocateVariable(const Decorations &varDecorations, rdcstr idx = StringFormat::Fmt("[%u]", i); ShaderVariable var; var.name = outVar.name + idx; + uint32_t locations = - AllocateVariable(varDecorations, curDecorations, sourceVarType, sourceName + idx, + AllocateVariable(varDecorations, childDecorations, sourceVarType, sourceName + idx, location + offset, dataTypes[inType.InnerType()], var); if(genLocations) diff --git a/renderdoc/driver/shaders/spirv/spirv_reflect.cpp b/renderdoc/driver/shaders/spirv/spirv_reflect.cpp index 09042248e..8f67d8ad9 100644 --- a/renderdoc/driver/shaders/spirv/spirv_reflect.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_reflect.cpp @@ -1157,6 +1157,9 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st if(a.regIndex != b.regIndex) return a.regIndex < b.regIndex; + if(a.regChannelMask != b.regChannelMask) + return a.regChannelMask < b.regChannelMask; + return a.varName < b.varName; } if(a.systemValue == ShaderBuiltin::Undefined) @@ -1596,6 +1599,12 @@ void Reflector::AddSignatureParameter(const bool isInput, const ShaderStage stag sig.regChannelMask = sig.channelUsedMask = (1 << sig.compCount) - 1; + for(const DecorationAndParamData &d : varDecorations.others) + if(d.value == Decoration::Component) + sig.regChannelMask <<= d.component; + + sig.channelUsedMask = sig.regChannelMask; + for(uint32_t a = 0; a < arraySize; a++) { rdcstr n = varName; diff --git a/renderdoc/driver/vulkan/vk_shaderdebug.cpp b/renderdoc/driver/vulkan/vk_shaderdebug.cpp index 30019edb4..3121151fa 100644 --- a/renderdoc/driver/vulkan/vk_shaderdebug.cpp +++ b/renderdoc/driver/vulkan/vk_shaderdebug.cpp @@ -395,12 +395,34 @@ public: return; } - // TODO handle components - RDCASSERT(component == 0); - if(location < location_inputs.size()) { - var.value = location_inputs[location].value; + const uint32_t typeSize = VarTypeByteSize(var.type); + if(var.rows == 1) + { + if(component > 3) + RDCERR("Unexpected component %u ", component); + + if(typeSize == 8) + memcpy(var.value.u64v, &location_inputs[location].value.u64v[component], + var.rows * var.columns * typeSize); + else + memcpy(var.value.uv, &location_inputs[location].value.uv[component], + var.rows * var.columns * typeSize); + } + else + { + for(uint8_t r = 0; r < var.rows; r++) + { + for(uint8_t c = 0; c < var.columns; c++) + { + if(typeSize == 8) + var.value.u64v[r * var.columns + c] = location_inputs[location + c].value.u64v[r]; + else + var.value.uv[r * var.columns + c] = location_inputs[location + c].value.uv[r]; + } + } + } return; } @@ -421,11 +443,43 @@ public: return DerivativeDeltas(); } - // TODO handle components - RDCASSERT(component == 0); - if(location < location_derivatives.size()) - return location_derivatives[location]; + { + const DerivativeDeltas &deriv = location_derivatives[location]; + + DerivativeDeltas ret; + if(component == 0) + { + ret = deriv; + } + else if(component == 1) + { + memcpy(&ret.ddxcoarse.x, &deriv.ddxcoarse.y, sizeof(Vec3f)); + memcpy(&ret.ddxfine.x, &deriv.ddxfine.y, sizeof(Vec3f)); + memcpy(&ret.ddycoarse.x, &deriv.ddycoarse.y, sizeof(Vec3f)); + memcpy(&ret.ddyfine.x, &deriv.ddyfine.y, sizeof(Vec3f)); + } + else if(component == 2) + { + memcpy(&ret.ddxcoarse.x, &deriv.ddxcoarse.z, sizeof(Vec2f)); + memcpy(&ret.ddxfine.x, &deriv.ddxfine.z, sizeof(Vec2f)); + memcpy(&ret.ddycoarse.x, &deriv.ddycoarse.z, sizeof(Vec2f)); + memcpy(&ret.ddyfine.x, &deriv.ddyfine.z, sizeof(Vec2f)); + } + else if(component == 3) + { + ret.ddxcoarse.x = deriv.ddxcoarse.w; + ret.ddxfine.x = deriv.ddxfine.w; + ret.ddycoarse.x = deriv.ddycoarse.w; + ret.ddyfine.x = deriv.ddyfine.w; + } + else + { + RDCERR("Unexpected component %u", component); + } + + return ret; + } RDCERR("Couldn't get derivative for location=%u, component=%u", location, component); return DerivativeDeltas(); @@ -3885,11 +3939,15 @@ ShaderDebugTrace *VulkanReplay::DebugPixel(uint32_t eventId, uint32_t x, uint32_ builtin ? apiWrapper->builtin_derivatives[param.systemValue] : apiWrapper->location_derivatives[param.regIndex]; - memcpy(&var.value.uv, &value[i], sizeof(Vec4f)); - memcpy(&deriv.ddxcoarse, &ddxcoarse[i], sizeof(Vec4f)); - memcpy(&deriv.ddycoarse, &ddycoarse[i], sizeof(Vec4f)); - memcpy(&deriv.ddxfine, &ddxfine[i], sizeof(Vec4f)); - memcpy(&deriv.ddyfine, &ddyfine[i], sizeof(Vec4f)); + uint32_t comp = Bits::CountTrailingZeroes(uint32_t(param.regChannelMask)); + + const size_t sz = sizeof(Vec4f) - sizeof(uint32_t) * comp; + + memcpy(((uint32_t *)&var.value.uv) + comp, &value[i], sz); + memcpy(((uint32_t *)&deriv.ddxcoarse.x) + comp, &ddxcoarse[i], sz); + memcpy(((uint32_t *)&deriv.ddycoarse.x) + comp, &ddycoarse[i], sz); + memcpy(((uint32_t *)&deriv.ddxfine.x) + comp, &ddxfine[i], sz); + memcpy(((uint32_t *)&deriv.ddyfine.x) + comp, &ddyfine[i], sz); } ret = debugger->BeginDebug(apiWrapper, ShaderStage::Pixel, entryPoint, spec, diff --git a/util/test/demos/vk/vk_shader_debug_zoo.cpp b/util/test/demos/vk/vk_shader_debug_zoo.cpp index ab650f21c..28dad0e96 100644 --- a/util/test/demos/vk/vk_shader_debug_zoo.cpp +++ b/util/test/demos/vk/vk_shader_debug_zoo.cpp @@ -35,6 +35,7 @@ RD_TEST(VK_Shader_Debug_Zoo, VulkanGraphicsTest) float zero; float one; float negone; + Vec2f uv; }; std::string v2f = @@ -154,6 +155,9 @@ layout(set = 0, binding = 21) uniform sampler2DMSArray queryTestMS; layout(push_constant) uniform PushData { layout(offset = 16) ivec4 data; } push; +)EOSHADER"; + + std::string pixel_glsl1 = pixel_glsl_header + R"EOSHADER( layout(location = 0, index = 0) out vec4 Color; @@ -161,9 +165,6 @@ layout(location = 0, index = 0) out vec4 Color; )EOSHADER" + v2f + R"EOSHADER( -)EOSHADER"; - - std::string pixel_glsl1 = pixel_glsl_header + R"EOSHADER( void main() { float posinf = linearData.oneVal/linearData.zeroVal.x; @@ -499,7 +500,7 @@ void main() break; } )EOSHADER" - R"EOSHADER( + R"EOSHADER( case 51: { Color = fwidthFine(vec4(inpos, inposIncreased)); @@ -866,7 +867,7 @@ void main() break; } )EOSHADER" - R"EOSHADER( + R"EOSHADER( case 102: { uint a = zerou + 0x0dadbeef; @@ -1102,14 +1103,100 @@ void main() )EOSHADER"; - std::string pixel_glsl2 = pixel_glsl_header + R"EOSHADER( + std::string vertex2 = R"EOSHADER( +#version 460 core + +layout(location = 0) in vec4 pos; +layout(location = 1) in float zero; +layout(location = 2) in float one; +layout(location = 3) in float negone; +layout(location = 4) in vec2 texcoord; + +layout(location = 0, component = 0) flat out uint test; +layout(location = 0, component = 1) flat out int zeroi; +layout(location = 0, component = 2) flat out uint intval; + +layout(location = 1, component = 1) out vec3 uv; + +struct nested +{ + float c; // location 4 + vec2 d; // location 5 +}; + +struct iostruct +{ + float a; // location 2 + float b; // location 3 + nested n; +}; + +layout(location = 2) out iostruct str; + +layout(location = 6) out mat3 matrix; + +layout(location = 9) out vec3 arr[3]; + void main() { - uint test = flatData.test; - int intval = int(flatData.intval); - uint zerou = flatData.intval - flatData.test - 7u; - int zeroi = int(zerou); + test = gl_InstanceIndex; + + gl_Position = vec4(pos.x + pos.z * float(test % 256), pos.y + pos.w * float(test / 256), 0.0, 1.0); + zeroi = 0; + intval = test + 7u; + + uv = vec3(texcoord.xy, pos.x); + + vec4 test = vec4(uv.x + 1.0f, uv.y + 2.0f, uv.x + 3.0f, uv.y + 4.0f); + + str.a = test.x; + str.b = test.y; + str.n.c = test.z; + str.n.d = vec2(test.w, 3.141592f); + + test *= 1.5f; + + matrix = mat3((test * 2.0f).xyz, (test * 3.0f).xyz, (test * 4.0f).xyz); + + arr[0] = (test * 5.0f).yzw; + arr[1] = (test * 6.0f).yzw; + arr[2] = (test * 7.0f).yzw; +} + +)EOSHADER"; + + std::string pixel_glsl2 = pixel_glsl_header + R"EOSHADER( + +layout(location = 0, component = 0) flat in uint test; +layout(location = 0, component = 1) flat in int zeroi; +layout(location = 0, component = 2) flat in uint intval; + +layout(location = 1, component = 1) in vec3 uv; + +struct nested +{ + float c; // location 4 + vec2 d; // location 5 +}; + +struct iostruct +{ + float a; // location 2 + float b; // location 3 + nested n; +}; + +layout(location = 2) in iostruct str; + +layout(location = 6) in mat3 matrix; + +layout(location = 9) in vec3 arr[3]; + +layout(location = 0) out vec4 Color; + +void main() +{ Color = vec4(0,0,0,0); switch(test) { @@ -1128,7 +1215,7 @@ void main() case 2: { // test loading from the storage buffer (after a nice big barrier) - Color = storebuf.arr[flatData.intval - flatData.test]; + Color = storebuf.arr[intval - test]; break; } case 3: @@ -1136,6 +1223,51 @@ void main() Color = imageLoad(storeImage, ivec2(zeroi+1,zeroi+3)); break; } + case 4: + { + Color = vec4(test, zeroi, intval, 1.0f); + break; + } + case 5: + { + Color = vec4(uv.xyz, 1.0f); + break; + } + case 6: + { + Color = vec4(str.a, str.b, str.n.c, length(str.n.d)); + break; + } + case 7: + { + Color = matrix[0].xyzx; + break; + } + case 8: + { + Color = matrix[1].xyzx; + break; + } + case 9: + { + Color = matrix[2].xyzx; + break; + } + case 10: + { + Color = arr[0].xyzx; + break; + } + case 11: + { + Color = arr[1].xyzx; + break; + } + case 12: + { + Color = arr[2].xyzx; + break; + } default: break; } } @@ -2490,6 +2622,7 @@ OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = { vkh::vertexAttr(0, 0, ConstsA2V, pos), vkh::vertexAttr(1, 0, ConstsA2V, zero), vkh::vertexAttr(2, 0, ConstsA2V, one), vkh::vertexAttr(3, 0, ConstsA2V, negone), + vkh::vertexAttr(4, 0, ConstsA2V, uv), }; pipeCreateInfo.stages = { @@ -2499,8 +2632,10 @@ OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource VkPipeline glslpipe1 = createGraphicsPipeline(pipeCreateInfo); - pipeCreateInfo.stages[1] = - CompileShaderModule(pixel_glsl2, ShaderLang::glsl, ShaderStage::frag, "main"); + pipeCreateInfo.stages = { + CompileShaderModule(vertex2, ShaderLang::glsl, ShaderStage::vert, "main"), + CompileShaderModule(pixel_glsl2, ShaderLang::glsl, ShaderStage::frag, "main"), + }; VkPipeline glslpipe2 = createGraphicsPipeline(pipeCreateInfo); @@ -2511,8 +2646,11 @@ OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource if(vk_version >= 0x12) target = SPIRVTarget::vulkan12; - pipeCreateInfo.stages[1] = CompileShaderModule(make_pixel_asm(), ShaderLang::spvasm, - ShaderStage::frag, "main", {}, target); + pipeCreateInfo.stages = { + CompileShaderModule(vertex, ShaderLang::glsl, ShaderStage::vert, "main"), + CompileShaderModule(make_pixel_asm(), ShaderLang::spvasm, ShaderStage::frag, "main", {}, + target), + }; VkPipeline asmpipe = createGraphicsPipeline(pipeCreateInfo); @@ -2520,9 +2658,9 @@ OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource float triHeight = 8.0f / float(texHeight); ConstsA2V triangle[] = { - {Vec4f(-1.0f, -1.0f, triWidth, triHeight), 0.0f, 1.0f, -1.0f}, - {Vec4f(-1.0f + triWidth, -1.0f, triWidth, triHeight), 0.0f, 1.0f, -1.0f}, - {Vec4f(-1.0f, -1.0f + triHeight, triWidth, triHeight), 0.0f, 1.0f, -1.0f}, + {Vec4f(-1.0f, -1.0f, triWidth, triHeight), 0.0f, 1.0f, -1.0f, Vec2f(0.0f, 0.0f)}, + {Vec4f(-1.0f + triWidth, -1.0f, triWidth, triHeight), 0.0f, 1.0f, -1.0f, Vec2f(1.0f, 0.0f)}, + {Vec4f(-1.0f, -1.0f + triHeight, triWidth, triHeight), 0.0f, 1.0f, -1.0f, Vec2f(0.0f, 1.0f)}, }; AllocatedBuffer vb(this,