diff --git a/qrenderdoc/Windows/ShaderViewer.cpp b/qrenderdoc/Windows/ShaderViewer.cpp index a0028c376..761de7ed8 100644 --- a/qrenderdoc/Windows/ShaderViewer.cpp +++ b/qrenderdoc/Windows/ShaderViewer.cpp @@ -1661,6 +1661,30 @@ QString ShaderViewer::stringRep(const ShaderVariable &var, uint32_t row) if(type == VarType::Unknown) type = ui->intView->isChecked() ? VarType::SInt : VarType::Float; + if(type == VarType::ReadOnlyResource || type == VarType::ReadWriteResource) + { + BindpointIndex varBind = var.GetBinding(); + + rdcarray resList; + + if(type == VarType::ReadOnlyResource) + resList = m_Ctx.CurPipelineState().GetReadOnlyResources(m_Stage); + else if(type == VarType::ReadWriteResource) + resList = m_Ctx.CurPipelineState().GetReadWriteResources(m_Stage); + + int32_t bindIdx = resList.indexOf(Bindpoint(varBind)); + + if(bindIdx < 0) + return QString(); + + BoundResourceArray res = resList[bindIdx]; + + if(varBind.arrayIndex >= res.resources.size()) + return QString(); + + return ToQStr(res.resources[varBind.arrayIndex].resourceId); + } + return RowString(var, row, type); } diff --git a/renderdoc/api/replay/replay_enums.h b/renderdoc/api/replay/replay_enums.h index 733c398f9..7c9eef874 100644 --- a/renderdoc/api/replay/replay_enums.h +++ b/renderdoc/api/replay/replay_enums.h @@ -195,6 +195,26 @@ DOCUMENT(R"(Represents the base type of a shader variable in debugging or consta A 64-bit pointer into GPU-addressable memory. Variables with this type are stored with opaque contents and should be decoded with :meth:`ShaderVariable.GetPointer`. +.. data:: ConstantBlock + + A reference to a constant block bound to the shader. Variables with this type are stored with + opaque contents and should be decoded with :meth:`ShaderVariable.GetBinding`. + +.. data:: ReadOnlyResource + + A reference to a read only resource bound to the shader. Variables with this type are stored with + opaque contents and should be decoded with :meth:`ShaderVariable.GetBinding`. + +.. data:: ReadWriteResource + + A reference to a read/write resource bound to the shader. Variables with this type are stored with + opaque contents and should be decoded with :meth:`ShaderVariable.GetBinding`. + +.. data:: Sampler + + A reference to a sampler bound to the shader. Variables with this type are stored with opaque + contents and should be decoded with :meth:`ShaderVariable.GetBinding`. + .. data:: Unknown An unknown type. @@ -213,6 +233,10 @@ enum class VarType : uint8_t SByte, UByte, GPUPointer, + ConstantBlock, + ReadOnlyResource, + ReadWriteResource, + Sampler, Unknown = 0xFF, }; diff --git a/renderdoc/api/replay/shader_types.h b/renderdoc/api/replay/shader_types.h index 0c206647e..cba8388df 100644 --- a/renderdoc/api/replay/shader_types.h +++ b/renderdoc/api/replay/shader_types.h @@ -125,6 +125,62 @@ struct PointerVal DECLARE_STRINGISE_TYPE(PointerVal); +DOCUMENT("References a particular element in a :class:`Bindpoint`."); +struct BindpointIndex +{ + DOCUMENT(""); + BindpointIndex() + { + bindset = 0; + bind = 0; + arrayIndex = 0; + } + BindpointIndex(const BindpointIndex &) = default; + BindpointIndex &operator=(const BindpointIndex &) = default; + + BindpointIndex(int32_t s, int32_t b) + { + bindset = s; + bind = b; + arrayIndex = 0; + } + BindpointIndex(int32_t s, int32_t b, uint32_t a) + { + bindset = s; + bind = b; + arrayIndex = a; + } + + bool operator<(const BindpointIndex &o) const + { + if(!(bindset == o.bindset)) + return bindset < o.bindset; + if(!(bind == o.bind)) + return bind < o.bind; + return arrayIndex < o.arrayIndex; + } + bool operator>(const BindpointIndex &o) const + { + if(!(bindset == o.bindset)) + return bindset > o.bindset; + if(!(bind == o.bind)) + return bind > o.bind; + return arrayIndex > o.arrayIndex; + } + bool operator==(const BindpointIndex &o) const + { + return bindset == o.bindset && bind == o.bind && arrayIndex == o.arrayIndex; + } + DOCUMENT("The binding set."); + int32_t bindset; + DOCUMENT("The binding index."); + int32_t bind; + DOCUMENT("If this is an arrayed binding, the element in the array being referenced."); + uint32_t arrayIndex; +}; + +DECLARE_REFLECTION_STRUCT(BindpointIndex); + DOCUMENT("A C union that holds 16 values, with each different basic variable type."); union ShaderValue { @@ -282,6 +338,7 @@ struct ShaderVariable type = VarType::GPUPointer; value.u64v[0] = pointer; } + DOCUMENT(R"(Utility function for setting a pointer value with type information. :param int pointer: The actual pointer value. @@ -300,6 +357,10 @@ struct ShaderVariable DOCUMENT(R"(Utility function for getting a pointer value, with optional type information. +.. note:: + + The return value is undefined if this variable is not a pointer. + :return: A :class:`PointerVal` with the pointer value. :rtype: PointerVal )"); @@ -309,6 +370,37 @@ struct ShaderVariable memcpy(&pointerShader, &value.u64v[2], sizeof(pointerShader)); return {value.u64v[0], pointerShader, uint32_t(value.u64v[1] & 0xFFFFFFFF)}; } + + DOCUMENT(R"(Utility function for setting a bindpoint reference. + +See :class:`ShaderBindpointMapping` for the details of how bindpoints are interpreted. The type of +binding is given by the :data:`type` member. + +:param int bindset: The bind set. +:param int bind: The bind itself. +:param int arrayIndex: The array index, if the bind is an array. If it isn't an array this should be + set to 0. +)"); + inline void SetBinding(int32_t bindset, int32_t bind, uint32_t arrayIndex) + { + value.iv[0] = bindset; + value.iv[1] = bind; + value.uv[2] = arrayIndex; + } + + DOCUMENT(R"(Utility function for getting the bindpoint referenced by this variable. + +.. note:: + + The return value is undefined if this variable is not a binding reference. + +:return: A :class:`BindpointIndex` with the binding referenced. +:rtype: BindpointIndex +)"); + inline BindpointIndex GetBinding() const + { + return BindpointIndex(value.iv[0], value.iv[1], value.uv[2]); + } }; DECLARE_REFLECTION_STRUCT(ShaderVariable); @@ -1286,62 +1378,6 @@ struct Bindpoint DECLARE_REFLECTION_STRUCT(Bindpoint); -DOCUMENT("References a particular element in a :class:`Bindpoint`."); -struct BindpointIndex -{ - DOCUMENT(""); - BindpointIndex() - { - bindset = 0; - bind = 0; - arrayIndex = 0; - } - BindpointIndex(const BindpointIndex &) = default; - BindpointIndex &operator=(const BindpointIndex &) = default; - - BindpointIndex(int32_t s, int32_t b) - { - bindset = s; - bind = b; - arrayIndex = 0; - } - BindpointIndex(int32_t s, int32_t b, uint32_t a) - { - bindset = s; - bind = b; - arrayIndex = a; - } - - bool operator<(const BindpointIndex &o) const - { - if(!(bindset == o.bindset)) - return bindset < o.bindset; - if(!(bind == o.bind)) - return bind < o.bind; - return arrayIndex < o.arrayIndex; - } - bool operator>(const BindpointIndex &o) const - { - if(!(bindset == o.bindset)) - return bindset > o.bindset; - if(!(bind == o.bind)) - return bind > o.bind; - return arrayIndex > o.arrayIndex; - } - bool operator==(const BindpointIndex &o) const - { - return bindset == o.bindset && bind == o.bind && arrayIndex == o.arrayIndex; - } - DOCUMENT("The binding set."); - int32_t bindset; - DOCUMENT("The binding index."); - int32_t bind; - DOCUMENT("If this is an arrayed binding, the element in the array being referenced."); - uint32_t arrayIndex; -}; - -DECLARE_REFLECTION_STRUCT(BindpointIndex); - DOCUMENT(R"(This structure goes hand in hand with :class:`ShaderReflection` to determine how to map from bindpoint indices in the resource lists there to API-specific binding points. The ``bindPoint`` member in :class:`ShaderResource` or :class:`ConstantBlock` refers to an index in these associated diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 82b8430f2..254995e27 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -2093,6 +2093,10 @@ void GLReplay::OpenGLFillCBufferVariables(ResourceId shader, GLuint prog, bool b { case VarType::Unknown: case VarType::GPUPointer: + case VarType::ConstantBlock: + case VarType::ReadOnlyResource: + case VarType::ReadWriteResource: + case VarType::Sampler: case VarType::SLong: case VarType::ULong: case VarType::SShort: @@ -2139,6 +2143,10 @@ void GLReplay::OpenGLFillCBufferVariables(ResourceId shader, GLuint prog, bool b { case VarType::Unknown: case VarType::GPUPointer: + case VarType::ConstantBlock: + case VarType::ReadOnlyResource: + case VarType::ReadWriteResource: + case VarType::Sampler: case VarType::SLong: case VarType::ULong: case VarType::SShort: diff --git a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp index 45aa31237..daff03ecf 100644 --- a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp @@ -418,6 +418,10 @@ rdcstr Reflector::Disassemble(const rdcstr &entryPoint, case VarType::SLong: ret += ToStr(value.s64v[0]); break; case VarType::Unknown: case VarType::GPUPointer: + case VarType::ConstantBlock: + case VarType::ReadOnlyResource: + case VarType::ReadWriteResource: + case VarType::Sampler: case VarType::ULong: ret += ToStr(value.u64v[0]); break; } @@ -1573,6 +1577,10 @@ rdcstr Reflector::StringiseConstant(rdcspv::Id id) const case VarType::SLong: return ToStr(value.value.s64v[0]); case VarType::Unknown: case VarType::GPUPointer: + case VarType::ConstantBlock: + case VarType::ReadOnlyResource: + case VarType::ReadWriteResource: + case VarType::Sampler: case VarType::ULong: return ToStr(value.value.u64v[0]); } } @@ -1595,6 +1603,10 @@ rdcstr Reflector::StringiseConstant(rdcspv::Id id) const case VarType::SLong: ret += ToStr(value.value.s64v[i]); break; case VarType::Unknown: case VarType::GPUPointer: + case VarType::ConstantBlock: + case VarType::ReadOnlyResource: + case VarType::ReadWriteResource: + case VarType::Sampler: case VarType::ULong: ret += ToStr(value.value.u64v[i]); break; } if(i + 1 < value.columns)