From b83e7516c599125fea1a338d1eed6e93b2b788b0 Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 8 May 2020 11:05:28 +0100 Subject: [PATCH] Handle busted debug info coming back from FXC for arrays * This seems to only happen in SM5.1 builds for some reason, if an array has 0 length and 1 stride then we try to auto-calculate the stride and length when needed in structs. --- renderdoc/driver/shaders/dxbc/dxbc_spdb.cpp | 38 +++++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/renderdoc/driver/shaders/dxbc/dxbc_spdb.cpp b/renderdoc/driver/shaders/dxbc/dxbc_spdb.cpp index f5060a044..01a1fca19 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_spdb.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_spdb.cpp @@ -584,17 +584,18 @@ SPDBChunk::SPDBChunk(void *chunk) { lfStridedArray *stridedArray = (lfStridedArray *)leaf; // documentation isn't clear, but seems like byte size is always a uint16_t - uint16_t *bytelength = (uint16_t *)stridedArray->data; + uint16_t bytelength = *(uint16_t *)stridedArray->data; + + uint16_t stride = uint16_t(stridedArray->stride); + + if(bytelength == 0) + { + // busted debug info - don't trust the stride + stride = typeInfo[stridedArray->elemtype].byteSize & 0xffff; + } typeInfo[id] = { - "", - typeInfo[stridedArray->elemtype].baseType, - *bytelength, - 1, - uint16_t(stridedArray->stride), - 0, - type, - {}, + "", typeInfo[stridedArray->elemtype].baseType, bytelength, 1, stride, 0, type, {}, }; break; @@ -1175,6 +1176,8 @@ SPDBChunk::SPDBChunk(void *chunk) RDCASSERT(varOffset + varLen <= vartype->byteSize); + uint32_t varTypeByteSize = vartype->byteSize; + // step through struct members while(!vartype->members.empty()) { @@ -1182,13 +1185,25 @@ SPDBChunk::SPDBChunk(void *chunk) // find the child member this register corresponds to. We don't handle overlaps between // members - for(const TypeMember &mem : vartype->members) + for(size_t memIndex = 0; memIndex < vartype->members.size(); memIndex++) { + const TypeMember &mem = vartype->members[memIndex]; + TypeDesc &childType = typeInfo[mem.typeIndex]; uint32_t memberOffset = mem.byteOffset; uint32_t memberLen = childType.byteSize; + if(memberLen == 0) + { + // if the member length is 0 this is busted debug info from fxc, so assume the member + // runs up to the end of the struct or the next member + if(memIndex == vartype->members.size() - 1) + memberLen = vartype->byteSize - memberOffset; + else + memberLen = vartype->members[memIndex + 1].byteOffset - memberOffset; + } + // if this member is before our variable, continue if(memberOffset + memberLen <= varOffset) continue; @@ -1212,6 +1227,7 @@ SPDBChunk::SPDBChunk(void *chunk) varOffset -= memberOffset; vartype = &childType; + varTypeByteSize = memberLen; found = true; @@ -1237,7 +1253,7 @@ SPDBChunk::SPDBChunk(void *chunk) { // number of rows is the number of vectors in the matrix's total byte size (each vector is // a row) - mapping.var.rows = uint8_t(vartype->byteSize / vartype->matArrayStride); + mapping.var.rows = uint8_t(varTypeByteSize / vartype->matArrayStride); // unless this is a column major matrix, in which case each vector is a column so swap the // rows/columns (the number of ROWS is the vector size, when each vector is a column)