From 49b2d16616f473c8d64779ea2d8c6b19a2a7f49c Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 6 Jan 2025 17:30:33 +0000 Subject: [PATCH] Reflect bitfield information out from DXIL data --- renderdoc/driver/shaders/dxbc/dxbc_common.h | 3 + .../driver/shaders/dxbc/dxbc_reflect.cpp | 2 + .../driver/shaders/dxil/dxil_reflect.cpp | 164 +++++++++++------- 3 files changed, 106 insertions(+), 63 deletions(-) diff --git a/renderdoc/driver/shaders/dxbc/dxbc_common.h b/renderdoc/driver/shaders/dxbc/dxbc_common.h index 5edad3413..7426c491e 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_common.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_common.h @@ -431,6 +431,9 @@ struct CBufferVariable rdcstr name; uint32_t offset; // offset in parent (cbuffer or nested struct) + uint16_t bitFieldOffset = 0; + uint16_t bitFieldSize = 0; + // type details of this variable CBufferVariableType type; }; diff --git a/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp b/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp index d2e9cdfb7..33220a71d 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp @@ -132,6 +132,8 @@ static ShaderConstant MakeConstantBufferVariable(bool cbufferPacking, const DXBC ret.byteOffset = var.offset; ret.defaultValue = 0; ret.type = MakeShaderConstantType(cbufferPacking, var.type); + ret.bitFieldOffset = var.bitFieldOffset; + ret.bitFieldSize = var.bitFieldSize; // fxc emits negative values for offsets of empty structs sometimes. Replace that with a single // value so we can say 'use the previous value' diff --git a/renderdoc/driver/shaders/dxil/dxil_reflect.cpp b/renderdoc/driver/shaders/dxil/dxil_reflect.cpp index 7c16fc27f..4a656ced7 100644 --- a/renderdoc/driver/shaders/dxil/dxil_reflect.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_reflect.cpp @@ -72,7 +72,7 @@ enum class StructMemberAnnotation Precise = 8, CBUsed = 9, // ResourceProperties = 10, - // BitFields = 11, + BitFields = 11, FieldWidth = 12, VectorSize = 13, }; @@ -157,6 +157,8 @@ struct TypeInfo ComponentType type; uint32_t fieldWidth; uint32_t vectorSize; + + rdcarray bitfieldMembers; }; struct StructData @@ -201,70 +203,81 @@ struct TypeInfo const Metadata *memberIn = structMembers->children[m + 1]; MemberData &memberOut = data.members[m]; - for(size_t tag = 0; tag < memberIn->children.size(); tag += 2) + const rdcarray &tagList = memberIn->children; + + ProcessTagListForMember(tagList, memberOut); + } + } + } + + void ProcessTagListForMember(const rdcarray &tagList, MemberData &out) + { + for(size_t tag = 0; tag < tagList.size(); tag += 2) + { + StructMemberAnnotation fieldTag = getival(tagList[tag]); + switch(fieldTag) + { + case StructMemberAnnotation::SNorm: { - StructMemberAnnotation fieldTag = getival(memberIn->children[tag]); - switch(fieldTag) - { - case StructMemberAnnotation::SNorm: - { - if(getival(memberIn->children[tag + 1]) != 0) - memberOut.flags = MemberData::Flags(memberOut.flags | MemberData::SNorm); - break; - } - case StructMemberAnnotation::UNorm: - { - if(getival(memberIn->children[tag + 1]) != 0) - memberOut.flags = MemberData::Flags(memberOut.flags | MemberData::UNorm); - break; - } - case StructMemberAnnotation::Matrix: - { - const Metadata *matrixData = memberIn->children[tag + 1]; - memberOut.rows = getival(matrixData->children[0]); - memberOut.cols = getival(matrixData->children[1]); - bool rowmajor = (getival(matrixData->children[2]) == 1); - if(rowmajor) - memberOut.flags = - MemberData::Flags(memberOut.flags | MemberData::RowMajor | MemberData::Matrix); - else - memberOut.flags = MemberData::Flags(memberOut.flags | MemberData::Matrix); - break; - } - case StructMemberAnnotation::CBufferOffset: - memberOut.offset = getival(memberIn->children[tag + 1]); - break; - case StructMemberAnnotation::SemanticString: - memberOut.semantic = memberIn->children[tag + 1]->str; - break; - case StructMemberAnnotation::InterpolationMode: break; - case StructMemberAnnotation::FieldName: - memberOut.name = memberIn->children[tag + 1]->str; - break; - case StructMemberAnnotation::CompType: - memberOut.type = getival(memberIn->children[tag + 1]); - break; - case StructMemberAnnotation::Precise: - { - if(getival(memberIn->children[tag + 1]) != 0) - memberOut.flags = MemberData::Flags(memberOut.flags | MemberData::Precise); - break; - } - case StructMemberAnnotation::CBUsed: - { - if(getival(memberIn->children[tag + 1]) != 0) - memberOut.flags = MemberData::Flags(memberOut.flags | MemberData::CBUsed); - break; - } - case StructMemberAnnotation::FieldWidth: - memberOut.fieldWidth = getival(memberIn->children[tag + 1]); - break; - case StructMemberAnnotation::VectorSize: - memberOut.vectorSize = getival(memberIn->children[tag + 1]); - break; - default: RDCWARN("Unexpected field tag %u", fieldTag); break; - } + if(getival(tagList[tag + 1]) != 0) + out.flags = MemberData::Flags(out.flags | MemberData::SNorm); + break; } + case StructMemberAnnotation::UNorm: + { + if(getival(tagList[tag + 1]) != 0) + out.flags = MemberData::Flags(out.flags | MemberData::UNorm); + break; + } + case StructMemberAnnotation::Matrix: + { + const Metadata *matrixData = tagList[tag + 1]; + out.rows = getival(matrixData->children[0]); + out.cols = getival(matrixData->children[1]); + bool rowmajor = (getival(matrixData->children[2]) == 1); + if(rowmajor) + out.flags = MemberData::Flags(out.flags | MemberData::RowMajor | MemberData::Matrix); + else + out.flags = MemberData::Flags(out.flags | MemberData::Matrix); + break; + } + case StructMemberAnnotation::CBufferOffset: + out.offset = getival(tagList[tag + 1]); + break; + case StructMemberAnnotation::SemanticString: out.semantic = tagList[tag + 1]->str; break; + case StructMemberAnnotation::InterpolationMode: break; + case StructMemberAnnotation::FieldName: out.name = tagList[tag + 1]->str; break; + case StructMemberAnnotation::CompType: + out.type = getival(tagList[tag + 1]); + break; + case StructMemberAnnotation::Precise: + { + if(getival(tagList[tag + 1]) != 0) + out.flags = MemberData::Flags(out.flags | MemberData::Precise); + break; + } + case StructMemberAnnotation::CBUsed: + { + if(getival(tagList[tag + 1]) != 0) + out.flags = MemberData::Flags(out.flags | MemberData::CBUsed); + break; + } + case StructMemberAnnotation::FieldWidth: + out.fieldWidth = getival(tagList[tag + 1]); + break; + case StructMemberAnnotation::VectorSize: + out.vectorSize = getival(tagList[tag + 1]); + break; + case StructMemberAnnotation::BitFields: + { + out.bitfieldMembers.resize(tagList[tag + 1]->children.size()); + for(size_t i = 0; i < tagList[tag + 1]->children.size(); i++) + { + ProcessTagListForMember(tagList[tag + 1]->children[i]->children, out.bitfieldMembers[i]); + } + break; + } + default: RDCWARN("Unexpected field tag %u", fieldTag); break; } } } @@ -1139,6 +1152,31 @@ static DXBC::CBufferVariableType MakeCBufferVariableType(const TypeInfo &typeInf { CBufferVariable var; + if(!it->second.members[i].bitfieldMembers.empty()) + { + for(size_t b = 0; b < it->second.members[i].bitfieldMembers.size(); b++) + { + const TypeInfo::MemberData &bitfieldMember = it->second.members[i].bitfieldMembers[b]; + + var.name = bitfieldMember.name; + var.offset = it->second.members[i].offset; + var.bitFieldOffset = bitfieldMember.offset & 0xffff; + var.bitFieldSize = bitfieldMember.fieldWidth & 0xffff; + + var.type.varType = VarTypeForComponentType(bitfieldMember.type); + var.type.bytesize = VarTypeByteSize(var.type.varType); + var.type.name = ToStr(var.type.varType); + var.type.rows = var.type.cols = var.type.elements = 1; + var.type.varClass = CLASS_SCALAR; + + ret.bytesize = var.offset + var.type.bytesize; + + ret.members.push_back(var); + } + + continue; + } + var.name = it->second.members[i].name; var.offset = it->second.members[i].offset;