From 00170e2ec30fd36bbb0a04c570df7841b51490d4 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 28 Nov 2019 12:01:33 +0000 Subject: [PATCH] Make GetVariants a free function taking interpreting format directly * We also store the format in BufferElementProperties for the buffer viewer since we'll later remove the ResourceFormat stored in FormatElement --- qrenderdoc/Code/FormatElement.cpp | 839 ++++++++++++++-------------- qrenderdoc/Code/QRDUtils.h | 4 +- qrenderdoc/Windows/BufferViewer.cpp | 128 ++--- 3 files changed, 476 insertions(+), 495 deletions(-) diff --git a/qrenderdoc/Code/FormatElement.cpp b/qrenderdoc/Code/FormatElement.cpp index db87140cf..3b6e421d3 100644 --- a/qrenderdoc/Code/FormatElement.cpp +++ b/qrenderdoc/Code/FormatElement.cpp @@ -27,90 +27,6 @@ #include #include "QRDUtils.h" -static QVariant interpret(const ResourceFormat &f, uint16_t comp) -{ - if(f.compByteWidth != 2 || f.compType == CompType::Float) - return QVariant(); - - if(f.compType == CompType::SInt) - { - return (int16_t)comp; - } - else if(f.compType == CompType::UInt) - { - return comp; - } - else if(f.compType == CompType::SScaled) - { - return (float)((int16_t)comp); - } - else if(f.compType == CompType::UScaled) - { - return (float)comp; - } - else if(f.compType == CompType::UNorm || f.compType == CompType::UNormSRGB) - { - return (float)comp / (float)0xffff; - } - else if(f.compType == CompType::SNorm) - { - int16_t cast = (int16_t)comp; - - float ret = -1.0f; - - if(cast == -32768) - ret = -1.0f; - else - ret = ((float)cast) / 32767.0f; - - return ret; - } - - return QVariant(); -} - -static QVariant interpret(const ResourceFormat &f, byte comp) -{ - if(f.compByteWidth != 1 || f.compType == CompType::Float) - return QVariant(); - - if(f.compType == CompType::SInt) - { - return (int8_t)comp; - } - else if(f.compType == CompType::UInt) - { - return comp; - } - else if(f.compType == CompType::SScaled) - { - return (float)((int8_t)comp); - } - else if(f.compType == CompType::UScaled) - { - return (float)comp; - } - else if(f.compType == CompType::UNorm || f.compType == CompType::UNormSRGB) - { - return ((float)comp) / 255.0f; - } - else if(f.compType == CompType::SNorm) - { - int8_t cast = (int8_t)comp; - - float ret = -1.0f; - - if(cast == -128) - ret = -1.0f; - else - ret = ((float)cast) / 127.0f; - - return ret; - } - - return QVariant(); -} - struct StructFormatData { QList elems; @@ -660,343 +576,9 @@ QString FormatElement::GenerateTextureBufferFormat(const TextureDescription &tex return QFormatStr("%1 %2[%3];").arg(baseType).arg(varName).arg(w); } -template -inline T readObj(const byte *&data, const byte *end, bool &ok) -{ - if(data + sizeof(T) > end) - { - ok = false; - return T(); - } - - T ret = *(T *)data; - - data += sizeof(T); - - return ret; -} - -QVariantList FormatElement::GetVariants(const byte *&data, const byte *end) const -{ - QVariantList ret; - - bool ok = true; - - if(format.type == ResourceFormatType::R5G5B5A1) - { - uint16_t packed = readObj(data, end, ok); - - ret.push_back((float)((packed >> 0) & 0x1f) / 31.0f); - ret.push_back((float)((packed >> 5) & 0x1f) / 31.0f); - ret.push_back((float)((packed >> 10) & 0x1f) / 31.0f); - ret.push_back(((packed & 0x8000) > 0) ? 1.0f : 0.0f); - - if(format.BGRAOrder()) - { - QVariant tmp = ret[2]; - ret[2] = ret[0]; - ret[0] = tmp; - } - } - else if(format.type == ResourceFormatType::R5G6B5) - { - uint16_t packed = readObj(data, end, ok); - - ret.push_back((float)((packed >> 0) & 0x1f) / 31.0f); - ret.push_back((float)((packed >> 5) & 0x3f) / 63.0f); - ret.push_back((float)((packed >> 11) & 0x1f) / 31.0f); - - if(format.BGRAOrder()) - { - QVariant tmp = ret[2]; - ret[2] = ret[0]; - ret[0] = tmp; - } - } - else if(format.type == ResourceFormatType::R4G4B4A4) - { - uint16_t packed = readObj(data, end, ok); - - ret.push_back((float)((packed >> 0) & 0xf) / 15.0f); - ret.push_back((float)((packed >> 4) & 0xf) / 15.0f); - ret.push_back((float)((packed >> 8) & 0xf) / 15.0f); - ret.push_back((float)((packed >> 12) & 0xf) / 15.0f); - - if(format.BGRAOrder()) - { - QVariant tmp = ret[2]; - ret[2] = ret[0]; - ret[0] = tmp; - } - } - else if(format.type == ResourceFormatType::R10G10B10A2) - { - // allow for vectors of this format - for raw buffer viewer - for(int i = 0; i < int(format.compCount / 4); i++) - { - uint32_t packed = readObj(data, end, ok); - - uint32_t r = (packed >> 0) & 0x3ff; - uint32_t g = (packed >> 10) & 0x3ff; - uint32_t b = (packed >> 20) & 0x3ff; - uint32_t a = (packed >> 30) & 0x003; - - if(format.BGRAOrder()) - { - uint32_t tmp = b; - b = r; - r = tmp; - } - - if(format.compType == CompType::UInt) - { - ret.push_back(r); - ret.push_back(g); - ret.push_back(b); - ret.push_back(a); - } - else if(format.compType == CompType::UScaled) - { - ret.push_back((float)r); - ret.push_back((float)g); - ret.push_back((float)b); - ret.push_back((float)a); - } - else if(format.compType == CompType::SInt || format.compType == CompType::SScaled || - format.compType == CompType::SNorm) - { - int ir, ig, ib, ia; - - // interpret RGB as 10-bit signed integers - if(r <= 511) - ir = (int)r; - else - ir = ((int)r) - 1024; - - if(g <= 511) - ig = (int)g; - else - ig = ((int)g) - 1024; - - if(b <= 511) - ib = (int)b; - else - ib = ((int)b) - 1024; - - // 2-bit signed integer - if(a <= 1) - ia = (int)a; - else - ia = ((int)a) - 4; - - if(format.compType == CompType::SInt) - { - ret.push_back(ir); - ret.push_back(ig); - ret.push_back(ib); - ret.push_back(ia); - } - else if(format.compType == CompType::SScaled) - { - ret.push_back((float)ir); - ret.push_back((float)ig); - ret.push_back((float)ib); - ret.push_back((float)ia); - } - else if(format.compType == CompType::SNorm) - { - if(ir == -512) - ir = -511; - if(ig == -512) - ig = -511; - if(ib == -512) - ib = -511; - if(ia == -2) - ia = -1; - - ret.push_back((float)ir / 511.0f); - ret.push_back((float)ig / 511.0f); - ret.push_back((float)ib / 511.0f); - ret.push_back((float)ia / 1.0f); - } - } - else - { - ret.push_back((float)r / 1023.0f); - ret.push_back((float)g / 1023.0f); - ret.push_back((float)b / 1023.0f); - ret.push_back((float)a / 3.0f); - } - } - } - else if(format.type == ResourceFormatType::R11G11B10) - { - uint32_t packed = readObj(data, end, ok); - - uint32_t mantissas[] = { - (packed >> 0) & 0x3f, (packed >> 11) & 0x3f, (packed >> 22) & 0x1f, - }; - int32_t exponents[] = { - int32_t(packed >> 6) & 0x1f, int32_t(packed >> 17) & 0x1f, int32_t(packed >> 27) & 0x1f, - }; - static const uint32_t leadbit[] = { - 0x40, 0x40, 0x20, - }; - - for(int i = 0; i < 3; i++) - { - if(mantissas[i] == 0 && exponents[i] == 0) - { - ret.push_back((float)0.0f); - } - else - { - if(exponents[i] == 0x1f) - { - // no sign bit, can't be negative infinity - if(mantissas[i] == 0) - ret.push_back((float)qInf()); - else - ret.push_back((float)qQNaN()); - } - else if(exponents[i] != 0) - { - // normal value, add leading bit - uint32_t combined = leadbit[i] | mantissas[i]; - - // calculate value - ret.push_back(((float)combined / (float)leadbit[i]) * - qPow(2.0f, (float)exponents[i] - 15.0f)); - } - else if(exponents[i] == 0) - { - // we know xMantissa isn't 0 also, or it would have been caught above so - // this is a subnormal value, pretend exponent is 1 and don't add leading bit - - ret.push_back(((float)mantissas[i] / (float)leadbit[i]) * qPow(2.0f, (float)1.0f - 15.0f)); - } - } - } - } - else - { - int dim = (int)(qMax(matrixdim, 1U) * format.compCount); - - for(int i = 0; i < dim; i++) - { - if(format.compType == CompType::Float) - { - if(format.compByteWidth == 8) - ret.push_back(readObj(data, end, ok)); - else if(format.compByteWidth == 4) - ret.push_back(readObj(data, end, ok)); - else if(format.compByteWidth == 2) - ret.push_back(RENDERDOC_HalfToFloat(readObj(data, end, ok))); - } - else if(format.compType == CompType::SInt) - { - if(format.compByteWidth == 8) - ret.push_back((qlonglong)readObj(data, end, ok)); - else if(format.compByteWidth == 4) - ret.push_back((int)readObj(data, end, ok)); - else if(format.compByteWidth == 2) - ret.push_back((int)readObj(data, end, ok)); - else if(format.compByteWidth == 1) - ret.push_back((int)readObj(data, end, ok)); - } - else if(format.compType == CompType::UInt) - { - if(format.compByteWidth == 8) - ret.push_back((qulonglong)readObj(data, end, ok)); - else if(format.compByteWidth == 4) - ret.push_back((uint32_t)readObj(data, end, ok)); - else if(format.compByteWidth == 2) - ret.push_back((uint32_t)readObj(data, end, ok)); - else if(format.compByteWidth == 1) - ret.push_back((uint32_t)readObj(data, end, ok)); - } - else if(format.compType == CompType::UScaled) - { - if(format.compByteWidth == 4) - ret.push_back((float)readObj(data, end, ok)); - else if(format.compByteWidth == 2) - ret.push_back((float)readObj(data, end, ok)); - else if(format.compByteWidth == 1) - ret.push_back((float)readObj(data, end, ok)); - } - else if(format.compType == CompType::SScaled) - { - if(format.compByteWidth == 4) - ret.push_back((float)readObj(data, end, ok)); - else if(format.compByteWidth == 2) - ret.push_back((float)readObj(data, end, ok)); - else if(format.compByteWidth == 1) - ret.push_back((float)readObj(data, end, ok)); - } - else if(format.compType == CompType::Depth) - { - if(format.compByteWidth == 4) - { - // 32-bit depth is native floats - ret.push_back(readObj(data, end, ok)); - } - else if(format.compByteWidth == 3) - { - // 32-bit depth is normalised, masked against non-stencil bits - uint32_t f = readObj(data, end, ok); - f &= 0x00ffffff; - ret.push_back((float)f / (float)0x00ffffff); - } - else if(format.compByteWidth == 2) - { - // 16-bit depth is normalised - float f = (float)readObj(data, end, ok); - ret.push_back(f / (float)0x0000ffff); - } - } - else if(format.compType == CompType::Double) - { - ret.push_back(readObj(data, end, ok)); - } - else - { - // unorm/snorm - - if(format.compByteWidth == 4) - { - // should never hit this - no 32bit unorm/snorm type - qCritical() << "Unexpected 4-byte unorm/snorm value"; - ret.push_back((float)readObj(data, end, ok) / (float)0xffffffff); - } - else if(format.compByteWidth == 2) - { - ret.push_back(interpret(format, readObj(data, end, ok))); - } - else if(format.compByteWidth == 1) - { - ret.push_back(interpret(format, readObj(data, end, ok))); - } - } - } - - if(format.BGRAOrder()) - { - QVariant tmp = ret[2]; - ret[2] = ret[0]; - ret[0] = tmp; - } - } - - // we read off the end, return empty set - if(!ok) - ret.clear(); - - return ret; -} - ShaderVariable FormatElement::GetShaderVar(const byte *&data, const byte *end) const { - QVariantList objs = GetVariants(data, end); + QVariantList objs = GetVariants(format, matrixdim, data, end); ShaderVariable ret; @@ -1104,6 +686,425 @@ uint32_t FormatElement::byteSize() const return vecSize * matrixdim; } +static QVariant interpret(const ResourceFormat &f, uint16_t comp) +{ + if(f.compByteWidth != 2 || f.compType == CompType::Float) + return QVariant(); + + if(f.compType == CompType::SInt) + { + return (int16_t)comp; + } + else if(f.compType == CompType::UInt) + { + return comp; + } + else if(f.compType == CompType::SScaled) + { + return (float)((int16_t)comp); + } + else if(f.compType == CompType::UScaled) + { + return (float)comp; + } + else if(f.compType == CompType::UNorm || f.compType == CompType::UNormSRGB) + { + return (float)comp / (float)0xffff; + } + else if(f.compType == CompType::SNorm) + { + int16_t cast = (int16_t)comp; + + float ret = -1.0f; + + if(cast == -32768) + ret = -1.0f; + else + ret = ((float)cast) / 32767.0f; + + return ret; + } + + return QVariant(); +} + +static QVariant interpret(const ResourceFormat &f, byte comp) +{ + if(f.compByteWidth != 1 || f.compType == CompType::Float) + return QVariant(); + + if(f.compType == CompType::SInt) + { + return (int8_t)comp; + } + else if(f.compType == CompType::UInt) + { + return comp; + } + else if(f.compType == CompType::SScaled) + { + return (float)((int8_t)comp); + } + else if(f.compType == CompType::UScaled) + { + return (float)comp; + } + else if(f.compType == CompType::UNorm || f.compType == CompType::UNormSRGB) + { + return ((float)comp) / 255.0f; + } + else if(f.compType == CompType::SNorm) + { + int8_t cast = (int8_t)comp; + + float ret = -1.0f; + + if(cast == -128) + ret = -1.0f; + else + ret = ((float)cast) / 127.0f; + + return ret; + } + + return QVariant(); +} + +template +inline T readObj(const byte *&data, const byte *end, bool &ok) +{ + if(data + sizeof(T) > end) + { + ok = false; + return T(); + } + + T ret = *(T *)data; + + data += sizeof(T); + + return ret; +} + +QVariantList GetVariants(ResourceFormat rowFormat, uint32_t rowCount, const byte *&data, + const byte *end) +{ + QVariantList ret; + + bool ok = true; + + if(rowFormat.type == ResourceFormatType::R5G5B5A1) + { + uint16_t packed = readObj(data, end, ok); + + ret.push_back((float)((packed >> 0) & 0x1f) / 31.0f); + ret.push_back((float)((packed >> 5) & 0x1f) / 31.0f); + ret.push_back((float)((packed >> 10) & 0x1f) / 31.0f); + ret.push_back(((packed & 0x8000) > 0) ? 1.0f : 0.0f); + + if(rowFormat.BGRAOrder()) + { + QVariant tmp = ret[2]; + ret[2] = ret[0]; + ret[0] = tmp; + } + } + else if(rowFormat.type == ResourceFormatType::R5G6B5) + { + uint16_t packed = readObj(data, end, ok); + + ret.push_back((float)((packed >> 0) & 0x1f) / 31.0f); + ret.push_back((float)((packed >> 5) & 0x3f) / 63.0f); + ret.push_back((float)((packed >> 11) & 0x1f) / 31.0f); + + if(rowFormat.BGRAOrder()) + { + QVariant tmp = ret[2]; + ret[2] = ret[0]; + ret[0] = tmp; + } + } + else if(rowFormat.type == ResourceFormatType::R4G4B4A4) + { + uint16_t packed = readObj(data, end, ok); + + ret.push_back((float)((packed >> 0) & 0xf) / 15.0f); + ret.push_back((float)((packed >> 4) & 0xf) / 15.0f); + ret.push_back((float)((packed >> 8) & 0xf) / 15.0f); + ret.push_back((float)((packed >> 12) & 0xf) / 15.0f); + + if(rowFormat.BGRAOrder()) + { + QVariant tmp = ret[2]; + ret[2] = ret[0]; + ret[0] = tmp; + } + } + else if(rowFormat.type == ResourceFormatType::R10G10B10A2) + { + // allow for vectors of this format - for raw buffer viewer + for(int i = 0; i < int(rowFormat.compCount / 4); i++) + { + uint32_t packed = readObj(data, end, ok); + + uint32_t r = (packed >> 0) & 0x3ff; + uint32_t g = (packed >> 10) & 0x3ff; + uint32_t b = (packed >> 20) & 0x3ff; + uint32_t a = (packed >> 30) & 0x003; + + if(rowFormat.BGRAOrder()) + { + uint32_t tmp = b; + b = r; + r = tmp; + } + + if(rowFormat.compType == CompType::UInt) + { + ret.push_back(r); + ret.push_back(g); + ret.push_back(b); + ret.push_back(a); + } + else if(rowFormat.compType == CompType::UScaled) + { + ret.push_back((float)r); + ret.push_back((float)g); + ret.push_back((float)b); + ret.push_back((float)a); + } + else if(rowFormat.compType == CompType::SInt || rowFormat.compType == CompType::SScaled || + rowFormat.compType == CompType::SNorm) + { + int ir, ig, ib, ia; + + // interpret RGB as 10-bit signed integers + if(r <= 511) + ir = (int)r; + else + ir = ((int)r) - 1024; + + if(g <= 511) + ig = (int)g; + else + ig = ((int)g) - 1024; + + if(b <= 511) + ib = (int)b; + else + ib = ((int)b) - 1024; + + // 2-bit signed integer + if(a <= 1) + ia = (int)a; + else + ia = ((int)a) - 4; + + if(rowFormat.compType == CompType::SInt) + { + ret.push_back(ir); + ret.push_back(ig); + ret.push_back(ib); + ret.push_back(ia); + } + else if(rowFormat.compType == CompType::SScaled) + { + ret.push_back((float)ir); + ret.push_back((float)ig); + ret.push_back((float)ib); + ret.push_back((float)ia); + } + else if(rowFormat.compType == CompType::SNorm) + { + if(ir == -512) + ir = -511; + if(ig == -512) + ig = -511; + if(ib == -512) + ib = -511; + if(ia == -2) + ia = -1; + + ret.push_back((float)ir / 511.0f); + ret.push_back((float)ig / 511.0f); + ret.push_back((float)ib / 511.0f); + ret.push_back((float)ia / 1.0f); + } + } + else + { + ret.push_back((float)r / 1023.0f); + ret.push_back((float)g / 1023.0f); + ret.push_back((float)b / 1023.0f); + ret.push_back((float)a / 3.0f); + } + } + } + else if(rowFormat.type == ResourceFormatType::R11G11B10) + { + uint32_t packed = readObj(data, end, ok); + + uint32_t mantissas[] = { + (packed >> 0) & 0x3f, (packed >> 11) & 0x3f, (packed >> 22) & 0x1f, + }; + int32_t exponents[] = { + int32_t(packed >> 6) & 0x1f, int32_t(packed >> 17) & 0x1f, int32_t(packed >> 27) & 0x1f, + }; + static const uint32_t leadbit[] = { + 0x40, 0x40, 0x20, + }; + + for(int i = 0; i < 3; i++) + { + if(mantissas[i] == 0 && exponents[i] == 0) + { + ret.push_back((float)0.0f); + } + else + { + if(exponents[i] == 0x1f) + { + // no sign bit, can't be negative infinity + if(mantissas[i] == 0) + ret.push_back((float)qInf()); + else + ret.push_back((float)qQNaN()); + } + else if(exponents[i] != 0) + { + // normal value, add leading bit + uint32_t combined = leadbit[i] | mantissas[i]; + + // calculate value + ret.push_back(((float)combined / (float)leadbit[i]) * + qPow(2.0f, (float)exponents[i] - 15.0f)); + } + else if(exponents[i] == 0) + { + // we know xMantissa isn't 0 also, or it would have been caught above so + // this is a subnormal value, pretend exponent is 1 and don't add leading bit + + ret.push_back(((float)mantissas[i] / (float)leadbit[i]) * qPow(2.0f, (float)1.0f - 15.0f)); + } + } + } + } + else + { + int dim = (int)(qMax(rowCount, 1U) * rowFormat.compCount); + + for(int i = 0; i < dim; i++) + { + if(rowFormat.compType == CompType::Float) + { + if(rowFormat.compByteWidth == 8) + ret.push_back(readObj(data, end, ok)); + else if(rowFormat.compByteWidth == 4) + ret.push_back(readObj(data, end, ok)); + else if(rowFormat.compByteWidth == 2) + ret.push_back(RENDERDOC_HalfToFloat(readObj(data, end, ok))); + } + else if(rowFormat.compType == CompType::SInt) + { + if(rowFormat.compByteWidth == 8) + ret.push_back((qlonglong)readObj(data, end, ok)); + else if(rowFormat.compByteWidth == 4) + ret.push_back((int)readObj(data, end, ok)); + else if(rowFormat.compByteWidth == 2) + ret.push_back((int)readObj(data, end, ok)); + else if(rowFormat.compByteWidth == 1) + ret.push_back((int)readObj(data, end, ok)); + } + else if(rowFormat.compType == CompType::UInt) + { + if(rowFormat.compByteWidth == 8) + ret.push_back((qulonglong)readObj(data, end, ok)); + else if(rowFormat.compByteWidth == 4) + ret.push_back((uint32_t)readObj(data, end, ok)); + else if(rowFormat.compByteWidth == 2) + ret.push_back((uint32_t)readObj(data, end, ok)); + else if(rowFormat.compByteWidth == 1) + ret.push_back((uint32_t)readObj(data, end, ok)); + } + else if(rowFormat.compType == CompType::UScaled) + { + if(rowFormat.compByteWidth == 4) + ret.push_back((float)readObj(data, end, ok)); + else if(rowFormat.compByteWidth == 2) + ret.push_back((float)readObj(data, end, ok)); + else if(rowFormat.compByteWidth == 1) + ret.push_back((float)readObj(data, end, ok)); + } + else if(rowFormat.compType == CompType::SScaled) + { + if(rowFormat.compByteWidth == 4) + ret.push_back((float)readObj(data, end, ok)); + else if(rowFormat.compByteWidth == 2) + ret.push_back((float)readObj(data, end, ok)); + else if(rowFormat.compByteWidth == 1) + ret.push_back((float)readObj(data, end, ok)); + } + else if(rowFormat.compType == CompType::Depth) + { + if(rowFormat.compByteWidth == 4) + { + // 32-bit depth is native floats + ret.push_back(readObj(data, end, ok)); + } + else if(rowFormat.compByteWidth == 3) + { + // 32-bit depth is normalised, masked against non-stencil bits + uint32_t f = readObj(data, end, ok); + f &= 0x00ffffff; + ret.push_back((float)f / (float)0x00ffffff); + } + else if(rowFormat.compByteWidth == 2) + { + // 16-bit depth is normalised + float f = (float)readObj(data, end, ok); + ret.push_back(f / (float)0x0000ffff); + } + } + else if(rowFormat.compType == CompType::Double) + { + ret.push_back(readObj(data, end, ok)); + } + else + { + // unorm/snorm + + if(rowFormat.compByteWidth == 4) + { + // should never hit this - no 32bit unorm/snorm type + qCritical() << "Unexpected 4-byte unorm/snorm value"; + ret.push_back((float)readObj(data, end, ok) / (float)0xffffffff); + } + else if(rowFormat.compByteWidth == 2) + { + ret.push_back(interpret(rowFormat, readObj(data, end, ok))); + } + else if(rowFormat.compByteWidth == 1) + { + ret.push_back(interpret(rowFormat, readObj(data, end, ok))); + } + } + } + + if(rowFormat.BGRAOrder()) + { + QVariant tmp = ret[2]; + ret[2] = ret[0]; + ret[0] = tmp; + } + } + + // we read off the end, return empty set + if(!ok) + ret.clear(); + + return ret; +} + QString TypeString(const ShaderVariable &v) { if(!v.members.isEmpty() || v.isStruct) diff --git a/qrenderdoc/Code/QRDUtils.h b/qrenderdoc/Code/QRDUtils.h index 855cc9de5..49c56354e 100644 --- a/qrenderdoc/Code/QRDUtils.h +++ b/qrenderdoc/Code/QRDUtils.h @@ -88,7 +88,6 @@ public: static QString GenerateTextureBufferFormat(const TextureDescription &tex); - QVariantList GetVariants(const byte *&data, const byte *end) const; ShaderVariable GetShaderVar(const byte *&data, const byte *end) const; uint32_t byteSize() const; @@ -102,6 +101,9 @@ public: bool hex, rgb; }; +QVariantList GetVariants(ResourceFormat rowFormat, uint32_t rowCount, const byte *&data, + const byte *end); + QString TypeString(const ShaderVariable &v); QString RowString(const ShaderVariable &v, uint32_t row, VarType type = VarType::Unknown); QString VarString(const ShaderVariable &v); diff --git a/qrenderdoc/Windows/BufferViewer.cpp b/qrenderdoc/Windows/BufferViewer.cpp index 9a13aa731..bb44366d4 100644 --- a/qrenderdoc/Windows/BufferViewer.cpp +++ b/qrenderdoc/Windows/BufferViewer.cpp @@ -336,6 +336,7 @@ struct BufferData struct BufferElementProperties { + ResourceFormat format; int buffer = 0; ShaderBuiltin systemValue = ShaderBuiltin::Undefined; bool perinstance = false; @@ -631,8 +632,9 @@ public: else { const FormatElement &el = elementForColumn(section); + const BufferElementProperties &prop = propForColumn(section); - if(el.format.compCount == 1 || role == columnGroupRole) + if(prop.format.compCount == 1 || role == columnGroupRole) return el.name; QChar comps[] = {QLatin1Char('x'), QLatin1Char('y'), QLatin1Char('z'), QLatin1Char('w')}; @@ -742,7 +744,7 @@ public: // only slightly wasteful, we need to fetch all variants together // since some formats are packed and can't be read individually - QVariantList list = el.GetVariants(data, end); + QVariantList list = GetVariants(prop.format, el.matrixdim, data, end); if(!list.isEmpty()) { @@ -837,7 +839,7 @@ public: const BufferElementProperties &prop = propForColumn(col); if(useGenerics(col)) - return interpretGeneric(col, el); + return interpretGeneric(col, el, prop); uint32_t instIdx = 0; if(prop.instancerate > 0) @@ -857,14 +859,14 @@ public: // only slightly wasteful, we need to fetch all variants together // since some formats are packed and can't be read individually - QVariantList list = el.GetVariants(data, end); + QVariantList list = GetVariants(prop.format, el.matrixdim, data, end); int comp = componentForIndex(col); if(comp < list.count()) { uint32_t rowdim = el.matrixdim; - uint32_t coldim = el.format.compCount; + uint32_t coldim = prop.format.compCount; if(rowdim == 1) { @@ -880,7 +882,7 @@ public: if(RichResourceTextCheck(v)) return v; - return interpretVariant(v, el); + return interpretVariant(v, el, prop); } else { @@ -892,9 +894,9 @@ public: ret += lit("\n"); if(el.rowmajor) - ret += interpretVariant(list[comp + r * coldim], el); + ret += interpretVariant(list[comp + r * coldim], el, prop); else - ret += interpretVariant(list[r + comp * rowdim], el); + ret += interpretVariant(list[r + comp * rowdim], el, prop); } return ret; @@ -1052,42 +1054,9 @@ private: for(int i = 0; i < config.columns.count(); i++) { - FormatElement &fmt = config.columns[i]; + const BufferElementProperties &prop = config.props[i]; - uint32_t compCount; - - switch(fmt.format.type) - { - case ResourceFormatType::BC6: - case ResourceFormatType::ETC2: - case ResourceFormatType::R11G11B10: - case ResourceFormatType::R5G6B5: - case ResourceFormatType::R9G9B9E5: compCount = 3; break; - case ResourceFormatType::BC1: - case ResourceFormatType::BC7: - case ResourceFormatType::BC3: - case ResourceFormatType::BC2: - case ResourceFormatType::R10G10B10A2: - case ResourceFormatType::R5G5B5A1: - case ResourceFormatType::R4G4B4A4: - case ResourceFormatType::ASTC: compCount = 4; break; - case ResourceFormatType::BC5: - case ResourceFormatType::R4G4: - case ResourceFormatType::D16S8: - case ResourceFormatType::D24S8: - case ResourceFormatType::D32S8: compCount = 2; break; - case ResourceFormatType::BC4: - case ResourceFormatType::S8: - case ResourceFormatType::A8: compCount = 1; break; - case ResourceFormatType::YUV8: - case ResourceFormatType::YUV10: - case ResourceFormatType::YUV12: - case ResourceFormatType::YUV16: - case ResourceFormatType::EAC: - default: compCount = fmt.format.compCount; - } - - for(uint32_t c = 0; c < compCount; c++) + for(uint32_t c = 0; c < prop.format.compCount; c++) { columnLookup.push_back(i); componentLookup.push_back((int)c); @@ -1096,7 +1065,7 @@ private: } QString outOfBounds() const { return lit("---"); } - QString interpretGeneric(int col, const FormatElement &el) const + QString interpretGeneric(int col, const FormatElement &el, const BufferElementProperties &prop) const { int comp = componentForIndex(col); @@ -1104,24 +1073,25 @@ private: if(col < config.generics.size()) { - if(el.format.compType == CompType::Float) + if(prop.format.compType == CompType::Float) { - return interpretVariant(QVariant(config.generics[col].floatValue[comp]), el); + return interpretVariant(QVariant(config.generics[col].floatValue[comp]), el, prop); } - else if(el.format.compType == CompType::SInt) + else if(prop.format.compType == CompType::SInt) { - return interpretVariant(QVariant(config.generics[col].intValue[comp]), el); + return interpretVariant(QVariant(config.generics[col].intValue[comp]), el, prop); } - else if(el.format.compType == CompType::UInt) + else if(prop.format.compType == CompType::UInt) { - return interpretVariant(QVariant(config.generics[col].uintValue[comp]), el); + return interpretVariant(QVariant(config.generics[col].uintValue[comp]), el, prop); } } return outOfBounds(); } - QString interpretVariant(const QVariant &v, const FormatElement &el) const + QString interpretVariant(const QVariant &v, const FormatElement &el, + const BufferElementProperties &prop) const { QString ret; @@ -1158,8 +1128,8 @@ private: else if(vt == QMetaType::UInt || vt == QMetaType::UShort || vt == QMetaType::UChar) { uint u = v.toUInt(); - if(el.hex && el.format.type == ResourceFormatType::Regular) - ret = Formatter::HexFormat(u, el.format.compByteWidth); + if(el.hex && prop.format.type == ResourceFormatType::Regular) + ret = Formatter::HexFormat(u, prop.format.compByteWidth); else ret = Formatter::Format(u, el.hex); } @@ -1289,10 +1259,6 @@ static void ConfigureColumnsForShader(ICaptureContext &ctx, const ShaderReflecti BufferElementProperties p; f.name = !sig.varName.isEmpty() ? sig.varName : sig.semanticIdxName; - f.format.compByteWidth = sizeof(float); - f.format.compCount = sig.compCount; - f.format.compType = sig.compType; - f.format.type = ResourceFormatType::Regular; f.rowmajor = false; f.matrixdim = 1; @@ -1300,6 +1266,10 @@ static void ConfigureColumnsForShader(ICaptureContext &ctx, const ShaderReflecti p.perinstance = false; p.instancerate = 1; p.systemValue = sig.systemValue; + p.format.type = ResourceFormatType::Regular; + p.format.compByteWidth = sizeof(float); + p.format.compCount = sig.compCount; + p.format.compType = sig.compType; if(sig.systemValue == ShaderBuiltin::Position) posidx = i; @@ -1320,10 +1290,13 @@ static void ConfigureColumnsForShader(ICaptureContext &ctx, const ShaderReflecti i = 0; uint32_t offset = 0; - for(FormatElement &sig : columns) + for(i = 0; i < columns.count(); i++) { - uint numComps = sig.format.compCount; - uint elemSize = sig.format.compType == CompType::Double ? 8U : 4U; + BufferElementProperties &prop = props[i]; + FormatElement &sig = columns[i]; + + uint numComps = prop.format.compCount; + uint elemSize = prop.format.compType == CompType::Double ? 8U : 4U; if(ctx.CurPipelineState().HasAlignedPostVSData( shader->stage == ShaderStage::Vertex ? MeshDataStage::VSOut : MeshDataStage::GSOut)) @@ -1367,6 +1340,7 @@ static void ConfigureMeshColumns(ICaptureContext &ctx, PopulateBufferData *bufda p.buffer = a.vertexBuffer; p.perinstance = a.perInstance; p.instancerate = a.instanceRate; + p.format = a.format; bufdata->vsinConfig.genericsEnabled[bufdata->vsinConfig.columns.size()] = false; @@ -2025,8 +1999,8 @@ void BufferViewer::meshHeaderMenu(MeshDataStage stage, const QPoint &pos) m_CurView = tableForStage(stage); m_ContextColumn = modelForStage(stage)->elementIndexForColumn(col); - m_SelectSecondAlphaColumn->setEnabled( - modelForStage(stage)->elementForColumn(col).format.compCount == 4); + m_SelectSecondAlphaColumn->setEnabled(modelForStage(stage)->propForColumn(col).format.compCount == + 4); m_HeaderMenu->popup(tableForStage(stage)->horizontalHeader()->mapToGlobal(pos)); } @@ -2424,11 +2398,11 @@ void BufferViewer::calcBoundingData(CalcBoundingBoxData &bbox) { FloatVector maxvec(FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX); - if(s.columns[i].format.compCount == 1) + if(s.props[i].format.compCount == 1) maxvec.y = maxvec.z = maxvec.w = 0.0; - else if(s.columns[i].format.compCount == 2) + else if(s.props[i].format.compCount == 2) maxvec.z = maxvec.w = 0.0; - else if(s.columns[i].format.compCount == 3) + else if(s.props[i].format.compCount == 3) maxvec.w = 0.0; minOutputList.push_back(maxvec); @@ -2470,7 +2444,7 @@ void BufferViewer::calcBoundingData(CalcBoundingBoxData &bbox) if(!prop->perinstance) bytes += d.stride * idx; - QVariantList list = el->GetVariants(bytes, d.end); + QVariantList list = GetVariants(prop->format, el->matrixdim, bytes, d.end); for(int comp = 0; comp < 4 && comp < list.count(); comp++) { @@ -2528,7 +2502,7 @@ void BufferViewer::UI_UpdateBoundingBoxLabels(int compCount) int posEl = model->posColumn(); if(posEl >= 0 && posEl < model->getConfig().columns.count()) { - compCount = model->getConfig().columns[posEl].format.compCount; + compCount = model->getConfig().props[posEl].format.compCount; } } } @@ -2667,7 +2641,7 @@ void BufferViewer::UI_CalculateMeshFormats() m_VSInPosition.vertexByteOffset = 0; } - m_VSInPosition.format = el.format; + m_VSInPosition.format = prop.format; } elIdx = m_ModelVSIn->secondaryColumn(); @@ -2694,7 +2668,7 @@ void BufferViewer::UI_CalculateMeshFormats() m_VSInSecondary.vertexByteOffset = 0; } - m_VSInSecondary.format = el.format; + m_VSInSecondary.format = prop.format; m_VSInSecondary.showAlpha = m_ModelVSIn->secondaryAlpha(); } } @@ -2885,7 +2859,7 @@ void BufferViewer::UpdateCurrentMeshConfig() m_Config.maxBounds = bbox.bounds[stage].Max[posEl]; m_Config.showBBox = !isCurrentRasterOut(); - int compCount = model->getConfig().columns[posEl].format.compCount; + int compCount = model->getConfig().props[posEl].format.compCount; UI_UpdateBoundingBoxLabels(compCount); } @@ -3211,17 +3185,21 @@ void BufferViewer::CalcColumnWidth(int maxNumRows) BufferConfiguration bufconfig; + BufferElementProperties floatProp, intProp; + floatProp.format = floatFmt; + intProp.format = intFmt; + bufconfig.columns.clear(); bufconfig.columns.push_back(FormatElement(headerText, 0, false, maxNumRows, floatFmt, false, false)); - bufconfig.props.push_back({}); + bufconfig.props.push_back(floatProp); bufconfig.columns.push_back(FormatElement(headerText, 4, false, 1, floatFmt, false, false)); - bufconfig.props.push_back({}); + bufconfig.props.push_back(floatProp); bufconfig.columns.push_back(FormatElement(headerText, 8, false, 1, floatFmt, false, false)); - bufconfig.props.push_back({}); + bufconfig.props.push_back(floatProp); bufconfig.columns.push_back(FormatElement(headerText, 12, false, 1, intFmt, true, false)); - bufconfig.props.push_back({}); + bufconfig.props.push_back(intProp); bufconfig.columns.push_back(FormatElement(headerText, 16, false, 1, intFmt, false, false)); - bufconfig.props.push_back({}); + bufconfig.props.push_back(intProp); bufconfig.numRows = 2; bufconfig.unclampedNumRows = 0;