From 82faf93a273c96d1ce350ac7c940f1f679facab8 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 7 Jan 2016 23:13:32 +0100 Subject: [PATCH] Fetch and store array stride with each constant block variable --- renderdoc/api/replay/shader_types.h | 1 + renderdoc/core/replay_proxy.cpp | 3 +- renderdoc/driver/d3d11/d3d11_common.cpp | 14 ++++++ renderdoc/driver/gl/gl_shader_refl.cpp | 11 +++-- .../shaders/spirv/spirv_disassemble.cpp | 44 +++++++++++++++++-- renderdocui/Interop/Shader.cs | 1 + 6 files changed, 67 insertions(+), 7 deletions(-) diff --git a/renderdoc/api/replay/shader_types.h b/renderdoc/api/replay/shader_types.h index d770c63e6..c77121aaf 100644 --- a/renderdoc/api/replay/shader_types.h +++ b/renderdoc/api/replay/shader_types.h @@ -154,6 +154,7 @@ struct ShaderVariableType uint32_t cols; uint32_t elements; bool32 rowMajorStorage; + uint32_t arrayStride; rdctype::str name; } descriptor; diff --git a/renderdoc/core/replay_proxy.cpp b/renderdoc/core/replay_proxy.cpp index e20bd6958..84fe31344 100644 --- a/renderdoc/core/replay_proxy.cpp +++ b/renderdoc/core/replay_proxy.cpp @@ -157,9 +157,10 @@ void Serialiser::Serialise(const char *name, ShaderVariableType &el) Serialise("", el.descriptor.cols); Serialise("", el.descriptor.elements); Serialise("", el.descriptor.rowMajorStorage); + Serialise("", el.descriptor.arrayStride); Serialise("", el.members); - SIZE_CHECK(ShaderVariableType, 36); + SIZE_CHECK(ShaderVariableType, 40); } template<> diff --git a/renderdoc/driver/d3d11/d3d11_common.cpp b/renderdoc/driver/d3d11/d3d11_common.cpp index 62722edb0..9be89d80a 100644 --- a/renderdoc/driver/d3d11/d3d11_common.cpp +++ b/renderdoc/driver/d3d11/d3d11_common.cpp @@ -884,6 +884,20 @@ ShaderVariableType MakeShaderVariableType(DXBC::CBufferVariableType type, uint32 ret.descriptor.elements = type.descriptor.elements; ret.descriptor.name = type.descriptor.name; ret.descriptor.rowMajorStorage = (type.descriptor.varClass == DXBC::CLASS_MATRIX_ROWS); + + uint32_t baseElemSize = (ret.descriptor.type == eVar_Double) ? 8 : 4; + if(ret.descriptor.rowMajorStorage) + { + uint32_t primary = ret.descriptor.rows; + if(primary == 3) primary = 4; + ret.descriptor.arrayStride = baseElemSize*primary*ret.descriptor.cols; + } + else + { + uint32_t primary = ret.descriptor.cols; + if(primary == 3) primary = 4; + ret.descriptor.arrayStride = baseElemSize*primary*ret.descriptor.rows; + } uint32_t o = offset; diff --git a/renderdoc/driver/gl/gl_shader_refl.cpp b/renderdoc/driver/gl/gl_shader_refl.cpp index 94aa905a4..b102ca6c2 100644 --- a/renderdoc/driver/gl/gl_shader_refl.cpp +++ b/renderdoc/driver/gl/gl_shader_refl.cpp @@ -39,6 +39,7 @@ struct DynShaderVariableType uint32_t cols; uint32_t elements; bool32 rowMajorStorage; + uint32_t arrayStride; string name; } descriptor; @@ -91,6 +92,7 @@ void copy(rdctype::array &outvars, const vector *parentBlocks, vector *defaultBlock) { - const size_t numProps = 7; + const size_t numProps = 8; GLenum resProps[numProps] = { - eGL_TYPE, eGL_NAME_LENGTH, eGL_LOCATION, eGL_BLOCK_INDEX, eGL_ARRAY_SIZE, eGL_OFFSET, eGL_IS_ROW_MAJOR, + eGL_TYPE, eGL_NAME_LENGTH, eGL_LOCATION, eGL_BLOCK_INDEX, eGL_ARRAY_SIZE, eGL_OFFSET, eGL_IS_ROW_MAJOR, eGL_ARRAY_STRIDE }; // GL_LOCATION not valid for buffer variables (it's only used if offset comes back -1, which will never @@ -422,7 +424,7 @@ void ReconstructVarTree(const GLHookSet &gl, GLenum query, GLuint sepProg, GLuin if(query == eGL_BUFFER_VARIABLE) resProps[2] = eGL_OFFSET; - GLint values[numProps] = { -1, -1, -1, -1, -1, -1, -1 }; + GLint values[numProps] = { -1, -1, -1, -1, -1, -1, -1, -1 }; gl.glGetProgramResourceiv(sepProg, query, varIdx, numProps, resProps, numProps, NULL, values); DynShaderConstant var; @@ -632,6 +634,7 @@ void ReconstructVarTree(const GLHookSet &gl, GLenum query, GLuint sepProg, GLuin } var.type.descriptor.rowMajorStorage = (values[6] > 0); + var.type.descriptor.arrayStride = values[7]; var.name.resize(values[1]-1); gl.glGetProgramResourceName(sepProg, query, varIdx, values[1], NULL, &var.name[0]); @@ -809,6 +812,7 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg, res.variableType.descriptor.cols = 4; res.variableType.descriptor.elements = 0; res.variableType.descriptor.rowMajorStorage = false; + res.variableType.descriptor.arrayStride = 0; // float samplers if(values[0] == eGL_SAMPLER_BUFFER) @@ -1385,6 +1389,7 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg, res.variableType.descriptor.cols = 0; res.variableType.descriptor.elements = len; res.variableType.descriptor.rowMajorStorage = false; + res.variableType.descriptor.arrayStride = 0; res.variableType.descriptor.name = "buffer"; res.variableType.descriptor.type = eVar_UInt; res.bindPoint = (int32_t)rwresources.size(); diff --git a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp index e5deaaef8..bca8e3c61 100644 --- a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp @@ -2367,13 +2367,24 @@ void MakeConstantBlockVariables(SPVTypeData *type, rdctype::arraychildren[i].first; cblock[i].name = type->children[i].second; - // TODO do we need to fill these out? - cblock[i].reg.vec = 0; - cblock[i].reg.comp = 0; + + for(size_t d=0; d < type->childDecorations[i].size(); d++) + { + if(type->childDecorations[i][d].decoration == spv::DecorationOffset) + { + uint32_t byteOffset = type->childDecorations[i][d].val; + RDCASSERT(byteOffset%4 == 0); // assume uint32_t aligned + byteOffset /= 4; + cblock[i].reg.vec = byteOffset/4; + cblock[i].reg.comp = byteOffset%4; + break; + } + } string suffix = ""; cblock[i].type.descriptor.elements = 1; + cblock[i].type.descriptor.arrayStride = 0; if(t->type == SPVTypeData::eArray) { @@ -2387,6 +2398,28 @@ void MakeConstantBlockVariables(SPVTypeData *type, rdctype::arrayarraySize); cblock[i].type.descriptor.elements = t->arraySize; } + + bool foundArrayStride = false; + + for(size_t d=0; d < type->childDecorations[i].size(); d++) + { + if(type->childDecorations[i][d].decoration == spv::DecorationArrayStride) + { + cblock[i].type.descriptor.arrayStride = type->childDecorations[i][d].val; + foundArrayStride = true; + break; + } + } + + for(size_t d=0; !foundArrayStride && t->decorations && d < t->decorations->size(); d++) + { + if((*t->decorations)[d].decoration == spv::DecorationArrayStride) + { + cblock[i].type.descriptor.arrayStride = (*t->decorations)[d].val; + break; + } + } + t = t->baseType; } @@ -2405,8 +2438,13 @@ void MakeConstantBlockVariables(SPVTypeData *type, rdctype::arraychildDecorations[i].size(); d++) + { if(type->childDecorations[i][d].decoration == spv::DecorationRowMajor) + { cblock[i].type.descriptor.rowMajorStorage = true; + break; + } + } if(t->type == SPVTypeData::eMatrix) { diff --git a/renderdocui/Interop/Shader.cs b/renderdocui/Interop/Shader.cs index 3f13a93af..489d2e781 100644 --- a/renderdocui/Interop/Shader.cs +++ b/renderdocui/Interop/Shader.cs @@ -296,6 +296,7 @@ namespace renderdoc public UInt32 cols; public UInt32 elements; public bool rowMajorStorage; + public UInt32 arrayStride; [CustomMarshalAs(CustomUnmanagedType.UTF8TemplatedString)] public string name; };