mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-04 09:00:44 +00:00
Add an optional 'rgb' specifier to colour buffer cells backgrounds
* When opening a texture as a buffer we can make use of this.
This commit is contained in:
@@ -120,11 +120,13 @@ FormatElement::FormatElement()
|
||||
rowmajor = false;
|
||||
matrixdim = 0;
|
||||
hex = false;
|
||||
rgb = false;
|
||||
systemValue = ShaderBuiltin::Undefined;
|
||||
}
|
||||
|
||||
FormatElement::FormatElement(const QString &Name, int buf, uint offs, bool perInst, int instRate,
|
||||
bool rowMat, uint matDim, ResourceFormat f, bool hexDisplay)
|
||||
bool rowMat, uint matDim, ResourceFormat f, bool hexDisplay,
|
||||
bool rgbDisplay)
|
||||
{
|
||||
name = Name;
|
||||
buffer = buf;
|
||||
@@ -135,6 +137,7 @@ FormatElement::FormatElement(const QString &Name, int buf, uint offs, bool perIn
|
||||
rowmajor = rowMat;
|
||||
matrixdim = matDim;
|
||||
hex = hexDisplay;
|
||||
rgb = rgbDisplay;
|
||||
systemValue = ShaderBuiltin::Undefined;
|
||||
}
|
||||
|
||||
@@ -146,20 +149,22 @@ QList<FormatElement> FormatElement::ParseFormatString(const QString &formatStrin
|
||||
// regex doesn't account for trailing or preceeding whitespace, or comments
|
||||
|
||||
QRegularExpression regExpr(
|
||||
lit("^(row_major\\s+)?" // row_major matrix
|
||||
"("
|
||||
"uintten|unormten"
|
||||
"|floateleven"
|
||||
"|unormh|unormb"
|
||||
"|snormh|snormb"
|
||||
"|bool" // bool is stored as 4-byte int
|
||||
"|byte|short|int" // signed ints
|
||||
"|ubyte|ushort|uint" // unsigned ints
|
||||
"|xbyte|xshort|xint" // hex ints
|
||||
"|half|float|double" // float types
|
||||
"|vec|uvec|ivec" // OpenGL vector types
|
||||
"|mat|umat|imat" // OpenGL matrix types
|
||||
")"
|
||||
lit("^" // start of the line
|
||||
"(row_major\\s+)?" // row_major matrix
|
||||
"(rgb\\s+)?" // rgb element colourising
|
||||
"(" // group the options for the type
|
||||
"uintten|unormten" // R10G10B10A2 types
|
||||
"|floateleven" // R11G11B10 special type
|
||||
"|unormh|unormb" // UNORM 16-bit and 8-bit types
|
||||
"|snormh|snormb" // SNORM 16-bit and 8-bit types
|
||||
"|bool" // bool is stored as 4-byte int
|
||||
"|byte|short|int" // signed ints
|
||||
"|ubyte|ushort|uint" // unsigned ints
|
||||
"|xbyte|xshort|xint" // hex ints
|
||||
"|half|float|double" // float types
|
||||
"|vec|uvec|ivec" // OpenGL vector types
|
||||
"|mat|umat|imat" // OpenGL matrix types
|
||||
")" // end of the type group
|
||||
"([1-9])?" // might be a vector
|
||||
"(x[1-9])?" // or a matrix
|
||||
"(\\s+[A-Za-z_][A-Za-z0-9_]*)?" // get identifier name
|
||||
@@ -197,15 +202,16 @@ QList<FormatElement> FormatElement::ParseFormatString(const QString &formatStrin
|
||||
break;
|
||||
}
|
||||
|
||||
QString basetype = match.captured(2);
|
||||
QString basetype = match.captured(3);
|
||||
bool row_major = !match.captured(1).isEmpty();
|
||||
QString vectorDim = !match.captured(3).isEmpty() ? match.captured(3) : lit("1");
|
||||
QString matrixDim = !match.captured(4).isEmpty() ? match.captured(4).mid(1) : lit("1");
|
||||
QString name = !match.captured(5).isEmpty() ? match.captured(5).trimmed() : lit("data");
|
||||
QString arrayDim = !match.captured(6).isEmpty() ? match.captured(6).trimmed() : lit("[1]");
|
||||
bool rgb = !match.captured(2).isEmpty();
|
||||
QString vectorDim = !match.captured(4).isEmpty() ? match.captured(4) : lit("1");
|
||||
QString matrixDim = !match.captured(5).isEmpty() ? match.captured(5).mid(1) : lit("1");
|
||||
QString name = !match.captured(6).isEmpty() ? match.captured(6).trimmed() : lit("data");
|
||||
QString arrayDim = !match.captured(7).isEmpty() ? match.captured(7).trimmed() : lit("[1]");
|
||||
arrayDim = arrayDim.mid(1, arrayDim.count() - 2);
|
||||
|
||||
if(!match.captured(4).isEmpty())
|
||||
if(!match.captured(5).isEmpty())
|
||||
{
|
||||
vectorDim.swap(matrixDim);
|
||||
}
|
||||
@@ -222,7 +228,7 @@ QList<FormatElement> FormatElement::ParseFormatString(const QString &formatStrin
|
||||
uint32_t width = 0;
|
||||
|
||||
// check for square matrix declarations like 'mat4' and 'mat3'
|
||||
if(basetype == lit("mat") && !match.captured(4).isEmpty())
|
||||
if(basetype == lit("mat") && !match.captured(5).isEmpty())
|
||||
matrixDim = vectorDim;
|
||||
|
||||
// calculate format
|
||||
@@ -367,7 +373,7 @@ QList<FormatElement> FormatElement::ParseFormatString(const QString &formatStrin
|
||||
|
||||
if(arrayCount == 1)
|
||||
{
|
||||
FormatElement elem(name, 0, offset, false, 1, row_major, matrixCount, fmt, hex);
|
||||
FormatElement elem(name, 0, offset, false, 1, row_major, matrixCount, fmt, hex, rgb);
|
||||
|
||||
uint32_t advance = elem.byteSize();
|
||||
|
||||
@@ -402,7 +408,7 @@ QList<FormatElement> FormatElement::ParseFormatString(const QString &formatStrin
|
||||
for(uint a = 0; a < arrayCount; a++)
|
||||
{
|
||||
FormatElement elem(QFormatStr("%1[%2]").arg(name).arg(a), 0, offset, false, 1, row_major,
|
||||
matrixCount, fmt, hex);
|
||||
matrixCount, fmt, hex, rgb);
|
||||
|
||||
elems.push_back(elem);
|
||||
|
||||
@@ -433,7 +439,7 @@ QList<FormatElement> FormatElement::ParseFormatString(const QString &formatStrin
|
||||
if(maxLen > 0 && maxLen < 4)
|
||||
fmt.compByteWidth = 1;
|
||||
|
||||
elems.push_back(FormatElement(lit("data"), 0, 0, false, 1, false, 1, fmt, true));
|
||||
elems.push_back(FormatElement(lit("data"), 0, 0, false, 1, false, 1, fmt, true, false));
|
||||
}
|
||||
|
||||
return elems;
|
||||
|
||||
@@ -589,7 +589,7 @@ struct FormatElement
|
||||
public:
|
||||
FormatElement();
|
||||
FormatElement(const QString &Name, int buf, uint offs, bool perInst, int instRate, bool rowMat,
|
||||
uint matDim, ResourceFormat f, bool hexDisplay);
|
||||
uint matDim, ResourceFormat f, bool hexDisplay, bool rgbDisplay);
|
||||
|
||||
static QList<FormatElement> ParseFormatString(const QString &formatString, uint64_t maxLen,
|
||||
bool tightPacking, QString &errors);
|
||||
@@ -602,15 +602,15 @@ public:
|
||||
uint32_t byteSize() const;
|
||||
|
||||
QString name;
|
||||
ResourceFormat format;
|
||||
ShaderBuiltin systemValue;
|
||||
int buffer;
|
||||
uint32_t offset;
|
||||
bool perinstance;
|
||||
int instancerate;
|
||||
bool rowmajor;
|
||||
uint32_t matrixdim;
|
||||
ResourceFormat format;
|
||||
bool hex;
|
||||
ShaderBuiltin systemValue;
|
||||
bool perinstance;
|
||||
bool rowmajor;
|
||||
bool hex, rgb;
|
||||
};
|
||||
|
||||
QString TypeString(const ShaderVariable &v);
|
||||
@@ -639,6 +639,19 @@ struct Formatter
|
||||
{
|
||||
return QFormatStr("%1").arg(u, hex ? 4 : 0, hex ? 16 : 10, QLatin1Char('0'));
|
||||
}
|
||||
static QString Format(uint8_t u, bool hex = false)
|
||||
{
|
||||
return QFormatStr("%1").arg(u, hex ? 2 : 0, hex ? 16 : 10, QLatin1Char('0'));
|
||||
}
|
||||
static QString HexFormat(uint32_t u, uint32_t byteSize)
|
||||
{
|
||||
if(byteSize == 1)
|
||||
return Format(uint8_t(u & 0xff), true);
|
||||
else if(byteSize == 2)
|
||||
return Format(uint16_t(u & 0xffff), true);
|
||||
else
|
||||
return Format(u, true);
|
||||
}
|
||||
static QString Format(int32_t i, bool hex = false) { return QString::number(i); }
|
||||
static const QFont &PreferredFont() { return m_Font; }
|
||||
private:
|
||||
|
||||
@@ -65,9 +65,9 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Apply</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Apply</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@@ -84,6 +84,8 @@ Hex-formatted integer types: xbyte, xshort, xint
|
||||
|
||||
Additionally special formats: unorm[hb] (half, byte) and snorm[hb], uintten/unormten (10:10:10:2 packing), floateleven (11:11:10F packing)
|
||||
|
||||
You can prepend 'rgb' onto an element to colour backgrounds with the RGB values, e.g. 'rgb xbyte4 pixels[256]'.
|
||||
|
||||
Vectors (e.g. float4), matrices ([row_major] half3x4) and arrays (float[16]) are supported.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
|
||||
@@ -447,37 +447,103 @@ public:
|
||||
|
||||
if((role == Qt::BackgroundRole || role == Qt::ForegroundRole) && col >= reservedColumnCount())
|
||||
{
|
||||
int elIdx = columnLookup[col - reservedColumnCount()];
|
||||
int compIdx = componentForIndex(col);
|
||||
if(elIdx == positionEl)
|
||||
if(meshView)
|
||||
{
|
||||
if(role == Qt::ForegroundRole)
|
||||
return QBrush(Qt::black);
|
||||
int elIdx = columnLookup[col - reservedColumnCount()];
|
||||
int compIdx = componentForIndex(col);
|
||||
|
||||
if(compIdx != 3 || !meshInput)
|
||||
if(elIdx == positionEl)
|
||||
{
|
||||
// C# SkyBlue
|
||||
return QBrush(QColor::fromRgb(135, 206, 235));
|
||||
if(role == Qt::ForegroundRole)
|
||||
return QBrush(Qt::black);
|
||||
|
||||
if(compIdx != 3 || !meshInput)
|
||||
{
|
||||
// C# SkyBlue
|
||||
return QBrush(QColor::fromRgb(135, 206, 235));
|
||||
}
|
||||
else
|
||||
{
|
||||
// C# LightCyan
|
||||
return QBrush(QColor::fromRgb(224, 255, 255));
|
||||
}
|
||||
}
|
||||
else
|
||||
else if(secondaryEnabled && elIdx == secondaryEl)
|
||||
{
|
||||
// C# LightCyan
|
||||
return QBrush(QColor::fromRgb(224, 255, 255));
|
||||
if(role == Qt::ForegroundRole)
|
||||
return QBrush(Qt::black);
|
||||
|
||||
if((secondaryElAlpha && compIdx == 3) || (!secondaryElAlpha && compIdx != 3))
|
||||
{
|
||||
// C# LightGreen
|
||||
return QBrush(QColor::fromRgb(144, 238, 144));
|
||||
}
|
||||
else
|
||||
{
|
||||
return QBrush(QColor::fromRgb(200, 238, 200));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(secondaryEnabled && elIdx == secondaryEl)
|
||||
else
|
||||
{
|
||||
if(role == Qt::ForegroundRole)
|
||||
return QBrush(Qt::black);
|
||||
const FormatElement &el = elementForColumn(col);
|
||||
|
||||
if((secondaryElAlpha && compIdx == 3) || (!secondaryElAlpha && compIdx != 3))
|
||||
if(el.rgb && el.buffer < buffers.size())
|
||||
{
|
||||
// C# LightGreen
|
||||
return QBrush(QColor::fromRgb(144, 238, 144));
|
||||
}
|
||||
else
|
||||
{
|
||||
return QBrush(QColor::fromRgb(200, 238, 200));
|
||||
const byte *data = buffers[el.buffer]->data;
|
||||
const byte *end = buffers[el.buffer]->end;
|
||||
|
||||
data += buffers[el.buffer]->stride * row;
|
||||
data += el.offset;
|
||||
|
||||
// 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);
|
||||
|
||||
if(!list.isEmpty())
|
||||
{
|
||||
QMetaType::Type vt = (QMetaType::Type)list[0].type();
|
||||
|
||||
QColor rgb;
|
||||
|
||||
if(vt == QMetaType::Double)
|
||||
{
|
||||
double r = qBound(0.0, list[0].toDouble(), 1.0);
|
||||
double g = list.size() > 1 ? qBound(0.0, list[1].toDouble(), 1.0) : 0.0;
|
||||
double b = list.size() > 2 ? qBound(0.0, list[2].toDouble(), 1.0) : 0.0;
|
||||
|
||||
rgb = QColor::fromRgbF(r, g, b);
|
||||
}
|
||||
else if(vt == QMetaType::Float)
|
||||
{
|
||||
float r = qBound(0.0f, list[0].toFloat(), 1.0f);
|
||||
float g = list.size() > 1 ? qBound(0.0f, list[1].toFloat(), 1.0f) : 0.0;
|
||||
float b = list.size() > 2 ? qBound(0.0f, list[2].toFloat(), 1.0f) : 0.0;
|
||||
|
||||
rgb = QColor::fromRgbF(r, g, b);
|
||||
}
|
||||
else if(vt == QMetaType::UInt || vt == QMetaType::UShort || vt == QMetaType::UChar)
|
||||
{
|
||||
uint r = qBound(0U, list[0].toUInt(), 255U);
|
||||
uint g = list.size() > 1 ? qBound(0U, list[1].toUInt(), 255U) : 0.0;
|
||||
uint b = list.size() > 2 ? qBound(0U, list[2].toUInt(), 255U) : 0.0;
|
||||
|
||||
rgb = QColor::fromRgb(r, g, b);
|
||||
}
|
||||
else if(vt == QMetaType::Int || vt == QMetaType::Short || vt == QMetaType::SChar)
|
||||
{
|
||||
int r = qBound(0, list[0].toInt(), 255);
|
||||
int g = list.size() > 1 ? qBound(0, list[1].toInt(), 255) : 0.0;
|
||||
int b = list.size() > 2 ? qBound(0, list[2].toInt(), 255) : 0.0;
|
||||
|
||||
rgb = QColor::fromRgb(r, g, b);
|
||||
}
|
||||
|
||||
if(role == Qt::BackgroundRole)
|
||||
return QBrush(rgb);
|
||||
else if(role == Qt::ForegroundRole)
|
||||
return QBrush(contrastingColor(rgb, QColor::fromRgb(0, 0, 0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -573,7 +639,11 @@ public:
|
||||
}
|
||||
else if(vt == QMetaType::UInt || vt == QMetaType::UShort || vt == QMetaType::UChar)
|
||||
{
|
||||
ret = Formatter::Format(v.toUInt(), el.hex);
|
||||
uint u = v.toUInt();
|
||||
if(el.hex && el.format.specialFormat == SpecialFormat::Unknown)
|
||||
ret = Formatter::HexFormat(u, el.format.compByteWidth);
|
||||
else
|
||||
ret = Formatter::Format(u, el.hex);
|
||||
}
|
||||
else if(vt == QMetaType::Int || vt == QMetaType::Short || vt == QMetaType::SChar)
|
||||
{
|
||||
@@ -2027,7 +2097,7 @@ void BufferViewer::configureMeshColumns()
|
||||
FormatElement f(a.Name, a.VertexBuffer, a.RelativeByteOffset, a.PerInstance, a.InstanceRate,
|
||||
false, // row major matrix
|
||||
1, // matrix dimension
|
||||
a.Format, false);
|
||||
a.Format, false, false);
|
||||
|
||||
m_ModelVSIn->columns.push_back(f);
|
||||
}
|
||||
@@ -2514,25 +2584,23 @@ void BufferViewer::CalcColumnWidth()
|
||||
floatFmt.compCount = 1;
|
||||
|
||||
ResourceFormat intFmt;
|
||||
floatFmt.compByteWidth = 4;
|
||||
floatFmt.compType = CompType::UInt;
|
||||
floatFmt.compCount = 1;
|
||||
intFmt.compByteWidth = 4;
|
||||
intFmt.compType = CompType::UInt;
|
||||
intFmt.compCount = 1;
|
||||
|
||||
FormatElement(lit("ColumnSizeTest"), 0, 0, false, 1, false, 1, floatFmt, false);
|
||||
FormatElement(lit("ColumnSizeTest"), 0, 0, false, 1, false, 1, intFmt, true);
|
||||
FormatElement(lit("ColumnSizeTest"), 0, 0, false, 1, false, 1, intFmt, false);
|
||||
QString headerText = lit("ColumnSizeTest");
|
||||
|
||||
m_ModelVSIn->columns.clear();
|
||||
m_ModelVSIn->columns.push_back(
|
||||
FormatElement(lit("ColumnSizeTest"), 0, 0, false, 1, false, 1, floatFmt, false));
|
||||
FormatElement(headerText, 0, 0, false, 1, false, 1, floatFmt, false, false));
|
||||
m_ModelVSIn->columns.push_back(
|
||||
FormatElement(lit("ColumnSizeTest"), 0, 4, false, 1, false, 1, floatFmt, false));
|
||||
FormatElement(headerText, 0, 4, false, 1, false, 1, floatFmt, false, false));
|
||||
m_ModelVSIn->columns.push_back(
|
||||
FormatElement(lit("ColumnSizeTest"), 0, 8, false, 1, false, 1, floatFmt, false));
|
||||
FormatElement(headerText, 0, 8, false, 1, false, 1, floatFmt, false, false));
|
||||
m_ModelVSIn->columns.push_back(
|
||||
FormatElement(lit("ColumnSizeTest"), 0, 12, false, 1, false, 1, intFmt, true));
|
||||
FormatElement(headerText, 0, 12, false, 1, false, 1, intFmt, true, false));
|
||||
m_ModelVSIn->columns.push_back(
|
||||
FormatElement(lit("ColumnSizeTest"), 0, 16, false, 1, false, 1, intFmt, false));
|
||||
FormatElement(headerText, 0, 16, false, 1, false, 1, intFmt, false, false));
|
||||
|
||||
m_ModelVSIn->numRows = 2;
|
||||
|
||||
@@ -2659,13 +2727,15 @@ void BufferViewer::processFormat(const QString &format)
|
||||
|
||||
Reset();
|
||||
|
||||
QList<FormatElement> cols = FormatElement::ParseFormatString(format, 0, true, errors);
|
||||
|
||||
CalcColumnWidth();
|
||||
|
||||
ClearModels();
|
||||
|
||||
m_Format = format;
|
||||
|
||||
m_ModelVSIn->columns = FormatElement::ParseFormatString(format, 0, true, errors);
|
||||
m_ModelVSIn->columns = cols;
|
||||
|
||||
uint32_t stride = 0;
|
||||
for(const FormatElement &el : m_ModelVSIn->columns)
|
||||
|
||||
@@ -3212,8 +3212,77 @@ void TextureViewer::on_viewTexBuffer_clicked()
|
||||
|
||||
if(texptr)
|
||||
{
|
||||
QString baseType;
|
||||
|
||||
QString varName = lit("pixels");
|
||||
|
||||
uint32_t w = texptr->width;
|
||||
|
||||
switch(texptr->format.specialFormat)
|
||||
{
|
||||
case SpecialFormat::BC1:
|
||||
case SpecialFormat::BC2:
|
||||
case SpecialFormat::BC3:
|
||||
case SpecialFormat::BC4:
|
||||
case SpecialFormat::BC5:
|
||||
case SpecialFormat::BC6:
|
||||
case SpecialFormat::BC7:
|
||||
case SpecialFormat::ETC2:
|
||||
case SpecialFormat::EAC:
|
||||
case SpecialFormat::ASTC:
|
||||
varName = lit("block");
|
||||
// display a 4x4 block at a time
|
||||
w /= 4;
|
||||
default: break;
|
||||
}
|
||||
|
||||
switch(texptr->format.specialFormat)
|
||||
{
|
||||
case SpecialFormat::Unknown:
|
||||
{
|
||||
if(texptr->format.compByteWidth == 1)
|
||||
baseType = lit("byte");
|
||||
else if(texptr->format.compByteWidth == 2)
|
||||
baseType = lit("short");
|
||||
else
|
||||
baseType = lit("int");
|
||||
|
||||
baseType = QFormatStr("rgb x%1%2").arg(baseType).arg(texptr->format.compCount);
|
||||
|
||||
break;
|
||||
}
|
||||
// 2x4 byte block, for 64-bit block formats
|
||||
case SpecialFormat::BC1:
|
||||
case SpecialFormat::BC4:
|
||||
case SpecialFormat::ETC2:
|
||||
case SpecialFormat::EAC:
|
||||
baseType = lit("row_major xint2x1");
|
||||
break;
|
||||
// 4x4 byte block, for 128-bit block formats
|
||||
case SpecialFormat::BC2:
|
||||
case SpecialFormat::BC3:
|
||||
case SpecialFormat::BC5:
|
||||
case SpecialFormat::BC6:
|
||||
case SpecialFormat::BC7:
|
||||
case SpecialFormat::ASTC: baseType = lit("row_major xint4x1"); break;
|
||||
case SpecialFormat::R10G10B10A2: baseType = lit("uintten"); break;
|
||||
case SpecialFormat::R11G11B10: baseType = lit("rgb floateleven"); break;
|
||||
case SpecialFormat::R5G6B5:
|
||||
case SpecialFormat::R5G5B5A1: baseType = lit("xshort"); break;
|
||||
case SpecialFormat::R9G9B9E5: baseType = lit("xint"); break;
|
||||
case SpecialFormat::R4G4B4A4: baseType = lit("xbyte2"); break;
|
||||
case SpecialFormat::R4G4: baseType = lit("xbyte"); break;
|
||||
case SpecialFormat::D16S8:
|
||||
case SpecialFormat::D24S8:
|
||||
case SpecialFormat::D32S8:
|
||||
case SpecialFormat::YUV: baseType = lit("xint4"); break;
|
||||
case SpecialFormat::S8: baseType = lit("xbyte"); break;
|
||||
}
|
||||
|
||||
QString format = QFormatStr("%1 %2[%3];").arg(baseType).arg(varName).arg(w);
|
||||
|
||||
IBufferViewer *viewer =
|
||||
m_Ctx.ViewTextureAsBuffer(m_TexDisplay.sliceFace, m_TexDisplay.mip, texptr->ID);
|
||||
m_Ctx.ViewTextureAsBuffer(m_TexDisplay.sliceFace, m_TexDisplay.mip, texptr->ID, format);
|
||||
|
||||
m_Ctx.AddDockWindow(viewer->Widget(), DockReference::AddTo, this);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user