From 48a24a31e498f5880091f3db54c60471ae7535a8 Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 20 Mar 2020 10:25:24 +0000 Subject: [PATCH] Implement location assignment for struct members on I/O variables --- renderdoc/driver/shaders/spirv/spirv_debug.h | 6 +-- .../shaders/spirv/spirv_debug_setup.cpp | 48 ++++++++++++------- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/renderdoc/driver/shaders/spirv/spirv_debug.h b/renderdoc/driver/shaders/spirv/spirv_debug.h index e1b54e916..5af6d45f6 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug.h +++ b/renderdoc/driver/shaders/spirv/spirv_debug.h @@ -169,9 +169,9 @@ private: virtual void PostParse(); virtual void RegisterOp(Iter it); - void AllocateVariable(const Decorations &varDecorations, const Decorations &curDecorations, - DebugVariableType sourceVarType, const rdcstr &sourceName, uint32_t offset, - const DataType &inType, ShaderVariable &outVar); + uint32_t AllocateVariable(const Decorations &varDecorations, const Decorations &curDecorations, + DebugVariableType sourceVarType, const rdcstr &sourceName, + uint32_t offset, const DataType &inType, ShaderVariable &outVar); void AddSourceVars(rdcarray &sourceVars, const DataType &inType, const rdcstr &sourceName, const rdcstr &varName, uint32_t &offset); void MakeSignatureNames(const rdcarray &sigList, rdcarray &sigNames); diff --git a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp index 16479ce95..f1d8986e6 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp @@ -266,15 +266,9 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader isInput ? DebugVariableType::Input : DebugVariableType::Variable, sourceName, 0, dataTypes[type.InnerType()], var); - // I/O variable structs don't have offsets, so give them fake offsets to ensure they sort as - // we want. Since FillVariable is depth-first the source vars are already in order. - // We also add the signature index for(size_t i = oldSize; i < globalSourceVars.size(); i++) - { - globalSourceVars[i].offset = uint32_t(i - oldSize); globalSourceVars[i].signatureIndex = (isInput ? inputSigNames : outputSigNames).indexOf(globalSourceVars[i].variables[0].name); - } if(isInput) { @@ -857,16 +851,19 @@ void Debugger::AllocateVariable(Id id, Id typeId, DebugVariableType sourceVarTyp dataTypes[dataTypes[typeId].InnerType()], outVar); } -void Debugger::AllocateVariable(const Decorations &varDecorations, const Decorations &curDecorations, - DebugVariableType sourceVarType, const rdcstr &sourceName, - uint32_t offset, const DataType &inType, ShaderVariable &outVar) +uint32_t Debugger::AllocateVariable(const Decorations &varDecorations, + const Decorations &curDecorations, + DebugVariableType sourceVarType, const rdcstr &sourceName, + uint32_t offset, const DataType &inType, ShaderVariable &outVar) { + const bool genLocations = (varDecorations.flags & Decorations::HasLocation) != 0; + switch(inType.type) { case DataType::PointerType: { RDCERR("Pointers not supported in interface variables"); - return; + return 0; } case DataType::ScalarType: { @@ -891,6 +888,7 @@ void Debugger::AllocateVariable(const Decorations &varDecorations, const Decorat } case DataType::StructType: { + uint32_t location = 0; for(int32_t i = 0; i < inType.children.count(); i++) { ShaderVariable var; @@ -909,28 +907,38 @@ void Debugger::AllocateVariable(const Decorations &varDecorations, const Decorat if(childDecorations.flags & Decorations::HasOffset) childOffset += childDecorations.offset; - AllocateVariable(varDecorations, childDecorations, sourceVarType, childName, childOffset, - dataTypes[inType.children[i].type], var); + uint32_t locations = + AllocateVariable(varDecorations, childDecorations, sourceVarType, childName, + location + childOffset, dataTypes[inType.children[i].type], var); + + if(genLocations) + location += locations; var.name = StringFormat::Fmt("_child%d", i); outVar.members.push_back(var); } - return; + return location; } case DataType::ArrayType: { // array stride is decorated on the type, not the member itself const Decorations &typeDecorations = decorations[inType.id]; + uint32_t location = 0; + ShaderVariable len = GetActiveLane().ids[inType.length]; for(uint32_t i = 0; i < len.value.u.x; i++) { rdcstr idx = StringFormat::Fmt("[%u]", i); ShaderVariable var; var.name = outVar.name + idx; - AllocateVariable(varDecorations, curDecorations, sourceVarType, sourceName + idx, offset, - dataTypes[inType.InnerType()], var); + uint32_t locations = + AllocateVariable(varDecorations, curDecorations, sourceVarType, sourceName + idx, + location + offset, dataTypes[inType.InnerType()], var); + + if(genLocations) + location += locations; var.name = idx; @@ -939,7 +947,7 @@ void Debugger::AllocateVariable(const Decorations &varDecorations, const Decorat outVar.members.push_back(var); } - return; + return location; } case DataType::ImageType: case DataType::SamplerType: @@ -952,7 +960,7 @@ void Debugger::AllocateVariable(const Decorations &varDecorations, const Decorat } if(sourceVarType == DebugVariableType::Undefined) - return; + return 0; SourceVariableMapping sourceVar; sourceVar.name = sourceName; @@ -971,9 +979,10 @@ void Debugger::AllocateVariable(const Decorations &varDecorations, const Decorat if(sourceVarType == DebugVariableType::Input) { + uint32_t location = genLocations ? offset : 0; apiWrapper->FillInputValue( outVar, builtin, - (curDecorations.flags & Decorations::HasLocation) ? curDecorations.location : 0, + (curDecorations.flags & Decorations::HasLocation) ? curDecorations.location : location, (curDecorations.flags & Decorations::HasOffset) ? curDecorations.offset : 0); } else if(sourceVarType == DebugVariableType::Constant) @@ -1030,6 +1039,9 @@ void Debugger::AllocateVariable(const Decorations &varDecorations, const Decorat } } } + + // each row consumes a new location + return outVar.rows; } void Debugger::PreParse(uint32_t maxId)