From cb60a268ad0e4657dc82f8a22425b007475dcc61 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 8 Jul 2021 14:05:21 +0100 Subject: [PATCH] Make sure custom data is ignored but preserved --- renderdoc/driver/shaders/dxbc/dxbc_bytecode.h | 16 +++- .../driver/shaders/dxbc/dxbc_bytecode_ops.cpp | 95 +++++++++++++------ renderdoc/driver/shaders/dxbc/dxbc_debug.cpp | 9 ++ .../driver/shaders/dxbc/dxbc_stringise.cpp | 3 + 4 files changed, 93 insertions(+), 30 deletions(-) diff --git a/renderdoc/driver/shaders/dxbc/dxbc_bytecode.h b/renderdoc/driver/shaders/dxbc/dxbc_bytecode.h index 23816115e..4663554ca 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_bytecode.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_bytecode.h @@ -369,6 +369,10 @@ enum OpcodeType OPCODE_NV_SHUFFLE_GENERIC, OPCODE_NV_VPRS_EVAL_ATTRIB_SAMPLE, OPCODE_NV_VPRS_EVAL_ATTRIB_SNAPPED, + + OPCODE_DCL_IMMEDIATE_CONSTANT_BUFFER, + OPCODE_OPAQUE_CUSTOMDATA, + OPCODE_SHADER_MESSAGE, }; size_t NumOperands(OpcodeType op); @@ -1020,6 +1024,9 @@ struct Declaration // OPCODE_DCL_FUNCTION_TABLE uint32_t functionTable; + // OPCODE_CUSTOMDATA + uint32_t customDataIndex; + // OPCODE_DCL_INTERFACE uint32_t interfaceID; uint32_t numInterfaces; @@ -1063,7 +1070,12 @@ struct Operation 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) - uint32_t stride; + + union + { + uint32_t stride; + uint32_t customDataIndex; + }; rdcarray operands; }; @@ -1126,6 +1138,8 @@ protected: rdcarray m_Immediate; + rdcarray>> m_CustomDatas; + uint32_t m_NumTemps = 0; rdcarray m_IndexTempSizes; diff --git a/renderdoc/driver/shaders/dxbc/dxbc_bytecode_ops.cpp b/renderdoc/driver/shaders/dxbc/dxbc_bytecode_ops.cpp index 86ba02ee6..962c973ff 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_bytecode_ops.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_bytecode_ops.cpp @@ -728,7 +728,19 @@ void Program::DecodeProgram() RDCASSERT(m_Declarations.size() <= numDecls); - if(m_Instructions.empty() || m_Instructions.back().operation != OPCODE_RET) + OpcodeType lastRealOp = NUM_REAL_OPCODES; + + for(size_t i = 0; i < m_Instructions.size(); i++) + { + OpcodeType o = m_Instructions[m_Instructions.size() - i - 1].operation; + if(o == OPCODE_CUSTOMDATA || o == OPCODE_OPAQUE_CUSTOMDATA) + continue; + + lastRealOp = o; + break; + } + + if(lastRealOp != OPCODE_RET) { Operation implicitRet; implicitRet.length = 1; @@ -816,6 +828,12 @@ void Program::MakeDisassemblyString() } } + if(m_Instructions[i].operation == OPCODE_CUSTOMDATA || + m_Instructions[i].operation == OPCODE_OPAQUE_CUSTOMDATA) + { + continue; + } + if(m_Instructions[i].operation == OPCODE_ENDIF || m_Instructions[i].operation == OPCODE_ENDLOOP) { indent--; @@ -1099,6 +1117,8 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie if(!IsDeclaration(op)) return false; + retDecl.declaration = op; + if(op == OPCODE_CUSTOMDATA) { CustomDataClass customClass = Opcode::CustomClass.Get(OpcodeToken0); @@ -1108,22 +1128,17 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie uint32_t customDataLength = tokenStream[0]; tokenStream++; + uint32_t dataLength = customDataLength - 2; + RDCASSERT(customDataLength >= 2); switch(customClass) { - case CUSTOMDATA_SHADER_MESSAGE: - { - // handle as opcode - tokenStream = begin; - return false; - } case CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER: { + retDecl.declaration = OPCODE_DCL_IMMEDIATE_CONSTANT_BUFFER; retDecl.str = "dcl_immediateConstantBuffer {"; - uint32_t dataLength = customDataLength - 2; - RDCASSERT(dataLength % 4 == 0); for(uint32_t i = 0; i < dataLength; i++) @@ -1148,34 +1163,25 @@ bool Program::DecodeDecl(uint32_t *&tokenStream, Declaration &retDecl, bool frie break; } - default: { - RDCWARN("Unsupported custom data class %d!", customClass); + // add this as an opaque declaration + retDecl.declaration = OPCODE_OPAQUE_CUSTOMDATA; - uint32_t dataLength = customDataLength - 2; - RDCLOG("Data length seems to be %d uint32s", dataLength); + retDecl.customDataIndex = (uint32_t)m_CustomDatas.size(); -#if 0 - for(uint32_t i = 0; i < dataLength; i++) - { - char *str = (char *)tokenStream; - RDCDEBUG("uint32 %d: 0x%08x %c %c %c %c", i, tokenStream[0], str[0], str[1], str[2], - str[3]); - tokenStream++; - } -#else + m_CustomDatas.push_back(make_rdcpair(customClass, rdcarray())); + m_CustomDatas.back().second.assign(tokenStream, dataLength); + + // unsupported custom data should be treated in operation as it's first + RDCWARN("Unsupported custom data class %d treated as declaration", customClass); tokenStream += dataLength; -#endif - - break; } } return true; } - retDecl.declaration = op; retDecl.length = Opcode::Length.Get(OpcodeToken0); tokenStream++; @@ -1936,13 +1942,21 @@ bool Program::DecodeOperation(uint32_t *&tokenStream, Operation &retOp, bool fri uint32_t customDataLength = tokenStream[0]; tokenStream++; + uint32_t dataLength = customDataLength - 2; + RDCASSERT(customDataLength >= 2); switch(customClass) { case CUSTOMDATA_SHADER_MESSAGE: { - uint32_t *end = tokenStream + customDataLength - 2; + uint32_t *end = tokenStream + dataLength; + + retOp.operation = OPCODE_SHADER_MESSAGE; + retOp.customDataIndex = (uint32_t)m_CustomDatas.size(); + + m_CustomDatas.push_back(make_rdcpair(customClass, rdcarray())); + m_CustomDatas.back().second.assign(tokenStream, dataLength); // uint32_t infoQueueMsgId = tokenStream[0]; uint32_t messageFormat = tokenStream[1]; // enum. 0 == text only, 1 == printf @@ -1982,13 +1996,36 @@ bool Program::DecodeOperation(uint32_t *&tokenStream, Operation &retOp, bool fri break; } - - default: + case CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER: { // handle as declaration tokenStream = begin; return false; } + default: + { + // if we haven't seen any instructions yet, handle as declaration + if(m_Instructions.empty()) + { + tokenStream = begin; + return false; + } + + RDCWARN("Unsupported custom data class %d!", customClass); + + RDCLOG("Data length seems to be %d uint32s", dataLength); + + retOp.operation = OPCODE_OPAQUE_CUSTOMDATA; + + retOp.customDataIndex = (uint32_t)m_CustomDatas.size(); + + m_CustomDatas.push_back(make_rdcpair(customClass, rdcarray())); + m_CustomDatas.back().second.assign(tokenStream, dataLength); + + tokenStream += dataLength; + + return true; + } } return true; diff --git a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp index 49eb525e7..88dd67224 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp @@ -82,6 +82,9 @@ VarType OperationType(const DXBCBytecode::OpcodeType &op) case OPCODE_DISCARD: case OPCODE_NOP: case OPCODE_CUSTOMDATA: + case OPCODE_OPAQUE_CUSTOMDATA: + case OPCODE_SHADER_MESSAGE: + case OPCODE_DCL_IMMEDIATE_CONSTANT_BUFFER: case OPCODE_SYNC: case OPCODE_STORE_UAV_TYPED: case OPCODE_STORE_RAW: @@ -352,6 +355,9 @@ bool OperationFlushing(const DXBCBytecode::OpcodeType &op) case OPCODE_DISCARD: case OPCODE_NOP: case OPCODE_CUSTOMDATA: + case OPCODE_OPAQUE_CUSTOMDATA: + case OPCODE_SHADER_MESSAGE: + case OPCODE_DCL_IMMEDIATE_CONSTANT_BUFFER: case OPCODE_SYNC: case OPCODE_STORE_UAV_TYPED: case OPCODE_STORE_RAW: @@ -2603,6 +2609,9 @@ void ThreadState::StepNext(ShaderDebugState *state, DebugAPIWrapper *apiWrapper, case OPCODE_NOP: case OPCODE_CUSTOMDATA: + case OPCODE_OPAQUE_CUSTOMDATA: + case OPCODE_SHADER_MESSAGE: + case OPCODE_DCL_IMMEDIATE_CONSTANT_BUFFER: break; case OPCODE_SYNC: // might never need to implement this. Who knows! break; case OPCODE_DMOV: diff --git a/renderdoc/driver/shaders/dxbc/dxbc_stringise.cpp b/renderdoc/driver/shaders/dxbc/dxbc_stringise.cpp index be1a566a3..9d0180be5 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_stringise.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_stringise.cpp @@ -320,6 +320,9 @@ rdcstr DoStringise(const DXBCBytecode::OpcodeType &el) STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_SHUFFLE_GENERIC, "nv_shuffle_generic") STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_VPRS_EVAL_ATTRIB_SAMPLE, "nv_vprs_eval_attrib_sample") STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_VPRS_EVAL_ATTRIB_SNAPPED, "nv_vprs_eval_attrib_snapped") + STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_IMMEDIATE_CONSTANT_BUFFER, "dcl_immediateConstantBuffer") + STRINGISE_ENUM_CLASS_NAMED(OPCODE_OPAQUE_CUSTOMDATA, "customdata") + STRINGISE_ENUM_CLASS_NAMED(OPCODE_SHADER_MESSAGE, "error") } END_ENUM_STRINGISE(); }