mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-01 20:31:01 +00:00
Add constant buffer previewer for qrenderdoc
This commit is contained in:
@@ -53,15 +53,6 @@ class TextureViewer;
|
||||
class CaptureDialog;
|
||||
class QProgressDialog;
|
||||
|
||||
struct Formatter
|
||||
{
|
||||
static QString Format(float f) { return QString::number(f); }
|
||||
static QString Format(double d) { return QString::number(d); }
|
||||
static QString Format(uint32_t u) { return QString::number(u); }
|
||||
static QString Format(uint16_t u) { return QString::number(u); }
|
||||
static QString Format(int32_t i) { return QString::number(i); }
|
||||
};
|
||||
|
||||
class CaptureContext
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -0,0 +1,877 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include <QRegularExpression>
|
||||
#include <QtMath>
|
||||
#include "QRDUtils.h"
|
||||
|
||||
static QVariant interpret(const ResourceFormat &f, uint16_t comp)
|
||||
{
|
||||
if(f.compByteWidth != 2 || f.compType == eCompType_Float)
|
||||
return QVariant();
|
||||
|
||||
if(f.compType == eCompType_SInt)
|
||||
{
|
||||
return (int16_t)comp;
|
||||
}
|
||||
else if(f.compType == eCompType_UInt)
|
||||
{
|
||||
return comp;
|
||||
}
|
||||
else if(f.compType == eCompType_SScaled)
|
||||
{
|
||||
return (float)((int16_t)comp);
|
||||
}
|
||||
else if(f.compType == eCompType_UScaled)
|
||||
{
|
||||
return (float)comp;
|
||||
}
|
||||
else if(f.compType == eCompType_UNorm)
|
||||
{
|
||||
return (float)comp / (float)0xffff;
|
||||
}
|
||||
else if(f.compType == eCompType_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 == eCompType_Float)
|
||||
return QVariant();
|
||||
|
||||
if(f.compType == eCompType_SInt)
|
||||
{
|
||||
return (int8_t)comp;
|
||||
}
|
||||
else if(f.compType == eCompType_UInt)
|
||||
{
|
||||
return comp;
|
||||
}
|
||||
else if(f.compType == eCompType_SScaled)
|
||||
{
|
||||
return (float)((int8_t)comp);
|
||||
}
|
||||
else if(f.compType == eCompType_UScaled)
|
||||
{
|
||||
return (float)comp;
|
||||
}
|
||||
else if(f.compType == eCompType_UNorm)
|
||||
{
|
||||
return ((float)comp) / 255.0f;
|
||||
}
|
||||
else if(f.compType == eCompType_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();
|
||||
}
|
||||
|
||||
FormatElement::FormatElement()
|
||||
{
|
||||
name = "";
|
||||
buffer = 0;
|
||||
offset = 0;
|
||||
perinstance = false;
|
||||
instancerate = 1;
|
||||
rowmajor = false;
|
||||
matrixdim = 0;
|
||||
hex = false;
|
||||
systemValue = eAttr_None;
|
||||
}
|
||||
|
||||
FormatElement::FormatElement(const QString &Name, int buf, uint offs, bool pi, int ir, bool rowMat,
|
||||
uint matDim, ResourceFormat f, bool h)
|
||||
{
|
||||
name = Name;
|
||||
buffer = buf;
|
||||
offset = offs;
|
||||
format = f;
|
||||
perinstance = pi;
|
||||
instancerate = ir;
|
||||
rowmajor = rowMat;
|
||||
matrixdim = matDim;
|
||||
hex = h;
|
||||
systemValue = eAttr_None;
|
||||
}
|
||||
|
||||
QList<FormatElement> FormatElement::ParseFormatString(const QString &formatString, uint64_t maxLen,
|
||||
bool tightPacking, QString &errors)
|
||||
{
|
||||
QList<FormatElement> elems;
|
||||
|
||||
// regex doesn't account for trailing or preceeding whitespace, or comments
|
||||
|
||||
QRegularExpression regExpr(
|
||||
"^(row_major\\s+)?" // row_major matrix
|
||||
"("
|
||||
"uintten|unormten"
|
||||
"|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
|
||||
")"
|
||||
"([1-9])?" // might be a vector
|
||||
"(x[1-9])?" // or a matrix
|
||||
"(\\s+[A-Za-z_][A-Za-z0-9_]*)?" // get identifier name
|
||||
"(\\[[0-9]+\\])?" // optional array dimension
|
||||
"(\\s*:\\s*[A-Za-z_][A-Za-z0-9_]*)?" // optional semantic
|
||||
"$");
|
||||
|
||||
bool success = true;
|
||||
errors = "";
|
||||
|
||||
QString text = formatString;
|
||||
|
||||
text = text.replace("{", "").replace("}", "");
|
||||
|
||||
QRegularExpression c_comments("/\\*[^*]*\\*+(?:[^*/][^*]*\\*+)*/");
|
||||
QRegularExpression cpp_comments("//.*");
|
||||
text = text.replace(c_comments, "").replace(cpp_comments, "");
|
||||
|
||||
uint32_t offset = 0;
|
||||
|
||||
// get each line and parse it to determine the format the user wanted
|
||||
for(QString &l : text.split(QChar(';')))
|
||||
{
|
||||
QString line = l.trimmed();
|
||||
|
||||
if(line.isEmpty())
|
||||
continue;
|
||||
|
||||
QRegularExpressionMatch match = regExpr.match(line);
|
||||
|
||||
if(!match.hasMatch())
|
||||
{
|
||||
errors = "Couldn't parse line:\n" + line;
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
QString basetype = match.captured(2);
|
||||
bool row_major = !match.captured(1).isEmpty();
|
||||
QString vectorDim = !match.captured(3).isEmpty() ? match.captured(3) : "1";
|
||||
QString matrixDim = !match.captured(4).isEmpty() ? match.captured(4).mid(1) : "1";
|
||||
QString name = !match.captured(5).isEmpty() ? match.captured(5).trimmed() : "data";
|
||||
QString arrayDim = !match.captured(6).isEmpty() ? match.captured(6).trimmed() : "[1]";
|
||||
arrayDim = arrayDim.mid(1, arrayDim.count() - 2);
|
||||
|
||||
if(!match.captured(4).isEmpty())
|
||||
{
|
||||
vectorDim.swap(matrixDim);
|
||||
}
|
||||
|
||||
ResourceFormat fmt;
|
||||
fmt.compType = eCompType_None;
|
||||
|
||||
bool hex = false;
|
||||
|
||||
FormatComponentType type = eCompType_Float;
|
||||
uint32_t count = 0;
|
||||
uint32_t arrayCount = 1;
|
||||
uint32_t matrixCount = 0;
|
||||
uint32_t width = 0;
|
||||
|
||||
// check for square matrix declarations like 'mat4' and 'mat3'
|
||||
if(basetype == "mat" && !match.captured(4).isEmpty())
|
||||
matrixDim = vectorDim;
|
||||
|
||||
// calculate format
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
count = vectorDim.toUInt(&ok);
|
||||
if(!ok)
|
||||
{
|
||||
errors = "Invalid vector dimension on line:\n" + line;
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
arrayCount = arrayDim.toUInt(&ok);
|
||||
if(!ok)
|
||||
{
|
||||
arrayCount = 1;
|
||||
}
|
||||
arrayCount = qMax(0U, arrayCount);
|
||||
|
||||
matrixCount = matrixDim.toUInt(&ok);
|
||||
if(!ok)
|
||||
{
|
||||
errors = "Invalid matrix second dimension on line:\n" + line;
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(basetype == "bool")
|
||||
{
|
||||
type = eCompType_UInt;
|
||||
width = 4;
|
||||
}
|
||||
else if(basetype == "byte")
|
||||
{
|
||||
type = eCompType_SInt;
|
||||
width = 1;
|
||||
}
|
||||
else if(basetype == "ubyte" || basetype == "xbyte")
|
||||
{
|
||||
type = eCompType_UInt;
|
||||
width = 1;
|
||||
}
|
||||
else if(basetype == "short")
|
||||
{
|
||||
type = eCompType_SInt;
|
||||
width = 2;
|
||||
}
|
||||
else if(basetype == "ushort" || basetype == "xshort")
|
||||
{
|
||||
type = eCompType_UInt;
|
||||
width = 2;
|
||||
}
|
||||
else if(basetype == "int" || basetype == "ivec" || basetype == "imat")
|
||||
{
|
||||
type = eCompType_SInt;
|
||||
width = 4;
|
||||
}
|
||||
else if(basetype == "uint" || basetype == "xint" || basetype == "uvec" || basetype == "umat")
|
||||
{
|
||||
type = eCompType_UInt;
|
||||
width = 4;
|
||||
}
|
||||
else if(basetype == "half")
|
||||
{
|
||||
type = eCompType_Float;
|
||||
width = 2;
|
||||
}
|
||||
else if(basetype == "float" || basetype == "vec" || basetype == "mat")
|
||||
{
|
||||
type = eCompType_Float;
|
||||
width = 4;
|
||||
}
|
||||
else if(basetype == "double")
|
||||
{
|
||||
type = eCompType_Double;
|
||||
width = 8;
|
||||
}
|
||||
else if(basetype == "unormh")
|
||||
{
|
||||
type = eCompType_UNorm;
|
||||
width = 2;
|
||||
}
|
||||
else if(basetype == "unormb")
|
||||
{
|
||||
type = eCompType_UNorm;
|
||||
width = 1;
|
||||
}
|
||||
else if(basetype == "snormh")
|
||||
{
|
||||
type = eCompType_SNorm;
|
||||
width = 2;
|
||||
}
|
||||
else if(basetype == "snormb")
|
||||
{
|
||||
type = eCompType_SNorm;
|
||||
width = 1;
|
||||
}
|
||||
else if(basetype == "uintten")
|
||||
{
|
||||
fmt.compType = eCompType_UInt;
|
||||
fmt.compCount = 4 * count;
|
||||
fmt.compByteWidth = 1;
|
||||
fmt.special = true;
|
||||
fmt.specialFormat = eSpecial_R10G10B10A2;
|
||||
}
|
||||
else if(basetype == "unormten")
|
||||
{
|
||||
fmt.compType = eCompType_UInt;
|
||||
fmt.compCount = 4 * count;
|
||||
fmt.compByteWidth = 1;
|
||||
fmt.special = true;
|
||||
fmt.specialFormat = eSpecial_R10G10B10A2;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors = "Unrecognised basic type on line:\n" + line;
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(basetype == "xint" || basetype == "xshort" || basetype == "xbyte")
|
||||
hex = true;
|
||||
|
||||
if(fmt.compType == eCompType_None)
|
||||
{
|
||||
fmt.compType = type;
|
||||
fmt.compCount = count;
|
||||
fmt.compByteWidth = width;
|
||||
}
|
||||
|
||||
if(arrayCount == 1)
|
||||
{
|
||||
FormatElement elem(name, 0, offset, false, 1, row_major, matrixCount, fmt, hex);
|
||||
|
||||
uint32_t advance = elem.byteSize();
|
||||
|
||||
if(!tightPacking)
|
||||
{
|
||||
// cbuffer packing always works in floats
|
||||
advance = (advance + 3U) & (~3U);
|
||||
|
||||
// cbuffer packing doesn't allow elements to cross float4 boundaries, nudge up if this was
|
||||
// the case
|
||||
if(offset / 16 != (offset + elem.byteSize() - 1) / 16)
|
||||
{
|
||||
elem.offset = offset = (offset + 0xFU) & (~0xFU);
|
||||
}
|
||||
}
|
||||
|
||||
elems.push_back(elem);
|
||||
|
||||
offset += advance;
|
||||
}
|
||||
else
|
||||
{
|
||||
// when cbuffer packing, arrays are always aligned at float4 boundary
|
||||
if(!tightPacking)
|
||||
{
|
||||
if(offset % 16 != 0)
|
||||
{
|
||||
offset = (offset + 0xFU) & (~0xFU);
|
||||
}
|
||||
}
|
||||
|
||||
for(uint a = 0; a < arrayCount; a++)
|
||||
{
|
||||
FormatElement elem(QString("%1[%2]").arg(name).arg(a), 0, offset, false, 1, row_major,
|
||||
matrixCount, fmt, hex);
|
||||
|
||||
elems.push_back(elem);
|
||||
|
||||
uint32_t advance = elem.byteSize();
|
||||
|
||||
// cbuffer packing each array element is always float4 aligned
|
||||
if(!tightPacking)
|
||||
{
|
||||
advance = (advance + 0xFU) & (~0xFU);
|
||||
}
|
||||
|
||||
offset += advance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!success || elems.isEmpty())
|
||||
{
|
||||
elems.clear();
|
||||
|
||||
ResourceFormat fmt;
|
||||
fmt.compType = eCompType_UInt;
|
||||
fmt.compByteWidth = 4;
|
||||
fmt.compCount = 4;
|
||||
|
||||
if(maxLen > 0 && maxLen < 16)
|
||||
fmt.compCount = 1;
|
||||
if(maxLen > 0 && maxLen < 4)
|
||||
fmt.compByteWidth = 1;
|
||||
|
||||
elems.push_back(FormatElement("data", 0, 0, false, 1, false, 1, fmt, true));
|
||||
}
|
||||
|
||||
return elems;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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)
|
||||
{
|
||||
QVariantList ret;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
if(format.special && format.specialFormat == eSpecial_R5G5B5A1)
|
||||
{
|
||||
uint16_t packed = readObj<uint16_t>(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.special && format.specialFormat == eSpecial_R5G6B5)
|
||||
{
|
||||
uint16_t packed = readObj<uint16_t>(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.special && format.specialFormat == eSpecial_R4G4B4A4)
|
||||
{
|
||||
uint16_t packed = readObj<uint16_t>(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.special && format.specialFormat == eSpecial_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<uint32_t>(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 == eCompType_UInt)
|
||||
{
|
||||
ret.push_back(r);
|
||||
ret.push_back(g);
|
||||
ret.push_back(b);
|
||||
ret.push_back(a);
|
||||
}
|
||||
else if(format.compType == eCompType_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 == eCompType_SInt || format.compType == eCompType_SScaled)
|
||||
{
|
||||
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 == eCompType_SInt)
|
||||
{
|
||||
ret.push_back(ir);
|
||||
ret.push_back(ig);
|
||||
ret.push_back(ib);
|
||||
ret.push_back(ia);
|
||||
}
|
||||
else if(format.compType == eCompType_SScaled)
|
||||
{
|
||||
ret.push_back((float)ir);
|
||||
ret.push_back((float)ig);
|
||||
ret.push_back((float)ib);
|
||||
ret.push_back((float)ia);
|
||||
}
|
||||
}
|
||||
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.special && format.specialFormat == eSpecial_R11G11B10)
|
||||
{
|
||||
uint32_t packed = readObj<uint32_t>(data, end, ok);
|
||||
|
||||
uint32_t xMantissa = ((packed >> 0) & 0x3f);
|
||||
uint32_t xExponent = ((packed >> 6) & 0x1f);
|
||||
uint32_t yMantissa = ((packed >> 11) & 0x3f);
|
||||
uint32_t yExponent = ((packed >> 17) & 0x1f);
|
||||
uint32_t zMantissa = ((packed >> 22) & 0x1f);
|
||||
uint32_t zExponent = ((packed >> 27) & 0x1f);
|
||||
|
||||
ret.push_back(((float)(xMantissa) / 64.0f) * qPow(2.0f, (float)xExponent - 15.0f));
|
||||
ret.push_back(((float)(yMantissa) / 32.0f) * qPow(2.0f, (float)yExponent - 15.0f));
|
||||
ret.push_back(((float)(zMantissa) / 32.0f) * qPow(2.0f, (float)zExponent - 15.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
int dim = (int)(qMax(matrixdim, 1U) * format.compCount);
|
||||
|
||||
for(int i = 0; i < dim; i++)
|
||||
{
|
||||
if(format.compType == eCompType_Float)
|
||||
{
|
||||
if(format.compByteWidth == 8)
|
||||
ret.push_back(readObj<double>(data, end, ok));
|
||||
else if(format.compByteWidth == 4)
|
||||
ret.push_back(readObj<float>(data, end, ok));
|
||||
else if(format.compByteWidth == 2)
|
||||
ret.push_back(Maths_HalfToFloat(readObj<uint16_t>(data, end, ok)));
|
||||
}
|
||||
else if(format.compType == eCompType_SInt)
|
||||
{
|
||||
if(format.compByteWidth == 4)
|
||||
ret.push_back((int)readObj<int32_t>(data, end, ok));
|
||||
else if(format.compByteWidth == 2)
|
||||
ret.push_back((int)readObj<int16_t>(data, end, ok));
|
||||
else if(format.compByteWidth == 1)
|
||||
ret.push_back((int)readObj<int8_t>(data, end, ok));
|
||||
}
|
||||
else if(format.compType == eCompType_UInt)
|
||||
{
|
||||
if(format.compByteWidth == 4)
|
||||
ret.push_back((uint32_t)readObj<uint32_t>(data, end, ok));
|
||||
else if(format.compByteWidth == 2)
|
||||
ret.push_back((uint32_t)readObj<uint16_t>(data, end, ok));
|
||||
else if(format.compByteWidth == 1)
|
||||
ret.push_back((uint32_t)readObj<uint8_t>(data, end, ok));
|
||||
}
|
||||
else if(format.compType == eCompType_UScaled)
|
||||
{
|
||||
if(format.compByteWidth == 4)
|
||||
ret.push_back((float)readObj<uint32_t>(data, end, ok));
|
||||
else if(format.compByteWidth == 2)
|
||||
ret.push_back((float)readObj<uint16_t>(data, end, ok));
|
||||
else if(format.compByteWidth == 1)
|
||||
ret.push_back((float)readObj<uint8_t>(data, end, ok));
|
||||
}
|
||||
else if(format.compType == eCompType_SScaled)
|
||||
{
|
||||
if(format.compByteWidth == 4)
|
||||
ret.push_back((float)readObj<int32_t>(data, end, ok));
|
||||
else if(format.compByteWidth == 2)
|
||||
ret.push_back((float)readObj<int16_t>(data, end, ok));
|
||||
else if(format.compByteWidth == 1)
|
||||
ret.push_back((float)readObj<int8_t>(data, end, ok));
|
||||
}
|
||||
else if(format.compType == eCompType_Depth)
|
||||
{
|
||||
if(format.compByteWidth == 4)
|
||||
{
|
||||
// 32-bit depth is native floats
|
||||
ret.push_back(readObj<float>(data, end, ok));
|
||||
}
|
||||
else if(format.compByteWidth == 3)
|
||||
{
|
||||
// 32-bit depth is normalised, masked against non-stencil bits
|
||||
uint32_t f = readObj<uint32_t>(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<uint16_t>(data, end, ok);
|
||||
ret.push_back(f / (float)0x0000ffff);
|
||||
}
|
||||
}
|
||||
else if(format.compType == eCompType_Double)
|
||||
{
|
||||
ret.push_back(readObj<double>(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<uint32_t>(data, end, ok) / (float)0xffffffff);
|
||||
}
|
||||
else if(format.compByteWidth == 2)
|
||||
{
|
||||
ret.push_back(interpret(format, readObj<uint16_t>(data, end, ok)));
|
||||
}
|
||||
else if(format.compByteWidth == 1)
|
||||
{
|
||||
ret.push_back(interpret(format, readObj<uint8_t>(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)
|
||||
{
|
||||
QVariantList objs = GetVariants(data, end);
|
||||
|
||||
ShaderVariable ret;
|
||||
|
||||
ret.name = name.toUtf8().data();
|
||||
ret.type = eVar_Float;
|
||||
if(format.compType == eCompType_UInt)
|
||||
ret.type = eVar_UInt;
|
||||
if(format.compType == eCompType_SInt)
|
||||
ret.type = eVar_Int;
|
||||
if(format.compType == eCompType_Double)
|
||||
ret.type = eVar_Double;
|
||||
|
||||
ret.columns = qMin(format.compCount, 4U);
|
||||
ret.rows = qMin(matrixdim, 4U);
|
||||
|
||||
ret.displayAsHex = hex;
|
||||
|
||||
for(uint32_t row = 0; row < ret.rows; row++)
|
||||
{
|
||||
for(uint32_t col = 0; col < ret.columns; col++)
|
||||
{
|
||||
uint32_t dst = row * ret.columns + col;
|
||||
uint32_t src = row * format.compCount + col;
|
||||
|
||||
// if we partially read a failure, reset the variable and return
|
||||
if((int)src >= objs.size())
|
||||
{
|
||||
ret.name = "-";
|
||||
memset(ret.value.dv, 0, sizeof(ret.value.dv));
|
||||
return ret;
|
||||
}
|
||||
|
||||
const QVariant &o = objs[src];
|
||||
|
||||
if(ret.type == eVar_Double)
|
||||
ret.value.dv[dst] = o.toDouble();
|
||||
else if(ret.type == eVar_UInt)
|
||||
ret.value.uv[dst] = o.toUInt();
|
||||
else if(ret.type == eVar_Int)
|
||||
ret.value.iv[dst] = o.toInt();
|
||||
else
|
||||
ret.value.fv[dst] = o.toFloat();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t FormatElement::byteSize()
|
||||
{
|
||||
uint32_t vecSize = format.compByteWidth * format.compCount;
|
||||
|
||||
if(format.special)
|
||||
{
|
||||
if(format.specialFormat == eSpecial_R5G5B5A1 || format.specialFormat == eSpecial_R5G6B5 ||
|
||||
format.specialFormat == eSpecial_R4G4B4A4)
|
||||
vecSize = 2;
|
||||
|
||||
if(format.specialFormat == eSpecial_R10G10B10A2 || format.specialFormat == eSpecial_R11G11B10)
|
||||
vecSize = 4;
|
||||
}
|
||||
|
||||
return vecSize * matrixdim;
|
||||
}
|
||||
|
||||
QString TypeString(const ShaderVariable &v)
|
||||
{
|
||||
if(v.members.count > 0)
|
||||
{
|
||||
if(v.isStruct)
|
||||
return "struct";
|
||||
else
|
||||
return QString("%1[%2]").arg(TypeString(v.members[0]), v.members.count);
|
||||
}
|
||||
|
||||
QString typeStr = ToQStr(v.type);
|
||||
|
||||
if(v.displayAsHex && v.type == eVar_UInt)
|
||||
typeStr = "xint";
|
||||
|
||||
if(v.rows == 1 && v.columns == 1)
|
||||
return typeStr;
|
||||
if(v.rows == 1)
|
||||
return QString("%1%2").arg(typeStr).arg(v.columns);
|
||||
else
|
||||
return QString("%1%2x%3").arg(typeStr).arg(v.rows).arg(v.columns);
|
||||
}
|
||||
|
||||
template <typename el>
|
||||
static QString RowValuesToString(int cols, el x, el y, el z, el w)
|
||||
{
|
||||
if(cols == 1)
|
||||
return Formatter::Format(x);
|
||||
else if(cols == 2)
|
||||
return Formatter::Format(x) + ", " + Formatter::Format(y);
|
||||
else if(cols == 3)
|
||||
return Formatter::Format(x) + ", " + Formatter::Format(y) + ", " + Formatter::Format(z);
|
||||
else
|
||||
return Formatter::Format(x) + ", " + Formatter::Format(y) + ", " + Formatter::Format(z) + ", " +
|
||||
Formatter::Format(w);
|
||||
}
|
||||
|
||||
QString RowString(const ShaderVariable &v, uint32_t row)
|
||||
{
|
||||
if(v.type == eVar_Double)
|
||||
return RowValuesToString((int)v.columns, v.value.dv[row * v.columns + 0],
|
||||
v.value.dv[row * v.columns + 1], v.value.dv[row * v.columns + 2],
|
||||
v.value.dv[row * v.columns + 3]);
|
||||
else if(v.type == eVar_Int)
|
||||
return RowValuesToString((int)v.columns, v.value.iv[row * v.columns + 0],
|
||||
v.value.iv[row * v.columns + 1], v.value.iv[row * v.columns + 2],
|
||||
v.value.iv[row * v.columns + 3]);
|
||||
else if(v.type == eVar_UInt)
|
||||
return RowValuesToString((int)v.columns, v.value.uv[row * v.columns + 0],
|
||||
v.value.uv[row * v.columns + 1], v.value.uv[row * v.columns + 2],
|
||||
v.value.uv[row * v.columns + 3]);
|
||||
else
|
||||
return RowValuesToString((int)v.columns, v.value.fv[row * v.columns + 0],
|
||||
v.value.fv[row * v.columns + 1], v.value.fv[row * v.columns + 2],
|
||||
v.value.fv[row * v.columns + 3]);
|
||||
}
|
||||
|
||||
QString VarString(const ShaderVariable &v)
|
||||
{
|
||||
if(v.members.count > 0)
|
||||
return "";
|
||||
|
||||
if(v.rows == 1)
|
||||
return RowString(v, 0);
|
||||
|
||||
QString ret = "";
|
||||
for(int i = 0; i < (int)v.rows; i++)
|
||||
{
|
||||
if(i > 0)
|
||||
ret += ", ";
|
||||
ret += "{" + RowString(v, i) + "}";
|
||||
}
|
||||
|
||||
return "{ " + ret + " }";
|
||||
}
|
||||
|
||||
QString RowTypeString(const ShaderVariable &v)
|
||||
{
|
||||
if(v.members.count > 0)
|
||||
{
|
||||
if(v.isStruct)
|
||||
return "struct";
|
||||
else
|
||||
return "flibbertygibbet";
|
||||
}
|
||||
|
||||
if(v.rows == 0 && v.columns == 0)
|
||||
return "-";
|
||||
|
||||
QString typeStr = ToQStr(v.type);
|
||||
|
||||
if(v.displayAsHex && v.type == eVar_UInt)
|
||||
typeStr = "xint";
|
||||
|
||||
if(v.columns == 1)
|
||||
return typeStr;
|
||||
|
||||
return QString("%1%2").arg(typeStr).arg(v.columns);
|
||||
}
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <QJsonDocument>
|
||||
#include <QMenu>
|
||||
#include <QMetaMethod>
|
||||
#include <QTreeWidget>
|
||||
|
||||
QString ToQStr(const ResourceUsage usage, const GraphicsAPI apitype)
|
||||
{
|
||||
@@ -478,3 +479,25 @@ void addGridLines(QGridLayout *grid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QTreeWidgetItem *makeTreeNode(const std::initializer_list<QVariant> &values)
|
||||
{
|
||||
QTreeWidgetItem *ret = new QTreeWidgetItem();
|
||||
|
||||
int i = 0;
|
||||
for(const QVariant &v : values)
|
||||
ret->setData(i++, Qt::DisplayRole, v);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *makeTreeNode(const QVariantList &values)
|
||||
{
|
||||
QTreeWidgetItem *ret = new QTreeWidgetItem();
|
||||
|
||||
int i = 0;
|
||||
for(const QVariant &v : values)
|
||||
ret->setData(i++, Qt::DisplayRole, v);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -314,6 +314,48 @@ QString ToQStr(const ResourceUsage usage, const GraphicsAPI apitype);
|
||||
// overload for a couple of things that need to know the pipeline type when converting
|
||||
QString ToQStr(const ShaderStageType stage, const GraphicsAPI apitype);
|
||||
|
||||
struct FormatElement
|
||||
{
|
||||
FormatElement();
|
||||
FormatElement(const QString &Name, int buf, uint offs, bool pi, int ir, bool rowMat, uint matDim,
|
||||
ResourceFormat f, bool h);
|
||||
|
||||
static QList<FormatElement> ParseFormatString(const QString &formatString, uint64_t maxLen,
|
||||
bool tightPacking, QString &errors);
|
||||
|
||||
QVariantList GetVariants(const byte *&data, const byte *end);
|
||||
ShaderVariable GetShaderVar(const byte *&data, const byte *end);
|
||||
|
||||
QString ElementString(const QVariant &var);
|
||||
|
||||
uint32_t byteSize();
|
||||
|
||||
QString name;
|
||||
int buffer;
|
||||
uint32_t offset;
|
||||
bool perinstance;
|
||||
int instancerate;
|
||||
bool rowmajor;
|
||||
uint32_t matrixdim;
|
||||
ResourceFormat format;
|
||||
bool hex;
|
||||
SystemAttribute systemValue;
|
||||
};
|
||||
|
||||
QString TypeString(const ShaderVariable &v);
|
||||
QString RowString(const ShaderVariable &v, uint32_t row);
|
||||
QString VarString(const ShaderVariable &v);
|
||||
QString RowTypeString(const ShaderVariable &v);
|
||||
|
||||
struct Formatter
|
||||
{
|
||||
static QString Format(float f) { return QString::number(f); }
|
||||
static QString Format(double d) { return QString::number(d); }
|
||||
static QString Format(uint32_t u) { return QString::number(u); }
|
||||
static QString Format(uint16_t u) { return QString::number(u); }
|
||||
static QString Format(int32_t i) { return QString::number(i); }
|
||||
};
|
||||
|
||||
bool SaveToJSON(QVariantMap &data, QIODevice &f, const char *magicIdentifier, uint32_t magicVersion);
|
||||
bool LoadFromJSON(QVariantMap &data, QIODevice &f, const char *magicIdentifier,
|
||||
uint32_t magicVersion);
|
||||
@@ -506,3 +548,8 @@ public:
|
||||
class QGridLayout;
|
||||
|
||||
void addGridLines(QGridLayout *grid);
|
||||
|
||||
class QTreeWidgetItem;
|
||||
|
||||
QTreeWidgetItem *makeTreeNode(const std::initializer_list<QVariant> &values);
|
||||
QTreeWidgetItem *makeTreeNode(const QVariantList &values);
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "BufferFormatSpecifier.h"
|
||||
#include <QFontDatabase>
|
||||
#include "Code/QRDUtils.h"
|
||||
#include "ui_BufferFormatSpecifier.h"
|
||||
|
||||
BufferFormatSpecifier::BufferFormatSpecifier(QWidget *parent)
|
||||
: QWidget(parent), ui(new Ui::BufferFormatSpecifier)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
QObject::connect(ui->toggleHelp, &QPushButton::clicked, this, &BufferFormatSpecifier::toggleHelp);
|
||||
|
||||
setErrors("");
|
||||
|
||||
ui->formatText->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
|
||||
}
|
||||
|
||||
BufferFormatSpecifier::~BufferFormatSpecifier()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::toggleHelp()
|
||||
{
|
||||
ui->helpText->setVisible(!ui->helpText->isVisible());
|
||||
|
||||
if(ui->helpText->isVisible())
|
||||
showHelp(true);
|
||||
else
|
||||
showHelp(false);
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::setErrors(const QString &errors)
|
||||
{
|
||||
ui->errors->setText(errors);
|
||||
if(errors.isEmpty())
|
||||
ui->errors->setVisible(false);
|
||||
else
|
||||
ui->errors->setVisible(true);
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::showHelp(bool help)
|
||||
{
|
||||
ui->helpText->setVisible(help);
|
||||
|
||||
if(help)
|
||||
{
|
||||
ui->gridLayout->removeWidget(ui->formatGroup);
|
||||
ui->gridLayout->addWidget(ui->formatGroup, 1, 0, 1, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->gridLayout->removeWidget(ui->formatGroup);
|
||||
ui->gridLayout->addWidget(ui->formatGroup, 0, 0, 2, 3);
|
||||
}
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::on_apply_clicked()
|
||||
{
|
||||
setErrors("");
|
||||
emit processFormat(ui->formatText->toPlainText());
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class BufferFormatSpecifier;
|
||||
}
|
||||
|
||||
class BufferFormatSpecifier : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit BufferFormatSpecifier(QWidget *parent = 0);
|
||||
~BufferFormatSpecifier();
|
||||
|
||||
void setErrors(const QString &errors);
|
||||
void showHelp(bool help);
|
||||
|
||||
signals:
|
||||
void processFormat(const QString &format);
|
||||
|
||||
public slots:
|
||||
void toggleHelp();
|
||||
|
||||
private slots:
|
||||
void on_apply_clicked();
|
||||
|
||||
private:
|
||||
Ui::BufferFormatSpecifier *ui;
|
||||
};
|
||||
@@ -0,0 +1,146 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BufferFormatSpecifier</class>
|
||||
<widget class="QWidget" name="BufferFormatSpecifier">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>713</width>
|
||||
<height>633</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Buffer Format</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="horizontalSpacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="3" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="toggleHelp">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Toggle Help</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="apply">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Apply</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="helpText">
|
||||
<property name="text">
|
||||
<string>Type in a buffer format declaration. Comments and {} braces are skipped, : semantics are ignored.
|
||||
Declare each element as an hlsl/glsl variable, e.g: "float4 first; float2 second; uint2 third;" or vec4/vec2.
|
||||
|
||||
Basic types accepted: bool, byte, short, int, half, float, double.
|
||||
Unsigned integer types: ubyte, ushort, uint
|
||||
Hex-formatted integer types: xbyte, xshort, xint
|
||||
|
||||
Additionally special formats: unorm[hb] (half, byte) and snorm[hb], and uintten/unormten (10:10:10:2 packing)
|
||||
|
||||
Vectors (e.g. float4), matrices ([row_major] half3x4) and arrays (float[16]) are supported.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="formatGroup">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Format</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="formatText"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QLabel" name="errors">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(171, 32, 32);</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,263 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "ConstantBufferPreviewer.h"
|
||||
#include <QFontDatabase>
|
||||
#include "ui_ConstantBufferPreviewer.h"
|
||||
|
||||
QList<ConstantBufferPreviewer *> ConstantBufferPreviewer::m_Previews;
|
||||
|
||||
ConstantBufferPreviewer::ConstantBufferPreviewer(CaptureContext *ctx, const ShaderStageType stage,
|
||||
uint32_t slot, uint32_t idx, QWidget *parent)
|
||||
: QFrame(parent), ui(new Ui::ConstantBufferPreviewer), m_Ctx(ctx)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_stage = stage;
|
||||
m_slot = slot;
|
||||
m_arrayIdx = idx;
|
||||
|
||||
QObject::connect(ui->formatSpecifier, &BufferFormatSpecifier::processFormat, this,
|
||||
&ConstantBufferPreviewer::processFormat);
|
||||
|
||||
ui->formatSpecifier->showHelp(false);
|
||||
|
||||
ui->splitter->setCollapsible(1, true);
|
||||
ui->splitter->setSizes({1, 0});
|
||||
ui->splitter->handle(1)->setEnabled(false);
|
||||
|
||||
{
|
||||
// Name | Value | Type
|
||||
ui->variables->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||
ui->variables->header()->setSectionResizeMode(1, QHeaderView::Stretch);
|
||||
ui->variables->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
|
||||
}
|
||||
|
||||
ui->variables->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
|
||||
|
||||
m_Previews.push_back(this);
|
||||
m_Ctx->AddLogViewer(this);
|
||||
}
|
||||
|
||||
ConstantBufferPreviewer::~ConstantBufferPreviewer()
|
||||
{
|
||||
m_Ctx->RemoveLogViewer(this);
|
||||
m_Previews.removeOne(this);
|
||||
delete ui;
|
||||
}
|
||||
|
||||
ConstantBufferPreviewer *ConstantBufferPreviewer::has(ShaderStageType stage, uint32_t slot,
|
||||
uint32_t idx)
|
||||
{
|
||||
for(ConstantBufferPreviewer *c : m_Previews)
|
||||
{
|
||||
if(c->m_stage == stage && c->m_slot == slot && c->m_arrayIdx == idx)
|
||||
return c;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ConstantBufferPreviewer::OnLogfileLoaded()
|
||||
{
|
||||
OnLogfileClosed();
|
||||
}
|
||||
|
||||
void ConstantBufferPreviewer::OnLogfileClosed()
|
||||
{
|
||||
ui->variables->clear();
|
||||
|
||||
ui->saveCSV->setEnabled(false);
|
||||
}
|
||||
|
||||
void ConstantBufferPreviewer::OnEventSelected(uint32_t eventID)
|
||||
{
|
||||
uint64_t offs = 0;
|
||||
uint64_t size = 0;
|
||||
m_Ctx->CurPipelineState.GetConstantBuffer(m_stage, m_slot, m_arrayIdx, m_cbuffer, offs, size);
|
||||
|
||||
m_shader = m_Ctx->CurPipelineState.GetShader(m_stage);
|
||||
QString entryPoint = m_Ctx->CurPipelineState.GetShaderEntryPoint(m_stage);
|
||||
ShaderReflection *reflection = m_Ctx->CurPipelineState.GetShaderReflection(m_stage);
|
||||
|
||||
updateLabels();
|
||||
|
||||
if(reflection == NULL || reflection->ConstantBlocks.count <= (int)m_slot)
|
||||
{
|
||||
setVariables({});
|
||||
return;
|
||||
}
|
||||
|
||||
if(!m_formatOverride.empty())
|
||||
{
|
||||
m_Ctx->Renderer()->AsyncInvoke([this, offs, size](IReplayRenderer *r) {
|
||||
rdctype::array<byte> data;
|
||||
r->GetBufferData(m_cbuffer, offs, size, &data);
|
||||
rdctype::array<ShaderVariable> vars = applyFormatOverride(data);
|
||||
GUIInvoke::call([this, vars] { setVariables(vars); });
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Ctx->Renderer()->AsyncInvoke([this, entryPoint, offs](IReplayRenderer *r) {
|
||||
rdctype::array<ShaderVariable> vars;
|
||||
r->GetCBufferVariableContents(m_shader, entryPoint.toUtf8().data(), m_slot, m_cbuffer, offs,
|
||||
&vars);
|
||||
GUIInvoke::call([this, vars] { setVariables(vars); });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void ConstantBufferPreviewer::on_setFormat_toggled(bool checked)
|
||||
{
|
||||
if(!checked)
|
||||
{
|
||||
ui->splitter->setCollapsible(1, true);
|
||||
ui->splitter->setSizes({1, 0});
|
||||
ui->splitter->handle(1)->setEnabled(false);
|
||||
|
||||
processFormat("");
|
||||
return;
|
||||
}
|
||||
|
||||
ui->splitter->setCollapsible(1, false);
|
||||
ui->splitter->setSizes({1, 1});
|
||||
ui->splitter->handle(1)->setEnabled(true);
|
||||
}
|
||||
|
||||
void ConstantBufferPreviewer::on_saveCSV_clicked()
|
||||
{
|
||||
}
|
||||
|
||||
void ConstantBufferPreviewer::processFormat(const QString &format)
|
||||
{
|
||||
if(format.isEmpty())
|
||||
{
|
||||
m_formatOverride.clear();
|
||||
ui->formatSpecifier->setErrors("");
|
||||
}
|
||||
else
|
||||
{
|
||||
QString errors;
|
||||
|
||||
m_formatOverride = FormatElement::ParseFormatString(format, 0, false, errors);
|
||||
ui->formatSpecifier->setErrors(errors);
|
||||
}
|
||||
|
||||
OnEventSelected(m_Ctx->CurEvent());
|
||||
}
|
||||
|
||||
void ConstantBufferPreviewer::addVariables(QTreeWidgetItem *root,
|
||||
const rdctype::array<ShaderVariable> &vars)
|
||||
{
|
||||
for(const ShaderVariable &v : vars)
|
||||
{
|
||||
QTreeWidgetItem *n = makeTreeNode({ToQStr(v.name), VarString(v), TypeString(v)});
|
||||
|
||||
root->addChild(n);
|
||||
|
||||
if(v.rows > 1)
|
||||
{
|
||||
for(uint32_t i = 0; i < v.rows; i++)
|
||||
n->addChild(makeTreeNode(
|
||||
{QString("%1.row%2").arg(ToQStr(v.name)).arg(i), RowString(v, i), RowTypeString(v)}));
|
||||
}
|
||||
|
||||
if(v.members.count > 0)
|
||||
addVariables(n, v.members);
|
||||
}
|
||||
}
|
||||
|
||||
void ConstantBufferPreviewer::setVariables(const rdctype::array<ShaderVariable> &vars)
|
||||
{
|
||||
ui->variables->setUpdatesEnabled(false);
|
||||
ui->variables->clear();
|
||||
|
||||
ui->saveCSV->setEnabled(false);
|
||||
|
||||
if(vars.count > 0)
|
||||
{
|
||||
addVariables(ui->variables->invisibleRootItem(), vars);
|
||||
ui->saveCSV->setEnabled(true);
|
||||
}
|
||||
|
||||
ui->variables->setUpdatesEnabled(true);
|
||||
}
|
||||
|
||||
void ConstantBufferPreviewer::updateLabels()
|
||||
{
|
||||
QString bufName = "";
|
||||
|
||||
bool needName = true;
|
||||
|
||||
FetchBuffer *buf = m_Ctx ? m_Ctx->GetBuffer(m_cbuffer) : NULL;
|
||||
if(buf)
|
||||
{
|
||||
bufName = buf->name;
|
||||
if(buf->customName)
|
||||
needName = false;
|
||||
}
|
||||
|
||||
ShaderReflection *reflection = m_Ctx ? m_Ctx->CurPipelineState.GetShaderReflection(m_stage) : NULL;
|
||||
|
||||
if(reflection != NULL)
|
||||
{
|
||||
if(needName && (int)m_slot < reflection->ConstantBlocks.count &&
|
||||
reflection->ConstantBlocks[m_slot].name.count > 0)
|
||||
bufName = "<" + ToQStr(reflection->ConstantBlocks[m_slot].name) + ">";
|
||||
}
|
||||
|
||||
ui->nameLabel->setText(bufName);
|
||||
|
||||
GraphicsAPI pipeType = eGraphicsAPI_D3D11;
|
||||
if(m_Ctx != NULL)
|
||||
pipeType = m_Ctx->APIProps().pipelineType;
|
||||
|
||||
QString title =
|
||||
QString("%1 %2 %3").arg(ToQStr(m_stage, pipeType)).arg(IsD3D(pipeType) ? "CB" : "UBO").arg(m_slot);
|
||||
|
||||
if(m_Ctx != NULL && m_Ctx->CurPipelineState.SupportsResourceArrays())
|
||||
title += QString(" [%1]").arg(m_arrayIdx);
|
||||
|
||||
ui->slotLabel->setText(title);
|
||||
setWindowTitle(title);
|
||||
}
|
||||
|
||||
rdctype::array<ShaderVariable> ConstantBufferPreviewer::applyFormatOverride(
|
||||
const rdctype::array<byte> &bytes)
|
||||
{
|
||||
QVector<ShaderVariable> variables;
|
||||
|
||||
variables.resize(m_formatOverride.length());
|
||||
|
||||
for(int i = 0; i < m_formatOverride.length(); i++)
|
||||
{
|
||||
const byte *b = bytes.begin() + m_formatOverride[i].offset;
|
||||
variables[i] = m_formatOverride[i].GetShaderVar(b, bytes.end());
|
||||
}
|
||||
|
||||
rdctype::array<ShaderVariable> ret;
|
||||
ret = variables.toStdVector();
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QFrame>
|
||||
#include "Code/CaptureContext.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ConstantBufferPreviewer;
|
||||
}
|
||||
|
||||
struct FormatElement;
|
||||
|
||||
class ConstantBufferPreviewer : public QFrame, public ILogViewerForm
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ConstantBufferPreviewer(CaptureContext *ctx, const ShaderStageType stage, uint32_t slot,
|
||||
uint32_t idx, QWidget *parent = 0);
|
||||
~ConstantBufferPreviewer();
|
||||
|
||||
static ConstantBufferPreviewer *has(ShaderStageType stage, uint32_t slot, uint32_t idx);
|
||||
|
||||
void OnLogfileLoaded();
|
||||
void OnLogfileClosed();
|
||||
void OnEventSelected(uint32_t eventID);
|
||||
|
||||
private slots:
|
||||
// automatic slots
|
||||
void on_setFormat_toggled(bool checked);
|
||||
void on_saveCSV_clicked();
|
||||
|
||||
// manual slots
|
||||
void processFormat(const QString &format);
|
||||
|
||||
private:
|
||||
Ui::ConstantBufferPreviewer *ui;
|
||||
CaptureContext *m_Ctx = NULL;
|
||||
|
||||
ResourceId m_cbuffer;
|
||||
ResourceId m_shader;
|
||||
ShaderStageType m_stage = eShaderStage_Vertex;
|
||||
uint32_t m_slot = 0;
|
||||
uint32_t m_arrayIdx = 0;
|
||||
|
||||
rdctype::array<ShaderVariable> applyFormatOverride(const rdctype::array<byte> &data);
|
||||
|
||||
void addVariables(QTreeWidgetItem *root, const rdctype::array<ShaderVariable> &vars);
|
||||
void setVariables(const rdctype::array<ShaderVariable> &vars);
|
||||
|
||||
void updateLabels();
|
||||
|
||||
static QList<ConstantBufferPreviewer *> m_Previews;
|
||||
|
||||
QList<FormatElement> m_formatOverride;
|
||||
};
|
||||
@@ -0,0 +1,242 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ConstantBufferPreviewer</class>
|
||||
<widget class="QFrame" name="ConstantBufferPreviewer">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Constant Buffer</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="childrenCollapsible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="toolbar">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>28</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Panel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="slotLabel">
|
||||
<property name="text">
|
||||
<string>Subresource</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="nameLabel">
|
||||
<property name="text">
|
||||
<string>Mip</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="setFormat">
|
||||
<property name="text">
|
||||
<string>{}</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextOnly</enum>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="saveCSV">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/Resources/save.png</normaloff>:/Resources/save.png</iconset>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="variables">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Panel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ContiguousSelection</enum>
|
||||
</property>
|
||||
<property name="allColumnsShowFocus">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="headerStretchLastSection">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Value</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Type</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="BufferFormatSpecifier" name="formatSpecifier" native="true"/>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>BufferFormatSpecifier</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>Widgets/BufferFormatSpecifier.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "Windows/Dialogs/CaptureDialog.h"
|
||||
#include "Windows/Dialogs/LiveCapture.h"
|
||||
#include "APIInspector.h"
|
||||
#include "ConstantBufferPreviewer.h"
|
||||
#include "EventBrowser.h"
|
||||
#include "TextureViewer.h"
|
||||
#include "ui_MainWindow.h"
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
#include "VulkanPipelineStateViewer.h"
|
||||
#include <float.h>
|
||||
#include <QScrollBar>
|
||||
#include "3rdparty/toolwindowmanager/ToolWindowManager.h"
|
||||
#include "Windows/ConstantBufferPreviewer.h"
|
||||
#include "Windows/MainWindow.h"
|
||||
#include "Windows/TextureViewer.h"
|
||||
#include "ui_VulkanPipelineStateViewer.h"
|
||||
|
||||
@@ -134,6 +137,10 @@ VulkanPipelineStateViewer::VulkanPipelineStateViewer(CaptureContext *ctx, QWidge
|
||||
QObject::connect(res, &RDTreeWidget::itemActivated, this,
|
||||
&VulkanPipelineStateViewer::resource_itemActivated);
|
||||
|
||||
for(RDTreeWidget *ubo : ubos)
|
||||
QObject::connect(ubo, &RDTreeWidget::itemActivated, this,
|
||||
&VulkanPipelineStateViewer::ubo_itemActivated);
|
||||
|
||||
addGridLines(ui->rasterizerGridLayout);
|
||||
addGridLines(ui->MSAAGridLayout);
|
||||
addGridLines(ui->blendStateGridLayout);
|
||||
@@ -422,28 +429,6 @@ void VulkanPipelineStateViewer::setViewDetails(QTreeWidgetItem *node, const bind
|
||||
}
|
||||
}
|
||||
|
||||
QTreeWidgetItem *VulkanPipelineStateViewer::makeNode(const std::initializer_list<QVariant> &values)
|
||||
{
|
||||
QTreeWidgetItem *ret = new QTreeWidgetItem();
|
||||
|
||||
int i = 0;
|
||||
for(const QVariant &v : values)
|
||||
ret->setData(i++, Qt::DisplayRole, v);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *VulkanPipelineStateViewer::makeNode(const QVariantList &values)
|
||||
{
|
||||
QTreeWidgetItem *ret = new QTreeWidgetItem();
|
||||
|
||||
int i = 0;
|
||||
for(const QVariant &v : values)
|
||||
ret->setData(i++, Qt::DisplayRole, v);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool VulkanPipelineStateViewer::showNode(bool usedSlot, bool filledSlot)
|
||||
{
|
||||
const bool showDisabled = ui->showDisabled->isChecked();
|
||||
@@ -762,7 +747,7 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
|
||||
if(arrayLength > 1)
|
||||
{
|
||||
QTreeWidgetItem *node =
|
||||
makeNode({"", setname, slotname, tr("Array[%1]").arg(arrayLength), "", "", "", ""});
|
||||
makeTreeNode({"", setname, slotname, tr("Array[%1]").arg(arrayLength), "", "", "", ""});
|
||||
|
||||
if(!filledSlot)
|
||||
setEmptyRow(node);
|
||||
@@ -864,7 +849,7 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
|
||||
{
|
||||
if(!isbuf)
|
||||
{
|
||||
node = makeNode({
|
||||
node = makeTreeNode({
|
||||
"", bindset, slotname, ToQStr(bindType), "-", "-", "",
|
||||
});
|
||||
|
||||
@@ -876,7 +861,7 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
|
||||
if(descriptorBind != NULL)
|
||||
range = QString("%1 - %2").arg(descriptorBind->offset).arg(descriptorBind->size);
|
||||
|
||||
node = makeNode({
|
||||
node = makeTreeNode({
|
||||
"", bindset, slotname, ToQStr(bindType), name, QString("%1 bytes").arg(len), range,
|
||||
});
|
||||
|
||||
@@ -895,7 +880,7 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
|
||||
{
|
||||
if(descriptorBind == NULL || descriptorBind->sampler == ResourceId())
|
||||
{
|
||||
node = makeNode({
|
||||
node = makeTreeNode({
|
||||
"", bindset, slotname, ToQStr(bindType), "-", "-", "",
|
||||
});
|
||||
|
||||
@@ -903,7 +888,7 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
|
||||
}
|
||||
else
|
||||
{
|
||||
node = makeNode(makeSampler(QString::number(bindset), slotname, *descriptorBind));
|
||||
node = makeTreeNode(makeSampler(QString::number(bindset), slotname, *descriptorBind));
|
||||
|
||||
if(!filledSlot)
|
||||
setEmptyRow(node);
|
||||
@@ -923,7 +908,7 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
|
||||
{
|
||||
if(descriptorBind == NULL || descriptorBind->res == ResourceId())
|
||||
{
|
||||
node = makeNode({
|
||||
node = makeTreeNode({
|
||||
"", bindset, slotname, ToQStr(bindType), "-", "-", "",
|
||||
});
|
||||
|
||||
@@ -963,7 +948,7 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
|
||||
if(restype == eResType_Texture2DMS || restype == eResType_Texture2DMSArray)
|
||||
dim += QString(", %1x MSAA").arg(samples);
|
||||
|
||||
node = makeNode({
|
||||
node = makeTreeNode({
|
||||
"", bindset, slotname, typeName, name, dim, format,
|
||||
});
|
||||
|
||||
@@ -982,7 +967,7 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
|
||||
{
|
||||
if(descriptorBind == NULL || descriptorBind->sampler == ResourceId())
|
||||
{
|
||||
samplerNode = makeNode({
|
||||
samplerNode = makeTreeNode({
|
||||
"", bindset, slotname, bindType, "-", "-", "",
|
||||
});
|
||||
|
||||
@@ -992,7 +977,7 @@ void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails,
|
||||
{
|
||||
if(!samplers.contains(descriptorBind->sampler))
|
||||
{
|
||||
samplerNode = makeNode(makeSampler("", "", *descriptorBind));
|
||||
samplerNode = makeTreeNode(makeSampler("", "", *descriptorBind));
|
||||
|
||||
if(!filledSlot)
|
||||
setEmptyRow(samplerNode);
|
||||
@@ -1111,7 +1096,7 @@ void VulkanPipelineStateViewer::addConstantBlockRow(ShaderReflection *shaderDeta
|
||||
if(arrayLength > 1)
|
||||
{
|
||||
QTreeWidgetItem *node =
|
||||
makeNode({"", setname, slotname, tr("Array[%1]").arg(arrayLength), "", ""});
|
||||
makeTreeNode({"", setname, slotname, tr("Array[%1]").arg(arrayLength), "", ""});
|
||||
|
||||
if(!filledSlot)
|
||||
setEmptyRow(node);
|
||||
@@ -1192,7 +1177,7 @@ void VulkanPipelineStateViewer::addConstantBlockRow(ShaderReflection *shaderDeta
|
||||
filledSlot = false;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *node = makeNode({"", setname, slotname, name, vecrange, sizestr});
|
||||
QTreeWidgetItem *node = makeTreeNode({"", setname, slotname, name, vecrange, sizestr});
|
||||
|
||||
ubos->setHoverIcons(node, action, action_hover);
|
||||
|
||||
@@ -1393,8 +1378,8 @@ void VulkanPipelineStateViewer::setShaderState(const VulkanPipelineState::Shader
|
||||
// could maybe get range from ShaderVariable.reg if it's filled out
|
||||
// from SPIR-V side.
|
||||
|
||||
QTreeWidgetItem *node = makeNode({"", "", ToQStr(cblock.name), "Push constants", "",
|
||||
tr("%1 Variable(s)", "", cblock.variables.count)});
|
||||
QTreeWidgetItem *node = makeTreeNode({"", "", ToQStr(cblock.name), "Push constants", "",
|
||||
tr("%1 Variable(s)", "", cblock.variables.count)});
|
||||
|
||||
ubos->setHoverIcons(node, action, action_hover);
|
||||
node->setData(0, Qt::UserRole, QVariant::fromValue(CBufferTag(cb, 0)));
|
||||
@@ -1465,7 +1450,7 @@ void VulkanPipelineStateViewer::setState()
|
||||
if(showNode(usedSlot, filledSlot))
|
||||
{
|
||||
QTreeWidgetItem *node =
|
||||
makeNode({i, name, a.location, a.binding, ToQStr(a.format.strname), a.byteoffset});
|
||||
makeTreeNode({i, name, a.location, a.binding, ToQStr(a.format.strname), a.byteoffset});
|
||||
|
||||
usedBindings[a.binding] = true;
|
||||
|
||||
@@ -1569,8 +1554,8 @@ void VulkanPipelineStateViewer::setState()
|
||||
length = buf->length;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *node = makeNode({"Index", name, "Index", (qulonglong)state.IA.ibuffer.offs,
|
||||
draw->indexByteWidth, (qulonglong)length, ""});
|
||||
QTreeWidgetItem *node = makeTreeNode({"Index", name, "Index", (qulonglong)state.IA.ibuffer.offs,
|
||||
draw->indexByteWidth, (qulonglong)length, ""});
|
||||
|
||||
ui->viBuffers->setHoverIcons(node, action, action_hover);
|
||||
|
||||
@@ -1591,7 +1576,8 @@ void VulkanPipelineStateViewer::setState()
|
||||
{
|
||||
if(ibufferUsed || showEmpty)
|
||||
{
|
||||
QTreeWidgetItem *node = makeNode({"Index", tr("No Buffer Set"), "Index", "-", "-", "-", ""});
|
||||
QTreeWidgetItem *node =
|
||||
makeTreeNode({"Index", tr("No Buffer Set"), "Index", "-", "-", "-", ""});
|
||||
|
||||
ui->viBuffers->setHoverIcons(node, action, action_hover);
|
||||
|
||||
@@ -1661,9 +1647,9 @@ void VulkanPipelineStateViewer::setState()
|
||||
QTreeWidgetItem *node = NULL;
|
||||
|
||||
if(filledSlot)
|
||||
node = makeNode({i, name, rate, (qulonglong)offset, stride, (qulonglong)length, ""});
|
||||
node = makeTreeNode({i, name, rate, (qulonglong)offset, stride, (qulonglong)length, ""});
|
||||
else
|
||||
node = makeNode({i, tr("No Binding"), "-", "-", "-", "-", ""});
|
||||
node = makeTreeNode({i, tr("No Binding"), "-", "-", "-", "-", ""});
|
||||
|
||||
ui->viBuffers->setHoverIcons(node, action, action_hover);
|
||||
|
||||
@@ -1687,7 +1673,7 @@ void VulkanPipelineStateViewer::setState()
|
||||
{
|
||||
if(usedBindings[i])
|
||||
{
|
||||
QTreeWidgetItem *node = makeNode({i, tr("No Binding"), "-", "-", "-", "-", ""});
|
||||
QTreeWidgetItem *node = makeTreeNode({i, tr("No Binding"), "-", "-", "-", "-", ""});
|
||||
|
||||
ui->viBuffers->setHoverIcons(node, action, action_hover);
|
||||
|
||||
@@ -1728,8 +1714,8 @@ void VulkanPipelineStateViewer::setState()
|
||||
if(state.Pass.renderpass.obj != ResourceId())
|
||||
{
|
||||
ui->scissors->addTopLevelItem(
|
||||
makeNode({"Render Area", state.Pass.renderArea.x, state.Pass.renderArea.y,
|
||||
state.Pass.renderArea.width, state.Pass.renderArea.height}));
|
||||
makeTreeNode({"Render Area", state.Pass.renderArea.x, state.Pass.renderArea.y,
|
||||
state.Pass.renderArea.width, state.Pass.renderArea.height}));
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1737,13 +1723,13 @@ void VulkanPipelineStateViewer::setState()
|
||||
for(const VulkanPipelineState::ViewState::ViewportScissor &v : state.VP.viewportScissors)
|
||||
{
|
||||
QTreeWidgetItem *node =
|
||||
makeNode({i, v.vp.x, v.vp.y, v.vp.width, v.vp.height, v.vp.minDepth, v.vp.maxDepth});
|
||||
makeTreeNode({i, v.vp.x, v.vp.y, v.vp.width, v.vp.height, v.vp.minDepth, v.vp.maxDepth});
|
||||
ui->viewports->addTopLevelItem(node);
|
||||
|
||||
if(v.vp.width == 0 || v.vp.height == 0)
|
||||
setEmptyRow(node);
|
||||
|
||||
node = makeNode({i, v.scissor.x, v.scissor.y, v.scissor.width, v.scissor.height});
|
||||
node = makeTreeNode({i, v.scissor.x, v.scissor.y, v.scissor.width, v.scissor.height});
|
||||
ui->scissors->addTopLevelItem(node);
|
||||
|
||||
if(v.scissor.width == 0 || v.scissor.height == 0)
|
||||
@@ -1854,7 +1840,7 @@ void VulkanPipelineStateViewer::setState()
|
||||
.arg(ToQStr(p.swizzle[3]));
|
||||
}
|
||||
|
||||
QTreeWidgetItem *node = makeNode({i, name, typeName, w, h, d, a, format, ""});
|
||||
QTreeWidgetItem *node = makeTreeNode({i, name, typeName, w, h, d, a, format, ""});
|
||||
|
||||
ui->framebuffer->setHoverIcons(node, action, action_hover);
|
||||
|
||||
@@ -1900,19 +1886,19 @@ void VulkanPipelineStateViewer::setState()
|
||||
if(showNode(usedSlot, filledSlot))
|
||||
{
|
||||
QTreeWidgetItem *node =
|
||||
makeNode({i, blend.blendEnable,
|
||||
makeTreeNode({i, blend.blendEnable,
|
||||
|
||||
ToQStr(blend.blend.Source), ToQStr(blend.blend.Destination),
|
||||
ToQStr(blend.blend.Operation),
|
||||
ToQStr(blend.blend.Source), ToQStr(blend.blend.Destination),
|
||||
ToQStr(blend.blend.Operation),
|
||||
|
||||
ToQStr(blend.alphaBlend.Source), ToQStr(blend.alphaBlend.Destination),
|
||||
ToQStr(blend.alphaBlend.Operation),
|
||||
ToQStr(blend.alphaBlend.Source), ToQStr(blend.alphaBlend.Destination),
|
||||
ToQStr(blend.alphaBlend.Operation),
|
||||
|
||||
QString("%1%2%3%4")
|
||||
.arg((blend.writeMask & 0x1) == 0 ? "_" : "R")
|
||||
.arg((blend.writeMask & 0x2) == 0 ? "_" : "G")
|
||||
.arg((blend.writeMask & 0x4) == 0 ? "_" : "B")
|
||||
.arg((blend.writeMask & 0x8) == 0 ? "_" : "A")});
|
||||
QString("%1%2%3%4")
|
||||
.arg((blend.writeMask & 0x1) == 0 ? "_" : "R")
|
||||
.arg((blend.writeMask & 0x2) == 0 ? "_" : "G")
|
||||
.arg((blend.writeMask & 0x4) == 0 ? "_" : "B")
|
||||
.arg((blend.writeMask & 0x8) == 0 ? "_" : "A")});
|
||||
|
||||
if(!filledSlot)
|
||||
setEmptyRow(node);
|
||||
@@ -1959,21 +1945,21 @@ void VulkanPipelineStateViewer::setState()
|
||||
if(state.DS.stencilTestEnable)
|
||||
{
|
||||
ui->stencils->addTopLevelItems(
|
||||
{makeNode({"Front", ToQStr(state.DS.front.func), ToQStr(state.DS.front.failOp),
|
||||
ToQStr(state.DS.front.depthFailOp), ToQStr(state.DS.front.passOp),
|
||||
QString("%1").arg(state.DS.front.writeMask, 2, 16, QChar('0')),
|
||||
QString("%1").arg(state.DS.front.compareMask, 2, 16, QChar('0')),
|
||||
QString("%1").arg(state.DS.front.ref, 2, 16, QChar('0'))}),
|
||||
makeNode({"Back", ToQStr(state.DS.back.func), ToQStr(state.DS.back.failOp),
|
||||
ToQStr(state.DS.back.depthFailOp), ToQStr(state.DS.back.passOp),
|
||||
QString("%1").arg(state.DS.back.writeMask, 2, 16, QChar('0')),
|
||||
QString("%1").arg(state.DS.back.compareMask, 2, 16, QChar('0')),
|
||||
QString("%1").arg(state.DS.back.ref, 2, 16, QChar('0'))})});
|
||||
{makeTreeNode({"Front", ToQStr(state.DS.front.func), ToQStr(state.DS.front.failOp),
|
||||
ToQStr(state.DS.front.depthFailOp), ToQStr(state.DS.front.passOp),
|
||||
QString("%1").arg(state.DS.front.writeMask, 2, 16, QChar('0')),
|
||||
QString("%1").arg(state.DS.front.compareMask, 2, 16, QChar('0')),
|
||||
QString("%1").arg(state.DS.front.ref, 2, 16, QChar('0'))}),
|
||||
makeTreeNode({"Back", ToQStr(state.DS.back.func), ToQStr(state.DS.back.failOp),
|
||||
ToQStr(state.DS.back.depthFailOp), ToQStr(state.DS.back.passOp),
|
||||
QString("%1").arg(state.DS.back.writeMask, 2, 16, QChar('0')),
|
||||
QString("%1").arg(state.DS.back.compareMask, 2, 16, QChar('0')),
|
||||
QString("%1").arg(state.DS.back.ref, 2, 16, QChar('0'))})});
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->stencils->addTopLevelItems({makeNode({"Front", "-", "-", "-", "-", "-", "-", "-"}),
|
||||
makeNode({"Back", "-", "-", "-", "-", "-", "-", "-"})});
|
||||
ui->stencils->addTopLevelItems({makeTreeNode({"Front", "-", "-", "-", "-", "-", "-", "-"}),
|
||||
makeTreeNode({"Back", "-", "-", "-", "-", "-", "-", "-"})});
|
||||
}
|
||||
ui->stencils->clearSelection();
|
||||
ui->stencils->setUpdatesEnabled(true);
|
||||
@@ -2134,6 +2120,37 @@ void VulkanPipelineStateViewer::resource_itemActivated(QTreeWidgetItem *item, in
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanPipelineStateViewer::ubo_itemActivated(QTreeWidgetItem *item, int column)
|
||||
{
|
||||
const VulkanPipelineState::ShaderStage *stage = stageForSender(item->treeWidget());
|
||||
|
||||
if(stage == NULL)
|
||||
return;
|
||||
|
||||
QVariant tag = item->data(0, Qt::UserRole);
|
||||
|
||||
if(!tag.canConvert<CBufferTag>())
|
||||
return;
|
||||
|
||||
CBufferTag cb = tag.value<CBufferTag>();
|
||||
|
||||
ConstantBufferPreviewer *existing =
|
||||
ConstantBufferPreviewer::has(stage->stage, cb.slotIdx, cb.arrayIdx);
|
||||
if(existing != NULL)
|
||||
{
|
||||
ToolWindowManager::raiseToolWindow(existing);
|
||||
return;
|
||||
}
|
||||
|
||||
ConstantBufferPreviewer *prev =
|
||||
new ConstantBufferPreviewer(m_Ctx, stage->stage, cb.slotIdx, cb.arrayIdx, m_Ctx->mainWindow());
|
||||
|
||||
ToolWindowManager *manager = ToolWindowManager::managerOf(this);
|
||||
|
||||
ToolWindowManager::AreaReference ref(ToolWindowManager::RightOf, manager->areaOf(this), 0.3f);
|
||||
manager->addToolWindow(prev, ref);
|
||||
}
|
||||
|
||||
void VulkanPipelineStateViewer::on_viAttrs_itemActivated(QTreeWidgetItem *item, int column)
|
||||
{
|
||||
// TODO Buffer Viewer
|
||||
|
||||
@@ -70,6 +70,7 @@ private slots:
|
||||
void shaderEdit_clicked();
|
||||
void shaderSave_clicked();
|
||||
void resource_itemActivated(QTreeWidgetItem *item, int column);
|
||||
void ubo_itemActivated(QTreeWidgetItem *item, int column);
|
||||
void vertex_leave(QEvent *e);
|
||||
|
||||
private:
|
||||
@@ -107,8 +108,6 @@ private:
|
||||
template <typename viewType>
|
||||
void setViewDetails(QTreeWidgetItem *node, const viewType &view, FetchBuffer *buf);
|
||||
|
||||
QTreeWidgetItem *makeNode(const std::initializer_list<QVariant> &values);
|
||||
QTreeWidgetItem *makeNode(const QVariantList &values);
|
||||
bool showNode(bool usedSlot, bool filledSlot);
|
||||
|
||||
// keep track of the VB nodes (we want to be able to highlight them easily on hover)
|
||||
|
||||
@@ -117,7 +117,10 @@ SOURCES += 3rdparty/toolwindowmanager/ToolWindowManager.cpp \
|
||||
Windows/PipelineState/D3D11PipelineStateViewer.cpp \
|
||||
Windows/PipelineState/D3D12PipelineStateViewer.cpp \
|
||||
Windows/PipelineState/GLPipelineStateViewer.cpp \
|
||||
Widgets/Extended/RDTreeWidget.cpp
|
||||
Widgets/Extended/RDTreeWidget.cpp \
|
||||
Windows/ConstantBufferPreviewer.cpp \
|
||||
Widgets/BufferFormatSpecifier.cpp \
|
||||
Code/FormatElement.cpp
|
||||
|
||||
HEADERS += 3rdparty/toolwindowmanager/ToolWindowManager.h \
|
||||
3rdparty/toolwindowmanager/ToolWindowManagerArea.h \
|
||||
@@ -152,7 +155,9 @@ HEADERS += 3rdparty/toolwindowmanager/ToolWindowManager.h \
|
||||
Windows/PipelineState/D3D11PipelineStateViewer.h \
|
||||
Windows/PipelineState/D3D12PipelineStateViewer.h \
|
||||
Windows/PipelineState/GLPipelineStateViewer.h \
|
||||
Widgets/Extended/RDTreeWidget.h
|
||||
Widgets/Extended/RDTreeWidget.h \
|
||||
Windows/ConstantBufferPreviewer.h \
|
||||
Widgets/BufferFormatSpecifier.h
|
||||
|
||||
FORMS += Windows/Dialogs/AboutDialog.ui \
|
||||
Windows/MainWindow.ui \
|
||||
@@ -168,7 +173,9 @@ FORMS += Windows/Dialogs/AboutDialog.ui \
|
||||
Windows/PipelineState/VulkanPipelineStateViewer.ui \
|
||||
Windows/PipelineState/D3D11PipelineStateViewer.ui \
|
||||
Windows/PipelineState/D3D12PipelineStateViewer.ui \
|
||||
Windows/PipelineState/GLPipelineStateViewer.ui
|
||||
Windows/PipelineState/GLPipelineStateViewer.ui \
|
||||
Windows/ConstantBufferPreviewer.ui \
|
||||
Widgets/BufferFormatSpecifier.ui
|
||||
|
||||
RESOURCES += \
|
||||
resources.qrc
|
||||
|
||||
@@ -281,12 +281,15 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Code\CommonPipelineState.cpp" />
|
||||
<ClCompile Include="Code\FormatElement.cpp" />
|
||||
<ClCompile Include="Code\PersistantConfig.cpp" />
|
||||
<ClCompile Include="Code\qprocessinfo.cpp" />
|
||||
<ClCompile Include="Code\QRDUtils.cpp" />
|
||||
<ClCompile Include="generated\moc_AboutDialog.cpp" />
|
||||
<ClCompile Include="generated\moc_APIInspector.cpp" />
|
||||
<ClCompile Include="generated\moc_BufferFormatSpecifier.cpp" />
|
||||
<ClCompile Include="generated\moc_CaptureDialog.cpp" />
|
||||
<ClCompile Include="generated\moc_ConstantBufferPreviewer.cpp" />
|
||||
<ClCompile Include="generated\moc_CustomPaintWidget.cpp" />
|
||||
<ClCompile Include="generated\moc_D3D11PipelineStateViewer.cpp" />
|
||||
<ClCompile Include="generated\moc_D3D12PipelineStateViewer.cpp" />
|
||||
@@ -313,6 +316,7 @@
|
||||
<ClCompile Include="generated\moc_ToolWindowManagerWrapper.cpp" />
|
||||
<ClCompile Include="generated\moc_VulkanPipelineStateViewer.cpp" />
|
||||
<ClCompile Include="generated\qrc_resources.cpp" />
|
||||
<ClCompile Include="Widgets\BufferFormatSpecifier.cpp" />
|
||||
<ClCompile Include="Widgets\Extended\RDListWidget.cpp" />
|
||||
<ClCompile Include="Widgets\Extended\RDTreeWidget.cpp" />
|
||||
<ClCompile Include="Widgets\RangeHistogram.cpp" />
|
||||
@@ -325,6 +329,7 @@
|
||||
<ClCompile Include="Code\CaptureContext.cpp" />
|
||||
<ClCompile Include="Widgets\CustomPaintWidget.cpp" />
|
||||
<ClCompile Include="Windows\APIInspector.cpp" />
|
||||
<ClCompile Include="Windows\ConstantBufferPreviewer.cpp" />
|
||||
<ClCompile Include="Windows\Dialogs\AboutDialog.cpp" />
|
||||
<ClCompile Include="Windows\Dialogs\CaptureDialog.cpp" />
|
||||
<ClCompile Include="Windows\Dialogs\LiveCapture.cpp" />
|
||||
@@ -360,7 +365,9 @@
|
||||
<ClInclude Include="Code\QRDUtils.h" />
|
||||
<ClInclude Include="generated\ui_AboutDialog.h" />
|
||||
<ClInclude Include="generated\ui_APIInspector.h" />
|
||||
<ClInclude Include="generated\ui_BufferFormatSpecifier.h" />
|
||||
<ClInclude Include="generated\ui_CaptureDialog.h" />
|
||||
<ClInclude Include="generated\ui_ConstantBufferPreviewer.h" />
|
||||
<ClInclude Include="generated\ui_D3D11PipelineStateViewer.h" />
|
||||
<ClInclude Include="generated\ui_D3D12PipelineStateViewer.h" />
|
||||
<ClInclude Include="generated\ui_EventBrowser.h" />
|
||||
@@ -374,6 +381,7 @@
|
||||
<ClInclude Include="generated\ui_ThumbnailStrip.h" />
|
||||
<ClInclude Include="generated\ui_VulkanPipelineStateViewer.h" />
|
||||
<ClInclude Include="Resources\resource.h" />
|
||||
<ClInclude Include="Widgets\BufferFormatSpecifier.h" />
|
||||
<ClInclude Include="Widgets\Extended\RDListWidget.h" />
|
||||
<ClInclude Include="Widgets\Extended\RDTreeWidget.h" />
|
||||
<ClInclude Include="Widgets\RangeHistogram.h" />
|
||||
@@ -386,6 +394,7 @@
|
||||
<ClInclude Include="Code\CaptureContext.h" />
|
||||
<ClInclude Include="Widgets\CustomPaintWidget.h" />
|
||||
<ClInclude Include="Windows\APIInspector.h" />
|
||||
<ClInclude Include="Windows\ConstantBufferPreviewer.h" />
|
||||
<ClInclude Include="Windows\Dialogs\AboutDialog.h" />
|
||||
<ClInclude Include="Windows\Dialogs\CaptureDialog.h" />
|
||||
<ClInclude Include="Windows\Dialogs\LiveCapture.h" />
|
||||
@@ -406,9 +415,11 @@
|
||||
<ClInclude Include="3rdparty\toolwindowmanager\ToolWindowManagerWrapper.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Widgets\BufferFormatSpecifier.ui" />
|
||||
<None Include="Widgets\ResourcePreview.ui" />
|
||||
<None Include="Widgets\ThumbnailStrip.ui" />
|
||||
<None Include="Windows\APIInspector.ui" />
|
||||
<None Include="Windows\ConstantBufferPreviewer.ui" />
|
||||
<None Include="Windows\Dialogs\AboutDialog.ui" />
|
||||
<None Include="Windows\Dialogs\CaptureDialog.ui" />
|
||||
<None Include="Windows\Dialogs\LiveCapture.ui" />
|
||||
|
||||
@@ -238,6 +238,21 @@
|
||||
<ClCompile Include="generated\moc_RDTreeWidget.cpp">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Windows\ConstantBufferPreviewer.cpp">
|
||||
<Filter>Windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Widgets\BufferFormatSpecifier.cpp">
|
||||
<Filter>Widgets</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="generated\moc_BufferFormatSpecifier.cpp">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="generated\moc_ConstantBufferPreviewer.cpp">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Code\FormatElement.cpp">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="3rdparty\flowlayout\FlowLayout.h">
|
||||
@@ -378,6 +393,18 @@
|
||||
<ClInclude Include="Widgets\Extended\RDTreeWidget.h">
|
||||
<Filter>Widgets\Extended</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Windows\ConstantBufferPreviewer.h">
|
||||
<Filter>Windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Widgets\BufferFormatSpecifier.h">
|
||||
<Filter>Widgets</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="generated\ui_ConstantBufferPreviewer.h">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="generated\ui_BufferFormatSpecifier.h">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="resources.qrc">
|
||||
@@ -602,6 +629,12 @@
|
||||
<None Include="Resources\action.png">
|
||||
<Filter>Resources\Files</Filter>
|
||||
</None>
|
||||
<None Include="Windows\ConstantBufferPreviewer.ui">
|
||||
<Filter>Windows</Filter>
|
||||
</None>
|
||||
<None Include="Widgets\BufferFormatSpecifier.ui">
|
||||
<Filter>Widgets</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="generated\ui_AboutDialog.h">
|
||||
|
||||
Reference in New Issue
Block a user