mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-13 05:20:45 +00:00
Support advanced cbuffer layouts
* This includes 8/16/64-bit integers, 16-bit/64-bit floats, and scalar block packing
This commit is contained in:
@@ -158,9 +158,9 @@ QList<FormatElement> FormatElement::ParseFormatString(const QString &formatStrin
|
||||
"|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
|
||||
"|byte|short|int|long" // signed ints
|
||||
"|ubyte|ushort|uint|ulong" // unsigned ints
|
||||
"|xbyte|xshort|xint|xlong" // hex ints
|
||||
"|half|float|double" // float types
|
||||
"|vec|uvec|ivec" // OpenGL vector types
|
||||
"|mat|umat|imat" // OpenGL matrix types
|
||||
@@ -283,6 +283,16 @@ QList<FormatElement> FormatElement::ParseFormatString(const QString &formatStrin
|
||||
type = CompType::UInt;
|
||||
width = 2;
|
||||
}
|
||||
else if(basetype == lit("long"))
|
||||
{
|
||||
type = CompType::SInt;
|
||||
width = 8;
|
||||
}
|
||||
else if(basetype == lit("ulong") || basetype == lit("xlong"))
|
||||
{
|
||||
type = CompType::UInt;
|
||||
width = 8;
|
||||
}
|
||||
else if(basetype == lit("int") || basetype == lit("ivec") || basetype == lit("imat"))
|
||||
{
|
||||
type = CompType::SInt;
|
||||
@@ -862,12 +872,51 @@ ShaderVariable FormatElement::GetShaderVar(const byte *&data, const byte *end) c
|
||||
ret.name = name.toUtf8().data();
|
||||
ret.type = VarType::Float;
|
||||
if(format.compType == CompType::UInt)
|
||||
ret.type = VarType::UInt;
|
||||
if(format.compType == CompType::SInt)
|
||||
ret.type = VarType::Int;
|
||||
if(format.compType == CompType::Double)
|
||||
{
|
||||
if(format.compByteWidth == 8)
|
||||
ret.type = VarType::ULong;
|
||||
else if(format.compByteWidth == 4)
|
||||
ret.type = VarType::UInt;
|
||||
else if(format.compByteWidth == 2)
|
||||
ret.type = VarType::UShort;
|
||||
else if(format.compByteWidth == 1)
|
||||
ret.type = VarType::UByte;
|
||||
else
|
||||
qCritical() << "Unexpeted component bytewidth for uint: " << format.compByteWidth;
|
||||
}
|
||||
else if(format.compType == CompType::SInt)
|
||||
{
|
||||
if(format.compByteWidth == 8)
|
||||
ret.type = VarType::SLong;
|
||||
else if(format.compByteWidth == 4)
|
||||
ret.type = VarType::SInt;
|
||||
else if(format.compByteWidth == 2)
|
||||
ret.type = VarType::SShort;
|
||||
else if(format.compByteWidth == 1)
|
||||
ret.type = VarType::SByte;
|
||||
else
|
||||
qCritical() << "Unexpeted component bytewidth for sint: " << format.compByteWidth;
|
||||
}
|
||||
else if(format.compType == CompType::Double)
|
||||
{
|
||||
ret.type = VarType::Double;
|
||||
|
||||
if(format.compByteWidth != 8)
|
||||
qCritical() << "Unexpeted component bytewidth for double: " << format.compByteWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
// assume float/double
|
||||
if(format.compByteWidth == 8)
|
||||
ret.type = VarType::Double;
|
||||
else if(format.compByteWidth == 4)
|
||||
ret.type = VarType::Float;
|
||||
else if(format.compByteWidth == 2)
|
||||
ret.type = VarType::Half;
|
||||
else
|
||||
qCritical() << "Unexpeted component bytewidth for float: " << format.compByteWidth;
|
||||
}
|
||||
|
||||
ret.columns = qMin(format.compCount, uint8_t(4));
|
||||
ret.rows = qMin(matrixdim, 4U);
|
||||
|
||||
@@ -892,9 +941,15 @@ ShaderVariable FormatElement::GetShaderVar(const byte *&data, const byte *end) c
|
||||
|
||||
if(ret.type == VarType::Double)
|
||||
ret.value.dv[dst] = o.toDouble();
|
||||
else if(ret.type == VarType::UInt)
|
||||
if(ret.type == VarType::Float || ret.type == VarType::Half)
|
||||
ret.value.dv[dst] = o.toFloat();
|
||||
else if(ret.type == VarType::ULong)
|
||||
ret.value.u64v[dst] = o.toULongLong();
|
||||
else if(ret.type == VarType::SLong)
|
||||
ret.value.s64v[dst] = o.toLongLong();
|
||||
else if(ret.type == VarType::UInt || ret.type == VarType::UShort || ret.type == VarType::UByte)
|
||||
ret.value.uv[dst] = o.toUInt();
|
||||
else if(ret.type == VarType::Int)
|
||||
else if(ret.type == VarType::SInt || ret.type == VarType::SShort || ret.type == VarType::SByte)
|
||||
ret.value.iv[dst] = o.toInt();
|
||||
else
|
||||
ret.value.fv[dst] = o.toFloat();
|
||||
@@ -930,8 +985,17 @@ QString TypeString(const ShaderVariable &v)
|
||||
|
||||
QString typeStr = ToQStr(v.type);
|
||||
|
||||
if(v.displayAsHex && v.type == VarType::UInt)
|
||||
typeStr = lit("xint");
|
||||
if(v.displayAsHex)
|
||||
{
|
||||
if(v.type == VarType::ULong)
|
||||
typeStr = lit("xlong");
|
||||
else if(v.type == VarType::UInt)
|
||||
typeStr = lit("xint");
|
||||
else if(v.type == VarType::UShort)
|
||||
typeStr = lit("xshort");
|
||||
else if(v.type == VarType::UByte)
|
||||
typeStr = lit("xbyte");
|
||||
}
|
||||
|
||||
if(v.rows == 1 && v.columns == 1)
|
||||
return typeStr;
|
||||
@@ -975,11 +1039,19 @@ QString RowString(const ShaderVariable &v, uint32_t row, VarType type)
|
||||
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(type == VarType::Int)
|
||||
else if(type == VarType::SLong)
|
||||
return RowValuesToString((int)v.columns, v.value.s64v[row * v.columns + 0],
|
||||
v.value.s64v[row * v.columns + 1], v.value.s64v[row * v.columns + 2],
|
||||
v.value.s64v[row * v.columns + 3]);
|
||||
else if(type == VarType::ULong)
|
||||
return RowValuesToString((int)v.columns, v.value.u64v[row * v.columns + 0],
|
||||
v.value.u64v[row * v.columns + 1], v.value.u64v[row * v.columns + 2],
|
||||
v.value.u64v[row * v.columns + 3]);
|
||||
else if(type == VarType::SInt || type == VarType::SShort || type == VarType::SByte)
|
||||
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(type == VarType::UInt)
|
||||
else if(type == VarType::UInt || type == VarType::UShort || type == VarType::UByte)
|
||||
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]);
|
||||
@@ -1023,8 +1095,17 @@ QString RowTypeString(const ShaderVariable &v)
|
||||
|
||||
QString typeStr = ToQStr(v.type);
|
||||
|
||||
if(v.displayAsHex && v.type == VarType::UInt)
|
||||
typeStr = lit("xint");
|
||||
if(v.displayAsHex)
|
||||
{
|
||||
if(v.type == VarType::ULong)
|
||||
typeStr = lit("xlong");
|
||||
else if(v.type == VarType::UInt)
|
||||
typeStr = lit("xint");
|
||||
else if(v.type == VarType::UShort)
|
||||
typeStr = lit("xshort");
|
||||
else if(v.type == VarType::UByte)
|
||||
typeStr = lit("xbyte");
|
||||
}
|
||||
|
||||
if(v.columns == 1)
|
||||
return typeStr;
|
||||
|
||||
@@ -189,6 +189,27 @@ struct TypeConversion<uint8_t, false>
|
||||
static PyObject *ConvertToPy(const uint8_t &in) { return PyLong_FromUnsignedLong(in); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TypeConversion<int8_t, false>
|
||||
{
|
||||
static int ConvertFromPy(PyObject *in, int8_t &out)
|
||||
{
|
||||
if(!PyLong_Check(in))
|
||||
return SWIG_TypeError;
|
||||
|
||||
uint32_t longval = PyLong_AsUnsignedLong(in);
|
||||
|
||||
if(PyErr_Occurred() || longval > 0xff)
|
||||
return SWIG_OverflowError;
|
||||
|
||||
out = int8_t(longval & 0xff);
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
static PyObject *ConvertToPy(const int8_t &in) { return PyLong_FromLong(in); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TypeConversion<uint16_t, false>
|
||||
{
|
||||
@@ -210,6 +231,27 @@ struct TypeConversion<uint16_t, false>
|
||||
static PyObject *ConvertToPy(const uint16_t &in) { return PyLong_FromUnsignedLong(in); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TypeConversion<int16_t, false>
|
||||
{
|
||||
static int ConvertFromPy(PyObject *in, int16_t &out)
|
||||
{
|
||||
if(!PyLong_Check(in))
|
||||
return SWIG_TypeError;
|
||||
|
||||
uint32_t longval = PyLong_AsLong(in);
|
||||
|
||||
if(PyErr_Occurred() || longval > 0xffff)
|
||||
return SWIG_OverflowError;
|
||||
|
||||
out = int16_t(longval & 0xff);
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
static PyObject *ConvertToPy(const int16_t &in) { return PyLong_FromLong(in); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TypeConversion<uint32_t, false>
|
||||
{
|
||||
@@ -267,6 +309,25 @@ struct TypeConversion<uint64_t, false>
|
||||
static PyObject *ConvertToPy(const uint64_t &in) { return PyLong_FromUnsignedLongLong(in); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TypeConversion<int64_t, false>
|
||||
{
|
||||
static int ConvertFromPy(PyObject *in, int64_t &out)
|
||||
{
|
||||
if(!PyLong_Check(in))
|
||||
return SWIG_TypeError;
|
||||
|
||||
out = PyLong_AsLongLong(in);
|
||||
|
||||
if(PyErr_Occurred())
|
||||
return SWIG_OverflowError;
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
static PyObject *ConvertToPy(const int64_t &in) { return PyLong_FromLongLong(in); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TypeConversion<float, false>
|
||||
{
|
||||
|
||||
@@ -155,9 +155,13 @@ FIXED_ARRAY_TYPEMAPS(double)
|
||||
FIXED_ARRAY_TYPEMAPS(float)
|
||||
FIXED_ARRAY_TYPEMAPS(bool)
|
||||
FIXED_ARRAY_TYPEMAPS(uint64_t)
|
||||
FIXED_ARRAY_TYPEMAPS(int64_t)
|
||||
FIXED_ARRAY_TYPEMAPS(uint32_t)
|
||||
FIXED_ARRAY_TYPEMAPS(int32_t)
|
||||
FIXED_ARRAY_TYPEMAPS(uint16_t)
|
||||
FIXED_ARRAY_TYPEMAPS(int16_t)
|
||||
FIXED_ARRAY_TYPEMAPS(uint8_t)
|
||||
FIXED_ARRAY_TYPEMAPS(int8_t)
|
||||
|
||||
REFCOUNTED_TYPE(SDChunk);
|
||||
REFCOUNTED_TYPE(SDObject);
|
||||
|
||||
@@ -1483,8 +1483,8 @@ void ShaderViewer::runTo(int runToInstruction, bool forward, ShaderEvents condit
|
||||
|
||||
QString ShaderViewer::stringRep(const ShaderVariable &var, bool useType)
|
||||
{
|
||||
if(ui->intView->isChecked() || (useType && var.type == VarType::Int))
|
||||
return RowString(var, 0, VarType::Int);
|
||||
if(ui->intView->isChecked() || (useType && var.type == VarType::SInt))
|
||||
return RowString(var, 0, VarType::SInt);
|
||||
|
||||
if(useType && var.type == VarType::UInt)
|
||||
return RowString(var, 0, VarType::UInt);
|
||||
@@ -1974,7 +1974,7 @@ void ShaderViewer::updateDebugging()
|
||||
|
||||
if(l.type == VarType::UInt)
|
||||
typeName = lit("uint");
|
||||
else if(l.type == VarType::Int)
|
||||
else if(l.type == VarType::SInt)
|
||||
typeName = lit("int");
|
||||
else if(l.type == VarType::Float)
|
||||
typeName = lit("float");
|
||||
@@ -2047,7 +2047,7 @@ void ShaderViewer::updateDebugging()
|
||||
|
||||
if(l.type == VarType::UInt)
|
||||
value += Formatter::Format(var->value.uv[r.component]);
|
||||
else if(l.type == VarType::Int)
|
||||
else if(l.type == VarType::SInt)
|
||||
value += Formatter::Format(var->value.iv[r.component]);
|
||||
else if(l.type == VarType::Float)
|
||||
value += Formatter::Format(var->value.fv[r.component]);
|
||||
@@ -3163,7 +3163,7 @@ void ShaderViewer::updateVariableTooltip()
|
||||
{
|
||||
if(l.type == VarType::UInt)
|
||||
tooltip += Formatter::Format(var->value.uv[r.component]);
|
||||
else if(l.type == VarType::Int)
|
||||
else if(l.type == VarType::SInt)
|
||||
tooltip += Formatter::Format(var->value.iv[r.component]);
|
||||
else if(l.type == VarType::Float)
|
||||
tooltip += Formatter::Format(var->value.fv[r.component]);
|
||||
|
||||
@@ -716,9 +716,16 @@ std::string DoStringise(const VarType &el)
|
||||
BEGIN_ENUM_STRINGISE(VarType)
|
||||
{
|
||||
STRINGISE_ENUM_CLASS_NAMED(Float, "float");
|
||||
STRINGISE_ENUM_CLASS_NAMED(Int, "int");
|
||||
STRINGISE_ENUM_CLASS_NAMED(UInt, "uint");
|
||||
STRINGISE_ENUM_CLASS_NAMED(Double, "double");
|
||||
STRINGISE_ENUM_CLASS_NAMED(Half, "half");
|
||||
STRINGISE_ENUM_CLASS_NAMED(SInt, "int");
|
||||
STRINGISE_ENUM_CLASS_NAMED(UInt, "uint");
|
||||
STRINGISE_ENUM_CLASS_NAMED(SShort, "short");
|
||||
STRINGISE_ENUM_CLASS_NAMED(UShort, "ushort");
|
||||
STRINGISE_ENUM_CLASS_NAMED(SLong, "long");
|
||||
STRINGISE_ENUM_CLASS_NAMED(ULong, "ulong");
|
||||
STRINGISE_ENUM_CLASS_NAMED(SByte, "byte");
|
||||
STRINGISE_ENUM_CLASS_NAMED(UByte, "ubyte");
|
||||
STRINGISE_ENUM_CLASS_NAMED(Unknown, "unknown");
|
||||
}
|
||||
END_ENUM_STRINGISE();
|
||||
|
||||
@@ -142,18 +142,46 @@ DOCUMENT(R"(Represents the base type of a shader variable in debugging or consta
|
||||
|
||||
A single-precision (32-bit) floating point value.
|
||||
|
||||
.. data:: Int
|
||||
|
||||
A signed integer value.
|
||||
|
||||
.. data:: UInt
|
||||
|
||||
An unsigned integer value.
|
||||
|
||||
.. data:: Double
|
||||
|
||||
A double-precision (64-bit) floating point value.
|
||||
|
||||
.. data:: Half
|
||||
|
||||
A half-precision (16-bit) floating point value.
|
||||
|
||||
.. data:: SInt
|
||||
|
||||
A signed 32-bit integer value.
|
||||
|
||||
.. data:: UInt
|
||||
|
||||
An unsigned 32-bit integer value.
|
||||
|
||||
.. data:: SShort
|
||||
|
||||
A signed 16-bit integer value.
|
||||
|
||||
.. data:: UShort
|
||||
|
||||
An unsigned 16-bit integer value.
|
||||
|
||||
.. data:: SLong
|
||||
|
||||
A signed 64-bit integer value.
|
||||
|
||||
.. data:: ULong
|
||||
|
||||
An unsigned 64-bit integer value.
|
||||
|
||||
.. data:: SByte
|
||||
|
||||
A signed 8-bit integer value.
|
||||
|
||||
.. data:: UByte
|
||||
|
||||
An unsigned 8-bit integer value.
|
||||
|
||||
.. data:: Unknown
|
||||
|
||||
An unknown type.
|
||||
@@ -161,9 +189,16 @@ DOCUMENT(R"(Represents the base type of a shader variable in debugging or consta
|
||||
enum class VarType : uint32_t
|
||||
{
|
||||
Float = 0,
|
||||
Int,
|
||||
UInt,
|
||||
Double,
|
||||
Half,
|
||||
SInt,
|
||||
UInt,
|
||||
SShort,
|
||||
UShort,
|
||||
SLong,
|
||||
ULong,
|
||||
SByte,
|
||||
UByte,
|
||||
Unknown = ~0U,
|
||||
};
|
||||
|
||||
|
||||
@@ -120,8 +120,11 @@ union ShaderValue
|
||||
DOCUMENT("``double`` values.");
|
||||
double dv[16];
|
||||
|
||||
DOCUMENT("64-bit integer values.");
|
||||
DOCUMENT("64-bit unsigned integer values.");
|
||||
uint64_t u64v[16];
|
||||
|
||||
DOCUMENT("64-bit signed integer values.");
|
||||
int64_t s64v[16];
|
||||
};
|
||||
|
||||
DOCUMENT(R"(Holds a single named shader variable. It contains either a primitive type (up to a 4x4
|
||||
@@ -166,7 +169,7 @@ struct ShaderVariable
|
||||
displayAsHex = isStruct = rowMajor = false;
|
||||
for(int i = 0; i < 16; i++)
|
||||
value.uv[i] = 0;
|
||||
type = VarType::Int;
|
||||
type = VarType::SInt;
|
||||
value.i.x = x;
|
||||
value.i.y = y;
|
||||
value.i.z = z;
|
||||
|
||||
@@ -288,7 +288,7 @@ ShaderDebug::State D3D11DebugManager::CreateShaderDebugState(ShaderDebugTrace &t
|
||||
if(sig.compType == CompType::UInt)
|
||||
v.type = VarType::UInt;
|
||||
else if(sig.compType == CompType::SInt)
|
||||
v.type = VarType::Int;
|
||||
v.type = VarType::SInt;
|
||||
|
||||
if(trace.inputs[sig.regIndex].columns == 0)
|
||||
trace.inputs[sig.regIndex] = v;
|
||||
|
||||
@@ -193,7 +193,7 @@ void DoSerialise(SerialiserType &ser, ProgramUniformValue &el)
|
||||
case eGL_INT:
|
||||
case eGL_INT_VEC2:
|
||||
case eGL_INT_VEC3:
|
||||
case eGL_INT_VEC4: baseType = VarType::Int; break;
|
||||
case eGL_INT_VEC4: baseType = VarType::SInt; break;
|
||||
case eGL_UNSIGNED_INT:
|
||||
case eGL_BOOL:
|
||||
case eGL_UNSIGNED_INT_VEC2:
|
||||
@@ -251,7 +251,7 @@ void DoSerialise(SerialiserType &ser, ProgramUniformValue &el)
|
||||
{
|
||||
if(baseType == VarType::Float)
|
||||
ser.Serialise("data", fv, elemCount, SerialiserFlags::NoFlags);
|
||||
else if(baseType == VarType::Int)
|
||||
else if(baseType == VarType::SInt)
|
||||
ser.Serialise("data", iv, elemCount, SerialiserFlags::NoFlags);
|
||||
else if(baseType == VarType::UInt)
|
||||
ser.Serialise("data", uv, elemCount, SerialiserFlags::NoFlags);
|
||||
@@ -264,7 +264,7 @@ void DoSerialise(SerialiserType &ser, ProgramUniformValue &el)
|
||||
ser.Serialise("data", fv, elemCount, SerialiserFlags::NoFlags);
|
||||
else if(baseType == VarType::Float)
|
||||
ser.Serialise("data", dv, elemCount, SerialiserFlags::NoFlags);
|
||||
else if(baseType == VarType::Int)
|
||||
else if(baseType == VarType::SInt)
|
||||
ser.Serialise("data", iv, elemCount, SerialiserFlags::NoFlags);
|
||||
else if(baseType == VarType::UInt)
|
||||
ser.Serialise("data", uv, elemCount, SerialiserFlags::NoFlags);
|
||||
|
||||
@@ -2025,10 +2025,20 @@ void GLReplay::OpenGLFillCBufferVariables(GLuint prog, bool bufferBacked, std::s
|
||||
switch(var.type)
|
||||
{
|
||||
case VarType::Unknown:
|
||||
case VarType::SLong:
|
||||
case VarType::ULong:
|
||||
case VarType::SShort:
|
||||
case VarType::UShort:
|
||||
case VarType::SByte:
|
||||
case VarType::UByte:
|
||||
case VarType::Half:
|
||||
RDCERR("Unexpected base variable type %s, treating as float",
|
||||
ToStr(var.type).c_str());
|
||||
// deliberate fall-through
|
||||
case VarType::Float:
|
||||
GL.glGetUniformfv(prog, location, (float *)uniformData.data());
|
||||
break;
|
||||
case VarType::Int:
|
||||
case VarType::SInt:
|
||||
GL.glGetUniformiv(prog, location, (int32_t *)uniformData.data());
|
||||
break;
|
||||
case VarType::UInt:
|
||||
@@ -2060,10 +2070,20 @@ void GLReplay::OpenGLFillCBufferVariables(GLuint prog, bool bufferBacked, std::s
|
||||
switch(var.type)
|
||||
{
|
||||
case VarType::Unknown:
|
||||
case VarType::SLong:
|
||||
case VarType::ULong:
|
||||
case VarType::SShort:
|
||||
case VarType::UShort:
|
||||
case VarType::SByte:
|
||||
case VarType::UByte:
|
||||
case VarType::Half:
|
||||
RDCERR("Unexpected base variable type %s, treating as float",
|
||||
ToStr(var.type).c_str());
|
||||
// deliberate fall-through
|
||||
case VarType::Float:
|
||||
GL.glGetUniformfv(prog, location + a, (float *)uniformData.data());
|
||||
break;
|
||||
case VarType::Int:
|
||||
case VarType::SInt:
|
||||
GL.glGetUniformiv(prog, location + a, (int32_t *)uniformData.data());
|
||||
break;
|
||||
case VarType::UInt:
|
||||
|
||||
@@ -575,7 +575,7 @@ void ReconstructVarTree(GLenum query, GLuint sepProg, GLuint varIdx, GLint numPa
|
||||
case eGL_INT_VEC4:
|
||||
case eGL_INT_VEC3:
|
||||
case eGL_INT_VEC2:
|
||||
case eGL_INT: var.type.descriptor.type = VarType::Int; break;
|
||||
case eGL_INT: var.type.descriptor.type = VarType::SInt; break;
|
||||
default:
|
||||
// not a variable (sampler etc)
|
||||
return;
|
||||
@@ -1163,67 +1163,67 @@ void MakeShaderReflection(GLenum shadType, GLuint sepProg, ShaderReflection &ref
|
||||
{
|
||||
res.resType = TextureType::Buffer;
|
||||
res.variableType.descriptor.name = "isamplerBuffer";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
}
|
||||
else if(values[0] == eGL_INT_SAMPLER_1D)
|
||||
{
|
||||
res.resType = TextureType::Texture1D;
|
||||
res.variableType.descriptor.name = "isampler1D";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
}
|
||||
else if(values[0] == eGL_INT_SAMPLER_1D_ARRAY)
|
||||
{
|
||||
res.resType = TextureType::Texture1DArray;
|
||||
res.variableType.descriptor.name = "isampler1DArray";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
}
|
||||
else if(values[0] == eGL_INT_SAMPLER_2D)
|
||||
{
|
||||
res.resType = TextureType::Texture2D;
|
||||
res.variableType.descriptor.name = "isampler2D";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
}
|
||||
else if(values[0] == eGL_INT_SAMPLER_2D_ARRAY)
|
||||
{
|
||||
res.resType = TextureType::Texture2DArray;
|
||||
res.variableType.descriptor.name = "isampler2DArray";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
}
|
||||
else if(values[0] == eGL_INT_SAMPLER_2D_RECT)
|
||||
{
|
||||
res.resType = TextureType::TextureRect;
|
||||
res.variableType.descriptor.name = "isampler2DRect";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
}
|
||||
else if(values[0] == eGL_INT_SAMPLER_3D)
|
||||
{
|
||||
res.resType = TextureType::Texture3D;
|
||||
res.variableType.descriptor.name = "isampler3D";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
}
|
||||
else if(values[0] == eGL_INT_SAMPLER_CUBE)
|
||||
{
|
||||
res.resType = TextureType::TextureCube;
|
||||
res.variableType.descriptor.name = "isamplerCube";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
}
|
||||
else if(values[0] == eGL_INT_SAMPLER_CUBE_MAP_ARRAY)
|
||||
{
|
||||
res.resType = TextureType::TextureCubeArray;
|
||||
res.variableType.descriptor.name = "isamplerCubeArray";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
}
|
||||
else if(values[0] == eGL_INT_SAMPLER_2D_MULTISAMPLE)
|
||||
{
|
||||
res.resType = TextureType::Texture2DMS;
|
||||
res.variableType.descriptor.name = "isampler2DMS";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
}
|
||||
else if(values[0] == eGL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY)
|
||||
{
|
||||
res.resType = TextureType::Texture2DMSArray;
|
||||
res.variableType.descriptor.name = "isampler2DMSArray";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
}
|
||||
// unsigned int samplers
|
||||
else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_BUFFER)
|
||||
@@ -1375,77 +1375,77 @@ void MakeShaderReflection(GLenum shadType, GLuint sepProg, ShaderReflection &ref
|
||||
{
|
||||
res.resType = TextureType::Buffer;
|
||||
res.variableType.descriptor.name = "iimageBuffer";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
res.isReadOnly = false;
|
||||
}
|
||||
else if(values[0] == eGL_INT_IMAGE_1D)
|
||||
{
|
||||
res.resType = TextureType::Texture1D;
|
||||
res.variableType.descriptor.name = "iimage1D";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
res.isReadOnly = false;
|
||||
}
|
||||
else if(values[0] == eGL_INT_IMAGE_1D_ARRAY)
|
||||
{
|
||||
res.resType = TextureType::Texture1DArray;
|
||||
res.variableType.descriptor.name = "iimage1DArray";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
res.isReadOnly = false;
|
||||
}
|
||||
else if(values[0] == eGL_INT_IMAGE_2D)
|
||||
{
|
||||
res.resType = TextureType::Texture2D;
|
||||
res.variableType.descriptor.name = "iimage2D";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
res.isReadOnly = false;
|
||||
}
|
||||
else if(values[0] == eGL_INT_IMAGE_2D_ARRAY)
|
||||
{
|
||||
res.resType = TextureType::Texture2DArray;
|
||||
res.variableType.descriptor.name = "iimage2DArray";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
res.isReadOnly = false;
|
||||
}
|
||||
else if(values[0] == eGL_INT_IMAGE_2D_RECT)
|
||||
{
|
||||
res.resType = TextureType::TextureRect;
|
||||
res.variableType.descriptor.name = "iimage2DRect";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
res.isReadOnly = false;
|
||||
}
|
||||
else if(values[0] == eGL_INT_IMAGE_3D)
|
||||
{
|
||||
res.resType = TextureType::Texture3D;
|
||||
res.variableType.descriptor.name = "iimage3D";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
res.isReadOnly = false;
|
||||
}
|
||||
else if(values[0] == eGL_INT_IMAGE_CUBE)
|
||||
{
|
||||
res.resType = TextureType::TextureCube;
|
||||
res.variableType.descriptor.name = "iimageCube";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
res.isReadOnly = false;
|
||||
}
|
||||
else if(values[0] == eGL_INT_IMAGE_CUBE_MAP_ARRAY)
|
||||
{
|
||||
res.resType = TextureType::TextureCubeArray;
|
||||
res.variableType.descriptor.name = "iimageCubeArray";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
res.isReadOnly = false;
|
||||
}
|
||||
else if(values[0] == eGL_INT_IMAGE_2D_MULTISAMPLE)
|
||||
{
|
||||
res.resType = TextureType::Texture2DMS;
|
||||
res.variableType.descriptor.name = "iimage2DMS";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
res.isReadOnly = false;
|
||||
}
|
||||
else if(values[0] == eGL_INT_IMAGE_2D_MULTISAMPLE_ARRAY)
|
||||
{
|
||||
res.resType = TextureType::Texture2DMSArray;
|
||||
res.variableType.descriptor.name = "iimage2DMSArray";
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
res.variableType.descriptor.type = VarType::SInt;
|
||||
res.isReadOnly = false;
|
||||
}
|
||||
// unsigned int images
|
||||
|
||||
@@ -154,14 +154,14 @@ VarType State::OperationType(const OpcodeType &op) const
|
||||
case OPCODE_BREAKC:
|
||||
case OPCODE_IF:
|
||||
case OPCODE_ITOF:
|
||||
case OPCODE_DTOI: return VarType::Int;
|
||||
case OPCODE_DTOI: return VarType::SInt;
|
||||
|
||||
case OPCODE_ATOMIC_IADD:
|
||||
case OPCODE_ATOMIC_IMAX:
|
||||
case OPCODE_ATOMIC_IMIN:
|
||||
case OPCODE_IMM_ATOMIC_IADD:
|
||||
case OPCODE_IMM_ATOMIC_IMAX:
|
||||
case OPCODE_IMM_ATOMIC_IMIN: return VarType::Int;
|
||||
case OPCODE_IMM_ATOMIC_IMIN: return VarType::SInt;
|
||||
case OPCODE_ATOMIC_AND:
|
||||
case OPCODE_ATOMIC_OR:
|
||||
case OPCODE_ATOMIC_XOR:
|
||||
@@ -243,7 +243,7 @@ ShaderVariable sat(const ShaderVariable &v, const VarType type)
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case VarType::Int:
|
||||
case VarType::SInt:
|
||||
{
|
||||
for(size_t i = 0; i < v.columns; i++)
|
||||
r.value.iv[i] = v.value.iv[i] < 0 ? 0 : (v.value.iv[i] > 1 ? 1 : v.value.iv[i]);
|
||||
@@ -292,7 +292,7 @@ ShaderVariable abs(const ShaderVariable &v, const VarType type)
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case VarType::Int:
|
||||
case VarType::SInt:
|
||||
{
|
||||
for(size_t i = 0; i < v.columns; i++)
|
||||
r.value.iv[i] = v.value.iv[i] > 0 ? v.value.iv[i] : -v.value.iv[i];
|
||||
@@ -337,7 +337,7 @@ ShaderVariable neg(const ShaderVariable &v, const VarType type)
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case VarType::Int:
|
||||
case VarType::SInt:
|
||||
{
|
||||
for(size_t i = 0; i < v.columns; i++)
|
||||
r.value.iv[i] = -v.value.iv[i];
|
||||
@@ -382,7 +382,7 @@ ShaderVariable mul(const ShaderVariable &a, const ShaderVariable &b, const VarTy
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case VarType::Int:
|
||||
case VarType::SInt:
|
||||
{
|
||||
for(size_t i = 0; i < a.columns; i++)
|
||||
r.value.iv[i] = a.value.iv[i] * b.value.iv[i];
|
||||
@@ -432,7 +432,7 @@ ShaderVariable div(const ShaderVariable &a, const ShaderVariable &b, const VarTy
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case VarType::Int:
|
||||
case VarType::SInt:
|
||||
{
|
||||
for(size_t i = 0; i < a.columns; i++)
|
||||
r.value.iv[i] = a.value.iv[i] / b.value.iv[i];
|
||||
@@ -482,7 +482,7 @@ ShaderVariable add(const ShaderVariable &a, const ShaderVariable &b, const VarTy
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case VarType::Int:
|
||||
case VarType::SInt:
|
||||
{
|
||||
for(size_t i = 0; i < a.columns; i++)
|
||||
r.value.iv[i] = a.value.iv[i] + b.value.iv[i];
|
||||
|
||||
@@ -35,9 +35,10 @@ static ShaderVariableType MakeShaderVariableType(DXBC::CBufferVariableType type)
|
||||
|
||||
switch(type.descriptor.type)
|
||||
{
|
||||
// D3D treats all cbuffer variables as 32-bit regardless of declaration
|
||||
case DXBC::VARTYPE_MIN12INT:
|
||||
case DXBC::VARTYPE_MIN16INT:
|
||||
case DXBC::VARTYPE_INT: ret.descriptor.type = VarType::Int; break;
|
||||
case DXBC::VARTYPE_INT: ret.descriptor.type = VarType::SInt; break;
|
||||
case DXBC::VARTYPE_BOOL:
|
||||
case DXBC::VARTYPE_MIN16UINT:
|
||||
case DXBC::VARTYPE_UINT: ret.descriptor.type = VarType::UInt; break;
|
||||
|
||||
@@ -196,12 +196,14 @@ SPDBChunk::SPDBChunk(DXBCFile *dxbc, void *chunk)
|
||||
std::map<uint32_t, TypeDesc> typeInfo;
|
||||
|
||||
// prepopulate with basic types
|
||||
typeInfo[T_INT4] = {"int32_t", VarType::Int, 4, 1, 0, LF_NUMERIC, {}};
|
||||
typeInfo[T_INT2] = {"int16_t", VarType::Int, 2, 1, 0, LF_NUMERIC, {}};
|
||||
typeInfo[T_INT1] = {"int8_t", VarType::Int, 1, 1, 0, LF_NUMERIC, {}};
|
||||
typeInfo[T_LONG] = {"int32_t", VarType::Int, 4, 1, 0, LF_NUMERIC, {}};
|
||||
typeInfo[T_SHORT] = {"int16_t", VarType::Int, 2, 1, 0, LF_NUMERIC, {}};
|
||||
typeInfo[T_CHAR] = {"char", VarType::Int, 1, 1, 0, LF_NUMERIC, {}};
|
||||
// for now we stick to full-precision 32-bit VarTypes. It's not clear if HLSL even emits the other
|
||||
// types
|
||||
typeInfo[T_INT4] = {"int32_t", VarType::SInt, 4, 1, 0, LF_NUMERIC, {}};
|
||||
typeInfo[T_INT2] = {"int16_t", VarType::SInt, 2, 1, 0, LF_NUMERIC, {}};
|
||||
typeInfo[T_INT1] = {"int8_t", VarType::SInt, 1, 1, 0, LF_NUMERIC, {}};
|
||||
typeInfo[T_LONG] = {"int32_t", VarType::SInt, 4, 1, 0, LF_NUMERIC, {}};
|
||||
typeInfo[T_SHORT] = {"int16_t", VarType::SInt, 2, 1, 0, LF_NUMERIC, {}};
|
||||
typeInfo[T_CHAR] = {"char", VarType::SInt, 1, 1, 0, LF_NUMERIC, {}};
|
||||
typeInfo[T_BOOL32FF] = {"bool", VarType::UInt, 4, 1, 0, LF_NUMERIC, {}};
|
||||
typeInfo[T_UINT4] = {"uint32_t", VarType::UInt, 4, 1, 0, LF_NUMERIC, {}};
|
||||
typeInfo[T_UINT2] = {"uint16_t", VarType::UInt, 2, 1, 0, LF_NUMERIC, {}};
|
||||
|
||||
@@ -606,6 +606,62 @@ struct SPVTypeData
|
||||
return name;
|
||||
}
|
||||
|
||||
VarType GetVarType()
|
||||
{
|
||||
if(type == SPVTypeData::eFloat)
|
||||
{
|
||||
if(bitCount == 64)
|
||||
return VarType::Double;
|
||||
else if(bitCount == 32)
|
||||
return VarType::Float;
|
||||
else if(bitCount == 16)
|
||||
return VarType::Half;
|
||||
|
||||
RDCERR("Unexpected float bitcount: %u", bitCount);
|
||||
|
||||
return VarType::Float;
|
||||
}
|
||||
else if(type == SPVTypeData::eBool)
|
||||
{
|
||||
// we treat bools as VkBool32 externally
|
||||
return VarType::UInt;
|
||||
}
|
||||
else if(type == SPVTypeData::eUInt)
|
||||
{
|
||||
if(bitCount == 64)
|
||||
return VarType::ULong;
|
||||
else if(bitCount == 32)
|
||||
return VarType::UInt;
|
||||
else if(bitCount == 16)
|
||||
return VarType::UShort;
|
||||
else if(bitCount == 8)
|
||||
return VarType::UByte;
|
||||
|
||||
RDCERR("Unexpected uint bitcount: %u", bitCount);
|
||||
|
||||
return VarType::UInt;
|
||||
}
|
||||
else if(type == SPVTypeData::eSInt)
|
||||
{
|
||||
if(bitCount == 64)
|
||||
return VarType::SLong;
|
||||
else if(bitCount == 32)
|
||||
return VarType::SInt;
|
||||
else if(bitCount == 16)
|
||||
return VarType::SShort;
|
||||
else if(bitCount == 8)
|
||||
return VarType::SByte;
|
||||
|
||||
RDCERR("Unexpected sint bitcount: %u", bitCount);
|
||||
|
||||
return VarType::SInt;
|
||||
}
|
||||
|
||||
RDCERR("Unexpected base type variable %u", type);
|
||||
|
||||
return VarType::Unknown;
|
||||
}
|
||||
|
||||
vector<SPVDecoration> *decorations;
|
||||
|
||||
// struct/function
|
||||
@@ -3565,14 +3621,7 @@ void MakeConstantBlockVariable(ShaderConstant &outConst, SPVTypeData *type, cons
|
||||
|
||||
if(type->type == SPVTypeData::eVector || type->type == SPVTypeData::eMatrix)
|
||||
{
|
||||
if(type->baseType->type == SPVTypeData::eFloat)
|
||||
outConst.type.descriptor.type = VarType::Float;
|
||||
else if(type->baseType->type == SPVTypeData::eUInt || type->baseType->type == SPVTypeData::eBool)
|
||||
outConst.type.descriptor.type = VarType::UInt;
|
||||
else if(type->baseType->type == SPVTypeData::eSInt)
|
||||
outConst.type.descriptor.type = VarType::Int;
|
||||
else
|
||||
RDCERR("Unexpected base type of constant variable %u", type->baseType->type);
|
||||
outConst.type.descriptor.type = type->baseType->GetVarType();
|
||||
|
||||
outConst.type.descriptor.rowMajorStorage = (type->type == SPVTypeData::eVector);
|
||||
|
||||
@@ -3599,15 +3648,7 @@ void MakeConstantBlockVariable(ShaderConstant &outConst, SPVTypeData *type, cons
|
||||
}
|
||||
else if(type->IsScalar())
|
||||
{
|
||||
if(type->type == SPVTypeData::eFloat)
|
||||
outConst.type.descriptor.type = VarType::Float;
|
||||
else if(type->type == SPVTypeData::eUInt || type->type == SPVTypeData::eBool)
|
||||
outConst.type.descriptor.type = VarType::UInt;
|
||||
else if(type->type == SPVTypeData::eSInt)
|
||||
outConst.type.descriptor.type = VarType::Int;
|
||||
else
|
||||
RDCERR("Unexpected base type of constant variable %u", type->type);
|
||||
|
||||
outConst.type.descriptor.type = type->GetVarType();
|
||||
outConst.type.descriptor.rowMajorStorage = true;
|
||||
outConst.type.descriptor.rows = 1;
|
||||
outConst.type.descriptor.columns = 1;
|
||||
@@ -4416,14 +4457,7 @@ void SPVModule::MakeReflection(GraphicsAPI sourceAPI, ShaderStage stage, const s
|
||||
{
|
||||
res.resType = TextureType::Texture2D;
|
||||
|
||||
if(sampledType->type == SPVTypeData::eFloat)
|
||||
res.variableType.descriptor.type = VarType::Float;
|
||||
else if(sampledType->type == SPVTypeData::eUInt)
|
||||
res.variableType.descriptor.type = VarType::UInt;
|
||||
else if(sampledType->type == SPVTypeData::eSInt)
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
else
|
||||
RDCERR("Unexpected base type of resource %u", sampledType->type);
|
||||
res.variableType.descriptor.type = sampledType->GetVarType();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4441,14 +4475,7 @@ void SPVModule::MakeReflection(GraphicsAPI sourceAPI, ShaderStage stage, const s
|
||||
|
||||
res.isReadOnly = !isrw;
|
||||
|
||||
if(sampledType->type == SPVTypeData::eFloat)
|
||||
res.variableType.descriptor.type = VarType::Float;
|
||||
else if(sampledType->type == SPVTypeData::eUInt)
|
||||
res.variableType.descriptor.type = VarType::UInt;
|
||||
else if(sampledType->type == SPVTypeData::eSInt)
|
||||
res.variableType.descriptor.type = VarType::Int;
|
||||
else
|
||||
RDCERR("Unexpected base type of resource %u", sampledType->type);
|
||||
res.variableType.descriptor.type = sampledType->GetVarType();
|
||||
}
|
||||
|
||||
res.variableType.descriptor.rows = 1;
|
||||
|
||||
@@ -267,8 +267,12 @@ void StandardFillCBufferVariable(uint32_t dataOffset, const bytebuf &data, Shade
|
||||
const uint32_t cols = outvar.columns;
|
||||
|
||||
size_t elemByteSize = 4;
|
||||
if(type == VarType::Double)
|
||||
if(type == VarType::Double || type == VarType::ULong || type == VarType::SLong)
|
||||
elemByteSize = 8;
|
||||
else if(type == VarType::Half || type == VarType::UShort || type == VarType::SShort)
|
||||
elemByteSize = 2;
|
||||
else if(type == VarType::UByte || type == VarType::SByte)
|
||||
elemByteSize = 1;
|
||||
|
||||
// primary is the 'major' direction
|
||||
// so a matrix is a secondaryDim number of primaryDim-sized vectors
|
||||
@@ -307,7 +311,7 @@ void StandardFillCBufferVariable(uint32_t dataOffset, const bytebuf &data, Shade
|
||||
{
|
||||
ShaderVariable tmp = outvar;
|
||||
|
||||
if(type == VarType::Double)
|
||||
if(elemByteSize == 8)
|
||||
{
|
||||
for(size_t ri = 0; ri < rows; ri++)
|
||||
for(size_t ci = 0; ci < cols; ci++)
|
||||
@@ -320,6 +324,35 @@ void StandardFillCBufferVariable(uint32_t dataOffset, const bytebuf &data, Shade
|
||||
outvar.value.uv[ri * cols + ci] = tmp.value.uv[ci * rows + ri];
|
||||
}
|
||||
}
|
||||
|
||||
// special case - decode halfs in-place, sign extend signed < 4 byte integers
|
||||
if(type == VarType::Half)
|
||||
{
|
||||
for(size_t ri = 0; ri < rows; ri++)
|
||||
{
|
||||
for(size_t ci = 0; ci < cols; ci++)
|
||||
{
|
||||
outvar.value.fv[ri * cols + ci] =
|
||||
ConvertFromHalf((uint16_t)outvar.value.uv[ri * cols + ci]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(type == VarType::SShort || type == VarType::SByte)
|
||||
{
|
||||
const uint32_t testMask = (type == VarType::SShort ? 0x8000 : 0x80);
|
||||
const uint32_t extendMask = (type == VarType::SShort ? 0xffff0000 : 0xffffff00);
|
||||
|
||||
for(size_t ri = 0; ri < rows; ri++)
|
||||
{
|
||||
for(size_t ci = 0; ci < cols; ci++)
|
||||
{
|
||||
uint32_t &u = outvar.value.uv[ri * cols + ci];
|
||||
|
||||
if(u & testMask)
|
||||
u |= extendMask;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -198,6 +198,7 @@
|
||||
<ClCompile Include="vk\vk_indirect.cpp" />
|
||||
<ClCompile Include="vk\vk_overlay_test.cpp" />
|
||||
<ClCompile Include="vk\vk_sample_locations.cpp" />
|
||||
<ClCompile Include="vk\vk_adv_cbuffer_zoo.cpp" />
|
||||
<ClCompile Include="vk\vk_secondary_cmdbuf.cpp" />
|
||||
<ClCompile Include="vk\vk_video_textures.cpp" />
|
||||
<ClCompile Include="vk\vk_vs_max_desc_set.cpp" />
|
||||
|
||||
@@ -252,6 +252,9 @@
|
||||
<ClCompile Include="vk\vk_discard_rects.cpp">
|
||||
<Filter>Vulkan\demos</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vk\vk_adv_cbuffer_zoo.cpp">
|
||||
<Filter>Vulkan\demos</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="D3D11">
|
||||
|
||||
@@ -0,0 +1,399 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018-2019 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 "vk_test.h"
|
||||
|
||||
struct vec2
|
||||
{
|
||||
float x, y;
|
||||
};
|
||||
struct vec3
|
||||
{
|
||||
float x, y, z;
|
||||
};
|
||||
struct i8vec4
|
||||
{
|
||||
int8_t x, y, z, w;
|
||||
};
|
||||
struct i8vec2
|
||||
{
|
||||
int8_t x, y;
|
||||
};
|
||||
struct i16vec4
|
||||
{
|
||||
int16_t x, y, z, w;
|
||||
};
|
||||
struct i16vec3
|
||||
{
|
||||
int16_t x, y, z;
|
||||
};
|
||||
struct i16vec2
|
||||
{
|
||||
int16_t x, y;
|
||||
};
|
||||
struct mat2x3
|
||||
{
|
||||
float m[2 * 3];
|
||||
};
|
||||
|
||||
// Block memory layout
|
||||
struct S
|
||||
{
|
||||
float a;
|
||||
vec2 b;
|
||||
double c;
|
||||
float d;
|
||||
vec3 e;
|
||||
float f;
|
||||
};
|
||||
|
||||
struct S8
|
||||
{
|
||||
int8_t a;
|
||||
i8vec4 b;
|
||||
i8vec2 c[4];
|
||||
};
|
||||
|
||||
struct S16
|
||||
{
|
||||
uint16_t a;
|
||||
i16vec4 b;
|
||||
i16vec2 c[4];
|
||||
int8_t d;
|
||||
};
|
||||
|
||||
struct UBO
|
||||
{
|
||||
float a;
|
||||
vec2 b;
|
||||
vec3 c;
|
||||
float d[2];
|
||||
mat2x3 e;
|
||||
mat2x3 f[2];
|
||||
float g;
|
||||
S h;
|
||||
S i[2];
|
||||
// i8vec4 pad1;
|
||||
int8_t j;
|
||||
S8 k;
|
||||
S8 l[2];
|
||||
int8_t m;
|
||||
S16 n;
|
||||
uint8_t o;
|
||||
S16 p[2];
|
||||
uint64_t q;
|
||||
int64_t r;
|
||||
uint16_t s;
|
||||
int8_t test;
|
||||
};
|
||||
|
||||
struct VK_Adv_CBuffer_Zoo : VulkanGraphicsTest
|
||||
{
|
||||
static constexpr const char *Description =
|
||||
"Tests VK_EXT_scalar_block_layout as well as 8-bit/16-bit storage "
|
||||
"to ensure we correctly handle all types of offset and type.";
|
||||
|
||||
std::string common = R"EOSHADER(
|
||||
|
||||
#version 460 core
|
||||
|
||||
#extension GL_EXT_scalar_block_layout : require
|
||||
#extension GL_EXT_shader_16bit_storage : require
|
||||
#extension GL_EXT_shader_8bit_storage : require
|
||||
#extension GL_ARB_gpu_shader_int64 : require
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types : require
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require
|
||||
|
||||
struct v2f
|
||||
{
|
||||
vec4 pos;
|
||||
vec4 col;
|
||||
vec4 uv;
|
||||
};
|
||||
|
||||
)EOSHADER";
|
||||
|
||||
const std::string vertex = R"EOSHADER(
|
||||
|
||||
layout(location = 0) in vec3 Position;
|
||||
layout(location = 1) in vec4 Color;
|
||||
layout(location = 2) in vec2 UV;
|
||||
|
||||
layout(location = 0) out v2f vertOut;
|
||||
|
||||
// Block memory layout
|
||||
struct S
|
||||
{
|
||||
float a; // offset 0
|
||||
vec2 b; // offset 4
|
||||
double c; // offset 16
|
||||
float d; // offset 24
|
||||
vec3 e; // offset 28
|
||||
float f; // offset 40
|
||||
// size = 44, align = 8
|
||||
};
|
||||
|
||||
struct S8
|
||||
{
|
||||
int8_t a; // offset 0
|
||||
i8vec4 b; // offset 1
|
||||
i8vec2 c[4]; // offset 5
|
||||
// size = 13, align = 1
|
||||
};
|
||||
|
||||
struct S16
|
||||
{
|
||||
uint16_t a; // offset 0
|
||||
i16vec4 b; // offset 2
|
||||
i16vec2 c[4]; // offset 10
|
||||
int8_t d; // offset 26
|
||||
// size = 27, align = 2
|
||||
};
|
||||
|
||||
layout(column_major, scalar) uniform B1
|
||||
{
|
||||
float a; // offset = 0
|
||||
vec2 b; // offset = 4
|
||||
vec3 c; // offset = 12
|
||||
float d[2]; // offset = 24
|
||||
mat2x3 e; // offset = 32, takes 24 bytes, matrixstride = 12
|
||||
mat2x3 f[2]; // offset = 56, takes 48 bytes, matrixstride = 12, arraystride = 24
|
||||
float g; // offset = 104
|
||||
S h; // offset = 112 (aligned to multiple of 8)
|
||||
S i[2]; // offset = 160 (aligned to multiple of 8) stride = 48
|
||||
i8vec4 pad1; // offset = 252 C pads after array here - not required in GLSL scalar packing
|
||||
int8_t j; // offset = 256
|
||||
S8 k; // offset = 257 (aligned to multiple of 1)
|
||||
S8 l[2]; // offset = 270 (aligned to multiple of 1) stride = 13
|
||||
int8_t m; // offset = 296
|
||||
S16 n; // offset = 298 (aligned to multiple of 2)
|
||||
int8_t pad2; // offset = 325 C pads after struct here - not required in GLSL scalar packing
|
||||
uint8_t o; // offset = 326
|
||||
S16 p[2]; // offset = 328 (aligned to multiple of 2) stride = 28
|
||||
int8_t pad3; // offset = 383 C pads after struct here - not required in GLSL scalar packing
|
||||
uint64_t q; // offset = 384
|
||||
int64_t r; // offset = 392
|
||||
float16_t s; // offset = 400
|
||||
int8_t test; // offset = 402
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
vertOut.pos = vec4(Position.xyz*vec3(1,-1,1), 1);
|
||||
gl_Position = vertOut.pos;
|
||||
vertOut.uv = vec4(UV.xy, 0, 1);
|
||||
|
||||
vertOut.col = vec4(1,0,0,0);
|
||||
|
||||
if(int(test) == 42)
|
||||
vertOut.col = vec4(0,1,0,0);
|
||||
}
|
||||
|
||||
)EOSHADER";
|
||||
|
||||
const std::string pixel = R"EOSHADER(
|
||||
|
||||
layout(location = 0) in v2f vertIn;
|
||||
|
||||
layout(location = 0, index = 0) out vec4 Color;
|
||||
|
||||
void main()
|
||||
{
|
||||
Color = vertIn.col;
|
||||
}
|
||||
|
||||
)EOSHADER";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
instExts.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
|
||||
devExts.push_back(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);
|
||||
devExts.push_back(VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME);
|
||||
devExts.push_back(VK_KHR_16BIT_STORAGE_EXTENSION_NAME);
|
||||
devExts.push_back(VK_KHR_8BIT_STORAGE_EXTENSION_NAME);
|
||||
|
||||
VkPhysicalDevice16BitStorageFeaturesKHR _16bitFeatures = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR,
|
||||
};
|
||||
|
||||
VkPhysicalDevice16BitStorageFeaturesKHR _8bitFeatures = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR,
|
||||
};
|
||||
|
||||
_16bitFeatures.uniformAndStorageBuffer16BitAccess = VK_TRUE;
|
||||
_8bitFeatures.uniformAndStorageBuffer16BitAccess = VK_TRUE;
|
||||
|
||||
devInfoNext = &_8bitFeatures;
|
||||
_8bitFeatures.pNext = &_16bitFeatures;
|
||||
|
||||
features.shaderFloat64 = true;
|
||||
features.shaderInt16 = true;
|
||||
features.shaderInt64 = true;
|
||||
|
||||
// initialise, create window, create context, etc
|
||||
if(!Init(argc, argv))
|
||||
return 3;
|
||||
|
||||
_16bitFeatures.uniformAndStorageBuffer16BitAccess = VK_FALSE;
|
||||
_8bitFeatures.uniformAndStorageBuffer16BitAccess = VK_FALSE;
|
||||
|
||||
vkGetPhysicalDeviceFeatures2KHR(phys, vkh::PhysicalDeviceFeatures2KHR().next(&_16bitFeatures));
|
||||
vkGetPhysicalDeviceFeatures2KHR(phys, vkh::PhysicalDeviceFeatures2KHR().next(&_8bitFeatures));
|
||||
|
||||
// a bit late, but...
|
||||
TEST_ASSERT(_16bitFeatures.uniformAndStorageBuffer16BitAccess &&
|
||||
_8bitFeatures.uniformAndStorageBuffer16BitAccess,
|
||||
"8-bit or 16-bit uniform storage not available");
|
||||
|
||||
VkDescriptorSetLayout setlayout = createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo({
|
||||
{0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT},
|
||||
}));
|
||||
|
||||
VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo({setlayout}));
|
||||
|
||||
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
|
||||
|
||||
pipeCreateInfo.layout = layout;
|
||||
pipeCreateInfo.renderPass = swapRenderPass;
|
||||
|
||||
pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
|
||||
pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
|
||||
vkh::vertexAttr(0, 0, DefaultA2V, pos), vkh::vertexAttr(1, 0, DefaultA2V, col),
|
||||
vkh::vertexAttr(2, 0, DefaultA2V, uv),
|
||||
};
|
||||
|
||||
pipeCreateInfo.stages = {
|
||||
CompileShaderModule(common + vertex, ShaderLang::glsl, ShaderStage::vert, "main"),
|
||||
CompileShaderModule(common + pixel, ShaderLang::glsl, ShaderStage::frag, "main"),
|
||||
};
|
||||
|
||||
VkPipeline pipe = createGraphicsPipeline(pipeCreateInfo);
|
||||
|
||||
AllocatedBuffer vb(
|
||||
allocator, vkh::BufferCreateInfo(sizeof(DefaultTri), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
||||
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
|
||||
|
||||
vb.upload(DefaultTri);
|
||||
|
||||
UBO cbufferdata = {};
|
||||
|
||||
// this value is checked by the shader to ensure everything has aligned just so.
|
||||
cbufferdata.test = 42;
|
||||
|
||||
// set some other values that we can inspect ourselves manually
|
||||
cbufferdata.a = 1.0f;
|
||||
cbufferdata.b.x = 2.0f;
|
||||
cbufferdata.c.y = 3.0f;
|
||||
cbufferdata.d[0] = 4.0f;
|
||||
cbufferdata.d[1] = 5.0f;
|
||||
cbufferdata.e.m[0] = 6.0f;
|
||||
cbufferdata.e.m[1] = 7.0f;
|
||||
cbufferdata.e.m[3] = 999.0f;
|
||||
cbufferdata.f[0].m[0] = 8.0f;
|
||||
cbufferdata.f[0].m[1] = 9.0f;
|
||||
cbufferdata.f[0].m[3] = 999.0f;
|
||||
cbufferdata.f[1].m[0] = 10.0f;
|
||||
cbufferdata.f[1].m[1] = 11.0f;
|
||||
cbufferdata.f[1].m[3] = 999.0f;
|
||||
cbufferdata.g = 12.0f;
|
||||
cbufferdata.h.c = 13.0;
|
||||
cbufferdata.h.d = 14.0f;
|
||||
cbufferdata.i[0].c = 15.0;
|
||||
cbufferdata.i[1].d = 16.0f;
|
||||
cbufferdata.j = 17;
|
||||
cbufferdata.k.c[1].y = 18;
|
||||
cbufferdata.l[0].a = 19;
|
||||
cbufferdata.l[0].c[1].y = 20;
|
||||
cbufferdata.l[1].a = 21;
|
||||
cbufferdata.l[1].c[0].y = 22;
|
||||
cbufferdata.m = -23;
|
||||
cbufferdata.n.a = 65524;
|
||||
cbufferdata.n.b.w = -2424;
|
||||
cbufferdata.n.d = 25;
|
||||
cbufferdata.o = 226;
|
||||
cbufferdata.p[0].b.z = 2727;
|
||||
cbufferdata.p[0].d = 28;
|
||||
cbufferdata.p[1].b.w = 2929;
|
||||
cbufferdata.q = 30303030303030ULL;
|
||||
cbufferdata.r = -31313131313131LL;
|
||||
cbufferdata.s = 19472; // 16.25f
|
||||
|
||||
AllocatedBuffer cb(
|
||||
allocator, vkh::BufferCreateInfo(sizeof(cbufferdata), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
||||
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
|
||||
|
||||
cb.upload(&cbufferdata, sizeof(cbufferdata));
|
||||
|
||||
VkDescriptorSet descset = allocateDescriptorSet(setlayout);
|
||||
|
||||
vkh::updateDescriptorSets(
|
||||
device, {
|
||||
vkh::WriteDescriptorSet(descset, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
{vkh::DescriptorBufferInfo(cb.buffer)}),
|
||||
});
|
||||
|
||||
while(Running())
|
||||
{
|
||||
VkCommandBuffer cmd = GetCommandBuffer();
|
||||
|
||||
vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());
|
||||
|
||||
VkImage swapimg =
|
||||
StartUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
vkCmdClearColorImage(cmd, swapimg, VK_IMAGE_LAYOUT_GENERAL,
|
||||
vkh::ClearColorValue(0.4f, 0.5f, 0.6f, 1.0f), 1,
|
||||
vkh::ImageSubresourceRange());
|
||||
|
||||
vkCmdBeginRenderPass(
|
||||
cmd, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor,
|
||||
{vkh::ClearValue(0.0f, 0.0f, 0.0f, 1.0f)}),
|
||||
VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
vkh::cmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, {descset}, {});
|
||||
vkCmdSetViewport(cmd, 0, 1, &viewport);
|
||||
vkCmdSetScissor(cmd, 0, 1, &scissor);
|
||||
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
|
||||
|
||||
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
|
||||
vkCmdDraw(cmd, 3, 1, 0, 0);
|
||||
|
||||
vkCmdEndRenderPass(cmd);
|
||||
|
||||
FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
vkEndCommandBuffer(cmd);
|
||||
|
||||
Submit(0, 1, {cmd});
|
||||
|
||||
Present();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST(VK_Adv_CBuffer_Zoo);
|
||||
@@ -283,6 +283,23 @@ struct PhysicalDeviceProperties2KHR : public VkPhysicalDeviceProperties2KHR
|
||||
operator VkPhysicalDeviceProperties2KHR *() { return this; }
|
||||
};
|
||||
|
||||
struct PhysicalDeviceFeatures2KHR : public VkPhysicalDeviceFeatures2KHR
|
||||
{
|
||||
PhysicalDeviceFeatures2KHR()
|
||||
{
|
||||
sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
|
||||
pNext = NULL;
|
||||
}
|
||||
|
||||
PhysicalDeviceFeatures2KHR &next(void *next)
|
||||
{
|
||||
this->pNext = next;
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator VkPhysicalDeviceFeatures2KHR *() { return this; }
|
||||
};
|
||||
|
||||
struct SemaphoreCreateInfo : public VkSemaphoreCreateInfo
|
||||
{
|
||||
SemaphoreCreateInfo() : VkSemaphoreCreateInfo()
|
||||
|
||||
@@ -33,7 +33,7 @@ class ShaderVariableCheck:
|
||||
def type(self, type_: rd.VarType):
|
||||
if self.var.type != type_:
|
||||
raise TestFailureException("Variable {} type mismatch, expected {} but got {}"
|
||||
.format(self.var.name, type_, self.var.type))
|
||||
.format(self.var.name, str(type_), str(self.var.type)))
|
||||
|
||||
return self
|
||||
|
||||
@@ -44,9 +44,26 @@ class ShaderVariableCheck:
|
||||
raise TestFailureException("Float variable {} value mismatch, expected {} but got {}"
|
||||
.format(self.var.name, value_, self.var.value.fv[0:count]))
|
||||
else:
|
||||
if self.var.value.iv[0:count] != value_:
|
||||
raise TestFailureException("Int variable {} value mismatch, expected {} but got {}"
|
||||
.format(self.var.name, value_, self.var.value.iv[0:count]))
|
||||
# hack - check signed and unsigned values
|
||||
if self.var.value.iv[0:count] != value_ and self.var.value.uv[0:count] != value_:
|
||||
raise TestFailureException("Int variable {} value mismatch, expected {} but got {} / {}"
|
||||
.format(self.var.name, value_, self.var.value.iv[0:count],
|
||||
self.var.value.uv[0:count]))
|
||||
|
||||
return self
|
||||
|
||||
def longvalue(self, value_: list):
|
||||
count = len(value_)
|
||||
if isinstance(value_[0], float):
|
||||
if self.var.value.dv[0:count] != value_:
|
||||
raise TestFailureException("Float variable {} value mismatch, expected {} but got {}"
|
||||
.format(self.var.name, value_, self.var.value.dv[0:count]))
|
||||
else:
|
||||
# hack - check signed and unsigned values
|
||||
if self.var.value.s64v[0:count] != value_ and self.var.value.u64v[0:count] != value_:
|
||||
raise TestFailureException("Int variable {} value mismatch, expected {} but got {} / {}"
|
||||
.format(self.var.name, value_, self.var.value.s64v[0:count],
|
||||
self.var.value.u64v[0:count]))
|
||||
|
||||
return self
|
||||
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
import rdtest
|
||||
import renderdoc as rd
|
||||
|
||||
|
||||
class VK_Adv_CBuffer_Zoo(rdtest.TestCase):
|
||||
def get_capture(self):
|
||||
return rdtest.run_and_capture("demos_x64", "VK_Adv_CBuffer_Zoo", 5)
|
||||
|
||||
def check_capture(self):
|
||||
draw = self.find_draw("Draw")
|
||||
|
||||
self.check(draw is not None)
|
||||
|
||||
self.controller.SetFrameEvent(draw.eventId, False)
|
||||
|
||||
# Make an output so we can pick pixels
|
||||
out: rd.ReplayOutput = self.controller.CreateOutput(rd.CreateHeadlessWindowingData(), rd.ReplayOutputType.Texture)
|
||||
|
||||
self.check(out is not None)
|
||||
|
||||
out.SetDimensions(100, 100)
|
||||
|
||||
pipe: rd.PipeState = self.controller.GetPipelineState()
|
||||
|
||||
stage = rd.ShaderStage.Vertex
|
||||
|
||||
cbuf: rd.BoundCBuffer = pipe.GetConstantBuffer(stage, 0, 0)
|
||||
|
||||
var_check = rdtest.ConstantBufferChecker(
|
||||
self.controller.GetCBufferVariableContents(pipe.GetShader(stage),
|
||||
pipe.GetShaderEntryPoint(stage), 0,
|
||||
cbuf.resourceId, cbuf.byteOffset))
|
||||
|
||||
# For more detailed reference for the below checks, see the commented definition of the cbuffer
|
||||
# in the shader source code in the demo itself
|
||||
|
||||
# float a;
|
||||
var_check.check('a').cols(1).rows(1).type(rd.VarType.Float).value([1.0])
|
||||
|
||||
# vec2 b;
|
||||
var_check.check('b').cols(2).rows(1).type(rd.VarType.Float).value([2.0, 0.0])
|
||||
|
||||
# vec3 c;
|
||||
var_check.check('c').cols(3).rows(1).type(rd.VarType.Float).value([0.0, 3.0])
|
||||
|
||||
# float d[2];
|
||||
var_check.check('d').cols(0).rows(0).arraySize(2).members({
|
||||
0: lambda x: x.cols(1).rows(1).type(rd.VarType.Float).value([4.0]),
|
||||
1: lambda x: x.cols(1).rows(1).type(rd.VarType.Float).value([5.0]),
|
||||
})
|
||||
|
||||
# mat2x3 e;
|
||||
var_check.check('e').cols(2).rows(3).column_major().type(rd.VarType.Float).value([6.0, 999.0,
|
||||
7.0, 0.0,
|
||||
0.0, 0.0])
|
||||
|
||||
# mat2x3 f[2];
|
||||
var_check.check('f').cols(0).rows(0).arraySize(2).members({
|
||||
0: lambda x: x.cols(2).rows(3).column_major().type(rd.VarType.Float).value([8.0, 999.0,
|
||||
9.0, 0.0,
|
||||
0.0, 0.0]),
|
||||
1: lambda x: x.cols(2).rows(3).column_major().type(rd.VarType.Float).value([10.0, 999.0,
|
||||
11.0, 0.0,
|
||||
0.0, 0.0]),
|
||||
})
|
||||
|
||||
# float g;
|
||||
var_check.check('g').cols(1).rows(1).type(rd.VarType.Float).value([12.0])
|
||||
|
||||
# struct S
|
||||
# {
|
||||
# float a;
|
||||
# vec2 b;
|
||||
# double c;
|
||||
# float d;
|
||||
# vec3 e;
|
||||
# float f;
|
||||
# };
|
||||
# S h;
|
||||
|
||||
var_check.check('h').cols(0).rows(0).structSize(6).members({
|
||||
'a': lambda x: x.cols(1).rows(1).type(rd.VarType.Float ).value([0.0]),
|
||||
'b': lambda x: x.cols(2).rows(1).type(rd.VarType.Float ).value([0.0]),
|
||||
'c': lambda x: x.cols(1).rows(1).type(rd.VarType.Double).longvalue([13.0]),
|
||||
'd': lambda x: x.cols(1).rows(1).type(rd.VarType.Float ).value([14.0]),
|
||||
'e': lambda x: x.cols(3).rows(1).type(rd.VarType.Float ).value([0.0]),
|
||||
'f': lambda x: x.cols(1).rows(1).type(rd.VarType.Float ).value([0.0]),
|
||||
})
|
||||
|
||||
# S i[2];
|
||||
var_check.check('i').cols(0).rows(0).arraySize(2).members({
|
||||
0: lambda x: x.cols(0).rows(0).structSize(6).members({
|
||||
'a': lambda x: x.cols(1).rows(1).type(rd.VarType.Float ).value([0.0]),
|
||||
'b': lambda x: x.cols(2).rows(1).type(rd.VarType.Float ).value([0.0]),
|
||||
'c': lambda x: x.cols(1).rows(1).type(rd.VarType.Double).longvalue([15.0]),
|
||||
'd': lambda x: x.cols(1).rows(1).type(rd.VarType.Float ).value([0.0]),
|
||||
'e': lambda x: x.cols(3).rows(1).type(rd.VarType.Float ).value([0.0]),
|
||||
'f': lambda x: x.cols(1).rows(1).type(rd.VarType.Float ).value([0.0]),
|
||||
}),
|
||||
1: lambda x: x.cols(0).rows(0).structSize(6).members({
|
||||
'a': lambda x: x.cols(1).rows(1).type(rd.VarType.Float ).value([0.0]),
|
||||
'b': lambda x: x.cols(2).rows(1).type(rd.VarType.Float ).value([0.0]),
|
||||
'c': lambda x: x.cols(1).rows(1).type(rd.VarType.Double).longvalue([0.0]),
|
||||
'd': lambda x: x.cols(1).rows(1).type(rd.VarType.Float ).value([16.0]),
|
||||
'e': lambda x: x.cols(3).rows(1).type(rd.VarType.Float ).value([0.0]),
|
||||
'f': lambda x: x.cols(1).rows(1).type(rd.VarType.Float ).value([0.0]),
|
||||
}),
|
||||
})
|
||||
|
||||
# i8vec4 pad1;
|
||||
var_check.check('pad1')
|
||||
|
||||
# int8_t j;
|
||||
var_check.check('j').cols(1).rows(1).type(rd.VarType.SByte).value([17])
|
||||
|
||||
# struct S8
|
||||
# {
|
||||
# int8_t a;
|
||||
# i8vec4 b;
|
||||
# i8vec2 c[4];
|
||||
# };
|
||||
# S8 k;
|
||||
var_check.check('k').cols(0).rows(0).structSize(3).members({
|
||||
'a': lambda x: x.cols(1).rows(1).type(rd.VarType.SByte).value([0]),
|
||||
'b': lambda x: x.cols(4).rows(1).type(rd.VarType.SByte).value([0, 0, 0, 0]),
|
||||
'c': lambda x: x.cols(0).rows(0).arraySize(4).members({
|
||||
0: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 0]),
|
||||
1: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 18]),
|
||||
2: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 0]),
|
||||
3: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 0]),
|
||||
}),
|
||||
})
|
||||
|
||||
# S8 l[2];
|
||||
var_check.check('l').cols(0).rows(0).arraySize(2).members({
|
||||
0: lambda x: x.cols(0).rows(0).structSize(3).members({
|
||||
'a': lambda x: x.cols(1).rows(1).type(rd.VarType.SByte).value([19]),
|
||||
'b': lambda x: x.cols(4).rows(1).type(rd.VarType.SByte).value([0, 0, 0, 0]),
|
||||
'c': lambda x: x.cols(0).rows(0).arraySize(4).members({
|
||||
0: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 0]),
|
||||
1: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 20]),
|
||||
2: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 0]),
|
||||
3: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 0]),
|
||||
}),
|
||||
}),
|
||||
1: lambda x: x.cols(0).rows(0).structSize(3).members({
|
||||
'a': lambda x: x.cols(1).rows(1).type(rd.VarType.SByte).value([21]),
|
||||
'b': lambda x: x.cols(4).rows(1).type(rd.VarType.SByte).value([0, 0, 0, 0]),
|
||||
'c': lambda x: x.cols(0).rows(0).arraySize(4).members({
|
||||
0: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 22]),
|
||||
1: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 0]),
|
||||
2: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 0]),
|
||||
3: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 0]),
|
||||
}),
|
||||
})
|
||||
})
|
||||
|
||||
# int8_t m;
|
||||
var_check.check('m').cols(1).rows(1).type(rd.VarType.SByte).value([-23])
|
||||
|
||||
# struct S16
|
||||
# {
|
||||
# uint16_t a;
|
||||
# i16vec4 b;
|
||||
# i16vec2 c[4];
|
||||
# int8_t d;
|
||||
# };
|
||||
# S16 n;
|
||||
var_check.check('n').cols(0).rows(0).structSize(4).members({
|
||||
'a': lambda x: x.cols(1).rows(1).type(rd.VarType.UShort).value([65524]),
|
||||
'b': lambda x: x.cols(4).rows(1).type(rd.VarType.SShort).value([0, 0, 0, -2424]),
|
||||
'c': lambda x: x.cols(0).rows(0).arraySize(4).members({
|
||||
0: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
|
||||
1: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
|
||||
2: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
|
||||
3: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
|
||||
}),
|
||||
'd': lambda x: x.cols(1).rows(1).type(rd.VarType.SByte).value([25]),
|
||||
})
|
||||
|
||||
# i8vec4 pad2;
|
||||
var_check.check('pad2')
|
||||
|
||||
# uint8_t o;
|
||||
var_check.check('o').cols(1).rows(1).type(rd.VarType.UByte).value([226])
|
||||
|
||||
# S16 p[2];
|
||||
var_check.check('p').cols(0).rows(0).arraySize(2).members({
|
||||
0: lambda x: x.cols(0).rows(0).structSize(4).members({
|
||||
'a': lambda x: x.cols(1).rows(1).type(rd.VarType.UShort).value([0]),
|
||||
'b': lambda x: x.cols(4).rows(1).type(rd.VarType.SShort).value([0, 0, 2727, 0]),
|
||||
'c': lambda x: x.cols(0).rows(0).arraySize(4).members({
|
||||
0: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
|
||||
1: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
|
||||
2: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
|
||||
3: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
|
||||
}),
|
||||
'd': lambda x: x.cols(1).rows(1).type(rd.VarType.SByte).value([28]),
|
||||
}),
|
||||
1: lambda x: x.cols(0).rows(0).structSize(4).members({
|
||||
'a': lambda x: x.cols(1).rows(1).type(rd.VarType.UShort).value([0]),
|
||||
'b': lambda x: x.cols(4).rows(1).type(rd.VarType.SShort).value([0, 0, 0, 2929]),
|
||||
'c': lambda x: x.cols(0).rows(0).arraySize(4).members({
|
||||
0: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
|
||||
1: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
|
||||
2: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
|
||||
3: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
|
||||
}),
|
||||
'd': lambda x: x.cols(1).rows(1).type(rd.VarType.SByte).value([0]),
|
||||
})
|
||||
})
|
||||
|
||||
# i8vec4 pad3;
|
||||
var_check.check('pad3')
|
||||
|
||||
# uint64_t q;
|
||||
var_check.check('q').cols(1).rows(1).type(rd.VarType.ULong).longvalue([30303030303030])
|
||||
|
||||
# int64_t r;
|
||||
var_check.check('r').cols(1).rows(1).type(rd.VarType.SLong).longvalue([-31313131313131])
|
||||
|
||||
# half s;
|
||||
var_check.check('s').cols(1).rows(1).type(rd.VarType.Half).value([16.25])
|
||||
|
||||
# int8_t test;
|
||||
var_check.check('test').cols(1).rows(1).type(rd.VarType.SByte).value([42])
|
||||
|
||||
var_check.done()
|
||||
|
||||
rdtest.log.success("CBuffer variables are as expected")
|
||||
|
||||
tex = rd.TextureDisplay()
|
||||
tex.resourceId = pipe.GetOutputTargets()[0].resourceId
|
||||
out.SetTextureDisplay(tex)
|
||||
|
||||
texdetails = self.get_texture(tex.resourceId)
|
||||
|
||||
picked: rd.PixelValue = out.PickPixel(tex.resourceId, False,
|
||||
int(texdetails.width / 2), int(texdetails.height / 2), 0, 0, 0)
|
||||
|
||||
# We just output green from the shader when the value is as expected
|
||||
if not rdtest.value_compare(picked.floatValue, [0.0, 1.0, 0.0, 0.0]):
|
||||
raise rdtest.TestFailureException("Picked value {} doesn't match expectation".format(picked.floatValue))
|
||||
|
||||
rdtest.log.success("Picked value is as expected")
|
||||
|
||||
out.Shutdown()
|
||||
Reference in New Issue
Block a user