Fix some cases handling arrays of matrices

* We also pick the output pixel in the CBuffer_Zoo tests to ensure the API
  agrees with our interpretation of the data.
* Follow-up commit will tidy D3D cbuffer code that needs it.
This commit is contained in:
baldurk
2019-02-07 15:23:05 +00:00
parent cf0353e630
commit 351c75e006
18 changed files with 970 additions and 172 deletions
+6 -1
View File
@@ -609,7 +609,8 @@ struct ShaderVariableDescriptor
{
return type == o.type && rows == o.rows && columns == o.columns &&
rowMajorStorage == o.rowMajorStorage && elements == o.elements &&
arrayByteStride == o.arrayByteStride && name == o.name;
arrayByteStride == o.arrayByteStride && matrixByteStride == o.matrixByteStride &&
name == o.name;
}
bool operator<(const ShaderVariableDescriptor &o) const
{
@@ -625,6 +626,8 @@ struct ShaderVariableDescriptor
return elements < o.elements;
if(!(arrayByteStride == o.arrayByteStride))
return arrayByteStride < o.arrayByteStride;
if(!(matrixByteStride == o.matrixByteStride))
return matrixByteStride < o.matrixByteStride;
if(!(name == o.name))
return name < o.name;
return false;
@@ -635,6 +638,8 @@ struct ShaderVariableDescriptor
uint8_t rows;
DOCUMENT("The number of columns in this matrix.");
uint8_t columns;
DOCUMENT("The number of bytes between the start of one column/row in a matrix and the next.");
uint8_t matrixByteStride;
DOCUMENT("``True`` if the matrix is stored as row major instead of column major.");
bool rowMajorStorage;
DOCUMENT("The number of elements in the array, or 1 if it's not an array.");
+24 -30
View File
@@ -605,6 +605,7 @@ void D3D11DebugManager::FillCBufferVariables(const std::string &prefix, size_t &
ShaderVariable &var = outvars[outIdx];
bool isArray = invars[v].type.descriptor.elements > 1;
bool isMatrix = rows > 1 && cols > 1;
if(rows * elems == 1)
{
@@ -667,7 +668,7 @@ void D3D11DebugManager::FillCBufferVariables(const std::string &prefix, size_t &
std::vector<ShaderVariable> varmembers;
std::vector<ShaderVariable> *out = &outvars;
size_t rowCopy = 1;
uint32_t rowCopy = 1;
uint32_t registers = rows;
uint32_t regLen = cols;
@@ -683,8 +684,13 @@ void D3D11DebugManager::FillCBufferVariables(const std::string &prefix, size_t &
out = &varmembers;
varmembers.resize(elems);
rowCopy = rows;
rows = 1;
registers = 1;
if(columnMajor)
{
regLen = rows;
rowCopy = cols;
}
}
else
{
@@ -708,38 +714,22 @@ void D3D11DebugManager::FillCBufferVariables(const std::string &prefix, size_t &
StringFormat::snprintf(buf, 63, "[%d]", r);
(*out)[outIdx + r].name = base + buf;
(*out)[outIdx + r].rows = (uint32_t)rowCopy;
(*out)[outIdx + r].rows = flattenVec4s ? rowCopy : rows;
(*out)[outIdx + r].type = type;
(*out)[outIdx + r].isStruct = false;
(*out)[outIdx + r].columns = regLen;
(*out)[outIdx + r].columns = flattenVec4s ? regLen : cols;
(*out)[outIdx + r].rowMajor = !columnMajor;
size_t totalSize = 0;
if(flattenVec4s)
{
totalSize = elemByteSize * regLen;
}
else
{
// in a matrix, each major element before the last takes up a full
// vec4 at least
size_t vecSize = elemByteSize * 4;
if(columnMajor)
totalSize = vecSize * (cols - 1) + elemByteSize * rowCopy;
else
totalSize = vecSize * (rowCopy - 1) + elemByteSize * cols;
}
size_t regSize = elemByteSize * regLen;
if((rowDataOffset % sizeof(Vec4f) != 0) &&
(rowDataOffset / sizeof(Vec4f) != (rowDataOffset + totalSize) / sizeof(Vec4f)))
(rowDataOffset / sizeof(Vec4f) != (rowDataOffset + regSize) / sizeof(Vec4f)))
{
rowDataOffset = AlignUp(rowDataOffset, sizeof(Vec4f));
}
// arrays are also aligned to the nearest Vec4f for each element
if(!flattenVec4s && isArray)
// arrays/matrices are also aligned to the nearest Vec4f for each element
if(!flattenVec4s && (isArray || isMatrix))
{
rowDataOffset = AlignUp(rowDataOffset, sizeof(Vec4f));
}
@@ -748,19 +738,23 @@ void D3D11DebugManager::FillCBufferVariables(const std::string &prefix, size_t &
{
const byte *d = &data[rowDataOffset];
memcpy(&((*out)[outIdx + r].value.uv[0]), d,
RDCMIN(data.size() - rowDataOffset, totalSize));
for(uint32_t reg = 0; reg < rowCopy; reg++)
{
if(rowDataOffset + reg * sizeof(Vec4f) + regSize <= data.size())
{
memcpy(&((*out)[outIdx + r].value.uv[reg * regLen]), d + reg * sizeof(Vec4f),
regSize);
}
}
if(!flattenVec4s && columnMajor)
{
ShaderVariable tmp = (*out)[outIdx + r];
size_t transposeRows = rowCopy > 1 ? 4 : 1;
// transpose
for(size_t ri = 0; ri < transposeRows; ri++)
for(size_t ri = 0; ri < rows; ri++)
for(size_t ci = 0; ci < cols; ci++)
(*out)[outIdx + r].value.uv[ri * cols + ci] = tmp.value.uv[ci * transposeRows + ri];
(*out)[outIdx + r].value.uv[ri * cols + ci] = tmp.value.uv[ci * rows + ri];
}
}
+24 -30
View File
@@ -822,6 +822,7 @@ void D3D12DebugManager::FillCBufferVariables(const std::string &prefix, size_t &
ShaderVariable &var = outvars[outIdx];
bool isArray = invars[v].type.descriptor.elements > 1;
bool isMatrix = rows > 1 && cols > 1;
if(rows * elems == 1)
{
@@ -884,7 +885,7 @@ void D3D12DebugManager::FillCBufferVariables(const std::string &prefix, size_t &
vector<ShaderVariable> varmembers;
vector<ShaderVariable> *out = &outvars;
size_t rowCopy = 1;
uint32_t rowCopy = 1;
uint32_t registers = rows;
uint32_t regLen = cols;
@@ -900,8 +901,13 @@ void D3D12DebugManager::FillCBufferVariables(const std::string &prefix, size_t &
out = &varmembers;
varmembers.resize(elems);
rowCopy = rows;
rows = 1;
registers = 1;
if(columnMajor)
{
regLen = rows;
rowCopy = cols;
}
}
else
{
@@ -925,38 +931,22 @@ void D3D12DebugManager::FillCBufferVariables(const std::string &prefix, size_t &
StringFormat::snprintf(buf, 63, "[%d]", r);
(*out)[outIdx + r].name = base + buf;
(*out)[outIdx + r].rows = (uint32_t)rowCopy;
(*out)[outIdx + r].rows = flatten ? rowCopy : rows;
(*out)[outIdx + r].type = type;
(*out)[outIdx + r].isStruct = false;
(*out)[outIdx + r].columns = regLen;
(*out)[outIdx + r].columns = flatten ? regLen : cols;
(*out)[outIdx + r].rowMajor = !columnMajor;
size_t totalSize = 0;
if(flatten)
{
totalSize = elemByteSize * regLen;
}
else
{
// in a matrix, each major element before the last takes up a full
// vec4 at least
size_t vecSize = elemByteSize * 4;
if(columnMajor)
totalSize = vecSize * (cols - 1) + elemByteSize * rowCopy;
else
totalSize = vecSize * (rowCopy - 1) + elemByteSize * cols;
}
size_t regSize = elemByteSize * regLen;
if((rowDataOffset % sizeof(Vec4f) != 0) &&
(rowDataOffset / sizeof(Vec4f) != (rowDataOffset + totalSize) / sizeof(Vec4f)))
(rowDataOffset / sizeof(Vec4f) != (rowDataOffset + regSize) / sizeof(Vec4f)))
{
rowDataOffset = AlignUp(rowDataOffset, sizeof(Vec4f));
}
// arrays are also aligned to the nearest Vec4f for each element
if(!flatten && isArray)
// arrays/matrices are also aligned to the nearest Vec4f for each element
if(!flatten && (isArray || isMatrix))
{
rowDataOffset = AlignUp(rowDataOffset, sizeof(Vec4f));
}
@@ -965,19 +955,23 @@ void D3D12DebugManager::FillCBufferVariables(const std::string &prefix, size_t &
{
const byte *d = &data[rowDataOffset];
memcpy(&((*out)[outIdx + r].value.uv[0]), d,
RDCMIN(data.size() - rowDataOffset, totalSize));
for(uint32_t reg = 0; reg < rowCopy; reg++)
{
if(rowDataOffset + reg * sizeof(Vec4f) + regSize <= data.size())
{
memcpy(&((*out)[outIdx + r].value.uv[reg * regLen]), d + reg * sizeof(Vec4f),
regSize);
}
}
if(!flatten && columnMajor)
{
ShaderVariable tmp = (*out)[outIdx + r];
size_t transposeRows = rowCopy > 1 ? 4 : 1;
// transpose
for(size_t ri = 0; ri < transposeRows; ri++)
for(size_t ri = 0; ri < rows; ri++)
for(size_t ci = 0; ci < cols; ci++)
(*out)[outIdx + r].value.uv[ri * cols + ci] = tmp.value.uv[ci * transposeRows + ri];
(*out)[outIdx + r].value.uv[ri * cols + ci] = tmp.value.uv[ci * rows + ri];
}
}
+5 -10
View File
@@ -2043,21 +2043,15 @@ void GLReplay::FillCBufferVariables(GLuint prog, bool bufferBacked, std::string
}
else
{
GLenum props[] = {eGL_OFFSET, eGL_MATRIX_STRIDE, eGL_ARRAY_STRIDE, eGL_LOCATION};
GLint values[] = {0, 0, 0, 0};
GLenum props[] = {bufferBacked ? eGL_OFFSET : eGL_LOCATION};
GLint values[] = {0};
GL.glGetProgramResourceiv(prog, eGL_UNIFORM, idx, ARRAY_COUNT(props), props,
ARRAY_COUNT(props), NULL, values);
if(!bufferBacked)
{
values[0] = values[3];
values[2] = 1;
}
if(desc.elements == 0)
{
FillCBufferValue(prog, bufferBacked, values[0], values[1], data, var);
FillCBufferValue(prog, bufferBacked, values[0], desc.matrixByteStride, data, var);
}
else
{
@@ -2072,7 +2066,8 @@ void GLReplay::FillCBufferVariables(GLuint prog, bool bufferBacked, std::string
else
el.name = StringFormat::Fmt("[%u]", a);
FillCBufferValue(prog, bufferBacked, values[0] + values[2] * a, values[1], data, el);
FillCBufferValue(prog, bufferBacked, values[0] + desc.arrayByteStride * a,
desc.matrixByteStride, data, el);
el.isStruct = false;
+10 -5
View File
@@ -526,14 +526,14 @@ void ReconstructVarTree(GLenum query, GLuint sepProg, GLuint varIdx, GLint numPa
rdcarray<ShaderConstant> *parentBlocks,
rdcarray<ShaderConstant> *defaultBlock)
{
const size_t numProps = 8;
const size_t numProps = 9;
GLenum resProps[numProps] = {eGL_TYPE, eGL_NAME_LENGTH, eGL_LOCATION, eGL_BLOCK_INDEX,
eGL_ARRAY_SIZE, eGL_OFFSET, eGL_IS_ROW_MAJOR, eGL_ARRAY_STRIDE};
GLenum resProps[numProps] = {eGL_TYPE, eGL_NAME_LENGTH, eGL_LOCATION,
eGL_BLOCK_INDEX, eGL_ARRAY_SIZE, eGL_OFFSET,
eGL_IS_ROW_MAJOR, eGL_ARRAY_STRIDE, eGL_MATRIX_STRIDE};
// GL_LOCATION not valid for buffer variables (it's only used if offset comes back -1, which will
// never
// happen for buffer variables)
// never happen for buffer variables)
if(query == eGL_BUFFER_VARIABLE)
resProps[2] = eGL_OFFSET;
@@ -723,6 +723,7 @@ void ReconstructVarTree(GLenum query, GLuint sepProg, GLuint varIdx, GLint numPa
var.type.descriptor.rowMajorStorage = (values[6] > 0);
var.type.descriptor.arrayByteStride = values[7];
var.type.descriptor.matrixByteStride = (uint8_t)values[8];
var.name.resize(values[1] - 1);
GL.glGetProgramResourceName(sepProg, query, varIdx, values[1], NULL, &var.name[0]);
@@ -816,6 +817,7 @@ void ReconstructVarTree(GLenum query, GLuint sepProg, GLuint varIdx, GLint numPa
parentVar.type.descriptor.elements =
isarray && !multiDimArray ? RDCMAX(1U, uint32_t(arrayIdx + 1)) : 0;
parentVar.type.descriptor.arrayByteStride = topLevelStride;
parentVar.type.descriptor.matrixByteStride = 0;
bool found = false;
@@ -982,6 +984,7 @@ void MakeShaderReflection(GLenum shadType, GLuint sepProg, ShaderReflection &ref
res.variableType.descriptor.elements = 0;
res.variableType.descriptor.rowMajorStorage = false;
res.variableType.descriptor.arrayByteStride = 0;
res.variableType.descriptor.matrixByteStride = 0;
// float samplers
if(values[0] == eGL_SAMPLER_BUFFER)
@@ -1525,6 +1528,7 @@ void MakeShaderReflection(GLenum shadType, GLuint sepProg, ShaderReflection &ref
res.variableType.descriptor.elements = len;
res.variableType.descriptor.rowMajorStorage = false;
res.variableType.descriptor.arrayByteStride = 0;
res.variableType.descriptor.matrixByteStride = 0;
res.variableType.descriptor.name = "buffer";
res.variableType.descriptor.type = VarType::UInt;
res.bindPoint = (int32_t)rwresources.size();
@@ -1598,6 +1602,7 @@ void MakeShaderReflection(GLenum shadType, GLuint sepProg, ShaderReflection &ref
paddingVar.type.descriptor.elements = 1;
paddingVar.type.descriptor.rowMajorStorage = false;
paddingVar.type.descriptor.arrayByteStride = 0;
paddingVar.type.descriptor.matrixByteStride = 0;
paddingVar.type.descriptor.name = StringFormat::Fmt("uint%u", padding);
members[ssbo][0].type.members.push_back(paddingVar);
+6 -12
View File
@@ -55,20 +55,14 @@ static ShaderVariableType MakeShaderVariableType(DXBC::CBufferVariableType type,
ret.descriptor.rowMajorStorage = (type.descriptor.varClass == DXBC::CLASS_MATRIX_ROWS);
uint32_t baseElemSize = (ret.descriptor.type == VarType::Double) ? 8 : 4;
// in D3D matrices always take up a float4 per row/column
ret.descriptor.matrixByteStride = uint8_t(baseElemSize * 4);
if(ret.descriptor.rowMajorStorage)
{
uint32_t primary = ret.descriptor.rows;
if(primary == 3)
primary = 4;
ret.descriptor.arrayByteStride = baseElemSize * primary * ret.descriptor.columns;
}
ret.descriptor.arrayByteStride = ret.descriptor.matrixByteStride * ret.descriptor.rows;
else
{
uint32_t primary = ret.descriptor.columns;
if(primary == 3)
primary = 4;
ret.descriptor.arrayByteStride = baseElemSize * primary * ret.descriptor.rows;
}
ret.descriptor.arrayByteStride = ret.descriptor.matrixByteStride * ret.descriptor.columns;
uint32_t o = offset;
@@ -145,6 +145,8 @@ void SPIRVFillCBufferVariables(const rdcarray<ShaderConstant> &invars,
ShaderVariable &var = outvars[outIdx];
const uint32_t matStride = invars[v].type.descriptor.matrixByteStride;
if(!isArray)
{
outvars[outIdx].rows = rows;
@@ -161,7 +163,7 @@ void SPIRVFillCBufferVariables(const rdcarray<ShaderConstant> &invars,
for(uint32_t c = 0; c < cols; c++)
{
size_t srcoffs = 4 * elemByteSize * c;
size_t srcoffs = matStride * c;
size_t dstoffs = rows * elemByteSize * c;
memcpy((byte *)(tmp) + dstoffs, d + srcoffs,
RDCMIN(data.size() - dataOffset + srcoffs, elemByteSize * rows));
@@ -176,7 +178,7 @@ void SPIRVFillCBufferVariables(const rdcarray<ShaderConstant> &invars,
{
for(uint32_t r = 0; r < rows; r++)
{
size_t srcoffs = 4 * elemByteSize * r;
size_t srcoffs = matStride * r;
size_t dstoffs = cols * elemByteSize * r;
memcpy((byte *)(&outvars[outIdx].value.uv[0]) + dstoffs, d + srcoffs,
RDCMIN(data.size() - dataOffset + srcoffs, elemByteSize * cols));
@@ -201,7 +203,7 @@ void SPIRVFillCBufferVariables(const rdcarray<ShaderConstant> &invars,
// so we copy secondaryDim number of primaryDim-sized elements
uint32_t primaryDim = cols;
uint32_t secondaryDim = rows;
if(isMatrix && rowMajor)
if(isMatrix && !rowMajor)
{
primaryDim = rows;
secondaryDim = cols;
@@ -229,10 +231,7 @@ void SPIRVFillCBufferVariables(const rdcarray<ShaderConstant> &invars,
// when we transpose
for(uint32_t s = 0; s < secondaryDim; s++)
{
uint32_t matStride = primaryDim;
if(matStride == 3)
matStride = 4;
memcpy(&(varmembers[e].value.uv[primaryDim * s]), d + matStride * elemByteSize * s,
memcpy(&(varmembers[e].value.uv[primaryDim * s]), d + matStride * s,
RDCMIN(data.size() - rowDataOffset, elemByteSize * primaryDim));
}
@@ -3514,6 +3514,7 @@ void MakeConstantBlockVariable(ShaderConstant &outConst, SPVTypeData *type, cons
outConst.type.descriptor.elements = 1;
outConst.type.descriptor.arrayByteStride = 0;
outConst.type.descriptor.matrixByteStride = 0;
if(type->type == SPVTypeData::eArray)
{
@@ -3526,7 +3527,7 @@ void MakeConstantBlockVariable(ShaderConstant &outConst, SPVTypeData *type, cons
outConst.type.descriptor.elements = type->arraySize;
}
bool foundArrayStride = false;
bool foundArrayStride = false, foundMatrixStride = false;
for(size_t d = 0; d < decorations.size(); d++)
{
@@ -3534,8 +3535,15 @@ void MakeConstantBlockVariable(ShaderConstant &outConst, SPVTypeData *type, cons
{
outConst.type.descriptor.arrayByteStride = decorations[d].val;
foundArrayStride = true;
break;
}
if(decorations[d].decoration == spv::DecorationMatrixStride)
{
outConst.type.descriptor.matrixByteStride = (uint8_t)decorations[d].val;
foundMatrixStride = true;
}
if(foundMatrixStride && foundArrayStride)
break;
}
for(size_t d = 0; !foundArrayStride && type->decorations && d < type->decorations->size(); d++)
@@ -3547,6 +3555,15 @@ void MakeConstantBlockVariable(ShaderConstant &outConst, SPVTypeData *type, cons
}
}
for(size_t d = 0; !foundMatrixStride && type->decorations && d < type->decorations->size(); d++)
{
if((*type->decorations)[d].decoration == spv::DecorationMatrixStride)
{
outConst.type.descriptor.matrixByteStride = (uint8_t)(*type->decorations)[d].val;
break;
}
}
type = type->baseType;
}
@@ -3566,10 +3583,9 @@ void MakeConstantBlockVariable(ShaderConstant &outConst, SPVTypeData *type, cons
for(size_t d = 0; d < decorations.size(); d++)
{
if(decorations[d].decoration == spv::DecorationRowMajor)
{
outConst.type.descriptor.rowMajorStorage = true;
break;
}
if(decorations[d].decoration == spv::DecorationMatrixStride)
outConst.type.descriptor.matrixByteStride = (uint8_t)decorations[d].val;
}
if(type->type == SPVTypeData::eMatrix)
+1
View File
@@ -176,6 +176,7 @@ void DoSerialise(SerialiserType &ser, ShaderVariableDescriptor &el)
SERIALISE_MEMBER(type);
SERIALISE_MEMBER(rows);
SERIALISE_MEMBER(columns);
SERIALISE_MEMBER(matrixByteStride);
SERIALISE_MEMBER(rowMajorStorage);
SERIALISE_MEMBER(elements);
SERIALISE_MEMBER(arrayByteStride);
+75 -2
View File
@@ -153,12 +153,85 @@ cbuffer consts : register(b0)
// .c[3] = { { 320, 321, 322 }, 323 }
// }
float4 test; // {324, 325, 326, 327}
column_major float3x2 ac; // covers 2 float4s with padding at end of each column (but not row)
// row0: {324, 328}
// row1: {325, 329}
// row2: {326, 330}
// <327, 331>
row_major float3x2 ad; // covers 3 float4s with padding at end of each row (but not column)
// row0: {332, 333}, <334, 335>
// row1: {336, 337}, <338, 339>
// row2: {340, 341}, <342, 343>
column_major float3x2 ae[2]; // covers 2 float4s with padding at end of each column (but not row)
// [0] = {
// row0: {344, 348}
// row1: {345, 349}
// row2: {346, 350}
// <347, 351>
// }
// [1] = {
// row0: {352, 356}
// row1: {353, 357}
// row2: {354, 358}
// <355, 359>
// }
row_major float3x2 af[2]; // covers 3 float4s with padding at end of each row (but not column)
// [0] = {
// row0: {360, 361}, <362, 363>
// row1: {364, 365}, <366, 367>
// row2: {368, 369}, <370, 371>
// }
// [1] = {
// row0: {372, 373}, <374, 375>
// row1: {376, 377}, <378, 379>
// row2: {380, 381},
// }
float2 dummy9; // consumes leftovers from above array = {382, 383}
float2 dummy10; // should have padding at the end = {384, 385}, <386, 387>
row_major float2x2 ag; // each row is aligned to float4:
// row0: {388, 389}, <390, 391>
// row1: {392, 393},
float2 dummy11; // consumes leftovers from above matrix = {394, 395}
float2 dummy12; // should have padding at the end = {396, 397}, <398, 399>
column_major float2x2 ah; // each column is aligned to float4:
// row0: {400, 404}
// row1: {401, 405}
// <402, 406>
// <403, 407>
row_major float2x2 ai[2]; // [0] = {
// row0: {408, 409}, <410, 411>
// row1: {412, 413}, <414, 415>
// }
// [1] = {
// row0: {416, 417}, <418, 419>
// row1: {420, 421}, <422, 423>
// }
column_major float2x2 aj[2]; // [0] = {
// row0: {424, 428}
// row1: {425, 429}
// <426, 430>
// <427, 431>
// }
// [1] = {
// row0: {432, 436}
// row1: {433, 437}
// <434, 438>
// <435, 439>
// }
float4 test; // {440, 441, 442, 443}
};
float4 main() : SV_Target0
{
return test;
return test + float4(0.1f, 0.0f, 0.0f, 0.0f);
}
)EOSHADER";
+88 -6
View File
@@ -153,12 +153,85 @@ cbuffer consts : register(b0)
// .c[3] = { { 320, 321, 322 }, 323 }
// }
float4 test; // {324, 325, 326, 327}
column_major float3x2 ac; // covers 2 float4s with padding at end of each column (but not row)
// row0: {324, 328}
// row1: {325, 329}
// row2: {326, 330}
// <327, 331>
row_major float3x2 ad; // covers 3 float4s with padding at end of each row (but not column)
// row0: {332, 333}, <334, 335>
// row1: {336, 337}, <338, 339>
// row2: {340, 341}, <342, 343>
column_major float3x2 ae[2]; // covers 2 float4s with padding at end of each column (but not row)
// [0] = {
// row0: {344, 348}
// row1: {345, 349}
// row2: {346, 350}
// <347, 351>
// }
// [1] = {
// row0: {352, 356}
// row1: {353, 357}
// row2: {354, 358}
// <355, 359>
// }
row_major float3x2 af[2]; // covers 3 float4s with padding at end of each row (but not column)
// [0] = {
// row0: {360, 361}, <362, 363>
// row1: {364, 365}, <366, 367>
// row2: {368, 369}, <370, 371>
// }
// [1] = {
// row0: {372, 373}, <374, 375>
// row1: {376, 377}, <378, 379>
// row2: {380, 381},
// }
float2 dummy9; // consumes leftovers from above array = {382, 383}
float2 dummy10; // should have padding at the end = {384, 385}, <386, 387>
row_major float2x2 ag; // each row is aligned to float4:
// row0: {388, 389}, <390, 391>
// row1: {392, 393},
float2 dummy11; // consumes leftovers from above matrix = {394, 395}
float2 dummy12; // should have padding at the end = {396, 397}, <398, 399>
column_major float2x2 ah; // each column is aligned to float4:
// row0: {400, 404}
// row1: {401, 405}
// <402, 406>
// <403, 407>
row_major float2x2 ai[2]; // [0] = {
// row0: {408, 409}, <410, 411>
// row1: {412, 413}, <414, 415>
// }
// [1] = {
// row0: {416, 417}, <418, 419>
// row1: {420, 421}, <422, 423>
// }
column_major float2x2 aj[2]; // [0] = {
// row0: {424, 428}
// row1: {425, 429}
// <426, 430>
// <427, 431>
// }
// [1] = {
// row0: {432, 436}
// row1: {433, 437}
// <434, 438>
// <435, 439>
// }
float4 test; // {440, 441, 442, 443}
};
float4 main() : SV_Target0
{
return test;
return test + float4(0.1f, 0.0f, 0.0f, 0.0f);
}
)EOSHADER";
@@ -184,11 +257,16 @@ float4 main() : SV_Target0
cbvParam(D3D12_SHADER_VISIBILITY_PIXEL, 0, 0),
});
ID3D12PipelineStatePtr pso = MakePSO().RootSig(sig).InputLayout().VS(vsblob).PS(psblob);
ID3D12PipelineStatePtr pso = MakePSO().RootSig(sig).InputLayout().VS(vsblob).PS(psblob).RTVs(
{DXGI_FORMAT_R32G32B32A32_FLOAT});
ResourceBarrier(vb, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
ResourceBarrier(cb, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
ID3D12ResourcePtr rtvtex = MakeTexture(DXGI_FORMAT_R32G32B32A32_FLOAT, screenWidth, screenHeight)
.RTV()
.InitialState(D3D12_RESOURCE_STATE_RENDER_TARGET);
while(Running())
{
ID3D12GraphicsCommandListPtr cmd = GetCommandBuffer();
@@ -197,10 +275,14 @@ float4 main() : SV_Target0
ID3D12ResourcePtr bb = StartUsingBackbuffer(cmd, D3D12_RESOURCE_STATE_RENDER_TARGET);
D3D12_CPU_DESCRIPTOR_HANDLE rtv =
D3D12_CPU_DESCRIPTOR_HANDLE bbrtv =
MakeRTV(bb).Format(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB).CreateCPU(0);
ClearRenderTargetView(cmd, rtv, {0.4f, 0.5f, 0.6f, 1.0f});
ClearRenderTargetView(cmd, bbrtv, {0.4f, 0.5f, 0.6f, 1.0f});
D3D12_CPU_DESCRIPTOR_HANDLE offrtv = MakeRTV(rtvtex).CreateCPU(0);
ClearRenderTargetView(cmd, offrtv, {0.4f, 0.5f, 0.6f, 1.0f});
cmd->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
@@ -212,7 +294,7 @@ float4 main() : SV_Target0
RSSetViewport(cmd, {0.0f, 0.0f, (float)screenWidth, (float)screenHeight, 0.0f, 1.0f});
RSSetScissorRect(cmd, {0, 0, screenWidth, screenHeight});
OMSetRenderTargets(cmd, {rtv}, {});
OMSetRenderTargets(cmd, {offrtv}, {});
cmd->DrawInstanced(3, 1, 0, 0);
+100 -30
View File
@@ -187,35 +187,105 @@ layout(binding = 0, std140) uniform constsbuf
// .c[3] = { { 320, 321, 322 }, 323 }
// }
vec4 test; // {324, 325, 326, 327}
layout(column_major) mat2x3 ac; // covers 2 vec4s with padding at end of each column (but not row)
// row0: {324, 328}
// row1: {325, 329}
// row2: {326, 330}
// <327, 331>
layout(row_major) mat2x3 ad; // covers 3 vec4s with padding at end of each row (but not column)
// row0: {332, 333}, <334, 335>
// row1: {336, 337}, <338, 339>
// row2: {340, 341}, <342, 343>
layout(column_major) mat2x3 ae[2]; // covers 2 vec4s with padding at end of each column (but not row)
// [0] = {
// row0: {344, 348}
// row1: {345, 349}
// row2: {346, 350}
// <347, 351>
// }
// [1] = {
// row0: {352, 356}
// row1: {353, 357}
// row2: {354, 358}
// <355, 359>
// }
layout(row_major) mat2x3 af[2]; // covers 3 vec4s with padding at end of each row (but not column)
// [0] = {
// row0: {360, 361}, <362, 363>
// row1: {364, 365}, <366, 367>
// row2: {368, 369}, <370, 371>
// }
// [1] = {
// row0: {372, 373}, <374, 375>
// row1: {376, 377}, <378, 379>
// row2: {380, 381}, <382, 383>
// }
vec2 dummy10; // should have padding at the end = {384, 385}, <386, 387>
layout(row_major) mat2x2 ag; // each row is aligned to float4:
// row0: {388, 389}, <390, 391>
// row1: {392, 393}, <394, 395>
vec2 dummy11; // should have padding at the end = {396, 397}, <398, 399>
layout(column_major) mat2x2 ah; // each column is aligned to float4:
// row0: {400, 404}
// row1: {401, 405}
// <402, 406>
// <403, 407>
layout(row_major) mat2x2 ai[2]; // [0] = {
// row0: {408, 409}, <410, 411>
// row1: {412, 413}, <414, 415>
// }
// [1] = {
// row0: {416, 417}, <418, 419>
// row1: {420, 421}, <422, 423>
// }
layout(column_major) mat2x2 aj[2]; // [0] = {
// row0: {424, 428}
// row1: {425, 429}
// <426, 430>
// <427, 431>
// }
// [1] = {
// row0: {432, 436}
// row1: {433, 437}
// <434, 438>
// <435, 439>
// }
vec4 test; // {440, 441, 442, 443}
// because GL has worse handling of multidimensional arrays than other APIs, we add an extra test
// here with more than 2 dimensions
vec4 multiarray2[4][3][2]; // [0][0][0] = {328, 329, 330, 331}
// [0][0][1] = {332, 333, 334, 335}
// [0][1][0] = {336, 337, 338, 339}
// [0][1][1] = {340, 341, 342, 343}
// [0][2][0] = {344, 345, 346, 347}
// [0][2][1] = {348, 349, 350, 351}
// [1][0][0] = {352, 353, 354, 355}
// [1][0][1] = {356, 357, 358, 359}
// [1][1][0] = {360, 361, 362, 363}
// [1][1][1] = {364, 365, 366, 367}
// [1][2][0] = {368, 369, 370, 371}
// [1][2][1] = {372, 373, 374, 375}
// [2][0][0] = {376, 377, 378, 379}
// [2][0][1] = {380, 381, 382, 383}
// [2][1][0] = {384, 385, 386, 387}
// [2][1][1] = {388, 389, 390, 391}
// [2][2][0] = {392, 393, 394, 395}
// [2][2][1] = {396, 397, 398, 399}
// [3][0][0] = {400, 401, 402, 403}
// [3][0][1] = {404, 405, 406, 407}
// [3][1][0] = {408, 409, 410, 411}
// [3][1][1] = {412, 413, 414, 415}
// [3][2][0] = {416, 417, 418, 419}
// [3][2][1] = {420, 421, 422, 423}
vec4 multiarray2[4][3][2]; // [0][0][0] = {444, 445, 446, 447}
// [0][0][1] = {448, 449, 450, 451}
// [0][1][0] = {452, ..., ..., ...}
// [0][1][1] = {..., ..., ..., ...}
// [0][2][0] = {..., ..., ..., ...}
// [0][2][1] = {..., ..., ..., ...}
// [1][0][0] = {..., ..., ..., ...}
// [1][0][1] = {..., ..., ..., ...}
// [1][1][0] = {..., ..., ..., ...}
// [1][1][1] = {..., ..., ..., ...}
// [1][2][0] = {..., ..., ..., ...}
// [1][2][1] = {..., ..., ..., ...}
// [2][0][0] = {..., ..., ..., ...}
// [2][0][1] = {..., ..., ..., ...}
// [2][1][0] = {..., ..., ..., ...}
// [2][1][1] = {..., ..., ..., ...}
// [2][2][0] = {..., ..., ..., ...}
// [2][2][1] = {..., ..., ..., ...}
// [3][0][0] = {..., ..., ..., ...}
// [3][0][1] = {..., ..., ..., ...}
// [3][1][0] = {..., ..., ..., ...}
// [3][1][1] = {..., ..., ..., ...}
// [3][2][0] = {..., ..., ..., ...}
// [3][2][1] = {..., ..., ..., ...}
};
void main()
@@ -224,9 +294,9 @@ void main()
float blah = a.x + b.x + c.x + d.x + e.x + f.x + j.x + k.x + l.x + m.x;
blah += n[0] + o[0] + p.x;
blah += q[0].x + r[0].x + s[0].x + t[0].x + u[0].x + v[0].x + w[0].x + x[0].x + y[0].x + z;
blah += multiarray[0][0].x;
blah *= 0.0000001f;
Color = blah + test;
blah += multiarray[0][0].x + ac[0][0] + ad[0][0] + ae[0][0][0] + af[0][0][0];
blah *= vertIn.uv.z;
Color = blah + test + vec4(0.1f, 0.0f, 0.0f, 0.0f);
}
)EOSHADER";
@@ -256,9 +326,9 @@ void main()
GLuint program = MakeProgram(common + vertex, common + pixel);
glObjectLabel(GL_PROGRAM, program, -1, "Full program");
Vec4f cbufferdata[512];
Vec4f cbufferdata[684];
for(int i = 0; i < 512; i++)
for(int i = 0; i < 684; i++)
cbufferdata[i] = Vec4f(float(i * 4 + 0), float(i * 4 + 1), float(i * 4 + 2), float(i * 4 + 3));
GLuint cb = MakeBuffer();
+148 -5
View File
@@ -186,12 +186,82 @@ layout(set = 0, binding = 0, std140) uniform constsbuf
// .c[3] = { { 320, 321, 322 }, 323 }
// }
vec4 test; // {324, 325, 326, 327}
layout(column_major) mat2x3 ac; // covers 2 vec4s with padding at end of each column (but not row)
// row0: {324, 328}
// row1: {325, 329}
// row2: {326, 330}
// <327, 331>
layout(row_major) mat2x3 ad; // covers 3 vec4s with padding at end of each row (but not column)
// row0: {332, 333}, <334, 335>
// row1: {336, 337}, <338, 339>
// row2: {340, 341}, <342, 343>
layout(column_major) mat2x3 ae[2]; // covers 2 vec4s with padding at end of each column (but not row)
// [0] = {
// row0: {344, 348}
// row1: {345, 349}
// row2: {346, 350}
// <347, 351>
// }
// [1] = {
// row0: {352, 356}
// row1: {353, 357}
// row2: {354, 358}
// <355, 359>
// }
layout(row_major) mat2x3 af[2]; // covers 3 vec4s with padding at end of each row (but not column)
// [0] = {
// row0: {360, 361}, <362, 363>
// row1: {364, 365}, <366, 367>
// row2: {368, 369}, <370, 371>
// }
// [1] = {
// row0: {372, 373}, <374, 375>
// row1: {376, 377}, <378, 379>
// row2: {380, 381}, <382, 383>
// }
vec2 dummy10; // should have padding at the end = {384, 385}, <386, 387>
layout(row_major) mat2x2 ag; // each row is aligned to float4:
// row0: {388, 389}, <390, 391>
// row1: {392, 393}, <394, 395>
vec2 dummy11; // should have padding at the end = {396, 397}, <398, 399>
layout(column_major) mat2x2 ah; // each column is aligned to float4:
// row0: {400, 404}
// row1: {401, 405}
// <402, 406>
// <403, 407>
layout(row_major) mat2x2 ai[2]; // [0] = {
// row0: {408, 409}, <410, 411>
// row1: {412, 413}, <414, 415>
// }
// [1] = {
// row0: {416, 417}, <418, 419>
// row1: {420, 421}, <422, 423>
// }
layout(column_major) mat2x2 aj[2]; // [0] = {
// row0: {424, 428}
// row1: {425, 429}
// <426, 430>
// <427, 431>
// }
// [1] = {
// row0: {432, 436}
// row1: {433, 437}
// <434, 438>
// <435, 439>
// }
vec4 test; // {440, 441, 442, 443}
};
void main()
{
Color = test;
Color = test + vec4(0.1f, 0.0f, 0.0f, 0.0f);
}
)EOSHADER";
@@ -284,7 +354,7 @@ layout(set = 0, binding = 0) cbuffer consts
// SPIR-V can't represent single-dimension matrices properly at the moment
/*
row_major float4x1 aa; // covers 4 vec4s with maximum padding
row_major float4x1 aa; // covers 4 float4s with maximum padding
// row0: {208, 212, 216, 220}
// <209, 213, 217, 221>
// <210, 214, 218, 222>
@@ -325,12 +395,85 @@ layout(set = 0, binding = 0) cbuffer consts
// .c[3] = { { 320, 321, 322 }, 323 }
// }
float4 test; // {324, 325, 326, 327}
column_major float3x2 ac; // covers 2 float4s with padding at end of each column (but not row)
// row0: {324, 328}
// row1: {325, 329}
// row2: {326, 330}
// <327, 331>
row_major float3x2 ad; // covers 3 float4s with padding at end of each row (but not column)
// row0: {332, 333}, <334, 335>
// row1: {336, 337}, <338, 339>
// row2: {340, 341}, <342, 343>
column_major float3x2 ae[2]; // covers 2 float4s with padding at end of each column (but not row)
// [0] = {
// row0: {344, 348}
// row1: {345, 349}
// row2: {346, 350}
// <347, 351>
// }
// [1] = {
// row0: {352, 356}
// row1: {353, 357}
// row2: {354, 358}
// <355, 359>
// }
row_major float3x2 af[2]; // covers 3 float4s with padding at end of each row (but not column)
// [0] = {
// row0: {360, 361}, <362, 363>
// row1: {364, 365}, <366, 367>
// row2: {368, 369}, <370, 371>
// }
// [1] = {
// row0: {372, 373}, <374, 375>
// row1: {376, 377}, <378, 379>
// row2: {380, 381},
// }
float2 dummy10; // consumes leftovers from above array = {382, 383}
float2 dummy11; // should have padding at the end = {384, 385}, <386, 387>
row_major float2x2 ag; // each row is aligned to float4:
// row0: {388, 389}, <390, 391>
// row1: {392, 393},
float2 dummy12; // consumes leftovers from above matrix = {394, 395}
float2 dummy13; // should have padding at the end = {396, 397}, <398, 399>
column_major float2x2 ah; // each column is aligned to float4:
// row0: {400, 404}
// row1: {401, 405}
// <402, 406>
// <403, 407>
row_major float2x2 ai[2]; // [0] = {
// row0: {408, 409}, <410, 411>
// row1: {412, 413}, <414, 415>
// }
// [1] = {
// row0: {416, 417}, <418, 419>
// row1: {420, 421}, <422, 423>
// }
column_major float2x2 aj[2]; // [0] = {
// row0: {424, 428}
// row1: {425, 429}
// <426, 430>
// <427, 431>
// }
// [1] = {
// row0: {432, 436}
// row1: {433, 437}
// <434, 438>
// <435, 439>
// }
float4 test; // {440, 441, 442, 443}
};
float4 main() : SV_Target0
{
return test;
return test + float4(0.1f, 0.0f, 0.0f, 0.0f);
}
)EOSHADER";
+10
View File
@@ -235,6 +235,16 @@ class TestCase:
return first_draw
def get_texture(self, id: rd.ResourceId):
texs = self.controller.GetTextures()
for t in texs:
t: rd.TextureDescription
if t.resourceId == id:
return t
return None
def get_last_draw(self):
last_draw: rd.DrawcallDescription = self.controller.GetDrawcalls()[-1]
+90 -1
View File
@@ -15,6 +15,13 @@ class D3D11_CBuffer_Zoo(rdtest.TestCase):
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.Pixel
@@ -236,9 +243,91 @@ class D3D11_CBuffer_Zoo(rdtest.TestCase):
}),
})
# column_major float3x2 ac;
var_check.check('ac').rows(3).cols(2).column_major().value([324.0, 328.0,
325.0, 329.0,
326.0, 330.0])
# row_major float3x2 ad;
var_check.check('ad').rows(3).cols(2).row_major().value([332.0, 333.0,
336.0, 337.0,
340.0, 341.0])
# column_major float3x2 ae[2];
var_check.check('ae').rows(0).cols(0).arraySize(2).members({
0: lambda x: x.rows(3).cols(2).column_major().value([344.0, 348.0,
345.0, 349.0,
346.0, 350.0]),
1: lambda x: x.rows(3).cols(2).column_major().value([352.0, 356.0,
353.0, 357.0,
354.0, 358.0]),
})
# row_major float3x2 af[2];
var_check.check('af').rows(0).cols(0).arraySize(2).members({
0: lambda x: x.rows(3).cols(2).row_major().value([360.0, 361.0,
364.0, 365.0,
368.0, 369.0]),
1: lambda x: x.rows(3).cols(2).row_major().value([372.0, 373.0,
376.0, 377.0,
380.0, 381.0]),
})
# float2 dummy9;
var_check.check('dummy9')
# float2 dummy10;
var_check.check('dummy10')
# row_major float2x2 ag;
var_check.check('ag').rows(2).cols(2).row_major().value([388.0, 389.0,
392.0, 393.0])
# float2 dummy11;
var_check.check('dummy11')
# float2 dummy12;
var_check.check('dummy12')
# column_major float2x2 ah;
var_check.check('ah').rows(2).cols(2).column_major().value([400.0, 404.0,
401.0, 405.0])
# row_major float2x2 ai[2];
var_check.check('ai').rows(0).cols(0).arraySize(2).members({
0: lambda x: x.rows(2).cols(2).row_major().value([408.0, 409.0,
412.0, 413.0]),
1: lambda x: x.rows(2).cols(2).row_major().value([416.0, 417.0,
420.0, 421.0]),
})
# column_major float2x2 aj[2];
var_check.check('aj').rows(0).cols(0).arraySize(2).members({
0: lambda x: x.rows(2).cols(2).column_major().value([424.0, 428.0,
425.0, 429.0]),
1: lambda x: x.rows(2).cols(2).column_major().value([432.0, 436.0,
433.0, 437.0]),
})
# float4 test;
var_check.check('test').rows(1).cols(4).value([324.0, 325.0, 326.0, 327.0])
var_check.check('test').rows(1).cols(4).value([440.0, 441.0, 442.0, 443.0])
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)
if not rdtest.value_compare(picked.floatValue, [440.1, 441.0, 442.0, 443.0]):
raise rdtest.TestFailureException("Picked value {} doesn't match expectation".format(picked.floatValue))
rdtest.log.success("Picked value is as expected")
out.Shutdown()
+90 -1
View File
@@ -16,6 +16,13 @@ class D3D12_CBuffer_Zoo(rdtest.TestCase):
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.Pixel
@@ -237,9 +244,91 @@ class D3D12_CBuffer_Zoo(rdtest.TestCase):
}),
})
# column_major float3x2 ac;
var_check.check('ac').rows(3).cols(2).column_major().value([324.0, 328.0,
325.0, 329.0,
326.0, 330.0])
# row_major float3x2 ad;
var_check.check('ad').rows(3).cols(2).row_major().value([332.0, 333.0,
336.0, 337.0,
340.0, 341.0])
# column_major float3x2 ae[2];
var_check.check('ae').rows(0).cols(0).arraySize(2).members({
0: lambda x: x.rows(3).cols(2).column_major().value([344.0, 348.0,
345.0, 349.0,
346.0, 350.0]),
1: lambda x: x.rows(3).cols(2).column_major().value([352.0, 356.0,
353.0, 357.0,
354.0, 358.0]),
})
# row_major float3x2 af[2];
var_check.check('af').rows(0).cols(0).arraySize(2).members({
0: lambda x: x.rows(3).cols(2).row_major().value([360.0, 361.0,
364.0, 365.0,
368.0, 369.0]),
1: lambda x: x.rows(3).cols(2).row_major().value([372.0, 373.0,
376.0, 377.0,
380.0, 381.0]),
})
# float2 dummy9;
var_check.check('dummy9')
# float2 dummy10;
var_check.check('dummy10')
# row_major float2x2 ag;
var_check.check('ag').rows(2).cols(2).row_major().value([388.0, 389.0,
392.0, 393.0])
# float2 dummy11;
var_check.check('dummy11')
# float2 dummy12;
var_check.check('dummy12')
# column_major float2x2 ah;
var_check.check('ah').rows(2).cols(2).column_major().value([400.0, 404.0,
401.0, 405.0])
# row_major float2x2 ai[2];
var_check.check('ai').rows(0).cols(0).arraySize(2).members({
0: lambda x: x.rows(2).cols(2).row_major().value([408.0, 409.0,
412.0, 413.0]),
1: lambda x: x.rows(2).cols(2).row_major().value([416.0, 417.0,
420.0, 421.0]),
})
# column_major float2x2 aj[2];
var_check.check('aj').rows(0).cols(0).arraySize(2).members({
0: lambda x: x.rows(2).cols(2).column_major().value([424.0, 428.0,
425.0, 429.0]),
1: lambda x: x.rows(2).cols(2).column_major().value([432.0, 436.0,
433.0, 437.0]),
})
# float4 test;
var_check.check('test').rows(1).cols(4).value([324.0, 325.0, 326.0, 327.0])
var_check.check('test').rows(1).cols(4).value([440.0, 441.0, 442.0, 443.0])
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)
if not rdtest.value_compare(picked.floatValue, [440.1, 441.0, 442.0, 443.0]):
raise rdtest.TestFailureException("Picked value {} doesn't match expectation".format(picked.floatValue))
rdtest.log.success("Picked value is as expected")
out.Shutdown()
+113 -25
View File
@@ -13,6 +13,13 @@ class GL_CBuffer_Zoo(rdtest.TestCase):
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.Pixel
@@ -225,65 +232,130 @@ class GL_CBuffer_Zoo(rdtest.TestCase):
}),
})
# column_major mat2x3 ac;
var_check.check('ac').cols(2).rows(3).column_major().value([324.0, 328.0,
325.0, 329.0,
326.0, 330.0])
# row_major mat2x3 ad;
var_check.check('ad').cols(2).rows(3).row_major().value([332.0, 333.0,
336.0, 337.0,
340.0, 341.0])
# column_major mat2x3 ae[2];
var_check.check('ae').cols(0).rows(0).arraySize(2).members({
0: lambda x: x.cols(2).rows(3).column_major().value([344.0, 348.0,
345.0, 349.0,
346.0, 350.0]),
1: lambda x: x.cols(2).rows(3).column_major().value([352.0, 356.0,
353.0, 357.0,
354.0, 358.0]),
})
# row_major mat2x3 af[2];
var_check.check('af').cols(0).rows(0).arraySize(2).members({
0: lambda x: x.cols(2).rows(3).row_major().value([360.0, 361.0,
364.0, 365.0,
368.0, 369.0]),
1: lambda x: x.cols(2).rows(3).row_major().value([372.0, 373.0,
376.0, 377.0,
380.0, 381.0]),
})
# vec2 dummy10;
var_check.check('dummy10')
# row_major mat2x2 ag;
var_check.check('ag').cols(2).rows(2).row_major().value([388.0, 389.0,
392.0, 393.0])
# vec2 dummy12;
var_check.check('dummy11')
# column_major float2x2 ah;
var_check.check('ah').cols(2).rows(2).column_major().value([400.0, 404.0,
401.0, 405.0])
# row_major mat2x2 ai[2];
var_check.check('ai').rows(0).cols(0).arraySize(2).members({
0: lambda x: x.cols(2).rows(2).row_major().value([408.0, 409.0,
412.0, 413.0]),
1: lambda x: x.cols(2).rows(2).row_major().value([416.0, 417.0,
420.0, 421.0]),
})
# column_major mat2x2 aj[2];
var_check.check('aj').rows(0).cols(0).arraySize(2).members({
0: lambda x: x.cols(2).rows(2).column_major().value([424.0, 428.0,
425.0, 429.0]),
1: lambda x: x.cols(2).rows(2).column_major().value([432.0, 436.0,
433.0, 437.0]),
})
# vec4 test;
var_check.check('test').cols(4).rows(1).value([324.0, 325.0, 326.0, 327.0])
var_check.check('test').rows(1).cols(4).value([440.0, 441.0, 442.0, 443.0])
# to save duplicating if this array changes, we calculate out from the start, as the array is tightly packed
base = 444.0
exp_vals = lambda wi,yi,xi: [base + wi * 24.0 + yi * 8.0 + xi * 4.0 + c * 1.0 for c in range(0,4)]
# vec4 multiarray2[4][3][2];
var_check.check('multiarray2').cols(0).rows(0).arraySize(4).members({
0: lambda w: w.cols(0).rows(0).arraySize(3).members({
0: lambda x: x.cols(0).rows(0).arraySize(2).members({
0: lambda y: y.cols(4).rows(1).value([328.0, 329.0, 330.0, 331.0]),
1: lambda y: y.cols(4).rows(1).value([332.0, 333.0, 334.0, 335.0]),
0: lambda y: y.cols(4).rows(1).value(exp_vals(0, 0, 0)),
1: lambda y: y.cols(4).rows(1).value(exp_vals(0, 0, 1)),
}),
1: lambda x: x.cols(0).rows(0).arraySize(2).members({
0: lambda y: y.cols(4).rows(1).value([336.0, 337.0, 338.0, 339.0]),
1: lambda y: y.cols(4).rows(1).value([340.0, 341.0, 342.0, 343.0]),
0: lambda y: y.cols(4).rows(1).value(exp_vals(0, 1, 0)),
1: lambda y: y.cols(4).rows(1).value(exp_vals(0, 1, 1)),
}),
2: lambda x: x.cols(0).rows(0).arraySize(2).members({
0: lambda y: y.cols(4).rows(1).value([344.0, 345.0, 346.0, 347.0]),
1: lambda y: y.cols(4).rows(1).value([348.0, 349.0, 350.0, 351.0]),
0: lambda y: y.cols(4).rows(1).value(exp_vals(0, 2, 0)),
1: lambda y: y.cols(4).rows(1).value(exp_vals(0, 2, 1)),
}),
}),
1: lambda w: w.cols(0).rows(0).arraySize(3).members({
0: lambda x: x.cols(0).rows(0).arraySize(2).members({
0: lambda y: y.cols(4).rows(1).value([352.0, 353.0, 354.0, 355.0]),
1: lambda y: y.cols(4).rows(1).value([356.0, 357.0, 358.0, 359.0]),
0: lambda y: y.cols(4).rows(1).value(exp_vals(1, 0, 0)),
1: lambda y: y.cols(4).rows(1).value(exp_vals(1, 0, 1)),
}),
1: lambda x: x.cols(0).rows(0).arraySize(2).members({
0: lambda y: y.cols(4).rows(1).value([360.0, 361.0, 362.0, 363.0]),
1: lambda y: y.cols(4).rows(1).value([364.0, 365.0, 366.0, 367.0]),
0: lambda y: y.cols(4).rows(1).value(exp_vals(1, 1, 0)),
1: lambda y: y.cols(4).rows(1).value(exp_vals(1, 1, 1)),
}),
2: lambda x: x.cols(0).rows(0).arraySize(2).members({
0: lambda y: y.cols(4).rows(1).value([368.0, 369.0, 370.0, 371.0]),
1: lambda y: y.cols(4).rows(1).value([372.0, 373.0, 374.0, 375.0]),
0: lambda y: y.cols(4).rows(1).value(exp_vals(1, 2, 0)),
1: lambda y: y.cols(4).rows(1).value(exp_vals(1, 2, 1)),
}),
}),
2: lambda w: w.cols(0).rows(0).arraySize(3).members({
0: lambda x: x.cols(0).rows(0).arraySize(2).members({
0: lambda y: y.cols(4).rows(1).value([376.0, 377.0, 378.0, 379.0]),
1: lambda y: y.cols(4).rows(1).value([380.0, 381.0, 382.0, 383.0]),
0: lambda y: y.cols(4).rows(1).value(exp_vals(2, 0, 0)),
1: lambda y: y.cols(4).rows(1).value(exp_vals(2, 0, 1)),
}),
1: lambda x: x.cols(0).rows(0).arraySize(2).members({
0: lambda y: y.cols(4).rows(1).value([384.0, 385.0, 386.0, 387.0]),
1: lambda y: y.cols(4).rows(1).value([388.0, 389.0, 390.0, 391.0]),
0: lambda y: y.cols(4).rows(1).value(exp_vals(2, 1, 0)),
1: lambda y: y.cols(4).rows(1).value(exp_vals(2, 1, 1)),
}),
2: lambda x: x.cols(0).rows(0).arraySize(2).members({
0: lambda y: y.cols(4).rows(1).value([392.0, 393.0, 394.0, 395.0]),
1: lambda y: y.cols(4).rows(1).value([396.0, 397.0, 398.0, 399.0]),
0: lambda y: y.cols(4).rows(1).value(exp_vals(2, 2, 0)),
1: lambda y: y.cols(4).rows(1).value(exp_vals(2, 2, 1)),
}),
}),
3: lambda w: w.cols(0).rows(0).arraySize(3).members({
0: lambda x: x.cols(0).rows(0).arraySize(2).members({
0: lambda y: y.cols(4).rows(1).value([400.0, 401.0, 402.0, 403.0]),
1: lambda y: y.cols(4).rows(1).value([404.0, 405.0, 406.0, 407.0]),
0: lambda y: y.cols(4).rows(1).value(exp_vals(3, 0, 0)),
1: lambda y: y.cols(4).rows(1).value(exp_vals(3, 0, 1)),
}),
1: lambda x: x.cols(0).rows(0).arraySize(2).members({
0: lambda y: y.cols(4).rows(1).value([408.0, 409.0, 410.0, 411.0]),
1: lambda y: y.cols(4).rows(1).value([412.0, 413.0, 414.0, 415.0]),
0: lambda y: y.cols(4).rows(1).value(exp_vals(3, 1, 0)),
1: lambda y: y.cols(4).rows(1).value(exp_vals(3, 1, 1)),
}),
2: lambda x: x.cols(0).rows(0).arraySize(2).members({
0: lambda y: y.cols(4).rows(1).value([416.0, 417.0, 418.0, 419.0]),
1: lambda y: y.cols(4).rows(1).value([420.0, 421.0, 422.0, 423.0]),
0: lambda y: y.cols(4).rows(1).value(exp_vals(3, 2, 0)),
1: lambda y: y.cols(4).rows(1).value(exp_vals(3, 2, 1)),
}),
}),
})
@@ -291,3 +363,19 @@ class GL_CBuffer_Zoo(rdtest.TestCase):
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)
if not rdtest.value_compare(picked.floatValue, [440.1, 441.0, 442.0, 443.0]):
raise rdtest.TestFailureException("Picked value {} doesn't match expectation".format(picked.floatValue))
rdtest.log.success("Picked value is as expected")
out.Shutdown()
+153 -2
View File
@@ -13,6 +13,13 @@ class VK_CBuffer_Zoo(rdtest.TestCase):
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.Pixel
@@ -232,13 +239,87 @@ class VK_CBuffer_Zoo(rdtest.TestCase):
}),
})
# column_major mat2x3 ac;
var_check.check('ac').cols(2).rows(3).column_major().value([324.0, 328.0,
325.0, 329.0,
326.0, 330.0])
# row_major mat2x3 ad;
var_check.check('ad').cols(2).rows(3).row_major().value([332.0, 333.0,
336.0, 337.0,
340.0, 341.0])
# column_major mat2x3 ae[2];
var_check.check('ae').cols(0).rows(0).arraySize(2).members({
0: lambda x: x.cols(2).rows(3).column_major().value([344.0, 348.0,
345.0, 349.0,
346.0, 350.0]),
1: lambda x: x.cols(2).rows(3).column_major().value([352.0, 356.0,
353.0, 357.0,
354.0, 358.0]),
})
# row_major mat2x3 af[2];
var_check.check('af').cols(0).rows(0).arraySize(2).members({
0: lambda x: x.cols(2).rows(3).row_major().value([360.0, 361.0,
364.0, 365.0,
368.0, 369.0]),
1: lambda x: x.cols(2).rows(3).row_major().value([372.0, 373.0,
376.0, 377.0,
380.0, 381.0]),
})
# vec2 dummy10;
var_check.check('dummy10')
# row_major mat2x2 ag;
var_check.check('ag').cols(2).rows(2).row_major().value([388.0, 389.0,
392.0, 393.0])
# vec2 dummy11;
var_check.check('dummy11')
# column_major mat2x2 ah;
var_check.check('ah').cols(2).rows(2).column_major().value([400.0, 404.0,
401.0, 405.0])
# row_major mat2x2 ai[2];
var_check.check('ai').rows(0).cols(0).arraySize(2).members({
0: lambda x: x.cols(2).rows(2).row_major().value([408.0, 409.0,
412.0, 413.0]),
1: lambda x: x.cols(2).rows(2).row_major().value([416.0, 417.0,
420.0, 421.0]),
})
# column_major mat2x2 aj[2];
var_check.check('aj').rows(0).cols(0).arraySize(2).members({
0: lambda x: x.cols(2).rows(2).column_major().value([424.0, 428.0,
425.0, 429.0]),
1: lambda x: x.cols(2).rows(2).column_major().value([432.0, 436.0,
433.0, 437.0]),
})
# vec4 test;
var_check.check('test').cols(4).rows(1).value([324.0, 325.0, 326.0, 327.0])
var_check.check('test').rows(1).cols(4).value([440.0, 441.0, 442.0, 443.0])
var_check.done()
rdtest.log.success("GLSL 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)
if not rdtest.value_compare(picked.floatValue, [440.1, 441.0, 442.0, 443.0]):
raise rdtest.TestFailureException("Picked value {} doesn't match expectation".format(picked.floatValue))
rdtest.log.success("GLSL picked value is as expected")
# Move to the HLSL draw
draw = draw.next
@@ -484,9 +565,79 @@ class VK_CBuffer_Zoo(rdtest.TestCase):
}),
})
# column_major float3x2 ac;
var_check.check('ac').rows(2).cols(3).row_major().value([324.0, 325.0, 326.0,
328.0, 329.0, 330.0])
# row_major float3x2 ad;
var_check.check('ad').rows(2).cols(3).column_major().value([332.0, 336.0, 340.0,
333.0, 337.0, 341.0])
# column_major float3x2 ae[2];
var_check.check('ae').rows(0).cols(0).arraySize(2).members({
0: lambda x: x.rows(2).cols(3).row_major().value([344.0, 345.0, 346.0,
348.0, 349.0, 350.0]),
1: lambda x: x.rows(2).cols(3).row_major().value([352.0, 353.0, 354.0,
356.0, 357.0, 358.0]),
})
# row_major float3x2 af[2];
var_check.check('af').rows(0).cols(0).arraySize(2).members({
0: lambda x: x.rows(2).cols(3).column_major().value([360.0, 364.0, 368.0,
361.0, 365.0, 369.0]),
1: lambda x: x.rows(2).cols(3).column_major().value([372.0, 376.0, 380.0,
373.0, 377.0, 381.0]),
})
# float2 dummy10;
var_check.check('dummy10')
# float2 dummy11;
var_check.check('dummy11')
# row_major float2x2 ag;
var_check.check('ag').rows(2).cols(2).column_major().value([388.0, 392.0,
389.0, 393.0])
# float2 dummy12;
var_check.check('dummy12')
# float2 dummy13;
var_check.check('dummy13')
# column_major float2x2 ah;
var_check.check('ah').rows(2).cols(2).row_major().value([400.0, 401.0,
404.0, 405.0])
# row_major float2x2 ai[2];
var_check.check('ai').rows(0).cols(0).arraySize(2).members({
0: lambda x: x.rows(2).cols(2).column_major().value([408.0, 412.0,
409.0, 413.0]),
1: lambda x: x.rows(2).cols(2).column_major().value([416.0, 420.0,
417.0, 421.0]),
})
# column_major float2x2 aj[2];
var_check.check('aj').rows(0).cols(0).arraySize(2).members({
0: lambda x: x.rows(2).cols(2).row_major().value([424.0, 425.0,
428.0, 429.0]),
1: lambda x: x.rows(2).cols(2).row_major().value([432.0, 433.0,
436.0, 437.0]),
})
# float4 test;
var_check.check('test').rows(1).cols(4).value([324.0, 325.0, 326.0, 327.0])
var_check.check('test').rows(1).cols(4).value([440.0, 441.0, 442.0, 443.0])
var_check.done()
rdtest.log.success("HLSL CBuffer variables are as expected")
picked: rd.PixelValue = out.PickPixel(tex.resourceId, False,
int(texdetails.width / 2), int(texdetails.height / 2), 0, 0, 0)
if not rdtest.value_compare(picked.floatValue, [440.1, 441.0, 442.0, 443.0]):
raise rdtest.TestFailureException("Picked value {} doesn't match expectation".format(picked.floatValue))
rdtest.log.success("HLSL picked value is as expected")
out.Shutdown()