diff --git a/qrenderdoc/Code/FormatElement.cpp b/qrenderdoc/Code/FormatElement.cpp index 3b6e421d3..41399b258 100644 --- a/qrenderdoc/Code/FormatElement.cpp +++ b/qrenderdoc/Code/FormatElement.cpp @@ -383,7 +383,7 @@ QList FormatElement::ParseFormatString(const QString &formatStrin { FormatElement elem(name, cur->offset, row_major, matrixCount, fmt, hex, rgb); - uint32_t advance = elem.byteSize(); + uint32_t advance = fmt.ElementSize() * matrixCount; if(!tightPacking) { @@ -392,7 +392,7 @@ QList FormatElement::ParseFormatString(const QString &formatStrin // cbuffer packing doesn't allow elements to cross float4 boundaries, nudge up if this was // the case - if(cur->offset / 16 != (cur->offset + elem.byteSize() - 1) / 16) + if(cur->offset / 16 != (cur->offset + fmt.ElementSize() * matrixCount - 1) / 16) { elem.offset = cur->offset = (cur->offset + 0xFU) & (~0xFU); } @@ -420,7 +420,7 @@ QList FormatElement::ParseFormatString(const QString &formatStrin cur->elems.push_back(elem); - uint32_t advance = elem.byteSize(); + uint32_t advance = fmt.ElementSize() * matrixCount; // cbuffer packing each array element is always float4 aligned if(!tightPacking) @@ -672,20 +672,6 @@ ShaderVariable FormatElement::GetShaderVar(const byte *&data, const byte *end) c return ret; } -uint32_t FormatElement::byteSize() const -{ - uint32_t vecSize = format.compByteWidth * format.compCount; - - if(format.type == ResourceFormatType::R5G5B5A1 || format.type == ResourceFormatType::R5G6B5 || - format.type == ResourceFormatType::R4G4B4A4) - vecSize = 2; - - if(format.type == ResourceFormatType::R10G10B10A2 || format.type == ResourceFormatType::R11G11B10) - vecSize = 4; - - return vecSize * matrixdim; -} - static QVariant interpret(const ResourceFormat &f, uint16_t comp) { if(f.compByteWidth != 2 || f.compType == CompType::Float) diff --git a/qrenderdoc/Code/QRDUtils.h b/qrenderdoc/Code/QRDUtils.h index 49c56354e..8d45de7c3 100644 --- a/qrenderdoc/Code/QRDUtils.h +++ b/qrenderdoc/Code/QRDUtils.h @@ -90,8 +90,6 @@ public: ShaderVariable GetShaderVar(const byte *&data, const byte *end) const; - uint32_t byteSize() const; - QString name; ResourceFormat format; uint32_t offset; diff --git a/qrenderdoc/Windows/BufferViewer.cpp b/qrenderdoc/Windows/BufferViewer.cpp index bb44366d4..d41841ebb 100644 --- a/qrenderdoc/Windows/BufferViewer.cpp +++ b/qrenderdoc/Windows/BufferViewer.cpp @@ -1219,7 +1219,7 @@ void CacheDataForIteration(QVector &cache, const QList 0) @@ -2239,8 +2239,9 @@ void BufferViewer::OnEventChanged(uint32_t eventId) { // calculate tight stride buf->stride = 0; - for(const FormatElement &el : bufdata->vsinConfig.columns) - buf->stride += el.byteSize(); + for(int i = 0; i < bufdata->vsinConfig.props.count(); i++) + buf->stride += bufdata->vsinConfig.props[i].format.ElementSize() * + bufdata->vsinConfig.columns[i].matrixdim; buf->stride = qMax((size_t)1, buf->stride); @@ -3375,7 +3376,7 @@ void BufferViewer::processFormat(const QString &format) uint32_t stride = 0; for(const FormatElement &el : cols) - stride += el.byteSize(); + stride += el.format.ElementSize() * el.matrixdim; stride = qMax(1U, stride); diff --git a/renderdoc/api/replay/data_types.h b/renderdoc/api/replay/data_types.h index a5c6fcceb..895086439 100644 --- a/renderdoc/api/replay/data_types.h +++ b/renderdoc/api/replay/data_types.h @@ -284,6 +284,70 @@ Invalid values will result in 1 being set. flags |= ResourceFormat_3Planes; } + DOCUMENT(R"(Return the size of a single element in this format, usually a pixel. For regular sized +formats this is just :data:`compByteWidth` times :data:`compCount`, for special packed formats it's +the tightly packed size of a single element, with no padding. + +Block-compressed formats define an 'element' as a whole block of texels. + +YUV formats where texel size varies depending on subsampling will return the size of a decompressed +texel. + +:return: The size of an element +:rtype: int +)"); + uint32_t ElementSize() const + { + switch(type) + { + case ResourceFormatType::Undefined: break; + case ResourceFormatType::Regular: return compByteWidth * compCount; + case ResourceFormatType::BC1: + case ResourceFormatType::BC4: + return 8; // 8 bytes for 4x4 block + case ResourceFormatType::BC2: + case ResourceFormatType::BC3: + case ResourceFormatType::BC5: + case ResourceFormatType::BC6: + case ResourceFormatType::BC7: + return 16; // 16 bytes for 4x4 block + case ResourceFormatType::ETC2: return 8; + case ResourceFormatType::EAC: + if(compCount == 1) + return 8; // single channel R11 EAC + else if(compCount == 2) + return 16; // two channel RG11 EAC + else + return 16; // RGBA8 EAC + case ResourceFormatType::ASTC: + return 16; // ASTC is always 128 bits per block + case ResourceFormatType::R10G10B10A2: + case ResourceFormatType::R11G11B10: + case ResourceFormatType::R9G9B9E5: return 4; + case ResourceFormatType::R5G6B5: + case ResourceFormatType::R5G5B5A1: + case ResourceFormatType::R4G4B4A4: return 2; + case ResourceFormatType::R4G4: return 1; + case ResourceFormatType::D16S8: + return 3; // we define the size as tightly packed, so 3 bytes. + case ResourceFormatType::D24S8: return 4; + case ResourceFormatType::D32S8: + return 5; // we define the size as tightly packed, so 5 bytes. + case ResourceFormatType::S8: + case ResourceFormatType::A8: + return 1; + // can't give a sensible answer for YUV formats as the texel varies. + case ResourceFormatType::YUV8: return compCount; + case ResourceFormatType::YUV10: + case ResourceFormatType::YUV12: + case ResourceFormatType::YUV16: return compCount * 2; + case ResourceFormatType::PVRTC: + return 8; // our representation can't differentiate 2bpp from 4bpp, so guess + } + + return 0; + } + ResourceFormatType type; DOCUMENT("The :class:`type ` of each component.");