From f30f49fce55c54ed889d99489711594ea5f0c3f3 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 19 Feb 2025 12:46:52 +0000 Subject: [PATCH] Determine threadscope for DXBC and DXIL shaders --- renderdoc/driver/shaders/dxbc/dxbc_bytecode.h | 2 ++ .../driver/shaders/dxbc/dxbc_bytecode_ops.cpp | 7 +++++++ renderdoc/driver/shaders/dxbc/dxbc_common.h | 10 ++++++++++ .../driver/shaders/dxbc/dxbc_container.cpp | 10 +++++++++- renderdoc/driver/shaders/dxbc/dxbc_container.h | 8 +++++++- renderdoc/driver/shaders/dxil/dxil_bytecode.h | 3 +++ .../driver/shaders/dxil/dxil_disassemble.cpp | 17 +++++++++++++++++ .../driver/shaders/spirv/spirv_processor.h | 3 ++- 8 files changed, 57 insertions(+), 3 deletions(-) diff --git a/renderdoc/driver/shaders/dxbc/dxbc_bytecode.h b/renderdoc/driver/shaders/dxbc/dxbc_bytecode.h index 5e67dcd2b..6dca65bc9 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_bytecode.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_bytecode.h @@ -1126,6 +1126,7 @@ public: uint32_t GetMajorVersion() const { return m_Major; } uint32_t GetMinorVersion() const { return m_Minor; } bool IsShaderModel51() const { return m_Major == 5 && m_Minor == 1; } + DXBC::ThreadScope GetThreadScope() const { return m_Threadscope; } D3D_PRIMITIVE_TOPOLOGY GetOutputTopology(); const rdcstr &GetDisassembly() { @@ -1163,6 +1164,7 @@ protected: DXBC::ShaderType m_Type = DXBC::ShaderType::Max; uint32_t m_Major = 0, m_Minor = 0; + DXBC::ThreadScope m_Threadscope = DXBC::ThreadScope::Thread; rdcarray m_ProgramWords; diff --git a/renderdoc/driver/shaders/dxbc/dxbc_bytecode_ops.cpp b/renderdoc/driver/shaders/dxbc/dxbc_bytecode_ops.cpp index 21454c362..8681acd12 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_bytecode_ops.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_bytecode_ops.cpp @@ -782,6 +782,10 @@ void Program::DecodeProgram() else m_LateDeclarations.back().push_back(decl); } + + if(decl.declaration == OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW || + decl.declaration == OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED) + m_Threadscope |= DXBC::ThreadScope::Workgroup; } else { @@ -791,6 +795,9 @@ void Program::DecodeProgram() if(op.operation == OPCODE_HS_CONTROL_POINT_PHASE || op.operation == OPCODE_HS_FORK_PHASE || op.operation == OPCODE_HS_JOIN_PHASE) m_LateDeclarations.push_back({}); + + if(decl.declaration == OPCODE_SYNC) + m_Threadscope |= DXBC::ThreadScope::Workgroup; } } diff --git a/renderdoc/driver/shaders/dxbc/dxbc_common.h b/renderdoc/driver/shaders/dxbc/dxbc_common.h index 7426c491e..125fd86c0 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_common.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_common.h @@ -85,6 +85,16 @@ enum class ShaderType : uint8_t ShaderStage GetShaderStage(ShaderType type); +enum class ThreadScope : uint32_t +{ + Thread = 0, + Quad = 0x1, + Subgroup = 0x2, + Workgroup = 0x4, +}; + +BITMASK_OPERATORS(ThreadScope); + ///////////////////////////////////////////////////////////////////////// // the below classes basically mimics the existing reflection interface. // diff --git a/renderdoc/driver/shaders/dxbc/dxbc_container.cpp b/renderdoc/driver/shaders/dxbc/dxbc_container.cpp index fa8e5a208..32f70dda5 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_container.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_container.cpp @@ -661,7 +661,7 @@ const rdcstr &DXBCContainer::GetDisassembly(bool dxcStyle) globalFlagsString += commentString + " Resource descriptor heap indexing\n"; if(m_GlobalFlags & GlobalShaderFlags::SamplerDescriptorHeapIndexing) globalFlagsString += commentString + " Sampler descriptor heap indexing\n"; - if(m_GlobalFlags & GlobalShaderFlags::Reserved) + if(m_GlobalFlags & GlobalShaderFlags::WaveMatrix) globalFlagsString += commentString + " Wave Matrix\n"; if(m_GlobalFlags & GlobalShaderFlags::AtomicInt64OnHeapResource) globalFlagsString += commentString + " 64-bit Atomics on Heap Resources\n"; @@ -697,6 +697,7 @@ const rdcstr &DXBCContainer::GetDisassembly(bool dxcStyle) m_Disassembly += "// Vendor shader extensions in use\n"; m_Disassembly += m_DXBCByteCode->GetDisassembly(); + m_Threadscope = m_DXBCByteCode->GetThreadScope(); } else if(m_DXILByteCode) { @@ -720,7 +721,14 @@ const rdcstr &DXBCContainer::GetDisassembly(bool dxcStyle) #endif m_Disassembly += m_DXILByteCode->GetDisassembly(dxcStyle, m_Reflection); + m_Threadscope = m_DXILByteCode->GetThreadScope(); } + + if(m_Type == DXBC::ShaderType::Pixel) + m_Threadscope |= ThreadScope::Quad; + + if(m_GlobalFlags & GlobalShaderFlags::WaveOps) + m_Threadscope |= ThreadScope::Subgroup; } return m_Disassembly; diff --git a/renderdoc/driver/shaders/dxbc/dxbc_container.h b/renderdoc/driver/shaders/dxbc/dxbc_container.h index c1ce09c6a..6d1163c85 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_container.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_container.h @@ -138,7 +138,7 @@ enum class GlobalShaderFlags : int64_t DerivativesInMeshAndAmpShaders = 0x1000000, ResourceDescriptorHeapIndexing = 0x2000000, SamplerDescriptorHeapIndexing = 0x4000000, - Reserved = 0x8000000, + WaveMatrix = 0x8000000, AtomicInt64OnHeapResource = 0x10000000, AdvancedTextureOps = 0x20000000, WriteableMSAATextures = 0x40000000, @@ -207,6 +207,11 @@ public: const IDebugInfo *GetDebugInfo() const { return m_DebugInfo; } const Reflection *GetReflection() const { return m_Reflection; } D3D_PRIMITIVE_TOPOLOGY GetOutputTopology(); + ThreadScope GetThreadScope() + { + GetDisassembly(false); + return m_Threadscope; + } CBufferVariableType GetRayPayload(const ShaderEntryPoint &entry) { @@ -306,6 +311,7 @@ private: rdcflatmap> m_RayPayloads; + ThreadScope m_Threadscope = ThreadScope::Thread; ShaderStatistics m_ShaderStats; DXBCBytecode::Program *m_DXBCByteCode = NULL; DXIL::Program *m_DXILByteCode = NULL; diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.h b/renderdoc/driver/shaders/dxil/dxil_bytecode.h index 93bb3d8b6..913ecedf5 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.h +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.h @@ -1617,6 +1617,8 @@ public: void FetchEntryPoint(); DXBC::Reflection *BuildReflection(); + DXBC::ThreadScope GetThreadScope() const { return m_Threadscope; } + rdcstr GetDefaultCommandLine() const { return "-T " + m_Profile; } rdcstr GetDebugStatus(); @@ -1717,6 +1719,7 @@ protected: rdcstr m_CompilerSig, m_EntryPoint, m_Profile; ShaderCompileFlags m_CompileFlags; + DXBC::ThreadScope m_Threadscope = DXBC::ThreadScope::Thread; const Type *m_CurParseType = NULL; diff --git a/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp b/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp index ce162d42f..00ec58ae2 100644 --- a/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp @@ -1158,6 +1158,23 @@ void Program::Parse(const DXBC::Reflection *reflection) m_SsaAliases.clear(); ParseReferences(reflection); + if(m_Type == DXBC::ShaderType::Compute || m_Type == DXBC::ShaderType::Amplification || + m_Type == DXBC::ShaderType::Mesh) + { + for(GlobalVar *g : m_GlobalVars) + { + RDCASSERT(g->type->type == Type::Pointer); + if(g->type->type == Type::Pointer && g->type->addrSpace == Type::PointerAddrSpace::GroupShared) + m_Threadscope |= DXBC::ThreadScope::Workgroup; + } + + for(Function *f : m_Functions) + { + if(f->name == "dx.op.barrier") + m_Threadscope |= DXBC::ThreadScope::Workgroup; + } + } + m_Parsed = true; } diff --git a/renderdoc/driver/shaders/spirv/spirv_processor.h b/renderdoc/driver/shaders/spirv/spirv_processor.h index 830c4a5fa..b62cab9a5 100644 --- a/renderdoc/driver/shaders/spirv/spirv_processor.h +++ b/renderdoc/driver/shaders/spirv/spirv_processor.h @@ -539,6 +539,7 @@ struct Section enum class ThreadScope : uint32_t { + Thread = 0, Quad = 0x1, Subgroup = 0x2, Workgroup = 0x4, @@ -637,7 +638,7 @@ protected: LogicalSection m_Sections[Section::Count]; - ThreadScope m_ThreadScope; + ThreadScope m_ThreadScope = ThreadScope::Thread; private: struct DeferredMemberDecoration