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:
baldurk
2017-05-10 14:25:23 +01:00
parent 6941444796
commit 1ca55a8237
5 changed files with 230 additions and 70 deletions
+31 -25
View File
@@ -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;
+19 -6
View File
@@ -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:
+5 -3
View File
@@ -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">
+105 -35
View File
@@ -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)
+70 -1
View File
@@ -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);
}