diff --git a/renderdoc/driver/d3d11/d3d11_shaderdebug.cpp b/renderdoc/driver/d3d11/d3d11_shaderdebug.cpp index 3c1ec8c2d..bb637b306 100644 --- a/renderdoc/driver/d3d11/d3d11_shaderdebug.cpp +++ b/renderdoc/driver/d3d11/d3d11_shaderdebug.cpp @@ -77,9 +77,10 @@ public: DXBCDebug::SampleGatherResourceData resourceData, DXBCDebug::SampleGatherSamplerData samplerData, ShaderVariable uv, ShaderVariable ddxCalc, ShaderVariable ddyCalc, - const int texelOffsets[3], int multisampleIndex, float lodOrCompareValue, - const uint8_t swizzle[4], DXBCDebug::GatherChannel gatherChannel, - const char *opString, ShaderVariable &output); + const int8_t texelOffsets[3], int multisampleIndex, + float lodOrCompareValue, const uint8_t swizzle[4], + DXBCDebug::GatherChannel gatherChannel, const char *opString, + ShaderVariable &output); private: DXBC::ShaderType GetShaderType() { return m_dxbc ? m_dxbc->m_Type : DXBC::ShaderType::Pixel; } @@ -991,7 +992,7 @@ ShaderVariable D3D11DebugAPIWrapper::GetResourceInfo(DXBCBytecode::OperandType t bool D3D11DebugAPIWrapper::CalculateSampleGather( DXBCBytecode::OpcodeType opcode, DXBCDebug::SampleGatherResourceData resourceData, DXBCDebug::SampleGatherSamplerData samplerData, ShaderVariable uv, ShaderVariable ddxCalc, - ShaderVariable ddyCalc, const int texelOffsets[3], int multisampleIndex, + ShaderVariable ddyCalc, const int8_t texelOffsets[3], int multisampleIndex, float lodOrCompareValue, const uint8_t swizzle[4], DXBCDebug::GatherChannel gatherChannel, const char *opString, ShaderVariable &output) { diff --git a/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp b/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp index 7c1e987a8..8280d2e01 100644 --- a/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp +++ b/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp @@ -88,9 +88,10 @@ public: DXBCDebug::SampleGatherResourceData resourceData, DXBCDebug::SampleGatherSamplerData samplerData, ShaderVariable uv, ShaderVariable ddxCalc, ShaderVariable ddyCalc, - const int texelOffsets[3], int multisampleIndex, float lodOrCompareValue, - const uint8_t swizzle[4], DXBCDebug::GatherChannel gatherChannel, - const char *opString, ShaderVariable &output); + const int8_t texelOffsets[3], int multisampleIndex, + float lodOrCompareValue, const uint8_t swizzle[4], + DXBCDebug::GatherChannel gatherChannel, const char *opString, + ShaderVariable &output); private: DXBC::ShaderType GetShaderType() { return m_dxbc ? m_dxbc->m_Type : DXBC::ShaderType::Pixel; } @@ -1101,7 +1102,7 @@ ShaderVariable D3D12DebugAPIWrapper::GetResourceInfo(DXBCBytecode::OperandType t bool D3D12DebugAPIWrapper::CalculateSampleGather( DXBCBytecode::OpcodeType opcode, DXBCDebug::SampleGatherResourceData resourceData, DXBCDebug::SampleGatherSamplerData samplerData, ShaderVariable uv, ShaderVariable ddxCalc, - ShaderVariable ddyCalc, const int texelOffsets[3], int multisampleIndex, + ShaderVariable ddyCalc, const int8_t texelOffsets[3], int multisampleIndex, float lodOrCompareValue, const uint8_t swizzle[4], DXBCDebug::GatherChannel gatherChannel, const char *opString, ShaderVariable &output) { diff --git a/renderdoc/driver/ihv/nv/nvapi_wrapper.h b/renderdoc/driver/ihv/nv/nvapi_wrapper.h index e176a13f4..faf8103ee 100644 --- a/renderdoc/driver/ihv/nv/nvapi_wrapper.h +++ b/renderdoc/driver/ihv/nv/nvapi_wrapper.h @@ -59,9 +59,8 @@ enum class NvShaderSpecial FootprintSingleLOD = 5, }; -enum class NvShaderAtomic +enum class NvShaderAtomic : uint8_t { - Unknown = -1, And = 0, Or = 1, Xor = 2, @@ -70,6 +69,7 @@ enum class NvShaderAtomic Min = 7, Swap = 8, CompareAndSwap = 9, + Unknown = 255, }; struct D3D12_GRAPHICS_PIPELINE_STATE_DESC; diff --git a/renderdoc/driver/shaders/dxbc/dxbc_bytecode.cpp b/renderdoc/driver/shaders/dxbc/dxbc_bytecode.cpp index ded0fed26..d727f4275 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_bytecode.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_bytecode.cpp @@ -97,7 +97,7 @@ bool Program::UsesExtensionUAV(uint32_t slot, uint32_t space, const byte *bytes, // nvidia is a structured buffer with counter // AMD is a RW byte address buffer if((op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED && - Opcode::HasOrderPreservingCounter.Get(OpcodeToken0)) || + Decl::HasOrderPreservingCounter.Get(OpcodeToken0)) || op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW) { uint32_t *tokenStream = cur; @@ -235,9 +235,9 @@ DXBC::Reflection *Program::GuessReflection() desc.space = dcl.space; desc.reg = idx; desc.bindCount = 1; - desc.retType = dcl.resType[0]; + desc.retType = dcl.resource.resType[0]; - switch(dcl.dim) + switch(dcl.resource.dim) { case RESOURCE_DIMENSION_BUFFER: desc.dimension = DXBC::ShaderInputBind::DIM_BUFFER; break; case RESOURCE_DIMENSION_TEXTURE1D: @@ -330,7 +330,7 @@ DXBC::Reflection *Program::GuessReflection() desc.bindCount = 1; desc.retType = DXBC::RETURN_TYPE_MIXED; desc.dimension = DXBC::ShaderInputBind::DIM_BUFFER; - desc.numComps = dcl.stride; + desc.numComps = dcl.structured.stride; HandleResourceArrayIndices(dcl.operand.indices, desc); @@ -353,14 +353,14 @@ DXBC::Reflection *Program::GuessReflection() DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED; // doesn't seem to be anything that // determines append vs consume vs // rwstructured - if(dcl.hasCounter) + if(dcl.structured.hasCounter) desc.type = DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED_WITH_COUNTER; desc.space = dcl.space; desc.reg = idx; desc.bindCount = 1; desc.retType = DXBC::RETURN_TYPE_MIXED; desc.dimension = DXBC::ShaderInputBind::DIM_BUFFER; - desc.numComps = dcl.stride; + desc.numComps = dcl.structured.stride; HandleResourceArrayIndices(dcl.operand.indices, desc); @@ -383,9 +383,9 @@ DXBC::Reflection *Program::GuessReflection() desc.space = dcl.space; desc.reg = idx; desc.bindCount = 1; - desc.retType = dcl.resType[0]; + desc.retType = dcl.uav_typed.resType[0]; - switch(dcl.dim) + switch(dcl.uav_typed.dim) { case RESOURCE_DIMENSION_BUFFER: desc.dimension = DXBC::ShaderInputBind::DIM_BUFFER; break; case RESOURCE_DIMENSION_TEXTURE1D: @@ -440,7 +440,8 @@ DXBC::Reflection *Program::GuessReflection() bool isShaderModel51 = IsShaderModel51(); uint32_t idx = (uint32_t)dcl.operand.indices[0].index; uint32_t reg = isShaderModel51 ? (uint32_t)dcl.operand.indices[1].index : idx; - uint32_t numVecs = isShaderModel51 ? dcl.float4size : (uint32_t)dcl.operand.indices[1].index; + uint32_t numVecs = + isShaderModel51 ? dcl.cbufferVectorSize : (uint32_t)dcl.operand.indices[1].index; desc.name = StringFormat::Fmt("cbuffer%u", idx); desc.type = DXBC::ShaderInputBind::TYPE_CBUFFER; @@ -560,10 +561,10 @@ D3D_PRIMITIVE_TOPOLOGY Program::GetOutputTopology() for(const DXBCBytecode::Declaration &decl : m_Declarations) { if(decl.declaration == DXBCBytecode::OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY) - return decl.outTopology; + return decl.geomOutputTopology; if(decl.declaration == DXBCBytecode::OPCODE_DCL_TESS_DOMAIN) { - if(decl.domain == DXBCBytecode::DOMAIN_ISOLINE) + if(decl.tessDomain == DXBCBytecode::DOMAIN_ISOLINE) return D3D_PRIMITIVE_TOPOLOGY_LINELIST; else return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; diff --git a/renderdoc/driver/shaders/dxbc/dxbc_bytecode.h b/renderdoc/driver/shaders/dxbc/dxbc_bytecode.h index 4663554ca..976a8adfe 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_bytecode.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_bytecode.h @@ -390,7 +390,7 @@ enum CustomDataClass NUM_CUSTOMDATA_CLASSES, }; -enum ResinfoRetType +enum ResinfoRetType : uint8_t { RETTYPE_FLOAT = 0, RETTYPE_RCPFLOAT, @@ -409,7 +409,7 @@ enum ExtendedOpcodeType NUM_EXTENDED_TYPES, }; -enum NumOperandComponents +enum NumOperandComponents : uint8_t { NUMCOMPS_0 = 0, NUMCOMPS_1, @@ -426,7 +426,7 @@ enum SelectionMode SELECTION_SELECT_1, }; -enum OperandType +enum OperandType : uint8_t { TYPE_TEMP = 0, TYPE_INPUT, @@ -499,7 +499,7 @@ enum ExtendedOperandType NUM_EXTENDED_OPERAND_TYPES, }; -enum OperandModifier +enum OperandModifier : uint8_t { OPERAND_MODIFIER_NONE = 0, OPERAND_MODIFIER_NEG, @@ -509,7 +509,7 @@ enum OperandModifier NUM_MODIFIERS, }; -enum MinimumPrecision +enum MinimumPrecision : uint8_t { PRECISION_DEFAULT, PRECISION_FLOAT16, @@ -659,7 +659,7 @@ enum SemanticName NUM_SEMANTICS, }; -enum ResourceDimension +enum ResourceDimension : uint8_t { RESOURCE_DIMENSION_UNKNOWN = 0, RESOURCE_DIMENSION_BUFFER, @@ -678,7 +678,7 @@ enum ResourceDimension NUM_DIMENSIONS, }; -enum VendorAtomicOp +enum VendorAtomicOp : uint8_t { ATOMIC_OP_NONE = 0, ATOMIC_OP_AND, @@ -744,9 +744,8 @@ struct Operand numComponents = MAX_COMPONENTS; comps[0] = comps[1] = comps[2] = comps[3] = 0xff; values[0] = values[1] = values[2] = values[3] = 0; - modifier = OPERAND_MODIFIER_NONE; + flags = FLAG_NONE; precision = PRECISION_DEFAULT; - funcNum = 0; declaration = NULL; } @@ -762,12 +761,22 @@ struct Operand // operands can be given names to make the assembly easier to read. // mostly used on vendor extensions where the syntax is non-standard/undocumented - rdcstr name; + rdcinflexiblestr name; // temp register, constant buffer, input, output, other more specialised types OperandType type; // scalar, 4-vector or N-vector (currently unused) NumOperandComponents numComponents; + enum Flags : uint8_t + { + FLAG_NONE = 0x00, + // these correspond to the bits in OperandModifier + FLAG_NEG = 0x01, + FLAG_ABS = 0x02, + } flags; + + MinimumPrecision precision; + uint8_t comps[4]; // the components. each is 0,1,2,3 for x,y,z,w or 0xff if unused. // e.g. .x = { 0, -1, -1, -1 } // .zzw = { 2, 2, 3, -1 } @@ -825,12 +834,6 @@ struct Operand Declaration *declaration; uint32_t values[4]; // if this operand is immediate, the values are here - - OperandModifier modifier; // modifier, neg, abs(), -abs() etc. Could potentially be multiple - // modifiers in future - MinimumPrecision precision; - - uint32_t funcNum; // interface this operand refers to }; struct RegIndex @@ -858,7 +861,7 @@ struct RegIndex return false; } - rdcstr str; + rdcstr toString(const DXBC::Reflection *reflection, ToString flags) const; /////////////////////////////////////// @@ -874,163 +877,160 @@ struct RegIndex struct Declaration { - Declaration() - { - offset = 0; - length = 0; - instruction = 0; - declaration = NUM_REAL_OPCODES; - refactoringAllowed = doublePrecisionFloats = forceEarlyDepthStencil = - enableRawAndStructuredBuffers = skipOptimisation = enableMinPrecision = - enableD3D11_1DoubleExtensions = enableD3D11_1ShaderExtensions = - enableD3D12AllResourcesBound = false; - stride = 0; - hasCounter = false; - rov = false; - numTemps = 0; - tempReg = 0; - tempComponentCount = 0; - count = 0; - groupSize[0] = groupSize[1] = groupSize[2] = 0; - space = 0; - resType[0] = resType[1] = resType[2] = resType[3] = DXBC::NUM_RETURN_TYPES; - dim = RESOURCE_DIMENSION_UNKNOWN; - sampleCount = 0; - float4size = 0; - interpolation = INTERPOLATION_UNDEFINED; - systemValue = DXBC::SVNAME_UNDEFINED; - maxOut = 0; - samplerMode = NUM_SAMPLERS; - domain = DOMAIN_UNDEFINED; - controlPointCount = 0; - partition = PARTITIONING_UNDEFINED; - outPrim = OUTPUT_PRIMITIVE_UNDEFINED; - inPrim = PRIMITIVE_UNDEFINED; - outTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; - instanceCount = 0; - indexRange = 0; - maxTessFactor = 0.0f; - globallyCoherant = false; - functionBody = 0; - functionTable = 0; - interfaceID = 0; - numInterfaces = 0; - numTypes = 0; - } - rdcstr str; + // many decls use an operand to declare things + Operand operand; + // function table for interface operations + rdcarray functionTableContents; - /////////////////////////////////////// + OpcodeType declaration = NUM_REAL_OPCODES; + // all the resource/cbuffer declarations can have a space in SM5.1, extract it here + uint32_t space = 0; - uint64_t offset; - uint32_t length; + // opcode specific data in anonymous union + union + { + // OPCODE_DCL_GLOBAL_FLAGS + struct + { + bool refactoringAllowed; + bool doublePrecisionFloats; + bool forceEarlyDepthStencil; + bool enableRawAndStructuredBuffers; + bool skipOptimisation; + bool enableMinPrecision; + bool enableD3D11_1DoubleExtensions; + bool enableD3D11_1ShaderExtensions; + bool enableD3D12AllResourcesBound; + } global_flags; - size_t instruction; // happens before this instruction. Usually 0 as all decls are up front, - // but can be non-zero for e.g. HS control point and join phase - OpcodeType declaration; + // OPCODE_DCL_RESOURCE + struct + { + DXBC::ResourceRetType resType[4]; + ResourceDimension dim; + uint32_t sampleCount; + } resource; - Operand operand; // many decls use an operand to declare things + // OPCODE_DCL_RESOURCE_STRUCTURED + // OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED + struct + { + uint32_t stride; + bool hasCounter; + bool globallyCoherant; + bool rov; + } structured; - rdcarray immediateData; // raw data (like default value of operand) for immediate - // constant buffer decl + // OPCODE_DCL_RESOURCE_RAW + // OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW + struct + { + ResourceDimension dim; + bool globallyCoherant; + bool rov; + DXBC::ResourceRetType resType[4]; + } raw; - // opcode specific data + // OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED + struct + { + ResourceDimension dim; + bool globallyCoherant; + bool rov; + DXBC::ResourceRetType resType[4]; + } uav_typed; - // OPCODE_DCL_GLOBAL_FLAGS - bool refactoringAllowed; - bool doublePrecisionFloats; - bool forceEarlyDepthStencil; - bool enableRawAndStructuredBuffers; - bool skipOptimisation; - bool enableMinPrecision; - bool enableD3D11_1DoubleExtensions; - bool enableD3D11_1ShaderExtensions; - bool enableD3D12AllResourcesBound; + // OPCODE_DCL_TEMPS + uint32_t numTemps; - // OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED - uint32_t stride; - bool hasCounter; - bool rov; + // OPCODE_DCL_INDEXABLE_TEMP + struct + { + uint32_t numTemps; + uint32_t tempReg; + uint32_t tempComponentCount; + } indexable_temp; - // OPCODE_DCL_TEMPS, OPCODE_DCL_INDEXABLE_TEMP - uint32_t numTemps; + // OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW + uint32_t tgsmCount; - // OPCODE_DCL_INDEXABLE_TEMP - uint32_t tempReg; - uint32_t tempComponentCount; + // OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED + struct + { + uint32_t count; + uint32_t stride; + } tsgm_structured; - // OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED - uint32_t count; + // OPCODE_DCL_THREAD_GROUP + uint32_t groupSize[3]; - // OPCODE_DCL_THREAD_GROUP - uint32_t groupSize[3]; + // OPCODE_DCL_CONSTANT_BUFFER + uint32_t cbufferVectorSize; - // OPCODE_DCL_RESOURCE - uint32_t space; - DXBC::ResourceRetType resType[4]; - ResourceDimension dim; - uint32_t sampleCount; + // OPCODE_DCL_INPUT_PS + InterpolationMode inputInterpolation; - // OPCODE_DCL_CONSTANT_BUFFER - uint32_t float4size; + // OPCODE_DCL_INPUT_SIV + // OPCODE_DCL_INPUT_SGV + // OPCODE_DCL_INPUT_PS_SIV + // OPCODE_DCL_INPUT_PS_SGV + // OPCODE_DCL_OUTPUT_SIV + // OPCODE_DCL_OUTPUT_SGV + DXBC::SVSemantic systemValue; - // OPCODE_DCL_INPUT_PS - InterpolationMode interpolation; + // OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT + uint32_t maxVertexOutCount; - // OPCODE_DCL_INPUT_SIV - DXBC::SVSemantic systemValue; + // OPCODE_DCL_SAMPLER + SamplerMode samplerMode; - // OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT - uint32_t maxOut; + // OPCODE_DCL_TESS_DOMAIN + TessellatorDomain tessDomain; - // OPCODE_DCL_SAMPLER - SamplerMode samplerMode; + // OPCODE_DCL_INPUT_CONTROL_POINT_COUNT + uint32_t controlPointCount; - // OPCODE_DCL_TESS_DOMAIN - TessellatorDomain domain; + // OPCODE_DCL_TESS_PARTITIONING + TessellatorPartitioning tessPartition; - // OPCODE_DCL_INPUT_CONTROL_POINT_COUNT - uint32_t controlPointCount; + // OPCODE_DCL_TESS_OUTPUT_PRIMITIVE + TessellatorOutputPrimitive tessOutputPrimitive; - // OPCODE_DCL_TESS_PARTITIONING - TessellatorPartitioning partition; + // OPCODE_DCL_GS_INPUT_PRIMITIVE + PrimitiveType geomInputPrimitive; - // OPCODE_DCL_TESS_OUTPUT_PRIMITIVE - TessellatorOutputPrimitive outPrim; + // OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY + D3D_PRIMITIVE_TOPOLOGY geomOutputTopology; - // OPCODE_DCL_GS_INPUT_PRIMITIVE - PrimitiveType inPrim; + // OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT + // OPCODE_DCL_HS_JOIN_PHASE_INSTANCE_COUNT + // OPCODE_DCL_GS_INSTANCE_COUNT + uint32_t instanceCount; - // OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY - D3D_PRIMITIVE_TOPOLOGY outTopology; + // OPCODE_DCL_INDEX_RANGE + uint32_t indexRange; - // OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT - // OPCODE_DCL_HS_JOIN_PHASE_INSTANCE_COUNT - // OPCODE_DCL_GS_INSTANCE_COUNT - uint32_t instanceCount; + // OPCODE_DCL_HS_MAX_TESSFACTOR + float maxTessFactor; - // OPCODE_DCL_INDEX_RANGE - uint32_t indexRange; + // OPCODE_DCL_FUNCTION_BODY + uint32_t functionBody; - // OPCODE_DCL_HS_MAX_TESSFACTOR - float maxTessFactor; + // OPCODE_DCL_FUNCTION_TABLE + uint32_t functionTable; - // OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED - bool globallyCoherant; + // OPCODE_CUSTOMDATA + uint32_t customDataIndex; - // OPCODE_DCL_FUNCTION_BODY - uint32_t functionBody; - - // OPCODE_DCL_FUNCTION_TABLE - uint32_t functionTable; - - // OPCODE_CUSTOMDATA - uint32_t customDataIndex; - - // OPCODE_DCL_INTERFACE - uint32_t interfaceID; - uint32_t numInterfaces; - uint32_t numTypes; + // OPCODE_DCL_INTERFACE + struct + { + uint32_t interfaceID; + uint32_t numInterfaces; + uint32_t numTypes; + } iface; + }; }; struct Operation @@ -1039,11 +1039,9 @@ struct Operation { offset = 0; line = 0; - length = 0; stride = 0; operation = NUM_REAL_OPCODES; - nonzero = false; - saturate = false; + flags = FLAG_NONE; preciseValues = 0; resinfoRetType = NUM_RETTYPES; syncFlags = 0; @@ -1054,22 +1052,16 @@ struct Operation rdcstr str; + // for if, etc. If it checks for zero or nonzero + bool nonzero() const { return (flags & FLAG_NONZERO) != 0; } + // should the result be saturated. + bool saturate() const { return (flags & FLAG_SATURATE) != 0; } /////////////////////////////////////// uintptr_t offset; uint32_t line; - uint32_t length; OpcodeType operation; - bool nonzero; // for if, etc. If it checks for zero or nonzero - bool saturate; // should the result be saturated. - uint32_t preciseValues; // for multiple output operand operations - ResinfoRetType resinfoRetType; // return type of resinfo - uint32_t syncFlags; // sync flags (for compute shader sync operations) - - int texelOffset[3]; // U,V,W texel offset - ResourceDimension resDim; // resource dimension (tex2d etc) - DXBC::ResourceRetType resType[4]; // return type (e.g. for a sample operation) union { @@ -1077,6 +1069,25 @@ struct Operation uint32_t customDataIndex; }; + uint8_t preciseValues; // for multiple output operand operations + + union + { + ResinfoRetType resinfoRetType; // return type of resinfo + uint8_t syncFlags; // sync flags (for compute shader sync operations) + }; + + int8_t texelOffset[3] = {0}; // U,V,W texel offset + ResourceDimension resDim; // resource dimension (tex2d etc) + DXBC::ResourceRetType resType[4]; // return type (e.g. for a sample operation) + + enum Flags : uint8_t + { + FLAG_NONE = 0x0, + FLAG_NONZERO = 0x01, + FLAG_SATURATE = 0x02, + } flags; + rdcarray operands; }; @@ -1162,6 +1173,10 @@ protected: rdcarray m_Declarations; rdcarray m_Instructions; + // declarations later in shaders - only used for different phases in hull shaders where + // declarations can happen after some instructions + rdcarray> m_LateDeclarations; + // these functions modify tokenStream pointer to point after the item // ExtractOperation/ExtractDecl returns false if not an operation (ie. it's a declaration) bool DecodeOperation(uint32_t *&tokenStream, Operation &op, bool friendlyName); diff --git a/renderdoc/driver/shaders/dxbc/dxbc_bytecode_ops.cpp b/renderdoc/driver/shaders/dxbc/dxbc_bytecode_ops.cpp index 983a63cdd..3c95230e2 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_bytecode_ops.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_bytecode_ops.cpp @@ -84,7 +84,7 @@ bool Operand::operator==(const Operand &o) const return false; if(memcmp(comps, o.comps, 4) != 0) return false; - if(modifier != o.modifier) + if((flags & (FLAG_ABS | FLAG_NEG)) != (o.flags & (FLAG_ABS | FLAG_NEG))) return false; if(indices.size() != o.indices.size()) @@ -115,13 +115,13 @@ bool Operand::sameResource(const Operand &o) const return indices[0] == o.indices[0]; } -rdcstr Operand::toString(const DXBC::Reflection *reflection, ToString flags) const +rdcstr Operand::toString(const DXBC::Reflection *reflection, ToString toStrFlags) const { rdcstr str, regstr; - const bool decl = flags & ToString::IsDecl; - const bool swizzle = flags & ToString::ShowSwizzle; - const bool friendly = flags & ToString::FriendlyNameRegisters; + const bool decl = toStrFlags & ToString::IsDecl; + const bool swizzle = toStrFlags & ToString::ShowSwizzle; + const bool friendly = toStrFlags & ToString::FriendlyNameRegisters; char swiz[6] = {0, 0, 0, 0, 0, 0}; @@ -144,7 +144,8 @@ rdcstr Operand::toString(const DXBC::Reflection *reflection, ToString flags) con { RDCASSERT(indices.size() == 2); - str = StringFormat::Fmt("fp%s[%s][%u]", indices[0].str.c_str(), indices[1].str.c_str(), funcNum); + str = StringFormat::Fmt("fp%s[%s][%u]", indices[0].toString(reflection, toStrFlags).c_str(), + indices[1].toString(reflection, toStrFlags).c_str(), values[0]); } else if(type == TYPE_RESOURCE || type == TYPE_SAMPLER || type == TYPE_UNORDERED_ACCESS_VIEW) { @@ -158,7 +159,7 @@ rdcstr Operand::toString(const DXBC::Reflection *reflection, ToString flags) con if(type == TYPE_UNORDERED_ACCESS_VIEW) str = "u"; - str += indices[0].str; + str += indices[0].toString(reflection, toStrFlags); if(friendly && reflection && indices[0].absolute) { @@ -207,15 +208,18 @@ rdcstr Operand::toString(const DXBC::Reflection *reflection, ToString flags) con RDCASSERT(indices[1].absolute && indices[2].absolute); if(indices[1].index == indices[2].index) { - str += indices[0].str; + str += indices[0].toString(reflection, toStrFlags); } else { if(indices[2].index == 0xffffffff) - str += StringFormat::Fmt("%s[%s:unbound]", indices[0].str.c_str(), indices[1].str.c_str()); + str += StringFormat::Fmt("%s[%s:unbound]", + indices[0].toString(reflection, toStrFlags).c_str(), + indices[1].toString(reflection, toStrFlags).c_str()); else - str += StringFormat::Fmt("%s[%s:%s]", indices[0].str.c_str(), indices[1].str.c_str(), - indices[2].str.c_str()); + str += StringFormat::Fmt("%s[%s:%s]", indices[0].toString(reflection, toStrFlags).c_str(), + indices[1].toString(reflection, toStrFlags).c_str(), + indices[2].toString(reflection, toStrFlags).c_str()); } } else if(indices.size() == 2) @@ -236,14 +240,16 @@ rdcstr Operand::toString(const DXBC::Reflection *reflection, ToString flags) con RDCASSERT(indices[1].absolute && indices[1].index == declaration->operand.indices[1].index); // just include ID - str += indices[0].str; + str += indices[0].toString(reflection, toStrFlags); } else { if(indices[1].relative) - str += StringFormat::Fmt("%s%s", indices[0].str.c_str(), indices[1].str.c_str()); + str += StringFormat::Fmt("%s%s", indices[0].toString(reflection, toStrFlags).c_str(), + indices[1].toString(reflection, toStrFlags).c_str()); else - str += StringFormat::Fmt("%s[%s]", indices[0].str.c_str(), indices[1].str.c_str()); + str += StringFormat::Fmt("%s[%s]", indices[0].toString(reflection, toStrFlags).c_str(), + indices[1].toString(reflection, toStrFlags).c_str()); } } else @@ -268,23 +274,25 @@ rdcstr Operand::toString(const DXBC::Reflection *reflection, ToString flags) con // just include ID and vector index if(indices[2].relative) - str += StringFormat::Fmt("%s%s", indices[0].str.c_str(), indices[2].str.c_str()); + str += StringFormat::Fmt("%s%s", indices[0].toString(reflection, toStrFlags).c_str(), + indices[2].toString(reflection, toStrFlags).c_str()); else - str += StringFormat::Fmt("%s[%s]", indices[0].str.c_str(), indices[2].str.c_str()); + str += StringFormat::Fmt("%s[%s]", indices[0].toString(reflection, toStrFlags).c_str(), + indices[2].toString(reflection, toStrFlags).c_str()); } else { - str += indices[0].str; + str += indices[0].toString(reflection, toStrFlags); if(indices[1].relative) - str += indices[1].str; + str += indices[1].toString(reflection, toStrFlags); else - str += "[" + indices[1].str + "]"; + str += "[" + indices[1].toString(reflection, toStrFlags) + "]"; if(indices[2].relative) - str += indices[1].str; + str += indices[1].toString(reflection, toStrFlags); else - str += "[" + indices[2].str + "]"; + str += "[" + indices[2].toString(reflection, toStrFlags) + "]"; } } else @@ -299,16 +307,18 @@ rdcstr Operand::toString(const DXBC::Reflection *reflection, ToString flags) con RDCASSERT(indices[1].absolute && indices[2].absolute); if(indices[1].index == indices[2].index) { - str += indices[0].str; + str += indices[0].toString(reflection, toStrFlags); } else { if(indices[2].index == 0xffffffff) - str += - StringFormat::Fmt("%s[%s:unbound]", indices[0].str.c_str(), indices[1].str.c_str()); + str += StringFormat::Fmt("%s[%s:unbound]", + indices[0].toString(reflection, toStrFlags).c_str(), + indices[1].toString(reflection, toStrFlags).c_str()); else - str += StringFormat::Fmt("%s[%s:%s]", indices[0].str.c_str(), indices[1].str.c_str(), - indices[2].str.c_str()); + str += StringFormat::Fmt("%s[%s:%s]", indices[0].toString(reflection, toStrFlags).c_str(), + indices[1].toString(reflection, toStrFlags).c_str(), + indices[2].toString(reflection, toStrFlags).c_str()); } } } @@ -317,9 +327,11 @@ rdcstr Operand::toString(const DXBC::Reflection *reflection, ToString flags) con str = "cb"; if(indices[1].relative) - str += StringFormat::Fmt("%s%s", indices[0].str.c_str(), indices[1].str.c_str()); + str += StringFormat::Fmt("%s%s", indices[0].toString(reflection, toStrFlags).c_str(), + indices[1].toString(reflection, toStrFlags).c_str()); else - str += StringFormat::Fmt("%s[%s]", indices[0].str.c_str(), indices[1].str.c_str()); + str += StringFormat::Fmt("%s[%s]", indices[0].toString(reflection, toStrFlags).c_str(), + indices[1].toString(reflection, toStrFlags).c_str()); if(friendly && reflection && indices[0].absolute) { @@ -431,7 +443,7 @@ rdcstr Operand::toString(const DXBC::Reflection *reflection, ToString flags) con RDCASSERTEQUAL(indices.size(), 1); - str += indices[0].str; + str += indices[0].toString(reflection, toStrFlags); } else if(type == TYPE_IMMEDIATE_CONSTANT_BUFFER || type == TYPE_INDEXABLE_TEMP || type == TYPE_INPUT || type == TYPE_INPUT_CONTROL_POINT || @@ -455,7 +467,7 @@ rdcstr Operand::toString(const DXBC::Reflection *reflection, ToString flags) con if(indices.size() == 1 && type != TYPE_IMMEDIATE_CONSTANT_BUFFER) { - str += indices[0].str; + str += indices[0].toString(reflection, toStrFlags); } else { @@ -463,14 +475,14 @@ rdcstr Operand::toString(const DXBC::Reflection *reflection, ToString flags) con { if(i == 0 && type == TYPE_INDEXABLE_TEMP) { - str += indices[i].str; + str += indices[i].toString(reflection, toStrFlags); continue; } if(indices[i].relative) - str += indices[i].str; + str += indices[i].toString(reflection, toStrFlags); else - str += "[" + indices[i].str + "]"; + str += "[" + indices[i].toString(reflection, toStrFlags) + "]"; } } } @@ -546,22 +558,37 @@ rdcstr Operand::toString(const DXBC::Reflection *reflection, ToString flags) con str += "}"; } - if(modifier == OPERAND_MODIFIER_NEG) - str = "-" + str; - if(modifier == OPERAND_MODIFIER_ABS) + if(flags & FLAG_ABS) str = "abs(" + str + ")"; - if(modifier == OPERAND_MODIFIER_ABSNEG) - str = "-abs(" + str + ")"; + if(flags & FLAG_NEG) + str = "-" + str; if(decl && !regstr.empty()) str += StringFormat::Fmt(" (%s)", regstr.c_str()); if(!name.empty()) - str = name + "=" + str; + { + rdcstr n = name; + str = n + "=" + str; + } return str; } +rdcstr RegIndex::toString(const DXBC::Reflection *reflection, ToString toStrFlags) const +{ + if(relative) + { + return StringFormat::Fmt( + "[%s + %llu]", operand.toString(reflection, toStrFlags | ToString::ShowSwizzle).c_str(), + index); + } + else + { + return ToStr(index); + } +} + void Program::FetchComputeProperties(DXBC::Reflection *reflection) { if(m_ProgramWords.empty()) @@ -705,8 +732,6 @@ void Program::DecodeProgram() uintptr_t offset = cur - begin; - decl.instruction = m_Instructions.size(); - decl.offset = offset * sizeof(uint32_t); op.offset = offset * sizeof(uint32_t); if(!DecodeOperation(cur, op, friendly)) @@ -717,12 +742,21 @@ void Program::DecodeProgram() } else { - m_Declarations.push_back(decl); + // once we have a set of late declarations, push it into the most recent one. Otherwise + if(m_LateDeclarations.empty()) + m_Declarations.push_back(decl); + else + m_LateDeclarations.back().push_back(decl); } } else { m_Instructions.push_back(op); + + // each HS phase, start a new set of late declarations + if(op.operation == OPCODE_HS_CONTROL_POINT_PHASE || op.operation == OPCODE_HS_FORK_PHASE || + op.operation == OPCODE_HS_JOIN_PHASE) + m_LateDeclarations.push_back({}); } } @@ -743,7 +777,6 @@ void Program::DecodeProgram() if(lastRealOp != OPCODE_RET) { Operation implicitRet; - implicitRet.length = 1; implicitRet.offset = (end - begin) * sizeof(uint32_t); implicitRet.operation = OPCODE_RET; implicitRet.str = "ret"; @@ -784,8 +817,6 @@ void Program::MakeDisassemblyString() int indent = 0; - size_t d = 0; - LineColumnInfo prevLineInfo; rdcarray prevCallstack; @@ -802,32 +833,23 @@ void Program::MakeDisassemblyString() split(m_DebugInfo->Files[i].second, fileLines[i], '\n'); } + for(size_t d = 0; d < m_Declarations.size(); d++) + { + m_Disassembly += StringFormat::Fmt("% 4s %s\n", "", m_Declarations[d].str.c_str()); + linenum++; + + int32_t nl = m_Declarations[d].str.indexOf('\n'); + while(nl >= 0) + { + linenum++; + nl = m_Declarations[d].str.indexOf('\n', nl + 1); + } + } + + size_t lt = 0; + for(size_t i = 0; i < m_Instructions.size(); i++) { - for(; d < m_Declarations.size(); d++) - { - if(m_Declarations[d].instruction > i) - { - if(i == 0) - { - m_Disassembly += "\n"; - linenum++; - } - - break; - } - - m_Disassembly += StringFormat::Fmt("% 4s %s\n", "", m_Declarations[d].str.c_str()); - linenum++; - - int32_t nl = m_Declarations[d].str.indexOf('\n'); - while(nl >= 0) - { - linenum++; - nl = m_Declarations[d].str.indexOf('\n', nl + 1); - } - } - if(m_Instructions[i].operation == OPCODE_CUSTOMDATA || m_Instructions[i].operation == OPCODE_OPAQUE_CUSTOMDATA) { @@ -939,7 +961,29 @@ void Program::MakeDisassemblyString() if(m_Instructions[i].operation != OPCODE_HS_CONTROL_POINT_PHASE && m_Instructions[i].operation != OPCODE_HS_FORK_PHASE && m_Instructions[i].operation != OPCODE_HS_JOIN_PHASE) + { debugInst++; + } + else + { + if(lt < m_LateDeclarations.size()) + { + for(size_t d = 0; d < m_LateDeclarations[lt].size(); d++) + { + m_Disassembly += StringFormat::Fmt("% 4s %s\n", "", m_LateDeclarations[lt][d].str.c_str()); + linenum++; + + int32_t nl = m_LateDeclarations[lt][d].str.indexOf('\n'); + while(nl >= 0) + { + linenum++; + nl = m_LateDeclarations[lt][d].str.indexOf('\n', nl + 1); + } + } + + lt++; + } + } } } @@ -996,7 +1040,7 @@ bool Program::DecodeOperand(uint32_t *&tokenStream, ToString flags, Operand &ret if(type == EXTENDED_OPERAND_MODIFIER) { - retOper.modifier = ExtendedOperand::Modifier.Get(OperandTokenN); + retOper.flags = Operand::Flags(retOper.flags | ExtendedOperand::Modifier.Get(OperandTokenN)); retOper.precision = ExtendedOperand::MinPrecision.Get(OperandTokenN); } else @@ -1066,18 +1110,6 @@ bool Program::DecodeOperand(uint32_t *&tokenStream, ToString flags, Operand &ret } RDCASSERT(retOper.indices[idx].relative || retOper.indices[idx].absolute); - - if(retOper.indices[idx].relative) - { - retOper.indices[idx].str = StringFormat::Fmt( - "[%s + %llu]", - retOper.indices[idx].operand.toString(m_Reflection, flags | ToString::ShowSwizzle).c_str(), - retOper.indices[idx].index); - } - else - { - retOper.indices[idx].str = ToStr(retOper.indices[idx].index); - } } if(retOper.type == TYPE_RESOURCE || retOper.type == TYPE_SAMPLER || @@ -1190,7 +1222,7 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie return true; } - retDecl.length = Opcode::Length.Get(OpcodeToken0); + uint32_t declLength = Opcode::Length.Get(OpcodeToken0); tokenStream++; @@ -1198,75 +1230,79 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie if(op == OPCODE_DCL_GLOBAL_FLAGS) { - retDecl.refactoringAllowed = Decl::RefactoringAllowed.Get(OpcodeToken0); - retDecl.doublePrecisionFloats = Decl::DoubleFloatOps.Get(OpcodeToken0); - retDecl.forceEarlyDepthStencil = Decl::ForceEarlyDepthStencil.Get(OpcodeToken0); - retDecl.enableRawAndStructuredBuffers = Decl::EnableRawStructuredBufs.Get(OpcodeToken0); - retDecl.skipOptimisation = Decl::SkipOptimisation.Get(OpcodeToken0); - retDecl.enableMinPrecision = Decl::EnableMinPrecision.Get(OpcodeToken0); - retDecl.enableD3D11_1DoubleExtensions = Decl::EnableD3D11_1DoubleExtensions.Get(OpcodeToken0); - retDecl.enableD3D11_1ShaderExtensions = Decl::EnableD3D11_1ShaderExtensions.Get(OpcodeToken0); - retDecl.enableD3D12AllResourcesBound = Decl::EnableD3D12AllResourcesBound.Get(OpcodeToken0); + retDecl.global_flags.refactoringAllowed = Decl::RefactoringAllowed.Get(OpcodeToken0); + retDecl.global_flags.doublePrecisionFloats = Decl::DoubleFloatOps.Get(OpcodeToken0); + retDecl.global_flags.forceEarlyDepthStencil = Decl::ForceEarlyDepthStencil.Get(OpcodeToken0); + retDecl.global_flags.enableRawAndStructuredBuffers = + Decl::EnableRawStructuredBufs.Get(OpcodeToken0); + retDecl.global_flags.skipOptimisation = Decl::SkipOptimisation.Get(OpcodeToken0); + retDecl.global_flags.enableMinPrecision = Decl::EnableMinPrecision.Get(OpcodeToken0); + retDecl.global_flags.enableD3D11_1DoubleExtensions = + Decl::EnableD3D11_1DoubleExtensions.Get(OpcodeToken0); + retDecl.global_flags.enableD3D11_1ShaderExtensions = + Decl::EnableD3D11_1ShaderExtensions.Get(OpcodeToken0); + retDecl.global_flags.enableD3D12AllResourcesBound = + Decl::EnableD3D12AllResourcesBound.Get(OpcodeToken0); retDecl.str += " "; bool added = false; - if(retDecl.refactoringAllowed) + if(retDecl.global_flags.refactoringAllowed) { retDecl.str += "refactoringAllowed"; added = true; } - if(retDecl.doublePrecisionFloats) + if(retDecl.global_flags.doublePrecisionFloats) { if(added) retDecl.str += ", "; retDecl.str += "doublePrecisionFloats"; added = true; } - if(retDecl.forceEarlyDepthStencil) + if(retDecl.global_flags.forceEarlyDepthStencil) { if(added) retDecl.str += ", "; retDecl.str += "forceEarlyDepthStencil"; added = true; } - if(retDecl.enableRawAndStructuredBuffers) + if(retDecl.global_flags.enableRawAndStructuredBuffers) { if(added) retDecl.str += ", "; retDecl.str += "enableRawAndStructuredBuffers"; added = true; } - if(retDecl.skipOptimisation) + if(retDecl.global_flags.skipOptimisation) { if(added) retDecl.str += ", "; retDecl.str += "skipOptimisation"; added = true; } - if(retDecl.enableMinPrecision) + if(retDecl.global_flags.enableMinPrecision) { if(added) retDecl.str += ", "; retDecl.str += "enableMinPrecision"; added = true; } - if(retDecl.enableD3D11_1DoubleExtensions) + if(retDecl.global_flags.enableD3D11_1DoubleExtensions) { if(added) retDecl.str += ", "; retDecl.str += "doubleExtensions"; added = true; } - if(retDecl.enableD3D11_1ShaderExtensions) + if(retDecl.global_flags.enableD3D11_1ShaderExtensions) { if(added) retDecl.str += ", "; retDecl.str += "shaderExtensions"; added = true; } - if(retDecl.enableD3D12AllResourcesBound) + if(retDecl.global_flags.enableD3D12AllResourcesBound) { if(added) retDecl.str += ", "; @@ -1287,10 +1323,10 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie { // Store the size provided. If there's no reflection data, this will be // necessary to guess the buffer size properly - retDecl.float4size = tokenStream[0]; + retDecl.cbufferVectorSize = tokenStream[0]; tokenStream++; - retDecl.str += StringFormat::Fmt("[%u]", retDecl.float4size); + retDecl.str += StringFormat::Fmt("[%u]", retDecl.cbufferVectorSize); } retDecl.str += ", "; @@ -1343,23 +1379,24 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie } else if(op == OPCODE_DCL_INDEXABLE_TEMP) { - retDecl.tempReg = tokenStream[0]; + retDecl.indexable_temp.tempReg = tokenStream[0]; tokenStream++; - retDecl.numTemps = tokenStream[0]; + retDecl.indexable_temp.numTemps = tokenStream[0]; tokenStream++; - retDecl.tempComponentCount = tokenStream[0]; + retDecl.indexable_temp.tempComponentCount = tokenStream[0]; tokenStream++; // I don't think the compiler will ever declare a non-compact list of indexable temps, but just // to be sure our indexing works let's be safe. - if(retDecl.tempReg >= m_IndexTempSizes.size()) - m_IndexTempSizes.resize(retDecl.tempReg + 1); - m_IndexTempSizes[retDecl.tempReg] = retDecl.numTemps; + if(retDecl.indexable_temp.tempReg >= m_IndexTempSizes.size()) + m_IndexTempSizes.resize(retDecl.indexable_temp.tempReg + 1); + m_IndexTempSizes[retDecl.indexable_temp.tempReg] = retDecl.indexable_temp.numTemps; - retDecl.str += StringFormat::Fmt(" x%u[%u], %u", retDecl.tempReg, retDecl.numTemps, - retDecl.tempComponentCount); + retDecl.str += StringFormat::Fmt(" x%u[%u], %u", retDecl.indexable_temp.tempReg, + retDecl.indexable_temp.numTemps, + retDecl.indexable_temp.tempComponentCount); } else if(op == OPCODE_DCL_OUTPUT) { @@ -1374,11 +1411,11 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie { retDecl.str += " "; - retDecl.maxOut = tokenStream[0]; + retDecl.maxVertexOutCount = tokenStream[0]; tokenStream++; - retDecl.str += StringFormat::Fmt(" %u", retDecl.maxOut); + retDecl.str += StringFormat::Fmt(" %u", retDecl.maxVertexOutCount); } else if(op == OPCODE_DCL_INPUT_SIV || op == OPCODE_DCL_INPUT_SGV || op == OPCODE_DCL_INPUT_PS_SIV || op == OPCODE_DCL_INPUT_PS_SGV || @@ -1439,13 +1476,13 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie } else if(op == OPCODE_DCL_RESOURCE) { - retDecl.dim = Decl::ResourceDim.Get(OpcodeToken0); + retDecl.resource.dim = Decl::ResourceDim.Get(OpcodeToken0); - retDecl.sampleCount = 0; - if(retDecl.dim == RESOURCE_DIMENSION_TEXTURE2DMS || - retDecl.dim == RESOURCE_DIMENSION_TEXTURE2DMSARRAY) + retDecl.resource.sampleCount = 0; + if(retDecl.resource.dim == RESOURCE_DIMENSION_TEXTURE2DMS || + retDecl.resource.dim == RESOURCE_DIMENSION_TEXTURE2DMSARRAY) { - retDecl.sampleCount = Decl::SampleCount.Get(OpcodeToken0); + retDecl.resource.sampleCount = Decl::SampleCount.Get(OpcodeToken0); } bool ret = DecodeOperand(tokenStream, flags, retDecl.operand); @@ -1454,29 +1491,29 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie uint32_t ResourceReturnTypeToken = tokenStream[0]; tokenStream++; - retDecl.resType[0] = Decl::ReturnTypeX.Get(ResourceReturnTypeToken); - retDecl.resType[1] = Decl::ReturnTypeY.Get(ResourceReturnTypeToken); - retDecl.resType[2] = Decl::ReturnTypeZ.Get(ResourceReturnTypeToken); - retDecl.resType[3] = Decl::ReturnTypeW.Get(ResourceReturnTypeToken); + retDecl.resource.resType[0] = Decl::ReturnTypeX.Get(ResourceReturnTypeToken); + retDecl.resource.resType[1] = Decl::ReturnTypeY.Get(ResourceReturnTypeToken); + retDecl.resource.resType[2] = Decl::ReturnTypeZ.Get(ResourceReturnTypeToken); + retDecl.resource.resType[3] = Decl::ReturnTypeW.Get(ResourceReturnTypeToken); retDecl.str += "_"; - retDecl.str += ToStr(retDecl.dim); - if(retDecl.sampleCount > 0) + retDecl.str += ToStr(retDecl.resource.dim); + if(retDecl.resource.sampleCount > 0) { retDecl.str += "("; - retDecl.str += ToStr(retDecl.sampleCount); + retDecl.str += ToStr(retDecl.resource.sampleCount); retDecl.str += ")"; } retDecl.str += " "; retDecl.str += "("; - retDecl.str += ToStr(retDecl.resType[0]); + retDecl.str += ToStr(retDecl.resource.resType[0]); retDecl.str += ","; - retDecl.str += ToStr(retDecl.resType[1]); + retDecl.str += ToStr(retDecl.resource.resType[1]); retDecl.str += ","; - retDecl.str += ToStr(retDecl.resType[2]); + retDecl.str += ToStr(retDecl.resource.resType[2]); retDecl.str += ","; - retDecl.str += ToStr(retDecl.resType[3]); + retDecl.str += ToStr(retDecl.resource.resType[3]); retDecl.str += ")"; retDecl.str += " " + retDecl.operand.toString(m_Reflection, flags); @@ -1498,13 +1535,13 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie } else if(op == OPCODE_DCL_INPUT_PS) { - retDecl.interpolation = Decl::InterpolationMode.Get(OpcodeToken0); + retDecl.inputInterpolation = Decl::InterpolationMode.Get(OpcodeToken0); bool ret = DecodeOperand(tokenStream, flags, retDecl.operand); RDCASSERT(ret); retDecl.str += " "; - retDecl.str += ToStr(retDecl.interpolation); + retDecl.str += ToStr(retDecl.inputInterpolation); retDecl.str += " "; retDecl.str += retDecl.operand.toString(m_Reflection, flags | ToString::ShowSwizzle); @@ -1543,11 +1580,11 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie bool ret = DecodeOperand(tokenStream, flags, retDecl.operand); RDCASSERT(ret); - retDecl.count = tokenStream[0]; + retDecl.tgsmCount = tokenStream[0]; tokenStream++; retDecl.str += retDecl.operand.toString(m_Reflection, flags); - retDecl.str += StringFormat::Fmt(", %u", retDecl.count); + retDecl.str += StringFormat::Fmt(", %u", retDecl.tgsmCount); } else if(op == OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED) { @@ -1556,14 +1593,15 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie bool ret = DecodeOperand(tokenStream, flags, retDecl.operand); RDCASSERT(ret); - retDecl.stride = tokenStream[0]; + retDecl.tsgm_structured.stride = tokenStream[0]; tokenStream++; - retDecl.count = tokenStream[0]; + retDecl.tsgm_structured.count = tokenStream[0]; tokenStream++; retDecl.str += retDecl.operand.toString(m_Reflection, flags); - retDecl.str += StringFormat::Fmt(", %u, %u", retDecl.stride, retDecl.count); + retDecl.str += + StringFormat::Fmt(", %u, %u", retDecl.tsgm_structured.stride, retDecl.tsgm_structured.count); } else if(op == OPCODE_DCL_INPUT_CONTROL_POINT_COUNT || op == OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT) { @@ -1573,106 +1611,107 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie } else if(op == OPCODE_DCL_TESS_DOMAIN) { - retDecl.domain = Decl::TessDomain.Get(OpcodeToken0); + retDecl.tessDomain = Decl::TessDomain.Get(OpcodeToken0); retDecl.str += " "; - if(retDecl.domain == DOMAIN_ISOLINE) + if(retDecl.tessDomain == DOMAIN_ISOLINE) retDecl.str += "domain_isoline"; - else if(retDecl.domain == DOMAIN_TRI) + else if(retDecl.tessDomain == DOMAIN_TRI) retDecl.str += "domain_tri"; - else if(retDecl.domain == DOMAIN_QUAD) + else if(retDecl.tessDomain == DOMAIN_QUAD) retDecl.str += "domain_quad"; else RDCERR("Unexpected Tessellation domain"); } else if(op == OPCODE_DCL_TESS_PARTITIONING) { - retDecl.partition = Decl::TessPartitioning.Get(OpcodeToken0); + retDecl.tessPartition = Decl::TessPartitioning.Get(OpcodeToken0); retDecl.str += " "; - if(retDecl.partition == PARTITIONING_INTEGER) + if(retDecl.tessPartition == PARTITIONING_INTEGER) retDecl.str += "partitioning_integer"; - else if(retDecl.partition == PARTITIONING_POW2) + else if(retDecl.tessPartition == PARTITIONING_POW2) retDecl.str += "partitioning_pow2"; - else if(retDecl.partition == PARTITIONING_FRACTIONAL_ODD) + else if(retDecl.tessPartition == PARTITIONING_FRACTIONAL_ODD) retDecl.str += "partitioning_fractional_odd"; - else if(retDecl.partition == PARTITIONING_FRACTIONAL_EVEN) + else if(retDecl.tessPartition == PARTITIONING_FRACTIONAL_EVEN) retDecl.str += "partitioning_fractional_even"; else RDCERR("Unexpected Partitioning"); } else if(op == OPCODE_DCL_GS_INPUT_PRIMITIVE) { - retDecl.inPrim = Decl::InputPrimitive.Get(OpcodeToken0); + retDecl.geomInputPrimitive = Decl::InputPrimitive.Get(OpcodeToken0); retDecl.str += " "; - if(retDecl.inPrim == PRIMITIVE_POINT) + if(retDecl.geomInputPrimitive == PRIMITIVE_POINT) retDecl.str += "point"; - else if(retDecl.inPrim == PRIMITIVE_LINE) + else if(retDecl.geomInputPrimitive == PRIMITIVE_LINE) retDecl.str += "line"; - else if(retDecl.inPrim == PRIMITIVE_TRIANGLE) + else if(retDecl.geomInputPrimitive == PRIMITIVE_TRIANGLE) retDecl.str += "triangle"; - else if(retDecl.inPrim == PRIMITIVE_LINE_ADJ) + else if(retDecl.geomInputPrimitive == PRIMITIVE_LINE_ADJ) retDecl.str += "line_adj"; - else if(retDecl.inPrim == PRIMITIVE_TRIANGLE_ADJ) + else if(retDecl.geomInputPrimitive == PRIMITIVE_TRIANGLE_ADJ) retDecl.str += "triangle_adj"; - else if(retDecl.inPrim >= PRIMITIVE_1_CONTROL_POINT_PATCH && - retDecl.inPrim <= PRIMITIVE_32_CONTROL_POINT_PATCH) + else if(retDecl.geomInputPrimitive >= PRIMITIVE_1_CONTROL_POINT_PATCH && + retDecl.geomInputPrimitive <= PRIMITIVE_32_CONTROL_POINT_PATCH) { - retDecl.str += StringFormat::Fmt("control_point_patch_%u", - 1 + int(retDecl.inPrim - PRIMITIVE_1_CONTROL_POINT_PATCH)); + retDecl.str += + StringFormat::Fmt("control_point_patch_%u", + 1 + int(retDecl.geomInputPrimitive - PRIMITIVE_1_CONTROL_POINT_PATCH)); } else RDCERR("Unexpected primitive type"); } else if(op == OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY) { - retDecl.outTopology = Decl::OutputPrimitiveTopology.Get(OpcodeToken0); + retDecl.geomOutputTopology = Decl::OutputPrimitiveTopology.Get(OpcodeToken0); retDecl.str += " "; - if(retDecl.outTopology == D3D_PRIMITIVE_TOPOLOGY_POINTLIST) + if(retDecl.geomOutputTopology == D3D_PRIMITIVE_TOPOLOGY_POINTLIST) retDecl.str += "point"; - else if(retDecl.outTopology == D3D_PRIMITIVE_TOPOLOGY_LINELIST) + else if(retDecl.geomOutputTopology == D3D_PRIMITIVE_TOPOLOGY_LINELIST) retDecl.str += "linelist"; - else if(retDecl.outTopology == D3D_PRIMITIVE_TOPOLOGY_LINESTRIP) + else if(retDecl.geomOutputTopology == D3D_PRIMITIVE_TOPOLOGY_LINESTRIP) retDecl.str += "linestrip"; - else if(retDecl.outTopology == D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST) + else if(retDecl.geomOutputTopology == D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST) retDecl.str += "trianglelist"; - else if(retDecl.outTopology == D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP) + else if(retDecl.geomOutputTopology == D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP) retDecl.str += "trianglestrip"; - else if(retDecl.outTopology == D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ) + else if(retDecl.geomOutputTopology == D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ) retDecl.str += "linelist_adj"; - else if(retDecl.outTopology == D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ) + else if(retDecl.geomOutputTopology == D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ) retDecl.str += "linestrip_adj"; - else if(retDecl.outTopology == D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ) + else if(retDecl.geomOutputTopology == D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ) retDecl.str += "trianglelist_adj"; - else if(retDecl.outTopology == D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ) + else if(retDecl.geomOutputTopology == D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ) retDecl.str += "trianglestrip_adj"; else RDCERR("Unexpected primitive topology"); } else if(op == OPCODE_DCL_TESS_OUTPUT_PRIMITIVE) { - retDecl.outPrim = Decl::OutputPrimitive.Get(OpcodeToken0); + retDecl.tessOutputPrimitive = Decl::OutputPrimitive.Get(OpcodeToken0); retDecl.str += " "; - if(retDecl.outPrim == OUTPUT_PRIMITIVE_POINT) + if(retDecl.tessOutputPrimitive == OUTPUT_PRIMITIVE_POINT) retDecl.str += "output_point"; - else if(retDecl.outPrim == OUTPUT_PRIMITIVE_LINE) + else if(retDecl.tessOutputPrimitive == OUTPUT_PRIMITIVE_LINE) retDecl.str += "output_line"; - else if(retDecl.outPrim == OUTPUT_PRIMITIVE_TRIANGLE_CW) + else if(retDecl.tessOutputPrimitive == OUTPUT_PRIMITIVE_TRIANGLE_CW) retDecl.str += "output_triangle_cw"; - else if(retDecl.outPrim == OUTPUT_PRIMITIVE_TRIANGLE_CCW) + else if(retDecl.tessOutputPrimitive == OUTPUT_PRIMITIVE_TRIANGLE_CCW) retDecl.str += "output_triangle_ccw"; else RDCERR("Unexpected output primitive"); } else if(op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW || op == OPCODE_DCL_RESOURCE_RAW) { - retDecl.rov = (op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW) && - Decl::RasterizerOrderedAccess.Get(OpcodeToken0); + retDecl.raw.rov = (op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW) && + Decl::RasterizerOrderedAccess.Get(OpcodeToken0); - retDecl.globallyCoherant = + retDecl.raw.globallyCoherant = (op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW) & Decl::GloballyCoherent.Get(OpcodeToken0); retDecl.str += " "; @@ -1682,10 +1721,10 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie retDecl.str += retDecl.operand.toString(m_Reflection, flags); - if(retDecl.globallyCoherant) + if(retDecl.raw.globallyCoherant) retDecl.str += ", globallyCoherant"; - if(retDecl.rov) + if(retDecl.raw.rov) retDecl.str += ", rasterizerOrderedAccess"; retDecl.space = 0; @@ -1705,33 +1744,33 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie } else if(op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED || op == OPCODE_DCL_RESOURCE_STRUCTURED) { - retDecl.hasCounter = (op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED) && - Opcode::HasOrderPreservingCounter.Get(OpcodeToken0); + retDecl.structured.hasCounter = (op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED) && + Decl::HasOrderPreservingCounter.Get(OpcodeToken0); - retDecl.rov = (op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED) && - Decl::RasterizerOrderedAccess.Get(OpcodeToken0); + retDecl.structured.rov = (op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED) && + Decl::RasterizerOrderedAccess.Get(OpcodeToken0); - retDecl.globallyCoherant = (op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED) & - Decl::GloballyCoherent.Get(OpcodeToken0); + retDecl.structured.globallyCoherant = (op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED) & + Decl::GloballyCoherent.Get(OpcodeToken0); retDecl.str += " "; bool ret = DecodeOperand(tokenStream, flags, retDecl.operand); RDCASSERT(ret); - retDecl.stride = tokenStream[0]; + retDecl.structured.stride = tokenStream[0]; tokenStream++; retDecl.str += retDecl.operand.toString(m_Reflection, flags); - retDecl.str += StringFormat::Fmt(", %u", retDecl.stride); + retDecl.str += StringFormat::Fmt(", %u", retDecl.structured.stride); - if(retDecl.hasCounter) + if(retDecl.structured.hasCounter) retDecl.str += ", hasOrderPreservingCounter"; - if(retDecl.globallyCoherant) + if(retDecl.structured.globallyCoherant) retDecl.str += ", globallyCoherant"; - if(retDecl.rov) + if(retDecl.structured.rov) retDecl.str += ", rasterizerOrderedAccess"; retDecl.space = 0; @@ -1751,16 +1790,16 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie } else if(op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED) { - retDecl.dim = Decl::ResourceDim.Get(OpcodeToken0); + retDecl.uav_typed.dim = Decl::ResourceDim.Get(OpcodeToken0); - retDecl.globallyCoherant = Decl::GloballyCoherent.Get(OpcodeToken0); + retDecl.uav_typed.globallyCoherant = Decl::GloballyCoherent.Get(OpcodeToken0); - retDecl.rov = Decl::RasterizerOrderedAccess.Get(OpcodeToken0); + retDecl.uav_typed.rov = Decl::RasterizerOrderedAccess.Get(OpcodeToken0); retDecl.str += "_"; - retDecl.str += ToStr(retDecl.dim); + retDecl.str += ToStr(retDecl.uav_typed.dim); - if(retDecl.globallyCoherant) + if(retDecl.uav_typed.globallyCoherant) retDecl.str += "_glc"; bool ret = DecodeOperand(tokenStream, flags, retDecl.operand); @@ -1769,28 +1808,28 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie uint32_t ResourceReturnTypeToken = tokenStream[0]; tokenStream++; - retDecl.resType[0] = Decl::ReturnTypeX.Get(ResourceReturnTypeToken); - retDecl.resType[1] = Decl::ReturnTypeY.Get(ResourceReturnTypeToken); - retDecl.resType[2] = Decl::ReturnTypeZ.Get(ResourceReturnTypeToken); - retDecl.resType[3] = Decl::ReturnTypeW.Get(ResourceReturnTypeToken); + retDecl.uav_typed.resType[0] = Decl::ReturnTypeX.Get(ResourceReturnTypeToken); + retDecl.uav_typed.resType[1] = Decl::ReturnTypeY.Get(ResourceReturnTypeToken); + retDecl.uav_typed.resType[2] = Decl::ReturnTypeZ.Get(ResourceReturnTypeToken); + retDecl.uav_typed.resType[3] = Decl::ReturnTypeW.Get(ResourceReturnTypeToken); retDecl.str += " "; retDecl.str += "("; - retDecl.str += ToStr(retDecl.resType[0]); + retDecl.str += ToStr(retDecl.uav_typed.resType[0]); retDecl.str += ","; - retDecl.str += ToStr(retDecl.resType[1]); + retDecl.str += ToStr(retDecl.uav_typed.resType[1]); retDecl.str += ","; - retDecl.str += ToStr(retDecl.resType[2]); + retDecl.str += ToStr(retDecl.uav_typed.resType[2]); retDecl.str += ","; - retDecl.str += ToStr(retDecl.resType[3]); + retDecl.str += ToStr(retDecl.uav_typed.resType[3]); retDecl.str += ")"; retDecl.str += " "; retDecl.str += retDecl.operand.toString(m_Reflection, flags); - if(retDecl.rov) + if(retDecl.uav_typed.rov) retDecl.str += ", rasterizerOrderedAccess"; retDecl.space = 0; @@ -1850,7 +1889,7 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie if(i + 1 < TableLength) retDecl.str += ", "; - retDecl.immediateData.push_back(tokenStream[0]); + retDecl.functionTableContents.push_back(tokenStream[0]); tokenStream++; } @@ -1858,20 +1897,20 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie } else if(op == OPCODE_DCL_INTERFACE) { - retDecl.interfaceID = tokenStream[0]; + retDecl.iface.interfaceID = tokenStream[0]; tokenStream++; - retDecl.numTypes = tokenStream[0]; + retDecl.iface.numTypes = tokenStream[0]; tokenStream++; uint32_t CountToken = tokenStream[0]; tokenStream++; - retDecl.numInterfaces = Decl::NumInterfaces.Get(CountToken); + retDecl.iface.numInterfaces = Decl::NumInterfaces.Get(CountToken); uint32_t TableLength = Decl::TableLength.Get(CountToken); - retDecl.str += StringFormat::Fmt(" fp%u[%u][%u]", retDecl.interfaceID, retDecl.numInterfaces, - retDecl.numTypes); + retDecl.str += StringFormat::Fmt(" fp%u[%u][%u]", retDecl.iface.interfaceID, + retDecl.iface.numInterfaces, retDecl.iface.numTypes); retDecl.str += " = {"; @@ -1882,7 +1921,7 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie if(i + 1 < TableLength) retDecl.str += ", "; - retDecl.immediateData.push_back(tokenStream[0]); + retDecl.functionTableContents.push_back(tokenStream[0]); tokenStream++; } @@ -1911,7 +1950,7 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie } // make sure we consumed all uint32s - RDCASSERT((uint32_t)(tokenStream - begin) == retDecl.length); + RDCASSERT((uint32_t)(tokenStream - begin) == declLength); return true; } @@ -1930,14 +1969,21 @@ bool Program::DecodeOperation(uint32_t *&tokenStream, Operation &retOp, bool fri if(IsDeclaration(op) && op != OPCODE_CUSTOMDATA) return false; + uint32_t opLength = Opcode::Length.Get(OpcodeToken0); + // possibly only set these when applicable retOp.operation = op; - retOp.length = Opcode::Length.Get(OpcodeToken0); - retOp.nonzero = Opcode::TestNonZero.Get(OpcodeToken0) == 1; - retOp.saturate = Opcode::Saturate.Get(OpcodeToken0) == 1; + if(Opcode::TestNonZero.Get(OpcodeToken0)) + retOp.flags = Operation::Flags(retOp.flags | Operation::FLAG_NONZERO); + if(Opcode::Saturate.Get(OpcodeToken0)) + retOp.flags = Operation::Flags(retOp.flags | Operation::FLAG_SATURATE); retOp.preciseValues = Opcode::PreciseValues.Get(OpcodeToken0); - retOp.resinfoRetType = Opcode::ResinfoReturn.Get(OpcodeToken0); - retOp.syncFlags = Opcode::SyncFlags.Get(OpcodeToken0); + + if(op == OPCODE_RESINFO) + retOp.resinfoRetType = Opcode::ResinfoReturn.Get(OpcodeToken0); + + if(op == OPCODE_SYNC) + retOp.syncFlags = Opcode::SyncFlags.Get(OpcodeToken0); bool extended = Opcode::Extended.Get(OpcodeToken0) == 1; @@ -2150,16 +2196,16 @@ bool Program::DecodeOperation(uint32_t *&tokenStream, Operation &retOp, bool fri if(op == OPCODE_INTERFACE_CALL) { - retOp.operands[0].funcNum = func; + retOp.operands[0].values[0] = func; } if(op == OPCODE_IF || op == OPCODE_BREAKC || op == OPCODE_CALLC || op == OPCODE_CONTINUEC || op == OPCODE_RETC || op == OPCODE_DISCARD) - retOp.str += retOp.nonzero ? "_nz" : "_z"; + retOp.str += retOp.nonzero() ? "_nz" : "_z"; if(op != OPCODE_SYNC) { - retOp.str += retOp.saturate ? "_sat" : ""; + retOp.str += retOp.saturate() ? "_sat" : ""; } if(retOp.preciseValues) @@ -2187,21 +2233,21 @@ bool Program::DecodeOperation(uint32_t *&tokenStream, Operation &retOp, bool fri } #if ENABLED(RDOC_DEVEL) - if((uint32_t)(tokenStream - begin) > retOp.length) + if((uint32_t)(tokenStream - begin) > opLength) { RDCERR("Consumed too many tokens for %d!", retOp.operation); // try to recover by rewinding the stream, this instruction will be garbage but at least the // next ones will be correct - uint32_t overread = (uint32_t)(tokenStream - begin) - retOp.length; + uint32_t overread = (uint32_t)(tokenStream - begin) - opLength; tokenStream -= overread; } - else if((uint32_t)(tokenStream - begin) < retOp.length) + else if((uint32_t)(tokenStream - begin) < opLength) { // sometimes this just happens, which is why we only print this in non-release so we can // inspect it. There's probably not much we can do though, it's just magic. RDCWARN("Consumed too few tokens for %d!", retOp.operation); - uint32_t missing = retOp.length - (uint32_t)(tokenStream - begin); + uint32_t missing = opLength - (uint32_t)(tokenStream - begin); for(uint32_t i = 0; i < missing; i++) { RDCLOG("missing token %d: 0x%08x", i, tokenStream[0]); @@ -2210,12 +2256,12 @@ bool Program::DecodeOperation(uint32_t *&tokenStream, Operation &retOp, bool fri } // make sure we consumed all uint32s - RDCASSERT((uint32_t)(tokenStream - begin) == retOp.length); + RDCASSERT((uint32_t)(tokenStream - begin) == opLength); #else // there's no good documentation for this, we're freewheeling blind in a nightmarish hellscape. // Instead of assuming we can predictably decode the whole of every opcode, just advance by the // defined length. - tokenStream = begin + retOp.length; + tokenStream = begin + opLength; #endif return true; diff --git a/renderdoc/driver/shaders/dxbc/dxbc_bytecode_ops.h b/renderdoc/driver/shaders/dxbc/dxbc_bytecode_ops.h index fdcff39e9..a422749ae 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_bytecode_ops.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_bytecode_ops.h @@ -116,7 +116,7 @@ static MaskedElement Extended; static MaskedElement CustomClass; // opcode specific -static MaskedElement PreciseValues; +static MaskedElement PreciseValues; // several static MaskedElement Saturate; @@ -126,16 +126,12 @@ static MaskedElement TestNonZero; static MaskedElement ResinfoReturn; // OPCODE_SYNC -static MaskedElement SyncFlags; +static MaskedElement SyncFlags; // relative to above uint32! ie. post shift. static MaskedElement Sync_Threads; static MaskedElement Sync_TGSM; static MaskedElement Sync_UAV_Group; static MaskedElement Sync_UAV_Global; - -// OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED -// OPCODE_DCL_RESOURCE_STRUCTURED -static MaskedElement HasOrderPreservingCounter; }; // Opcode // Declarations are Opcode tokens, but with their own particular definitions @@ -194,6 +190,10 @@ static MaskedElement OutputPrimitive; static MaskedElement GloballyCoherent; static MaskedElement RasterizerOrderedAccess; +// OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED +// OPCODE_DCL_RESOURCE_STRUCTURED +static MaskedElement HasOrderPreservingCounter; + // OPCODE_DCL_INTERFACE static MaskedElement TableLength; static MaskedElement NumInterfaces; @@ -205,9 +205,9 @@ static MaskedElement Extended; static MaskedElement Type; // OPCODE_EX_SAMPLE_CONTROLS -static MaskedElement TexelOffsetU; -static MaskedElement TexelOffsetV; -static MaskedElement TexelOffsetW; +static MaskedElement TexelOffsetU; +static MaskedElement TexelOffsetV; +static MaskedElement TexelOffsetW; // OPCODE_EX_RESOURCE_DIM static MaskedElement ResourceDim; diff --git a/renderdoc/driver/shaders/dxbc/dxbc_bytecode_vendorext.cpp b/renderdoc/driver/shaders/dxbc/dxbc_bytecode_vendorext.cpp index a31befe60..4bcc042c6 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_bytecode_vendorext.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_bytecode_vendorext.cpp @@ -178,7 +178,7 @@ static MaskedElement VtxParamComponent; static MaskedElement VtxParamParameter; static MaskedElement VtxParamVertex; -static MaskedElement WaveOp; +static MaskedElement WaveOp; static MaskedElement WaveOpFlags; static MaskedElement AtomicOp; @@ -428,7 +428,7 @@ void Program::PostprocessVendorExtensions() op.operation = OPCODE_AMD_READFIRSTLANE; op.operands.resize(2); op.operands[0] = dstOperand; - op.operands[1].name = "src"; + op.operands[1].name = "src"_lit; op.operands[1] = srcParam[0]; break; } @@ -437,10 +437,10 @@ void Program::PostprocessVendorExtensions() op.operation = OPCODE_AMD_READLANE; op.operands.resize(3); op.operands[0] = dstOperand; - op.operands[1].name = "src"; + op.operands[1].name = "src"_lit; op.operands[1] = srcParam[0]; // lane is encoded in instruction data - op.operands[2].name = "lane"; + op.operands[2].name = "lane"_lit; op.operands[2].type = TYPE_IMMEDIATE32; op.operands[2].numComponents = NUMCOMPS_1; op.operands[2].values[0] = AMDInstruction::Data.Get(instruction); @@ -457,7 +457,7 @@ void Program::PostprocessVendorExtensions() op.operation = OPCODE_AMD_SWIZZLE; op.operands.resize(2); op.operands[0] = dstOperand; - op.operands[1].name = "src"; + op.operands[1].name = "src"_lit; op.operands[1] = srcParam[0]; break; } @@ -475,7 +475,7 @@ void Program::PostprocessVendorExtensions() op.operands[0] = dstParam[0]; op.operands[1] = dstOperand; op.operands[2] = srcParam[0]; - op.operands[2].name = "predicate"; + op.operands[2].name = "predicate"_lit; } break; } @@ -533,9 +533,9 @@ void Program::PostprocessVendorExtensions() // all modes except pull model have two outputs op.operation = OPCODE_AMD_BARYCOORD; op.operands.resize(2); - op.operands[0].name = "i"; + op.operands[0].name = "i"_lit; op.operands[0] = dstParam[0]; - op.operands[0].name = "j"; + op.operands[0].name = "j"_lit; op.operands[1] = dstOperand; } else @@ -548,11 +548,11 @@ void Program::PostprocessVendorExtensions() // all modes except pull model have two outputs op.operation = OPCODE_AMD_BARYCOORD; op.operands.resize(3); - op.operands[0].name = "invW"; + op.operands[0].name = "invW"_lit; op.operands[0] = dstParam[0]; - op.operands[1].name = "invI"; + op.operands[1].name = "invI"_lit; op.operands[1] = dstParam[1]; - op.operands[2].name = "invJ"; + op.operands[2].name = "invJ"_lit; op.operands[2] = dstOperand; } break; @@ -563,13 +563,13 @@ void Program::PostprocessVendorExtensions() op.operands.resize(3); op.operands[0] = dstOperand; // vertexIndex is encoded in instruction data - op.operands[1].name = "vertexIndex"; + op.operands[1].name = "vertexIndex"_lit; op.operands[1].type = TYPE_IMMEDIATE32; op.operands[1].numComponents = NUMCOMPS_1; op.operands[1].values[0] = AMDInstruction::VtxParamVertex.Get(instruction); // decode and pretty-ify the parameter index and component - op.operands[2].name = "parameter"; + op.operands[2].name = "parameter"_lit; op.operands[2].type = TYPE_INPUT; op.operands[2].numComponents = NUMCOMPS_1; op.operands[2].indices.resize(1); @@ -615,11 +615,11 @@ void Program::PostprocessVendorExtensions() op.operands.resize(4); op.operands[0] = dstOperand; op.operands[1] = srcParam[0]; - op.operands[1].name = "gpuVaLoBits"; + op.operands[1].name = "gpuVaLoBits"_lit; op.operands[2] = srcParam[1]; - op.operands[2].name = "gpuVaHiBits"; + op.operands[2].name = "gpuVaHiBits"_lit; op.operands[3] = srcParam[2]; - op.operands[3].name = "offset"; + op.operands[3].name = "offset"_lit; } break; } @@ -681,7 +681,7 @@ void Program::PostprocessVendorExtensions() op.operands.push_back(srcParam[0]); op.operands.back().setComps(srcParam[0].comps[0], srcParam[1].comps[0], srcParam[2].comps[0], 0xff); - op.operands.back().name = "address"; + op.operands.back().name = "address"_lit; // store in texelOffset whether the parameter is combined (1) or split (2) op.texelOffset[0] = 1; @@ -689,13 +689,13 @@ void Program::PostprocessVendorExtensions() else { op.operands.push_back(srcParam[0]); - op.operands.back().name = "address.x"; + op.operands.back().name = "address.x"_lit; op.operands.back().setComps(srcParam[0].comps[0], 0xff, 0xff, 0xff); op.operands.push_back(srcParam[1]); - op.operands.back().name = "address.y"; + op.operands.back().name = "address.y"_lit; op.operands.back().setComps(srcParam[1].comps[0], 0xff, 0xff, 0xff); op.operands.push_back(srcParam[2]); - op.operands.back().name = "address.z"; + op.operands.back().name = "address.z"_lit; op.operands.back().setComps(srcParam[2].comps[0], 0xff, 0xff, 0xff); // store in texelOffset whether the parameter is combined (1) or split (2) @@ -710,7 +710,7 @@ void Program::PostprocessVendorExtensions() op.operands.push_back(srcParam[5]); op.operands.back().setComps(srcParam[5].comps[0], srcParam[6].comps[0], 0xff, 0xff); op.operands.back().values[1] = srcParam[6].values[0]; - op.operands.back().name = "compare_value"; + op.operands.back().name = "compare_value"_lit; // store in texelOffset whether the parameter is combined (1) or split (2) op.texelOffset[1] = 1; @@ -718,10 +718,10 @@ void Program::PostprocessVendorExtensions() else { op.operands.push_back(srcParam[5].swizzle(0)); - op.operands.back().name = "compare_value.x"; + op.operands.back().name = "compare_value.x"_lit; op.operands.back().setComps(srcParam[5].comps[0], 0xff, 0xff, 0xff); op.operands.push_back(srcParam[6].swizzle(0)); - op.operands.back().name = "compare_value.y"; + op.operands.back().name = "compare_value.y"_lit; op.operands.back().setComps(srcParam[6].comps[0], 0xff, 0xff, 0xff); // store in texelOffset whether the parameter is combined (1) or split (2) @@ -735,7 +735,7 @@ void Program::PostprocessVendorExtensions() op.operands.push_back(srcParam[3]); op.operands.back().setComps(srcParam[3].comps[0], srcParam[4].comps[0], 0xff, 0xff); op.operands.back().values[1] = srcParam[4].values[0]; - op.operands.back().name = "value"; + op.operands.back().name = "value"_lit; // store in texelOffset whether the parameter is combined (1) or split (2) op.texelOffset[2] = 1; @@ -743,10 +743,10 @@ void Program::PostprocessVendorExtensions() else { op.operands.push_back(srcParam[3].swizzle(0)); - op.operands.back().name = "value.x"; + op.operands.back().name = "value.x"_lit; op.operands.back().setComps(srcParam[3].comps[0], 0xff, 0xff, 0xff); op.operands.push_back(srcParam[4].swizzle(0)); - op.operands.back().name = "value.y"; + op.operands.back().name = "value.y"_lit; op.operands.back().setComps(srcParam[4].comps[0], 0xff, 0xff, 0xff); // store in texelOffset whether the parameter is combined (1) or split (2) @@ -858,8 +858,10 @@ void Program::PostprocessVendorExtensions() // remove this operation, but keep the old operation so we can undo this if things go // wrong - curOp.syncFlags = curOp.operation; + curOp.stride = curOp.operation; curOp.operation = OPCODE_VENDOR_REMOVED; + RDCCOMPILE_ASSERT(sizeof(curOp.stride) >= sizeof(curOp.operation), + "Hackily assuming stride is big enough to hold an operation"); } else if(curOp.operation == OPCODE_IMM_ATOMIC_ALLOC && curOp.operands[1].indices[0].index == magicID) @@ -916,16 +918,16 @@ void Program::PostprocessVendorExtensions() op.operands.resize(4); op.operands[0] = curOp.operands[0]; - op.operands[1].name = "value"; + op.operands[1].name = "value"_lit; op.operands[1] = srcParam[0].swizzle(0); if(nvopcode == NvShaderOpcode::Shuffle) - op.operands[2].name = "srcLane"; + op.operands[2].name = "srcLane"_lit; else if(nvopcode == NvShaderOpcode::ShuffleXor) - op.operands[2].name = "laneMask"; + op.operands[2].name = "laneMask"_lit; else - op.operands[2].name = "delta"; + op.operands[2].name = "delta"_lit; op.operands[2] = srcParam[0].swizzle(1); - op.operands[3].name = "width"; + op.operands[3].name = "width"_lit; op.operands[3] = srcParam[0].swizzle(3); break; } @@ -943,7 +945,7 @@ void Program::PostprocessVendorExtensions() op.operands.resize(2); op.operands[0] = curOp.operands[0]; op.operands[1] = srcParam[0]; - op.operands[1].name = "predicate"; + op.operands[1].name = "predicate"_lit; break; } case NvShaderOpcode::GetLaneId: @@ -998,7 +1000,7 @@ void Program::PostprocessVendorExtensions() dstParam[1].indices == curOp.operands[0].indices) { op.operands.push_back(curOp.operands[0]); - op.operands.back().name = "result"; + op.operands.back().name = "result"_lit; // fixup the comps according to the shuffle op.operands.back().setComps( @@ -1013,12 +1015,12 @@ void Program::PostprocessVendorExtensions() { // these are in reverse order because we read them as numOutputs was decrementing op.operands.push_back(dstParam[1]); - op.operands.back().name = "result.x"; + op.operands.back().name = "result.x"_lit; op.operands.push_back(dstParam[0]); - op.operands.back().name = "result.y"; + op.operands.back().name = "result.y"_lit; // z is last op.operands.push_back(curOp.operands[0]); - op.operands.back().name = "result.z"; + op.operands.back().name = "result.z"_lit; } break; @@ -1047,7 +1049,7 @@ void Program::PostprocessVendorExtensions() dstParam[2].indices == curOp.operands[0].indices) { op.operands.push_back(curOp.operands[0]); - op.operands.back().name = "result"; + op.operands.back().name = "result"_lit; // fixup the comps according to the shuffle op.operands.back().setComps( @@ -1064,56 +1066,56 @@ void Program::PostprocessVendorExtensions() { // these are in reverse order because we read them as numOutputs was decrementing op.operands.push_back(dstParam[2]); - op.operands.back().name = "result.x"; + op.operands.back().name = "result.x"_lit; op.operands.push_back(dstParam[1]); - op.operands.back().name = "result.y"; + op.operands.back().name = "result.y"_lit; op.operands.push_back(dstParam[0]); - op.operands.back().name = "result.z"; + op.operands.back().name = "result.z"_lit; // w is last op.operands.push_back(curOp.operands[0]); - op.operands.back().name = "result.w"; + op.operands.back().name = "result.w"_lit; } // peel out the source parameters op.operands.push_back(srcParam[3].swizzle(0)); - op.operands.back().name = "texSpace"; + op.operands.back().name = "texSpace"_lit; op.operands.push_back(srcParam[0].swizzle(0)); - op.operands.back().name = "texIndex"; + op.operands.back().name = "texIndex"_lit; op.operands.push_back(srcParam[3].swizzle(1)); - op.operands.back().name = "smpSpace"; + op.operands.back().name = "smpSpace"_lit; op.operands.push_back(srcParam[0].swizzle(1)); - op.operands.back().name = "smpIndex"; + op.operands.back().name = "smpIndex"_lit; op.operands.push_back(srcParam[3].swizzle(2)); - op.operands.back().name = "texType"; + op.operands.back().name = "texType"_lit; op.operands.push_back(srcParam[1]); op.operands.back().comps[3] = 0xff; // location is a float3 op.operands.back().values[3] = 0; - op.operands.back().name = "location"; + op.operands.back().name = "location"_lit; op.operands.push_back(srcParam[3].swizzle(3)); - op.operands.back().name = "coarse"; + op.operands.back().name = "coarse"_lit; op.operands.push_back(srcParam[1].swizzle(3)); - op.operands.back().name = "gran"; + op.operands.back().name = "gran"_lit; if(nvopcode == NvShaderOpcode::FootprintBias) { op.operands.push_back(srcParam[2].swizzle(0)); - op.operands.back().name = "bias"; + op.operands.back().name = "bias"_lit; } else if(nvopcode == NvShaderOpcode::FootprintLevel) { op.operands.push_back(srcParam[2].swizzle(0)); - op.operands.back().name = "lodLevel"; + op.operands.back().name = "lodLevel"_lit; } else if(nvopcode == NvShaderOpcode::FootprintGrad) { op.operands.push_back(srcParam[2]); - op.operands.back().name = "ddx"; + op.operands.back().name = "ddx"_lit; op.operands.push_back(srcParam[5]); - op.operands.back().name = "ddy"; + op.operands.back().name = "ddy"_lit; } op.operands.push_back(srcParam[4]); - op.operands.back().name = "offset"; + op.operands.back().name = "offset"_lit; break; } @@ -1125,16 +1127,16 @@ void Program::PostprocessVendorExtensions() op.operands[0] = curOp.operands[0]; // second output is the laneValid we stored previously op.operands[1] = dstParam[0]; - op.operands[1].name = "out laneValid"; + op.operands[1].name = "out laneValid"_lit; // we expect the params are packed into srcParam[0] op.operands[2] = srcParam[0].swizzle(0); - op.operands[2].name = "value"; + op.operands[2].name = "value"_lit; op.operands[3] = srcParam[0].swizzle(1); - op.operands[3].name = "srcLane"; + op.operands[3].name = "srcLane"_lit; op.operands[4] = srcParam[0].swizzle(2); - op.operands[4].name = "width"; + op.operands[4].name = "width"_lit; break; } case NvShaderOpcode::VPRSEvalAttribAtSample: @@ -1164,7 +1166,7 @@ void Program::PostprocessVendorExtensions() if(allSameReg) { op.operands.push_back(curOp.operands[0]); - op.operands.back().name = "result"; + op.operands.back().name = "result"_lit; for(int o = 0; o < 4; o++) { @@ -1184,28 +1186,26 @@ void Program::PostprocessVendorExtensions() // these are in reverse order because we read them as numOutputs was // decrementing op.operands.push_back(dstParam[numOutputs - 2 - o]); - op.operands.back().name = "result."; - op.operands.back().name += swz[o]; + op.operands.back().name = rdcstr("result.") + swz[o]; } op.operands.push_back(curOp.operands[0]); - op.operands.back().name = "result."; - op.operands.back().name += swz[numOutputs - 1]; + op.operands.back().name = rdcstr("result.") + swz[numOutputs - 1]; } op.operands.push_back(srcParam[0]); - op.operands.back().name = "attrib"; + op.operands.back().name = "attrib"_lit; if(nvopcode == NvShaderOpcode::VPRSEvalAttribAtSample) { op.operands.push_back(srcParam[1]); - op.operands.back().name = "sampleIndex"; + op.operands.back().name = "sampleIndex"_lit; op.operands.push_back(srcParam[2]); - op.operands.back().name = "pixelOffset"; + op.operands.back().name = "pixelOffset"_lit; } else if(nvopcode == NvShaderOpcode::VPRSEvalAttribSnapped) { op.operands.push_back(srcParam[1]); - op.operands.back().name = "offset"; + op.operands.back().name = "offset"_lit; } break; @@ -1266,7 +1266,7 @@ void Program::PostprocessVendorExtensions() // remove this operation, but keep the old operation so we can undo this if things go // wrong - curOp.syncFlags = curOp.operation; + curOp.stride = curOp.operation; curOp.operation = OPCODE_VENDOR_REMOVED; } else if(curOp.operation == OPCODE_STORE_STRUCTURED && @@ -1346,9 +1346,9 @@ void Program::PostprocessVendorExtensions() atomicop = (NvShaderAtomic)srcParam[2].values[0]; op.operands.push_back(srcParam[0]); - op.operands.back().name = "address"; + op.operands.back().name = "address"_lit; op.operands.push_back(srcParam[1]); - op.operands.back().name = "value"; + op.operands.back().name = "value"_lit; break; } @@ -1368,9 +1368,9 @@ void Program::PostprocessVendorExtensions() atomicop = (NvShaderAtomic)srcParam[2].values[0]; op.operands.push_back(srcParam[0].swizzle(0)); - op.operands.back().name = "byteAddress"; + op.operands.back().name = "byteAddress"_lit; op.operands.push_back(srcParam[1].swizzle(0)); - op.operands.back().name = "value"; + op.operands.back().name = "value"_lit; break; } @@ -1400,7 +1400,7 @@ void Program::PostprocessVendorExtensions() op.operands.push_back(srcParam[0]); op.operands.back().numComponents = NUMCOMPS_1; - op.operands.back().name = "address"; + op.operands.back().name = "address"_lit; // store in texelOffset whether the parameter is combined (1) or split (2). // on nv we assume the parameters are always combined @@ -1414,12 +1414,12 @@ void Program::PostprocessVendorExtensions() op.operands.back().numComponents = NUMCOMPS_4; op.operands.back().setComps(srcParam[1].comps[0], srcParam[1].comps[1], 0xff, 0xff); op.operands.back().values[1] = srcParam[1].values[1]; - op.operands.back().name = "compareValue"; + op.operands.back().name = "compareValue"_lit; op.operands.push_back(srcParam[1]); op.operands.back().numComponents = NUMCOMPS_4; op.operands.back().setComps(srcParam[1].comps[2], srcParam[1].comps[3], 0xff, 0xff); op.operands.back().values[1] = srcParam[1].values[3]; - op.operands.back().name = "value"; + op.operands.back().name = "value"_lit; } else { @@ -1427,7 +1427,7 @@ void Program::PostprocessVendorExtensions() op.operands.back().numComponents = NUMCOMPS_4; op.operands.back().setComps(srcParam[1].comps[0], srcParam[1].comps[1], 0xff, 0xff); op.operands.back().values[1] = srcParam[1].values[1]; - op.operands.back().name = "value"; + op.operands.back().name = "value"_lit; } break; @@ -1449,7 +1449,7 @@ void Program::PostprocessVendorExtensions() } op.offset = curOp.offset; - op.preciseValues = (uint32_t)atomicop; + op.preciseValues = (uint8_t)atomicop; op.str = ToStr(op.operation); switch(atomicop) @@ -1612,7 +1612,7 @@ void Program::PostprocessVendorExtensions() // remove this operation, but keep the old operation so we can undo this if things go // wrong - curOp.syncFlags = curOp.operation; + curOp.stride = curOp.operation; curOp.operation = OPCODE_VENDOR_REMOVED; } else if(curOp.operation == OPCODE_LD_STRUCTURED && curOp.operands[3].indices[0].index == magicID) @@ -1676,11 +1676,11 @@ void Program::PostprocessVendorExtensions() // remove the old one, we've replaced it m_Instructions[j].operation = OPCODE_VENDOR_REMOVED; // if we break and try to revert this one, keep it removed - m_Instructions[j].syncFlags = OPCODE_VENDOR_REMOVED; + m_Instructions[j].stride = OPCODE_VENDOR_REMOVED; // also remove the current one! but back up the original in case something // goes // wrong - curOp.syncFlags = curOp.operation; + curOp.stride = curOp.operation; curOp.operation = OPCODE_VENDOR_REMOVED; break; } @@ -1714,7 +1714,7 @@ void Program::PostprocessVendorExtensions() // remove this operation, but keep the old operation so we can undo this if things go // wrong - curOp.syncFlags = curOp.operation; + curOp.stride = curOp.operation; curOp.operation = OPCODE_VENDOR_REMOVED; } } @@ -1729,7 +1729,7 @@ void Program::PostprocessVendorExtensions() // remove this operation, but keep the old operation so we can undo this if things go // wrong - curOp.syncFlags = curOp.operation; + curOp.stride = curOp.operation; curOp.operation = OPCODE_VENDOR_REMOVED; } } @@ -1743,7 +1743,7 @@ void Program::PostprocessVendorExtensions() for(size_t i = 0; i < m_Instructions.size(); i++) { if(m_Instructions[i].operation == OPCODE_VENDOR_REMOVED) - m_Instructions[i].operation = (OpcodeType)m_Instructions[i].syncFlags; + m_Instructions[i].operation = (OpcodeType)m_Instructions[i].stride; else if(m_Instructions[i].operation >= OPCODE_VENDOR_FIRST) m_Instructions[i].operation = OPCODE_VENDOR_REMOVED; } diff --git a/renderdoc/driver/shaders/dxbc/dxbc_common.h b/renderdoc/driver/shaders/dxbc/dxbc_common.h index cabc5cf9e..2453d661a 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_common.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_common.h @@ -26,6 +26,7 @@ #include #include "api/replay/rdcarray.h" +#include "api/replay/rdcpair.h" #include "api/replay/rdcstr.h" #include "api/replay/shader_types.h" @@ -80,7 +81,7 @@ enum class ShaderType // // essentially all information comes from the wine project. ///////////////////////////////////////////////////////////////////////// -enum ResourceRetType +enum ResourceRetType : uint8_t { RETURN_TYPE_UNKNOWN = 0, RETURN_TYPE_UNORM = 1, diff --git a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp index 88dd67224..1c2981df2 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp @@ -1270,7 +1270,7 @@ void ThreadState::SetDst(ShaderDebugState *state, const Operand &dstoper, const // in a vector operation like r0.zw = r4.xxxy + r6.yyyz // then we must write from matching component to matching component - if(op.saturate) + if(op.saturate()) right = sat(right, OperationType(op.operation)); ShaderVariableChange change = {*changeVar}; @@ -1688,12 +1688,12 @@ ShaderVariable ThreadState::GetSrc(const Operand &oper, const Operation &op, boo v.columns = 4; } - if(oper.modifier == OPERAND_MODIFIER_ABS || oper.modifier == OPERAND_MODIFIER_ABSNEG) + if(oper.flags & Operand::FLAG_ABS) { v = abs(v, OperationType(op.operation)); } - if(oper.modifier == OPERAND_MODIFIER_NEG || oper.modifier == OPERAND_MODIFIER_ABSNEG) + if(oper.flags & Operand::FLAG_NEG) { v = neg(v, OperationType(op.operation)); } @@ -3065,7 +3065,7 @@ void ThreadState::StepNext(ShaderDebugState *state, DebugAPIWrapper *apiWrapper, } else if(pDecl->declaration == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED) { - stride = pDecl->stride; + stride = pDecl->structured.stride; structured = true; } } @@ -3203,7 +3203,7 @@ void ThreadState::StepNext(ShaderDebugState *state, DebugAPIWrapper *apiWrapper, srv ? OPCODE_DCL_RESOURCE_STRUCTURED : OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED; const DXBCBytecode::Declaration *pDecl = program->FindDeclaration(declType, resIndex); if(pDecl && pDecl->declaration == declOpcode) - stride = pDecl->stride; + stride = pDecl->structured.stride; } } @@ -3751,7 +3751,7 @@ void ThreadState::StepNext(ShaderDebugState *state, DebugAPIWrapper *apiWrapper, program->FindDeclaration(TYPE_RESOURCE, (uint32_t)op.operands[2].indices[0].index); if(pDecl && pDecl->declaration == OPCODE_DCL_RESOURCE) { - switch(pDecl->dim) + switch(pDecl->resource.dim) { default: case RESOURCE_DIMENSION_UNKNOWN: @@ -3873,10 +3873,11 @@ void ThreadState::StepNext(ShaderDebugState *state, DebugAPIWrapper *apiWrapper, samplerMode = decl.samplerMode; samplerBinding = GetBindingSlotForDeclaration(*program, decl); } - if(op.operation == OPCODE_LD && decl.dim == RESOURCE_DIMENSION_BUFFER && - decl.declaration == OPCODE_DCL_RESOURCE && decl.operand.sameResource(op.operands[2])) + if(op.operation == OPCODE_LD && decl.declaration == OPCODE_DCL_RESOURCE && + decl.resource.dim == RESOURCE_DIMENSION_BUFFER && + decl.operand.sameResource(op.operands[2])) { - resourceDim = decl.dim; + resourceDim = decl.resource.dim; resourceBinding = GetBindingSlotForDeclaration(*program, decl); GlobalState::SRVIterator srv = global.srvs.find(resourceBinding); @@ -3930,9 +3931,9 @@ void ThreadState::StepNext(ShaderDebugState *state, DebugAPIWrapper *apiWrapper, } if(decl.declaration == OPCODE_DCL_RESOURCE && decl.operand.sameResource(op.operands[2])) { - resourceDim = decl.dim; - resourceRetType = decl.resType[0]; - sampleCount = decl.sampleCount; + resourceDim = decl.resource.dim; + resourceRetType = decl.resource.resType[0]; + sampleCount = decl.resource.sampleCount; resourceBinding = GetBindingSlotForDeclaration(*program, decl); @@ -3943,12 +3944,14 @@ void ThreadState::StepNext(ShaderDebugState *state, DebugAPIWrapper *apiWrapper, // doesn't seem like these are ever less than four components, even if the texture is // declared for example. // shouldn't matter though is it just comes out in the wash. - RDCASSERT(decl.resType[0] == decl.resType[1] && decl.resType[1] == decl.resType[2] && - decl.resType[2] == decl.resType[3]); - RDCASSERT(decl.resType[0] != DXBC::RETURN_TYPE_CONTINUED && - decl.resType[0] != DXBC::RETURN_TYPE_UNUSED && - decl.resType[0] != DXBC::RETURN_TYPE_MIXED && decl.resType[0] >= 0 && - decl.resType[0] < DXBC::NUM_RETURN_TYPES); + RDCASSERT(decl.resource.resType[0] == decl.resource.resType[1] && + decl.resource.resType[1] == decl.resource.resType[2] && + decl.resource.resType[2] == decl.resource.resType[3]); + RDCASSERT(decl.resource.resType[0] != DXBC::RETURN_TYPE_CONTINUED && + decl.resource.resType[0] != DXBC::RETURN_TYPE_UNUSED && + decl.resource.resType[0] != DXBC::RETURN_TYPE_MIXED && + decl.resource.resType[0] >= 0 && + decl.resource.resType[0] < DXBC::NUM_RETURN_TYPES); } } @@ -4150,7 +4153,7 @@ void ThreadState::StepNext(ShaderDebugState *state, DebugAPIWrapper *apiWrapper, if(op.operation == OPCODE_CONTINUE || op.operation == OPCODE_CONTINUEC) depth = 1; - if((test == 0 && !op.nonzero) || (test != 0 && op.nonzero) || + if((test == 0 && !op.nonzero()) || (test != 0 && op.nonzero()) || op.operation == OPCODE_CONTINUE || op.operation == OPCODE_ENDLOOP) { // skip back one to the endloop that we're processing @@ -4179,7 +4182,7 @@ void ThreadState::StepNext(ShaderDebugState *state, DebugAPIWrapper *apiWrapper, { int32_t test = op.operation == OPCODE_BREAKC ? GetSrc(op.operands[0], op).value.s32v[0] : 0; - if((test == 0 && !op.nonzero) || (test != 0 && op.nonzero) || op.operation == OPCODE_BREAK) + if((test == 0 && !op.nonzero()) || (test != 0 && op.nonzero()) || op.operation == OPCODE_BREAK) { // break out (jump to next endloop/endswitch) int depth = 1; @@ -4212,7 +4215,7 @@ void ThreadState::StepNext(ShaderDebugState *state, DebugAPIWrapper *apiWrapper, { int32_t test = GetSrc(op.operands[0], op).value.s32v[0]; - if((test == 0 && !op.nonzero) || (test != 0 && op.nonzero)) + if((test == 0 && !op.nonzero()) || (test != 0 && op.nonzero())) { // nothing, we go into the if. } @@ -4280,7 +4283,7 @@ void ThreadState::StepNext(ShaderDebugState *state, DebugAPIWrapper *apiWrapper, { int32_t test = GetSrc(op.operands[0], op).value.s32v[0]; - if((test != 0 && !op.nonzero) || (test == 0 && op.nonzero)) + if((test != 0 && !op.nonzero()) || (test == 0 && op.nonzero())) { // don't discard break; @@ -4295,7 +4298,7 @@ void ThreadState::StepNext(ShaderDebugState *state, DebugAPIWrapper *apiWrapper, { int32_t test = op.operation == OPCODE_RETC ? GetSrc(op.operands[0], op).value.s32v[0] : 0; - if((test == 0 && !op.nonzero) || (test != 0 && op.nonzero) || op.operation == OPCODE_RET) + if((test == 0 && !op.nonzero()) || (test != 0 && op.nonzero()) || op.operation == OPCODE_RET) { // assumes not in a function call done = true; @@ -4502,11 +4505,16 @@ void GlobalState::PopulateGroupshared(const DXBCBytecode::Program *pBytecode) mem.structured = (decl.declaration == DXBCBytecode::OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED); - mem.count = decl.count; if(mem.structured) - mem.bytestride = decl.stride; + { + mem.count = decl.tsgm_structured.count; + mem.bytestride = decl.tsgm_structured.stride; + } else + { + mem.count = decl.tgsmCount; mem.bytestride = 4; // raw groupshared is implicitly uint32s + } mem.data.resize(mem.bytestride * mem.count); } @@ -4848,7 +4856,7 @@ DXBCBytecode::InterpolationMode GetInterpolationModeForInputParam(const SigParam if(decl.declaration == DXBCBytecode::OPCODE_DCL_INPUT_PS && decl.operand.indices[0].absolute && decl.operand.indices[0].index == sig.regIndex) { - interpolation = decl.interpolation; + interpolation = decl.inputInterpolation; break; } } diff --git a/renderdoc/driver/shaders/dxbc/dxbc_debug.h b/renderdoc/driver/shaders/dxbc/dxbc_debug.h index 8433e71f2..d05d52ccd 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_debug.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_debug.h @@ -39,7 +39,7 @@ namespace DXBCBytecode { struct Declaration; class Program; -enum OperandType; +enum OperandType : uint8_t; } class WrappedID3D11Device; @@ -263,7 +263,7 @@ public: SampleGatherResourceData resourceData, SampleGatherSamplerData samplerData, ShaderVariable uv, ShaderVariable ddxCalc, ShaderVariable ddyCalc, - const int texelOffsets[3], int multisampleIndex, + const int8_t texelOffsets[3], int multisampleIndex, float lodOrCompareValue, const uint8_t swizzle[4], GatherChannel gatherChannel, const char *opString, ShaderVariable &output) = 0;