From cef00a102b5547c7aed128fa1547148ec57b375a Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 21 Feb 2022 16:28:27 +0000 Subject: [PATCH] Add struct VarType and combine flags into single field * This is not a space saving right now, but allows more flags to be added without adding more storage. --- qrenderdoc/Code/BufferFormatter.cpp | 93 ++++++++------- qrenderdoc/Windows/BufferViewer.cpp | 12 +- qrenderdoc/Windows/ShaderViewer.cpp | 6 +- renderdoc/api/replay/renderdoc_tostr.inl | 15 +++ renderdoc/api/replay/replay_enums.h | 41 ++++++- renderdoc/api/replay/shader_types.h | 108 ++++++++++++------ renderdoc/data/glsl_shaders.cpp | 14 +-- renderdoc/driver/gl/gl_replay.cpp | 18 +-- renderdoc/driver/gl/gl_shader_refl.cpp | 13 +-- renderdoc/driver/shaders/dxbc/dxbc_debug.cpp | 59 +++++----- .../driver/shaders/dxbc/dxbc_reflect.cpp | 13 +-- .../driver/shaders/spirv/spirv_debug.cpp | 6 +- .../shaders/spirv/spirv_debug_glsl450.cpp | 4 +- .../shaders/spirv/spirv_disassemble.cpp | 11 +- .../driver/shaders/spirv/spirv_processor.cpp | 15 ++- .../driver/shaders/spirv/spirv_reflect.cpp | 15 +-- renderdoc/replay/renderdoc_serialise.inl | 8 +- renderdoc/replay/replay_driver.cpp | 37 +++--- util/test/rdtest/testcase.py | 14 +-- util/test/tests/D3D12/D3D12_Reflection_Zoo.py | 2 +- 20 files changed, 293 insertions(+), 211 deletions(-) diff --git a/qrenderdoc/Code/BufferFormatter.cpp b/qrenderdoc/Code/BufferFormatter.cpp index b13cf42de..01ed219a7 100644 --- a/qrenderdoc/Code/BufferFormatter.cpp +++ b/qrenderdoc/Code/BufferFormatter.cpp @@ -182,7 +182,7 @@ ShaderConstant BufferFormatter::ParseFormatString(const QString &formatString, u el.byteOffset = cur->offset; el.type.descriptor.pointerTypeID = structContext.pointerTypeId; el.type.descriptor.type = VarType::ULong; - el.type.descriptor.displayAsHex = true; + el.type.descriptor.flags |= ShaderVariableFlags::HexDisplay; el.type.descriptor.arrayByteStride = 8; el.type.descriptor.elements = arrayCount; @@ -223,8 +223,10 @@ ShaderConstant BufferFormatter::ParseFormatString(const QString &formatString, u el.name = !match.captured(6).isEmpty() ? match.captured(6).trimmed() : lit("data"); QString basetype = match.captured(3); - el.type.descriptor.rowMajorStorage = match.captured(1).trimmed() == lit("row_major"); - el.type.descriptor.displayAsRGB = !match.captured(2).isEmpty(); + if(match.captured(1).trimmed() == lit("row_major")) + el.type.descriptor.flags |= ShaderVariableFlags::RowMajorMatrix; + if(!match.captured(2).isEmpty()) + el.type.descriptor.flags |= ShaderVariableFlags::RGBDisplay; QString firstDim = !match.captured(4).isEmpty() ? match.captured(4) : lit("1"); QString secondDim = !match.captured(5).isEmpty() ? match.captured(5).mid(1) : lit("1"); QString arrayDim = !match.captured(7).isEmpty() ? match.captured(7).trimmed() : lit("[1]"); @@ -267,9 +269,9 @@ ShaderConstant BufferFormatter::ParseFormatString(const QString &formatString, u break; } - // vectors are never marked as row major + // vectors are marked as row-major by convention if(el.type.descriptor.rows == 1) - el.type.descriptor.rowMajorStorage = false; + el.type.descriptor.flags |= ShaderVariableFlags::RowMajorMatrix; if(basetype == lit("bool")) { @@ -370,7 +372,7 @@ ShaderConstant BufferFormatter::ParseFormatString(const QString &formatString, u if(basetype == lit("xlong") || basetype == lit("xint") || basetype == lit("xshort") || basetype == lit("xbyte")) - el.type.descriptor.displayAsHex = true; + el.type.descriptor.flags |= ShaderVariableFlags::HexDisplay; SetInterpretedResourceFormat(el, interpretType, interpretCompType); @@ -392,7 +394,7 @@ ShaderConstant BufferFormatter::ParseFormatString(const QString &formatString, u } uint8_t majorDim = - el.type.descriptor.rowMajorStorage ? el.type.descriptor.rows : el.type.descriptor.columns; + el.type.descriptor.RowMajor() ? el.type.descriptor.rows : el.type.descriptor.columns; // total matrix size is el.type.descriptor.arrayByteStride = el.type.descriptor.matrixByteStride * majorDim; @@ -453,7 +455,7 @@ ShaderConstant BufferFormatter::ParseFormatString(const QString &formatString, u ShaderConstant el; el.byteOffset = 0; - el.type.descriptor.displayAsHex = true; + el.type.descriptor.flags |= ShaderVariableFlags::HexDisplay; el.name = "data"; el.type.descriptor.type = VarType::UInt; el.type.descriptor.columns = 4; @@ -666,7 +668,7 @@ QString BufferFormatter::GetBufferFormatString(const ShaderResource &res, } else { - if(desc.rowMajorStorage) + if(desc.RowMajor() && desc.rows > 1 && desc.columns > 1) format += lit("row_major "); format += ToQStr(desc.type); @@ -758,7 +760,7 @@ uint32_t BufferFormatter::GetVarSize(const ShaderConstant &var) if(var.type.descriptor.rows > 1) { - if(var.type.descriptor.rowMajorStorage) + if(var.type.descriptor.RowMajor()) size = var.type.descriptor.matrixByteStride * var.type.descriptor.rows; else size = var.type.descriptor.matrixByteStride * var.type.descriptor.columns; @@ -887,7 +889,7 @@ QString BufferFormatter::DeclareStruct(QList &declaredStructs, const QS if(members[i].type.descriptor.rows > 1) { - if(members[i].type.descriptor.rowMajorStorage) + if(members[i].type.descriptor.RowMajor()) { varTypeName = lit("row_major ") + varTypeName; @@ -984,7 +986,7 @@ ResourceFormat GetInterpretedResourceFormat(const ShaderConstant &elem) format.compByteWidth = VarTypeByteSize(elem.type.descriptor.type); - if(elem.type.descriptor.rowMajorStorage || elem.type.descriptor.rows == 1) + if(elem.type.descriptor.RowMajor() || elem.type.descriptor.rows == 1) format.compCount = elem.type.descriptor.columns; else format.compCount = elem.type.descriptor.rows; @@ -1015,7 +1017,7 @@ static void FillShaderVarData(ShaderVariable &var, const ShaderConstant &elem, c bool colMajor = false; - if(!elem.type.descriptor.rowMajorStorage && outerCount > 1) + if(elem.type.descriptor.ColMajor() && outerCount > 1) { colMajor = true; std::swap(outerCount, innerCount); @@ -1071,6 +1073,7 @@ static void FillShaderVarData(ShaderVariable &var, const ShaderConstant &elem, c case VarType::ReadWriteResource: case VarType::Sampler: case VarType::Unknown: + case VarType::Struct: qCritical() << "Unexpected variable type" << ToQStr(var.type) << "in variable" << (QString)var.name; break; @@ -1087,10 +1090,8 @@ ShaderVariable InterpretShaderVar(const ShaderConstant &elem, const byte *data, ret.type = elem.type.descriptor.type; ret.columns = qMin(elem.type.descriptor.columns, uint8_t(4)); ret.rows = qMin(elem.type.descriptor.rows, uint8_t(4)); - ret.isStruct = !elem.type.members.isEmpty(); - ret.displayAsHex = elem.type.descriptor.displayAsHex; - ret.rowMajor = elem.type.descriptor.rowMajorStorage; + ret.flags = elem.type.descriptor.flags; if(!elem.type.members.isEmpty()) { @@ -1118,7 +1119,6 @@ ShaderVariable InterpretShaderVar(const ShaderConstant &elem, const byte *data, data += elem.type.descriptor.arrayByteStride; } - ret.isStruct = false; ret.members = arrayElements; } else @@ -1472,7 +1472,7 @@ QVariantList GetVariants(ResourceFormat format, const ShaderConstantDescriptor & { for(uint32_t col = 0; col < qMax(colCount, 1U); col++) { - if(varDesc.rowMajorStorage || rowCount == 1) + if(varDesc.RowMajor() || rowCount == 1) data = base + row * varDesc.matrixByteStride + col * format.compByteWidth; else data = base + col * varDesc.matrixByteStride + row * format.compByteWidth; @@ -1586,12 +1586,19 @@ QVariantList GetVariants(ResourceFormat format, const ShaderConstantDescriptor & QString TypeString(const ShaderVariable &v) { - if(!v.members.isEmpty() || v.isStruct) + if(!v.members.isEmpty() || v.type == VarType::Struct) { - if(v.isStruct) - return lit("struct"); + if(v.type == VarType::Struct) + { + if(!v.members.empty() && v.members[0].name.contains('[')) + return lit("struct[%2]").arg(v.members.count()); + else + return lit("struct"); + } else + { return QFormatStr("%1[%2]").arg(TypeString(v.members[0])).arg(v.members.count()); + } } if(v.type == VarType::GPUPointer) @@ -1608,7 +1615,7 @@ QString TypeString(const ShaderVariable &v) else if(v.type == VarType::ConstantBlock) typeStr = lit("Constant Block"); - if(v.displayAsHex) + if(v.flags & ShaderVariableFlags::HexDisplay) { if(v.type == VarType::ULong) typeStr = lit("xlong"); @@ -1631,12 +1638,14 @@ QString TypeString(const ShaderVariable &v) .arg(typeStr) .arg(v.rows) .arg(v.columns) - .arg(v.rowMajor ? lit("row_major") : lit("column_major")); + .arg(v.RowMajor() ? lit("row_major") : lit("column_major")); } template -static QString RowValuesToString(int cols, bool hex, el x, el y, el z, el w) +static QString RowValuesToString(int cols, ShaderVariableFlags flags, el x, el y, el z, el w) { + const bool hex = bool(flags & ShaderVariableFlags::HexDisplay); + if(cols == 1) return Formatter::Format(x, hex); else if(cols == 2) @@ -1662,56 +1671,59 @@ QString RowString(const ShaderVariable &v, uint32_t row, VarType type) if(v.type == VarType::GPUPointer) return ToQStr(v.GetPointer()); + if(v.type == VarType::Struct) + return lit("{ ... }"); + switch(type) { case VarType::Float: - return RowValuesToString((int)v.columns, v.displayAsHex, v.value.f32v[row * v.columns + 0], + return RowValuesToString((int)v.columns, v.flags, v.value.f32v[row * v.columns + 0], v.value.f32v[row * v.columns + 1], v.value.f32v[row * v.columns + 2], v.value.f32v[row * v.columns + 3]); case VarType::Double: - return RowValuesToString((int)v.columns, v.displayAsHex, v.value.f64v[row * v.columns + 0], + return RowValuesToString((int)v.columns, v.flags, v.value.f64v[row * v.columns + 0], v.value.f64v[row * v.columns + 1], v.value.f64v[row * v.columns + 2], v.value.f64v[row * v.columns + 3]); case VarType::Half: - return RowValuesToString((int)v.columns, v.displayAsHex, v.value.f16v[row * v.columns + 0], + return RowValuesToString((int)v.columns, v.flags, v.value.f16v[row * v.columns + 0], v.value.f16v[row * v.columns + 1], v.value.f16v[row * v.columns + 2], v.value.f16v[row * v.columns + 3]); case VarType::Bool: - return RowValuesToString((int)v.columns, v.displayAsHex, + return RowValuesToString((int)v.columns, v.flags, v.value.u32v[row * v.columns + 0] ? true : false, v.value.u32v[row * v.columns + 1] ? true : false, v.value.u32v[row * v.columns + 2] ? true : false, v.value.u32v[row * v.columns + 3] ? true : false); case VarType::ULong: - return RowValuesToString((int)v.columns, v.displayAsHex, v.value.u64v[row * v.columns + 0], + return RowValuesToString((int)v.columns, v.flags, v.value.u64v[row * v.columns + 0], v.value.u64v[row * v.columns + 1], v.value.u64v[row * v.columns + 2], v.value.u64v[row * v.columns + 3]); case VarType::UInt: - return RowValuesToString((int)v.columns, v.displayAsHex, v.value.u32v[row * v.columns + 0], + return RowValuesToString((int)v.columns, v.flags, v.value.u32v[row * v.columns + 0], v.value.u32v[row * v.columns + 1], v.value.u32v[row * v.columns + 2], v.value.u32v[row * v.columns + 3]); case VarType::UShort: - return RowValuesToString((int)v.columns, v.displayAsHex, v.value.u16v[row * v.columns + 0], + return RowValuesToString((int)v.columns, v.flags, v.value.u16v[row * v.columns + 0], v.value.u16v[row * v.columns + 1], v.value.u16v[row * v.columns + 2], v.value.u16v[row * v.columns + 3]); case VarType::UByte: - return RowValuesToString((int)v.columns, v.displayAsHex, v.value.u8v[row * v.columns + 0], + return RowValuesToString((int)v.columns, v.flags, v.value.u8v[row * v.columns + 0], v.value.u8v[row * v.columns + 1], v.value.u8v[row * v.columns + 2], v.value.u8v[row * v.columns + 3]); case VarType::SLong: - return RowValuesToString((int)v.columns, v.displayAsHex, v.value.s64v[row * v.columns + 0], + return RowValuesToString((int)v.columns, v.flags, v.value.s64v[row * v.columns + 0], v.value.s64v[row * v.columns + 1], v.value.s64v[row * v.columns + 2], v.value.s64v[row * v.columns + 3]); case VarType::SInt: - return RowValuesToString((int)v.columns, v.displayAsHex, v.value.s32v[row * v.columns + 0], + return RowValuesToString((int)v.columns, v.flags, v.value.s32v[row * v.columns + 0], v.value.s32v[row * v.columns + 1], v.value.s32v[row * v.columns + 2], v.value.s32v[row * v.columns + 3]); case VarType::SShort: - return RowValuesToString((int)v.columns, v.displayAsHex, v.value.s16v[row * v.columns + 0], + return RowValuesToString((int)v.columns, v.flags, v.value.s16v[row * v.columns + 0], v.value.s16v[row * v.columns + 1], v.value.s16v[row * v.columns + 2], v.value.s16v[row * v.columns + 3]); case VarType::SByte: - return RowValuesToString((int)v.columns, v.displayAsHex, v.value.s8v[row * v.columns + 0], + return RowValuesToString((int)v.columns, v.flags, v.value.s8v[row * v.columns + 0], v.value.s8v[row * v.columns + 1], v.value.s8v[row * v.columns + 2], v.value.s8v[row * v.columns + 3]); case VarType::GPUPointer: return ToQStr(v.GetPointer()); @@ -1719,7 +1731,8 @@ QString RowString(const ShaderVariable &v, uint32_t row, VarType type) case VarType::ReadOnlyResource: case VarType::ReadWriteResource: case VarType::Sampler: - case VarType::Unknown: break; + case VarType::Unknown: + case VarType::Struct: break; } return lit("???"); @@ -1746,9 +1759,9 @@ QString VarString(const ShaderVariable &v) QString RowTypeString(const ShaderVariable &v) { - if(!v.members.isEmpty() || v.isStruct) + if(!v.members.isEmpty() || v.type == VarType::Struct) { - if(v.isStruct) + if(v.type == VarType::Struct) return lit("struct"); else return lit("flibbertygibbet"); @@ -1762,7 +1775,7 @@ QString RowTypeString(const ShaderVariable &v) QString typeStr = ToQStr(v.type); - if(v.displayAsHex) + if(v.flags & ShaderVariableFlags::HexDisplay) { if(v.type == VarType::ULong) typeStr = lit("xlong"); diff --git a/qrenderdoc/Windows/BufferViewer.cpp b/qrenderdoc/Windows/BufferViewer.cpp index 39e0b6e48..f8b11f340 100644 --- a/qrenderdoc/Windows/BufferViewer.cpp +++ b/qrenderdoc/Windows/BufferViewer.cpp @@ -749,10 +749,12 @@ static QString interpretVariant(const QVariant &v, const ShaderConstant &el, memcpy(&u, &f, sizeof(f)); } - if(el.type.descriptor.displayAsHex && prop.format.type == ResourceFormatType::Regular) + const bool hexDisplay = bool(el.type.descriptor.flags & ShaderVariableFlags::HexDisplay); + + if(hexDisplay && prop.format.type == ResourceFormatType::Regular) ret = Formatter::HexFormat(u, prop.format.compByteWidth); else - ret = Formatter::Format(u, el.type.descriptor.displayAsHex); + ret = Formatter::Format(u, hexDisplay); } else if(vt == QMetaType::Int || vt == QMetaType::Short || vt == QMetaType::SChar) { @@ -771,7 +773,8 @@ static QString interpretVariant(const QVariant &v, const ShaderConstant &el, } else if(vt == QMetaType::ULongLong) { - ret = Formatter::Format((uint64_t)v.toULongLong(), el.type.descriptor.displayAsHex); + ret = Formatter::Format((uint64_t)v.toULongLong(), + bool(el.type.descriptor.flags & ShaderVariableFlags::HexDisplay)); } else if(vt == QMetaType::LongLong) { @@ -980,7 +983,8 @@ public: const ShaderConstant &el = elementForColumn(col); const BufferElementProperties &prop = propForColumn(col); - if(el.type.descriptor.displayAsRGB && prop.buffer < config.buffers.size()) + if((el.type.descriptor.flags & ShaderVariableFlags::RGBDisplay) && + prop.buffer < config.buffers.size()) { const byte *data = config.buffers[prop.buffer]->data(); const byte *end = config.buffers[prop.buffer]->end(); diff --git a/qrenderdoc/Windows/ShaderViewer.cpp b/qrenderdoc/Windows/ShaderViewer.cpp index 8bcad9937..93fd0f391 100644 --- a/qrenderdoc/Windows/ShaderViewer.cpp +++ b/qrenderdoc/Windows/ShaderViewer.cpp @@ -3057,7 +3057,7 @@ const RDTreeWidgetItem *ShaderViewer::evaluateVar(const RDTreeWidgetItem *item, ShaderVariable &ret = *var; ret.name = mapping.name; - ret.rowMajor = true; + ret.flags |= ShaderVariableFlags::RowMajorMatrix; ret.rows = mapping.rows; ret.columns = mapping.columns; ret.type = mapping.type; @@ -4177,6 +4177,7 @@ bool ShaderViewer::updateWatchVariable(RDTreeWidgetItem *watchItem, const RDTree case VarType::SInt: case VarType::SShort: case VarType::SByte: regcast = QLatin1Char('i'); break; + case VarType::Struct: case VarType::GPUPointer: regcast = QLatin1Char('#'); dataSize = 8; @@ -4638,7 +4639,8 @@ RDTreeWidgetItem *ShaderViewer::makeSourceVariableNode(const SourceVariableMappi case VarType::ConstantBlock: case VarType::ReadOnlyResource: case VarType::ReadWriteResource: - case VarType::Sampler: value += stringRep(*reg, 0); break; + case VarType::Sampler: + case VarType::Struct: value += stringRep(*reg, 0); break; case VarType::Unknown: qCritical() << "Unexpected unknown variable" << (QString)l.name; break; diff --git a/renderdoc/api/replay/renderdoc_tostr.inl b/renderdoc/api/replay/renderdoc_tostr.inl index 7052da3d7..86310ffe6 100644 --- a/renderdoc/api/replay/renderdoc_tostr.inl +++ b/renderdoc/api/replay/renderdoc_tostr.inl @@ -863,6 +863,7 @@ rdcstr DoStringise(const VarType &el) STRINGISE_ENUM_CLASS_NAMED(SByte, "byte"); STRINGISE_ENUM_CLASS_NAMED(UByte, "ubyte"); STRINGISE_ENUM_CLASS_NAMED(Bool, "bool"); + STRINGISE_ENUM_CLASS_NAMED(Struct, "struct"); STRINGISE_ENUM_CLASS_NAMED(GPUPointer, "pointer"); STRINGISE_ENUM_CLASS_NAMED(ConstantBlock, "cbuffer"); STRINGISE_ENUM_CLASS_NAMED(ReadOnlyResource, "resource"); @@ -1109,6 +1110,20 @@ rdcstr DoStringise(const SectionFlags &el) END_BITFIELD_STRINGISE(); } +template <> +rdcstr DoStringise(const ShaderVariableFlags &el) +{ + BEGIN_BITFIELD_STRINGISE(ShaderVariableFlags); + { + STRINGISE_BITFIELD_CLASS_VALUE_NAMED(NoFlags, "None"); + + STRINGISE_BITFIELD_CLASS_BIT(RowMajorMatrix); + STRINGISE_BITFIELD_CLASS_BIT(HexDisplay); + STRINGISE_BITFIELD_CLASS_BIT(RGBDisplay); + } + END_BITFIELD_STRINGISE(); +} + template <> rdcstr DoStringise(const ShaderEvents &el) { diff --git a/renderdoc/api/replay/replay_enums.h b/renderdoc/api/replay/replay_enums.h index 85e745ffd..2dbc72209 100644 --- a/renderdoc/api/replay/replay_enums.h +++ b/renderdoc/api/replay/replay_enums.h @@ -132,8 +132,6 @@ enum class SectionType : uint32_t ITERABLE_OPERATORS(SectionType); DECLARE_REFLECTION_ENUM(SectionType); -// replay_shader.h - DOCUMENT(R"(Represents the category of debugging variable that a source variable maps to. .. data:: Undefined @@ -227,6 +225,10 @@ DOCUMENT(R"(Represents the base type of a shader variable in debugging or consta A boolean value. +.. data:: Struct + + A structure with some number of members. + .. data:: GPUPointer A 64-bit pointer into GPU-addressable memory. Variables with this type are stored with opaque @@ -270,6 +272,7 @@ enum class VarType : uint8_t SByte, UByte, Bool, + Struct, GPUPointer, ConstantBlock, ReadOnlyResource, @@ -1153,8 +1156,6 @@ enum class ShaderBuiltin : uint32_t ITERABLE_OPERATORS(ShaderBuiltin); DECLARE_REFLECTION_ENUM(ShaderBuiltin); -// replay_render.h - DOCUMENT(R"(The type of :class:`ReplayOutput` to create .. data:: Headless @@ -4265,6 +4266,38 @@ enum class ShaderEvents : uint32_t BITMASK_OPERATORS(ShaderEvents); DECLARE_REFLECTION_ENUM(ShaderEvents); +DOCUMENT(R"(A set of flags for events that control how a shader/buffer value is interpreted and +displayed + +.. data:: NoFlags + + No flags are specified. + +.. data:: RowMajorMatrix + + This matrix is stored in row-major order in memory, instead of column-major. In RenderDoc values + are always provided row-major regardless, for consistency of access, but if this flag is not + present then the original values were in column order in memory, so the data has been transposed. + +.. data:: HexDisplay + + This value should be displayed using hexadecimal where possible. + +.. data:: RGBDisplay + + This value should be interpreted as an RGB colour for display where possible. +)"); +enum class ShaderVariableFlags : uint32_t +{ + NoFlags = 0x0000, + RowMajorMatrix = 0x0001, + HexDisplay = 0x0002, + RGBDisplay = 0x0004, +}; + +BITMASK_OPERATORS(ShaderVariableFlags); +DECLARE_REFLECTION_ENUM(ShaderVariableFlags); + DOCUMENT(R"(A set of flags describing the properties of a particular action. An action is a call such as a draw, a compute dispatch, clears, copies, resolves, etc. Any GPU event which may have deliberate visible side-effects to application-visible memory, typically resources such as textures diff --git a/renderdoc/api/replay/shader_types.h b/renderdoc/api/replay/shader_types.h index ee1d875ac..7a65478d3 100644 --- a/renderdoc/api/replay/shader_types.h +++ b/renderdoc/api/replay/shader_types.h @@ -224,7 +224,6 @@ struct ShaderVariable { name = ""; rows = columns = 0; - displayAsHex = isStruct = rowMajor = false; type = VarType::Unknown; memset(&value, 0, sizeof(value)); } @@ -235,7 +234,6 @@ struct ShaderVariable name = n; rows = 1; columns = 4; - displayAsHex = isStruct = rowMajor = false; memset(&value, 0, sizeof(value)); type = VarType::Float; value.f32v[0] = x; @@ -248,7 +246,6 @@ struct ShaderVariable name = n; rows = 1; columns = 4; - displayAsHex = isStruct = rowMajor = false; memset(&value, 0, sizeof(value)); type = VarType::SInt; value.s32v[0] = x; @@ -261,7 +258,6 @@ struct ShaderVariable name = n; rows = 1; columns = 4; - displayAsHex = isStruct = rowMajor = false; memset(&value, 0, sizeof(value)); type = VarType::UInt; value.u32v[0] = x; @@ -272,8 +268,7 @@ struct ShaderVariable bool operator==(const ShaderVariable &o) const { return rows == o.rows && columns == o.columns && name == o.name && type == o.type && - displayAsHex == o.displayAsHex && !memcmp(&value, &o.value, sizeof(value)) && - isStruct == o.isStruct && rowMajor == o.rowMajor && members == o.members; + flags == o.flags && value.u64v == o.value.u64v && members == o.members; } bool operator<(const ShaderVariable &o) const { @@ -285,14 +280,10 @@ struct ShaderVariable return name < o.name; if(!(type == o.type)) return type < o.type; - if(!(displayAsHex == o.displayAsHex)) - return displayAsHex < o.displayAsHex; - if(!(isStruct == o.isStruct)) - return isStruct < o.isStruct; - if(!(rowMajor == o.rowMajor)) - return rowMajor < o.rowMajor; - if(memcmp(&value, &o.value, sizeof(value)) < 0) - return true; + if(!(flags == o.flags)) + return flags < o.flags; + if(value.u64v != o.value.u64v) + return value.u64v < o.value.u64v; if(!(members == o.members)) return members < o.members; return false; @@ -306,18 +297,15 @@ struct ShaderVariable DOCUMENT("The number of columns in this matrix."); uint8_t columns; - DOCUMENT("``True`` if the contents of this variable should be displayed as hex."); - bool displayAsHex; - - DOCUMENT("``True`` if this variable is a structure and not an array or basic type."); - bool isStruct; - - DOCUMENT("``True`` if this variable is stored in rows in memory. Only relevant for matrices."); - bool rowMajor; - DOCUMENT("The :class:`basic type ` of this variable."); VarType type; + DOCUMENT(R"(The flags controlling how this constant is interpreted and displayed. + +:type: ShaderVariableFlags +)"); + ShaderVariableFlags flags = ShaderVariableFlags::NoFlags; + DOCUMENT(R"(The contents of this variable if it has no members. :type: ShaderValue @@ -330,6 +318,28 @@ struct ShaderVariable )"); rdcarray members; + DOCUMENT(R"(Helper function for checking if :data:`flags` has +:data:`ShaderVariableFlags.RowMajorMatrix` set. This is entirely equivalent to checking that flag +manually, but since it is common this helper is provided. + +.. note:: + Vectors and scalars will be marked as row-major by convention for convenience. + +:return: If the storage is row-major order in memory +:rtype: Bool +)"); + inline bool RowMajor() const { return bool(flags & ShaderVariableFlags::RowMajorMatrix); } + DOCUMENT(R"(Helper function for checking if :data:`flags` *does not* have +:data:`ShaderVariableFlags.RowMajorMatrix` set. This is entirely equivalent to checking that flag +manually, but since it is common this helper is provided. + +.. note:: + Vectors and scalars will be marked as row-major by convention for convenience. + +:return: If the storage is column-major order in memory +:rtype: Bool +)"); + inline bool ColMajor() const { return !(flags & ShaderVariableFlags::RowMajorMatrix); } DOCUMENT(R"(Utility function for setting a pointer value with no type information. :param int pointer: The actual pointer value. @@ -920,10 +930,10 @@ struct ShaderConstantDescriptor bool operator==(const ShaderConstantDescriptor &o) const { - return type == o.type && rows == o.rows && columns == o.columns && - rowMajorStorage == o.rowMajorStorage && elements == o.elements && - arrayByteStride == o.arrayByteStride && matrixByteStride == o.matrixByteStride && - pointerTypeID == o.pointerTypeID && name == o.name; + return type == o.type && rows == o.rows && columns == o.columns && flags == o.flags && + elements == o.elements && arrayByteStride == o.arrayByteStride && + matrixByteStride == o.matrixByteStride && pointerTypeID == o.pointerTypeID && + name == o.name; } bool operator<(const ShaderConstantDescriptor &o) const { @@ -933,8 +943,8 @@ struct ShaderConstantDescriptor return rows < o.rows; if(!(columns == o.columns)) return columns < o.columns; - if(!(rowMajorStorage == o.rowMajorStorage)) - return rowMajorStorage < o.rowMajorStorage; + if(!(flags == o.flags)) + return flags < o.flags; if(!(elements == o.elements)) return elements < o.elements; if(!(arrayByteStride == o.arrayByteStride)) @@ -961,14 +971,34 @@ struct ShaderConstantDescriptor uint8_t columns = 1; DOCUMENT("The number of bytes between the start of one column/row in a matrix and the next."); uint8_t matrixByteStride = 0; - DOCUMENT("``True`` if the matrix is stored as row major instead of column major."); - bool rowMajorStorage = false; - DOCUMENT("``True`` if the contents of this variable should be displayed as hex."); - bool displayAsHex = false; - DOCUMENT(R"(``True`` if the contents of this variable should be displayed as RGB color (where - possible). - )"); - bool displayAsRGB = false; + DOCUMENT(R"(The flags controlling how this constant is interpreted and displayed. + +:type: ShaderVariableFlags +)"); + ShaderVariableFlags flags = ShaderVariableFlags::NoFlags; + + DOCUMENT(R"(Helper function for checking if :data:`flags` has +:data:`ShaderVariableFlags.RowMajorMatrix` set. This is entirely equivalent to checking that flag +manually, but since it is common this helper is provided. + +.. note:: + Vectors and scalars will be marked as row-major by convention for convenience. + +:return: If the storage is row-major order in memory +:rtype: Bool +)"); + inline bool RowMajor() const { return bool(flags & ShaderVariableFlags::RowMajorMatrix); } + DOCUMENT(R"(Helper function for checking if :data:`flags` *does not* have +:data:`ShaderVariableFlags.RowMajorMatrix` set. This is entirely equivalent to checking that flag +manually, but since it is common this helper is provided. + +.. note:: + Vectors and scalars will be marked as row-major by convention for convenience. + +:return: If the storage is column-major order in memory +:rtype: Bool +)"); + inline bool ColMajor() const { return !(flags & ShaderVariableFlags::RowMajorMatrix); } }; DECLARE_REFLECTION_STRUCT(ShaderConstantDescriptor); @@ -1008,7 +1038,9 @@ struct ShaderConstantType DECLARE_REFLECTION_STRUCT(ShaderConstantType); -DOCUMENT("Contains the detail of a constant within a :class:`ConstantBlock` in memory."); +DOCUMENT(R"(Contains the detail of a constant within a struct, such as a :class:`ConstantBlock`, +with its type and relative location in memory. +)"); struct ShaderConstant { DOCUMENT(""); diff --git a/renderdoc/data/glsl_shaders.cpp b/renderdoc/data/glsl_shaders.cpp index 38ad5f711..4b72b054d 100644 --- a/renderdoc/data/glsl_shaders.cpp +++ b/renderdoc/data/glsl_shaders.cpp @@ -336,7 +336,7 @@ void main() { CHECK(member.type.descriptor.rows == 2); CHECK(member.type.descriptor.columns == 3); CHECK(member.type.descriptor.elements == 3); - CHECK(member.type.descriptor.rowMajorStorage == false); + CHECK(member.type.descriptor.ColMajor()); } } } @@ -963,7 +963,7 @@ void main() { CHECK(member.type.descriptor.type == VarType::Float); CHECK(member.type.descriptor.rows == 3); CHECK(member.type.descriptor.columns == 4); - CHECK(member.type.descriptor.rowMajorStorage == false); + CHECK(member.type.descriptor.ColMajor()); } CHECK(ubo_root[2].name == "ubo_c"); @@ -976,7 +976,7 @@ void main() { CHECK(member.type.descriptor.type == VarType::Float); CHECK(member.type.descriptor.rows == 3); CHECK(member.type.descriptor.columns == 4); - CHECK(member.type.descriptor.rowMajorStorage == true); + CHECK(member.type.descriptor.RowMajor()); } CHECK(ubo_root[3].name == "ubo_d"); @@ -1052,7 +1052,7 @@ void main() { CHECK(submember.type.descriptor.type == VarType::Float); CHECK(submember.type.descriptor.rows == 2); CHECK(submember.type.descriptor.columns == 2); - CHECK(submember.type.descriptor.rowMajorStorage == false); + CHECK(submember.type.descriptor.ColMajor()); } } } @@ -1299,7 +1299,7 @@ void main() { CHECK(submember.type.descriptor.type == VarType::Float); CHECK(submember.type.descriptor.rows == 2); CHECK(submember.type.descriptor.columns == 2); - CHECK(submember.type.descriptor.rowMajorStorage == false); + CHECK(submember.type.descriptor.ColMajor()); } } } @@ -1385,7 +1385,7 @@ void main() { CHECK(subsubmember.type.descriptor.type == VarType::Float); CHECK(subsubmember.type.descriptor.rows == 2); CHECK(subsubmember.type.descriptor.columns == 2); - CHECK(subsubmember.type.descriptor.rowMajorStorage == false); + CHECK(subsubmember.type.descriptor.ColMajor()); } } } @@ -1435,7 +1435,7 @@ void main() { CHECK(subsubmember.type.descriptor.type == VarType::Float); CHECK(subsubmember.type.descriptor.rows == 2); CHECK(subsubmember.type.descriptor.columns == 2); - CHECK(subsubmember.type.descriptor.rowMajorStorage == false); + CHECK(subsubmember.type.descriptor.ColMajor()); } } } diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 7a9731edd..a0fbd5cbe 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -2095,7 +2095,7 @@ void GLReplay::OpenGLFillCBufferVariables(ResourceId shader, GLuint prog, bool b var.rows = desc.rows; var.columns = desc.columns; var.type = desc.type; - var.rowMajor = desc.rowMajorStorage; + var.flags = desc.flags; const uint32_t matStride = desc.matrixByteStride; @@ -2105,7 +2105,7 @@ void GLReplay::OpenGLFillCBufferVariables(ResourceId shader, GLuint prog, bool b { OpenGLFillCBufferVariables(shader, prog, bufferBacked, prefix + var.name.c_str() + ".", variables[i].type.members, var.members, data); - var.isStruct = true; + var.type = VarType::Struct; } else { @@ -2116,14 +2116,12 @@ void GLReplay::OpenGLFillCBufferVariables(ResourceId shader, GLuint prog, bool b arrEl.rows = var.rows; arrEl.columns = var.columns; arrEl.name = StringFormat::Fmt("%s[%u]", var.name.c_str(), a); - arrEl.type = var.type; - arrEl.isStruct = true; - arrEl.rowMajor = var.rowMajor; + arrEl.type = VarType::Struct; + arrEl.flags = var.flags; OpenGLFillCBufferVariables(shader, prog, bufferBacked, prefix + arrEl.name.c_str() + ".", variables[i].type.members, arrEl.members, data); } - var.isStruct = false; var.rows = var.columns = 0; } } @@ -2166,13 +2164,10 @@ void GLReplay::OpenGLFillCBufferVariables(ResourceId shader, GLuint prog, bool b else el.name = StringFormat::Fmt("[%u]", a); - el.isStruct = false; - elems.push_back(el); } var.members = elems; - var.isStruct = false; var.rows = var.columns = 0; } } @@ -2209,6 +2204,7 @@ void GLReplay::OpenGLFillCBufferVariables(ResourceId shader, GLuint prog, bool b case VarType::SByte: case VarType::UByte: case VarType::Half: + case VarType::Struct: RDCERR("Unexpected base variable type %s, treating as float", ToStr(var.type).c_str()); DELIBERATE_FALLTHROUGH(); @@ -2260,6 +2256,7 @@ void GLReplay::OpenGLFillCBufferVariables(ResourceId shader, GLuint prog, bool b case VarType::SByte: case VarType::UByte: case VarType::Half: + case VarType::Struct: RDCERR("Unexpected base variable type %s, treating as float", ToStr(var.type).c_str()); DELIBERATE_FALLTHROUGH(); @@ -2284,13 +2281,10 @@ void GLReplay::OpenGLFillCBufferVariables(ResourceId shader, GLuint prog, bool b if(bufferBacked) offset += desc.arrayByteStride; - el.isStruct = false; - elems.push_back(el); } var.members = elems; - var.isStruct = false; var.rows = var.columns = 0; } } diff --git a/renderdoc/driver/gl/gl_shader_refl.cpp b/renderdoc/driver/gl/gl_shader_refl.cpp index d69dd06dd..4904e0ae3 100644 --- a/renderdoc/driver/gl/gl_shader_refl.cpp +++ b/renderdoc/driver/gl/gl_shader_refl.cpp @@ -742,7 +742,8 @@ void ReconstructVarTree(GLenum query, GLuint sepProg, GLuint varIdx, GLint numPa var.byteOffset = ~0U; } - var.type.descriptor.rowMajorStorage = (values[6] > 0); + if(values[6] > 0) + var.type.descriptor.flags |= ShaderVariableFlags::RowMajorMatrix; var.type.descriptor.matrixByteStride = (uint8_t)values[8]; RDCASSERTMSG("Stride is too large for uint16_t", values[7] <= 0xffff); @@ -756,7 +757,7 @@ void ReconstructVarTree(GLenum query, GLuint sepProg, GLuint varIdx, GLint numPa bareUniform = true; // plain matrices are always column major, so this is the size of a column - var.type.descriptor.rowMajorStorage = false; + var.type.descriptor.flags &= ~ShaderVariableFlags::RowMajorMatrix; const uint32_t elemByteStride = (var.type.descriptor.type == VarType::Double) ? 8 : 4; var.type.descriptor.matrixByteStride = uint8_t(var.type.descriptor.rows * elemByteStride); @@ -765,7 +766,8 @@ void ReconstructVarTree(GLenum query, GLuint sepProg, GLuint varIdx, GLint numPa var.type.descriptor.arrayByteStride = 0; } - // set vectors as row major for convenience, since that's how they're stored in the fv array. + // set vectors/scalars as row major for convenience, since that's how they're stored in the fv + // array. switch(values[0]) { case eGL_FLOAT_VEC4: @@ -787,7 +789,7 @@ void ReconstructVarTree(GLenum query, GLuint sepProg, GLuint varIdx, GLint numPa case eGL_INT_VEC4: case eGL_INT_VEC3: case eGL_INT_VEC2: - case eGL_INT: var.type.descriptor.rowMajorStorage = true; break; + case eGL_INT: var.type.descriptor.flags |= ShaderVariableFlags::RowMajorMatrix; break; default: break; } @@ -881,7 +883,6 @@ void ReconstructVarTree(GLenum query, GLuint sepProg, GLuint varIdx, GLint numPa parentVar.type.descriptor.name = "struct"; parentVar.type.descriptor.rows = 0; parentVar.type.descriptor.columns = 0; - parentVar.type.descriptor.rowMajorStorage = false; parentVar.type.descriptor.type = var.type.descriptor.type; parentVar.type.descriptor.elements = isarray && !multiDimArray ? RDCMAX(1U, uint32_t(arrayIdx + 1)) : 0; @@ -1155,7 +1156,6 @@ void MakeShaderReflection(GLenum shadType, GLuint sepProg, ShaderReflection &ref res.variableType.descriptor.rows = 1; res.variableType.descriptor.columns = 4; res.variableType.descriptor.elements = 0; - res.variableType.descriptor.rowMajorStorage = false; res.variableType.descriptor.arrayByteStride = 0; res.variableType.descriptor.matrixByteStride = 0; @@ -1701,7 +1701,6 @@ void MakeShaderReflection(GLenum shadType, GLuint sepProg, ShaderReflection &ref res.variableType.descriptor.rows = 0; res.variableType.descriptor.columns = 0; res.variableType.descriptor.elements = 0; - res.variableType.descriptor.rowMajorStorage = false; res.variableType.descriptor.arrayByteStride = 0; res.variableType.descriptor.matrixByteStride = 0; res.variableType.descriptor.name = "buffer"; diff --git a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp index 2551506ac..ecdb7710f 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp @@ -1746,7 +1746,7 @@ void FlattenSingleVariable(const rdcstr &cbufferName, uint32_t byteOffset, const size_t outIdx = byteOffset / 16; size_t outComp = (byteOffset % 16) / 4; - if(v.rowMajor) + if(v.RowMajor()) outvars.resize(RDCMAX(outIdx + v.rows, outvars.size())); else outvars.resize(RDCMAX(outIdx + v.columns, outvars.size())); @@ -1777,17 +1777,16 @@ void FlattenSingleVariable(const rdcstr &cbufferName, uint32_t byteOffset, const } else { - const uint32_t numRegisters = v.rowMajor ? v.rows : v.columns; + const uint32_t numRegisters = v.RowMajor() ? v.rows : v.columns; for(uint32_t reg = 0; reg < numRegisters; reg++) { outvars[outIdx + reg].rows = 1; outvars[outIdx + reg].type = VarType::Unknown; - outvars[outIdx + reg].isStruct = false; outvars[outIdx + reg].columns = v.columns; - outvars[outIdx + reg].rowMajor = v.rowMajor; + outvars[outIdx + reg].flags = v.flags; } - if(v.rowMajor) + if(v.RowMajor()) { for(size_t ri = 0; ri < v.rows; ri++) memcpy(&outvars[outIdx + ri].value.u32v[0], &v.value.u32v[ri * v.columns], @@ -1817,8 +1816,8 @@ void FlattenSingleVariable(const rdcstr &cbufferName, uint32_t byteOffset, const { for(uint8_t c = 0; c < v.columns; c++) { - size_t regIndex = outIdx + (v.rowMajor ? r : c); - size_t compIndex = outComp + (v.rowMajor ? c : r); + size_t regIndex = outIdx + (v.RowMajor() ? r : c); + size_t compIndex = outComp + (v.RowMajor() ? c : r); mapping.variables[i].type = DebugVariableType::Constant; mapping.variables[i].name = StringFormat::Fmt("%s[%zu]", cbufferName.c_str(), regIndex); @@ -1847,43 +1846,37 @@ void FlattenVariables(const rdcstr &cbufferName, const rdcarray rdcstr basename = prefix + rdcstr(v.name); - if((v.rows == 0 && v.columns == 0) || !v.members.empty()) + if(v.type == VarType::Struct) { - if(v.isStruct) + // check if this is an array of structs or not + if(c.type.descriptor.elements == 1) { FlattenVariables(cbufferName, c.type.members, v.members, outvars, basename + ".", byteOffset, sourceVars); } else { - if(c.type.members.empty()) + for(int m = 0; m < v.members.count(); m++) { - // if there are no members in this type, it means it's a basic array - unroll directly - - for(int m = 0; m < v.members.count(); m++) - { - FlattenSingleVariable(cbufferName, byteOffset + m * c.type.descriptor.arrayByteStride, - StringFormat::Fmt("%s[%zu]", basename.c_str(), m), v.members[m], - outvars, sourceVars); - } - } - else - { - // otherwise we recurse into each member and flatten - - for(int m = 0; m < v.members.count(); m++) - { - FlattenVariables(cbufferName, c.type.members, v.members[m].members, outvars, - StringFormat::Fmt("%s[%zu].", basename.c_str(), m), - byteOffset + m * c.type.descriptor.arrayByteStride, sourceVars); - } + FlattenVariables(cbufferName, c.type.members, v.members[m].members, outvars, + StringFormat::Fmt("%s[%zu].", basename.c_str(), m), + byteOffset + m * c.type.descriptor.arrayByteStride, sourceVars); } } - - continue; } - - FlattenSingleVariable(cbufferName, byteOffset, basename, v, outvars, sourceVars); + else if(c.type.descriptor.elements > 1 || (v.rows == 0 && v.columns == 0) || !v.members.empty()) + { + for(int m = 0; m < v.members.count(); m++) + { + FlattenSingleVariable(cbufferName, byteOffset + m * c.type.descriptor.arrayByteStride, + StringFormat::Fmt("%s[%zu]", basename.c_str(), m), v.members[m], + outvars, sourceVars); + } + } + else + { + FlattenSingleVariable(cbufferName, byteOffset, basename, v, outvars, sourceVars); + } } } diff --git a/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp b/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp index 53c9b531f..fe05f453c 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp @@ -40,9 +40,9 @@ static ShaderConstantType MakeShaderConstantType(bool cbufferPacking, DXBC::CBuf ret.descriptor.columns = (uint8_t)type.descriptor.cols; ret.descriptor.elements = type.descriptor.elements; ret.descriptor.name = type.descriptor.name; - ret.descriptor.rowMajorStorage = (type.descriptor.varClass == DXBC::CLASS_MATRIX_ROWS || - type.descriptor.varClass == DXBC::CLASS_VECTOR || - type.descriptor.varClass == DXBC::CLASS_SCALAR); + if(type.descriptor.varClass == DXBC::CLASS_MATRIX_ROWS || + type.descriptor.varClass == DXBC::CLASS_VECTOR || type.descriptor.varClass == DXBC::CLASS_SCALAR) + ret.descriptor.flags |= ShaderVariableFlags::RowMajorMatrix; uint32_t baseElemSize = (ret.descriptor.type == VarType::Double) ? 8 : 4; @@ -51,9 +51,8 @@ static ShaderConstantType MakeShaderConstantType(bool cbufferPacking, DXBC::CBuf if(cbufferPacking) ret.descriptor.matrixByteStride = uint8_t(baseElemSize * 4); else - ret.descriptor.matrixByteStride = - uint8_t(baseElemSize * - (ret.descriptor.rowMajorStorage ? ret.descriptor.rows : ret.descriptor.columns)); + ret.descriptor.matrixByteStride = uint8_t( + baseElemSize * (ret.descriptor.RowMajor() ? ret.descriptor.columns : ret.descriptor.rows)); if(type.descriptor.varClass == DXBC::CLASS_STRUCT) { @@ -69,7 +68,7 @@ static ShaderConstantType MakeShaderConstantType(bool cbufferPacking, DXBC::CBuf } else { - if(ret.descriptor.rowMajorStorage) + if(ret.descriptor.RowMajor()) ret.descriptor.arrayByteStride = ret.descriptor.matrixByteStride * ret.descriptor.rows; else ret.descriptor.arrayByteStride = ret.descriptor.matrixByteStride * ret.descriptor.columns; diff --git a/renderdoc/driver/shaders/spirv/spirv_debug.cpp b/renderdoc/driver/shaders/spirv/spirv_debug.cpp index c0975d96a..41390db91 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug.cpp @@ -2234,7 +2234,7 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray ShaderVariable result; result.rows = 1; result.columns = 1; - result.isStruct = true; + result.type = VarType::Struct; result.members = {lsb, msb}; result.members[0].name = "lsb"; result.members[1].name = "msb"; @@ -2482,7 +2482,7 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray ShaderVariable result; result.rows = 1; result.columns = 1; - result.isStruct = true; + result.type = VarType::Struct; result.members = {GetSrc(sampled.image), GetSrc(sampled.sampler)}; result.members[0].name = "image"; result.members[1].name = "sampler"; @@ -3022,7 +3022,7 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray ShaderVariable result; result.rows = 1; result.columns = 1; - result.isStruct = true; + result.type = VarType::Struct; result.members = {ReadPointerValue(ptr.image), GetSrc(ptr.coordinate), GetSrc(ptr.sample)}; result.members[0].name = "image"; result.members[1].name = "coord"; diff --git a/renderdoc/driver/shaders/spirv/spirv_debug_glsl450.cpp b/renderdoc/driver/shaders/spirv/spirv_debug_glsl450.cpp index 63e9f771a..e221109c1 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug_glsl450.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug_glsl450.cpp @@ -415,7 +415,7 @@ ShaderVariable ModfStruct(ThreadState &state, uint32_t, const rdcarray ¶ ShaderVariable ret; ret.rows = 1; ret.columns = 1; - ret.isStruct = true; + ret.type = VarType::Struct; ret.members = {var, var}; ret.members[0].name = "_child0"; ret.members[1].name = "_child1"; @@ -788,7 +788,7 @@ ShaderVariable FrexpStruct(ThreadState &state, uint32_t, const rdcarray &par ShaderVariable ret; ret.rows = 1; ret.columns = 1; - ret.isStruct = true; + ret.type = VarType::Struct; ret.members = {var, var}; ret.members[0].name = "_child0"; ret.members[1].name = "_child1"; diff --git a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp index adc54d2f4..354b699c0 100644 --- a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp @@ -446,13 +446,18 @@ rdcstr Reflector::Disassemble(const rdcstr &entryPoint, case VarType::UShort: ret += ToStr(value.u16v[0]); break; case VarType::UByte: ret += ToStr(value.u8v[0]); break; case VarType::SLong: ret += ToStr(value.s64v[0]); break; + case VarType::ULong: + ret += ToStr(value.u64v[0]); + break; + // none of these types are expected, either because they're opaque or (for struct) + // because ConstantComposite should have been used + case VarType::Struct: 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; + case VarType::Sampler: ret += "???"; break; } ret += getDecorationString(decorations[decoded.result]); @@ -1675,6 +1680,7 @@ rdcstr Reflector::StringiseConstant(rdcspv::Id id) const case VarType::UByte: return ToStr(value.value.u8v[0]); case VarType::SLong: return ToStr(value.value.s64v[0]); case VarType::ULong: return ToStr(value.value.u64v[0]); + case VarType::Struct: case VarType::Unknown: case VarType::GPUPointer: case VarType::ConstantBlock: @@ -1702,6 +1708,7 @@ rdcstr Reflector::StringiseConstant(rdcspv::Id id) const case VarType::UByte: ret += ToStr(value.value.u8v[i]); break; case VarType::SLong: ret += ToStr(value.value.s64v[i]); break; case VarType::ULong: ret += ToStr(value.value.u64v[i]); break; + case VarType::Struct: case VarType::Unknown: case VarType::GPUPointer: case VarType::ConstantBlock: diff --git a/renderdoc/driver/shaders/spirv/spirv_processor.cpp b/renderdoc/driver/shaders/spirv/spirv_processor.cpp index d921e1a9d..fa37d6868 100644 --- a/renderdoc/driver/shaders/spirv/spirv_processor.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_processor.cpp @@ -619,7 +619,6 @@ void Processor::RegisterOp(Iter it) ShaderVariable v("composite", 0, 0, 0, 0); v.rows = v.columns = 0; - v.isStruct = (type.type == DataType::StructType); if(type.type == DataType::VectorType) { @@ -633,7 +632,11 @@ void Processor::RegisterOp(Iter it) v.rows = type.vector().count & 0xf; v.columns = type.matrix().count & 0xf; // always store constants row major - v.rowMajor = true; + v.flags |= ShaderVariableFlags::RowMajorMatrix; + } + else if(type.type == DataType::StructType) + { + v.type = VarType::Struct; } rdcarray members; @@ -961,7 +964,6 @@ ShaderVariable Processor::MakeNULL(const DataType &type, uint64_t value) { ShaderVariable v("", 0, 0, 0, 0); v.rows = v.columns = 0; - v.isStruct = (type.type == DataType::StructType); for(uint8_t c = 0; c < 16; c++) v.value.u64v[c] = value; @@ -977,7 +979,7 @@ ShaderVariable Processor::MakeNULL(const DataType &type, uint64_t value) v.type = type.scalar().Type(); v.rows = type.vector().count & 0xf; v.columns = type.matrix().count & 0xf; - v.rowMajor = true; + v.flags |= ShaderVariableFlags::RowMajorMatrix; } else if(type.type == DataType::ScalarType) { @@ -1003,6 +1005,11 @@ ShaderVariable Processor::MakeNULL(const DataType &type, uint64_t value) } else { + if(type.type == DataType::StructType) + v.type = VarType::Struct; + else + RDCWARN("Unexpected type %d making NULL", type.type); + v.members.resize(type.children.size()); for(size_t i = 0; i < v.members.size(); i++) { diff --git a/renderdoc/driver/shaders/spirv/spirv_reflect.cpp b/renderdoc/driver/shaders/spirv/spirv_reflect.cpp index 1a53dbfae..ab20b5f94 100644 --- a/renderdoc/driver/shaders/spirv/spirv_reflect.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_reflect.cpp @@ -286,11 +286,11 @@ static uint32_t CalculateMinimumByteSize(const rdcarray &variabl return byteOffset + rows * basicTypeSize; // for matrices we need to pad 3-column or 3-row up to 4 - if(cols == 3 && last.type.descriptor.rowMajorStorage) + if(cols == 3 && last.type.descriptor.RowMajor()) { return byteOffset + rows * 4 * basicTypeSize; } - else if(rows == 3 && !last.type.descriptor.rowMajorStorage) + else if(rows == 3 && last.type.descriptor.ColMajor()) { return byteOffset + cols * 4 * basicTypeSize; } @@ -995,7 +995,6 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st res.variableType.descriptor.columns = 1; res.variableType.descriptor.rows = 1; - res.variableType.descriptor.rowMajorStorage = false; res.variableType.descriptor.type = VarType::UInt; res.variableType.descriptor.name = varType->name; @@ -1110,8 +1109,6 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st res.variableType.descriptor.columns = 0; res.variableType.descriptor.rows = 0; - res.variableType.descriptor.rowMajorStorage = false; - res.variableType.descriptor.rows = 0; res.variableType.descriptor.type = VarType::Float; res.variableType.descriptor.name = varType->name; @@ -1482,8 +1479,8 @@ void Reflector::MakeConstantBlockVariable(ShaderConstant &outConst, { outConst.type.descriptor.type = curType->scalar().Type(); - outConst.type.descriptor.rowMajorStorage = - (curType->type == DataType::VectorType || varDecorations.flags & Decorations::RowMajor); + if(curType->type == DataType::VectorType || (varDecorations.flags & Decorations::RowMajor)) + outConst.type.descriptor.flags |= ShaderVariableFlags::RowMajorMatrix; if(varDecorations.matrixStride != ~0U) outConst.type.descriptor.matrixByteStride = varDecorations.matrixStride & 0xff; @@ -1503,7 +1500,7 @@ void Reflector::MakeConstantBlockVariable(ShaderConstant &outConst, else if(curType->type == DataType::ScalarType) { outConst.type.descriptor.type = curType->scalar().Type(); - outConst.type.descriptor.rowMajorStorage = true; + outConst.type.descriptor.flags |= ShaderVariableFlags::RowMajorMatrix; outConst.type.descriptor.name = curType->name; } @@ -1512,7 +1509,6 @@ void Reflector::MakeConstantBlockVariable(ShaderConstant &outConst, if(curType->type == DataType::PointerType) { outConst.type.descriptor.type = VarType::ULong; - outConst.type.descriptor.rowMajorStorage = false; outConst.type.descriptor.rows = 1; outConst.type.descriptor.columns = 1; outConst.type.descriptor.name = curType->name; @@ -1529,7 +1525,6 @@ void Reflector::MakeConstantBlockVariable(ShaderConstant &outConst, RDCASSERT(curType->type == DataType::StructType || curType->type == DataType::ArrayType); outConst.type.descriptor.type = VarType::Float; - outConst.type.descriptor.rowMajorStorage = false; outConst.type.descriptor.rows = 0; outConst.type.descriptor.columns = 0; diff --git a/renderdoc/replay/renderdoc_serialise.inl b/renderdoc/replay/renderdoc_serialise.inl index 6647653e3..eefc781ac 100644 --- a/renderdoc/replay/renderdoc_serialise.inl +++ b/renderdoc/replay/renderdoc_serialise.inl @@ -167,12 +167,10 @@ void DoSerialise(SerialiserType &ser, ShaderConstantDescriptor &el) SERIALISE_MEMBER(rows); SERIALISE_MEMBER(columns); SERIALISE_MEMBER(matrixByteStride); - SERIALISE_MEMBER(rowMajorStorage); SERIALISE_MEMBER(elements); SERIALISE_MEMBER(arrayByteStride); SERIALISE_MEMBER(name); - SERIALISE_MEMBER(displayAsHex); - SERIALISE_MEMBER(displayAsRGB); + SERIALISE_MEMBER(flags); SERIALISE_MEMBER(pointerTypeID); SIZE_CHECK(48); @@ -320,9 +318,7 @@ void DoSerialise(SerialiserType &ser, ShaderVariable &el) SERIALISE_MEMBER(name); SERIALISE_MEMBER(type); - SERIALISE_MEMBER(displayAsHex); - SERIALISE_MEMBER(isStruct); - SERIALISE_MEMBER(rowMajor); + SERIALISE_MEMBER(flags); SERIALISE_MEMBER(value.u64v); diff --git a/renderdoc/replay/replay_driver.cpp b/renderdoc/replay/replay_driver.cpp index 598f3e545..941249106 100644 --- a/renderdoc/replay/replay_driver.cpp +++ b/renderdoc/replay/replay_driver.cpp @@ -362,7 +362,7 @@ void StandardFillCBufferVariable(ResourceId shader, const ShaderConstantDescript // so a matrix is a secondaryDim number of primaryDim-sized vectors uint32_t primaryDim = cols; uint32_t secondaryDim = rows; - if(rows > 1 && !outvar.rowMajor) + if(rows > 1 && outvar.ColMajor()) { primaryDim = rows; secondaryDim = cols; @@ -390,7 +390,7 @@ void StandardFillCBufferVariable(ResourceId shader, const ShaderConstantDescript } // if it's a matrix and not row major, transpose - if(primaryDim > 1 && secondaryDim > 1 && !outvar.rowMajor) + if(primaryDim > 1 && secondaryDim > 1 && outvar.ColMajor()) { ShaderVariable tmp = outvar; @@ -436,7 +436,7 @@ static void StandardFillCBufferVariables(ResourceId shader, const rdcarray 1; const uint32_t matStride = invars[v].type.descriptor.matrixByteStride; @@ -448,8 +448,9 @@ static void StandardFillCBufferVariables(ResourceId shader, const rdcarray varmembers; @@ -461,23 +462,18 @@ static void StandardFillCBufferVariables(ResourceId shader, const rdcarray