blob: bcc4d36f7de789e143d2808033be4e7f375c5b64 [file] [log] [blame]
/*------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2015 The Khronos Group Inc.
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
* Copyright (c) 2016 The Android Open Source Project
* Copyright (c) 2018 The Khronos Group Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*//*!
* \file
* \brief Vulkan Transform Feedback Fuzz Layout Tests
*//*--------------------------------------------------------------------*/
#include "vktTransformFeedbackFuzzLayoutCase.hpp"
#include "vktTransformFeedbackRandomLayoutCase.hpp"
#include "tcuCommandLine.hpp"
#include "deStringUtil.hpp"
namespace vkt
{
namespace TransformFeedback
{
namespace
{
class BlockBasicTypeCase : public InterfaceBlockCase
{
public:
BlockBasicTypeCase (tcu::TestContext& testCtx,
const std::string& name,
const std::string& description,
const VarType& type,
deUint32 layoutFlags,
int numInstances,
MatrixLoadFlags matrixLoadFlag,
TestStageFlags testStageFlags)
: InterfaceBlockCase(testCtx, name, description, matrixLoadFlag, testStageFlags)
{
InterfaceBlock& block = m_interface.allocBlock("Block");
block.addInterfaceMember(InterfaceBlockMember("var", type, 0));
VarType tempType = type;
while (tempType.isArrayType())
{
tempType = tempType.getElementType();
}
block.setFlags(layoutFlags);
if (numInstances > 0)
{
block.setArraySize(numInstances);
block.setInstanceName("block");
}
}
};
void createBlockBasicTypeCases (tcu::TestCaseGroup& group, tcu::TestContext& testCtx, const std::string& name, const VarType& type, deUint32 layoutFlags, int numInstances = 0)
{
de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(group.getTestContext(), name.c_str(), ""));
typeGroup->addChild(new BlockBasicTypeCase(testCtx, "vertex", "", type, layoutFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
typeGroup->addChild(new BlockBasicTypeCase(testCtx, "geometry", "", type, layoutFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
group.addChild(typeGroup.release());
}
class BlockSingleStructCase : public InterfaceBlockCase
{
public:
BlockSingleStructCase (tcu::TestContext& testCtx,
const std::string& name,
const std::string& description,
deUint32 layoutFlags,
int numInstances,
MatrixLoadFlags matrixLoadFlag,
TestStageFlags testStageFlags)
: InterfaceBlockCase (testCtx, name, description, matrixLoadFlag, testStageFlags)
{
StructType& typeS = m_interface.allocStruct("S");
typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), FIELD_UNASSIGNED); // First member is unused.
typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_VEC3, PRECISION_HIGH), 2));
typeS.addMember("c", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM));
InterfaceBlock& block = m_interface.allocBlock("Block");
block.addInterfaceMember(InterfaceBlockMember("s", VarType(&typeS), 0));
block.setFlags(layoutFlags);
if (numInstances > 0)
{
block.setInstanceName("block");
block.setArraySize(numInstances);
}
}
};
class BlockSingleStructArrayCase : public InterfaceBlockCase
{
public:
BlockSingleStructArrayCase (tcu::TestContext& testCtx,
const std::string& name,
const std::string& description,
deUint32 layoutFlags,
int numInstances,
MatrixLoadFlags matrixLoadFlag,
TestStageFlags testStageFlags)
: InterfaceBlockCase (testCtx, name, description, matrixLoadFlag, testStageFlags)
{
StructType& typeS = m_interface.allocStruct("S");
typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH), FIELD_UNASSIGNED);
typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM), 2));
typeS.addMember("c", VarType(glu::TYPE_FLOAT, PRECISION_HIGH));
InterfaceBlock& block = m_interface.allocBlock("Block");
block.addInterfaceMember(InterfaceBlockMember("u", VarType(glu::TYPE_UINT, PRECISION_LOW)));
block.addInterfaceMember(InterfaceBlockMember("s", VarType(VarType(&typeS), 2)));
block.addInterfaceMember(InterfaceBlockMember("v", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_MEDIUM)));
block.setFlags(layoutFlags);
if (numInstances > 0)
{
block.setInstanceName("block");
block.setArraySize(numInstances);
}
}
};
class BlockSingleNestedStructCase : public InterfaceBlockCase
{
public:
BlockSingleNestedStructCase (tcu::TestContext& testCtx,
const std::string& name,
const std::string& description,
deUint32 layoutFlags,
int numInstances,
MatrixLoadFlags matrixLoadFlag,
TestStageFlags testStageFlags)
: InterfaceBlockCase (testCtx, name, description, matrixLoadFlag, testStageFlags)
{
StructType& typeS = m_interface.allocStruct("S");
typeS.addMember("a", VarType(glu::TYPE_INT_VEC3, PRECISION_HIGH));
typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM), 2));
typeS.addMember("c", VarType(glu::TYPE_FLOAT, PRECISION_HIGH), FIELD_UNASSIGNED);
StructType& typeT = m_interface.allocStruct("T");
typeT.addMember("a", VarType(glu::TYPE_FLOAT_VEC3, PRECISION_MEDIUM));
typeT.addMember("b", VarType(&typeS));
InterfaceBlock& block = m_interface.allocBlock("Block");
block.addInterfaceMember(InterfaceBlockMember("s", VarType(&typeS), 0));
block.addInterfaceMember(InterfaceBlockMember("v", VarType(glu::TYPE_UINT, PRECISION_LOW), FIELD_UNASSIGNED));
block.addInterfaceMember(InterfaceBlockMember("t", VarType(&typeT), 0));
block.addInterfaceMember(InterfaceBlockMember("u", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_HIGH), 0));
block.setFlags(layoutFlags);
if (numInstances > 0)
{
block.setInstanceName("block");
block.setArraySize(numInstances);
}
}
};
class BlockSingleNestedStructArrayCase : public InterfaceBlockCase
{
public:
BlockSingleNestedStructArrayCase (tcu::TestContext& testCtx,
const std::string& name,
const std::string& description,
deUint32 layoutFlags,
int numInstances,
MatrixLoadFlags matrixLoadFlag,
TestStageFlags testStageFlags)
: InterfaceBlockCase (testCtx, name, description, matrixLoadFlag, testStageFlags)
{
StructType& typeS = m_interface.allocStruct("S");
typeS.addMember("a", VarType(VarType(glu::TYPE_FLOAT, PRECISION_HIGH), 2));
StructType& typeT = m_interface.allocStruct("T");
typeT.addMember("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM));
typeT.addMember("b", VarType(VarType(&typeS), 2));
InterfaceBlock& block = m_interface.allocBlock("Block");
block.addInterfaceMember(InterfaceBlockMember("s", VarType(&typeS), 0));
block.addInterfaceMember(InterfaceBlockMember("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_LOW), FIELD_UNASSIGNED));
block.addInterfaceMember(InterfaceBlockMember("t", VarType(VarType(&typeT), 2), 0));
block.addInterfaceMember(InterfaceBlockMember("u", VarType(glu::TYPE_UINT, PRECISION_HIGH), 0));
block.setFlags(layoutFlags);
if (numInstances > 0)
{
block.setInstanceName("block");
block.setArraySize(numInstances);
}
}
};
class BlockMultiBasicTypesCase : public InterfaceBlockCase
{
public:
BlockMultiBasicTypesCase (tcu::TestContext& testCtx,
const std::string& name,
const std::string& description,
deUint32 flagsA,
deUint32 flagsB,
int numInstances,
MatrixLoadFlags matrixLoadFlag,
TestStageFlags testStageFlags)
: InterfaceBlockCase (testCtx, name, description, matrixLoadFlag, testStageFlags)
{
InterfaceBlock& blockA = m_interface.allocBlock("BlockA");
blockA.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
blockA.addInterfaceMember(InterfaceBlockMember("b", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), FIELD_UNASSIGNED));
blockA.addInterfaceMember(InterfaceBlockMember("c", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
blockA.setInstanceName("blockA");
blockA.setFlags(flagsA);
InterfaceBlock& blockB = m_interface.allocBlock("BlockB");
blockB.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_FLOAT_MAT3, PRECISION_MEDIUM)));
blockB.addInterfaceMember(InterfaceBlockMember("b", VarType(glu::TYPE_INT_VEC2, PRECISION_LOW)));
blockB.addInterfaceMember(InterfaceBlockMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH), FIELD_UNASSIGNED));
blockB.addInterfaceMember(InterfaceBlockMember("d", VarType(glu::TYPE_INT, 0)));
blockB.setInstanceName("blockB");
blockB.setFlags(flagsB);
if (numInstances > 0)
{
blockA.setArraySize(numInstances);
blockB.setArraySize(numInstances);
}
}
};
class BlockMultiNestedStructCase : public InterfaceBlockCase
{
public:
BlockMultiNestedStructCase (tcu::TestContext& testCtx,
const std::string& name,
const std::string& description,
deUint32 flagsA,
deUint32 flagsB,
int numInstances,
MatrixLoadFlags matrixLoadFlag,
TestStageFlags testStageFlags)
: InterfaceBlockCase (testCtx, name, description, matrixLoadFlag, testStageFlags)
{
StructType& typeS = m_interface.allocStruct("S");
typeS.addMember("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_LOW));
typeS.addMember("b", VarType(VarType(glu::TYPE_INT_VEC2, PRECISION_MEDIUM), 2));
StructType& typeT = m_interface.allocStruct("T");
typeT.addMember("a", VarType(glu::TYPE_UINT, PRECISION_MEDIUM), FIELD_UNASSIGNED);
typeT.addMember("b", VarType(&typeS));
typeT.addMember("c", VarType(glu::TYPE_UINT_VEC3, 0));
InterfaceBlock& blockA = m_interface.allocBlock("BlockA");
blockA.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_FLOAT, PRECISION_HIGH)));
blockA.addInterfaceMember(InterfaceBlockMember("b", VarType(&typeS)));
blockA.addInterfaceMember(InterfaceBlockMember("c", VarType(glu::TYPE_UINT, PRECISION_LOW), FIELD_UNASSIGNED));
blockA.setInstanceName("blockA");
blockA.setFlags(flagsA);
InterfaceBlock& blockB = m_interface.allocBlock("BlockB");
blockB.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
blockB.addInterfaceMember(InterfaceBlockMember("b", VarType(&typeT)));
blockB.addInterfaceMember(InterfaceBlockMember("c", VarType(glu::TYPE_INT, 0)));
blockB.setInstanceName("blockB");
blockB.setFlags(flagsB);
if (numInstances > 0)
{
blockA.setArraySize(numInstances);
blockB.setArraySize(numInstances);
}
}
};
class BlockVariousBuffersCase : public InterfaceBlockCase
{
public:
BlockVariousBuffersCase (tcu::TestContext& testCtx,
const std::string& name,
const std::string& description,
deUint32 flags,
deUint32 xfbBufferA,
deUint32 xfbBufferB,
deUint32 xfbBufferC,
int numInstances,
MatrixLoadFlags matrixLoadFlag,
TestStageFlags testStageFlags)
: InterfaceBlockCase (testCtx, name, description, matrixLoadFlag, testStageFlags)
{
StructType& typeS = m_interface.allocStruct("S");
typeS.addMember("a", VarType(VarType(glu::TYPE_FLOAT, PRECISION_LOW), 3));
typeS.addMember("b", VarType(VarType(glu::TYPE_FLOAT_VEC2, PRECISION_MEDIUM), 2));
typeS.addMember("c", VarType(glu::TYPE_FLOAT_VEC4, PRECISION_HIGH));
StructType& typeT = m_interface.allocStruct("T");
typeT.addMember("a", VarType(glu::TYPE_UINT, PRECISION_MEDIUM), FIELD_UNASSIGNED);
typeT.addMember("b", VarType(glu::TYPE_INT_VEC3, 0));
InterfaceBlock& blockA = m_interface.allocBlock("BlockA");
blockA.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_INT, PRECISION_HIGH)));
blockA.addInterfaceMember(InterfaceBlockMember("b", VarType(&typeS)));
blockA.addInterfaceMember(InterfaceBlockMember("c", VarType(glu::TYPE_UINT_VEC3, PRECISION_LOW), FIELD_UNASSIGNED));
blockA.setInstanceName("blockA");
blockA.setFlags(flags);
blockA.setXfbBuffer(xfbBufferA);
InterfaceBlock& blockB = m_interface.allocBlock("BlockB");
blockB.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM)));
blockB.addInterfaceMember(InterfaceBlockMember("b", VarType(&typeT)));
blockB.addInterfaceMember(InterfaceBlockMember("c", VarType(glu::TYPE_INT_VEC4, 0), FIELD_UNASSIGNED));
blockB.addInterfaceMember(InterfaceBlockMember("d", VarType(glu::TYPE_INT, 0)));
blockB.setInstanceName("blockB");
blockB.setFlags(flags);
blockB.setXfbBuffer(xfbBufferB);
InterfaceBlock& blockC = m_interface.allocBlock("BlockC");
blockC.addInterfaceMember(InterfaceBlockMember("a", VarType(glu::TYPE_UINT, PRECISION_HIGH)));
blockC.addInterfaceMember(InterfaceBlockMember("b", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_HIGH)));
blockC.setInstanceName("blockC");
blockC.setFlags(flags);
blockC.setXfbBuffer(xfbBufferC);
if (numInstances > 0)
{
blockA.setArraySize(numInstances);
blockB.setArraySize(numInstances);
}
}
};
class Block2LevelStructArrayCase : public InterfaceBlockCase
{
public:
Block2LevelStructArrayCase (tcu::TestContext& testCtx,
const std::string& name,
const std::string& description,
deUint32 flags,
int numInstances,
MatrixLoadFlags matrixLoadFlag,
TestStageFlags testStageFlags)
: InterfaceBlockCase (testCtx, name, description, matrixLoadFlag, testStageFlags)
{
StructType& typeS = m_interface.allocStruct("S");
typeS.addMember("a", VarType(glu::TYPE_UINT_VEC3, PRECISION_HIGH), FIELD_UNASSIGNED);
typeS.addMember("b", VarType(glu::TYPE_FLOAT_MAT2, PRECISION_MEDIUM));
InterfaceBlock& block = m_interface.allocBlock("Block");
block.addInterfaceMember(InterfaceBlockMember("u", VarType(glu::TYPE_INT, PRECISION_MEDIUM)));
block.addInterfaceMember(InterfaceBlockMember("s", VarType(VarType(VarType(&typeS), 2), 2)));
block.addInterfaceMember(InterfaceBlockMember("v", VarType(glu::TYPE_FLOAT_VEC2, PRECISION_MEDIUM)));
block.setFlags(flags);
if (numInstances > 0)
{
block.setInstanceName("block");
block.setArraySize(numInstances);
}
}
};
void createRandomCaseGroup (tcu::TestCaseGroup* parentGroup, tcu::TestContext& testCtx, const char* groupName, const char* description, deUint32 numCases, TestStageFlags testStageFlags, deUint32 features)
{
const deUint32 baseSeed = deStringHash(groupName) + static_cast<deUint32>(testCtx.getCommandLine().getBaseSeed());
tcu::TestCaseGroup* group = new tcu::TestCaseGroup(testCtx, groupName, description);
parentGroup->addChild(group);
for (deUint32 ndx = 0; ndx < numCases; ndx++)
group->addChild(new RandomInterfaceBlockCase(testCtx, de::toString(ndx), "", testStageFlags, features, ndx + baseSeed));
}
// InterfaceBlockTests
class InterfaceBlockTests : public tcu::TestCaseGroup
{
public:
InterfaceBlockTests (tcu::TestContext& testCtx);
~InterfaceBlockTests (void);
void init (void);
private:
InterfaceBlockTests (const InterfaceBlockTests& other);
InterfaceBlockTests& operator= (const InterfaceBlockTests& other);
};
InterfaceBlockTests::InterfaceBlockTests (tcu::TestContext& testCtx)
: TestCaseGroup(testCtx, "fuzz", "Transform feedback fuzz tests")
{
}
InterfaceBlockTests::~InterfaceBlockTests (void)
{
}
void InterfaceBlockTests::init (void)
{
static const glu::DataType basicTypes[] =
{
glu::TYPE_FLOAT,
glu::TYPE_FLOAT_VEC2,
glu::TYPE_FLOAT_VEC3,
glu::TYPE_FLOAT_VEC4,
glu::TYPE_INT,
glu::TYPE_INT_VEC2,
glu::TYPE_INT_VEC3,
glu::TYPE_INT_VEC4,
glu::TYPE_UINT,
glu::TYPE_UINT_VEC2,
glu::TYPE_UINT_VEC3,
glu::TYPE_UINT_VEC4,
glu::TYPE_FLOAT_MAT2,
glu::TYPE_FLOAT_MAT3,
glu::TYPE_FLOAT_MAT4,
glu::TYPE_FLOAT_MAT2X3,
glu::TYPE_FLOAT_MAT2X4,
glu::TYPE_FLOAT_MAT3X2,
glu::TYPE_FLOAT_MAT3X4,
glu::TYPE_FLOAT_MAT4X2,
glu::TYPE_FLOAT_MAT4X3,
glu::TYPE_DOUBLE,
glu::TYPE_DOUBLE_VEC2,
glu::TYPE_DOUBLE_VEC3,
glu::TYPE_DOUBLE_VEC4,
glu::TYPE_DOUBLE_MAT2,
glu::TYPE_DOUBLE_MAT2X3,
glu::TYPE_DOUBLE_MAT2X4,
glu::TYPE_DOUBLE_MAT3X2,
glu::TYPE_DOUBLE_MAT3,
glu::TYPE_DOUBLE_MAT3X4,
glu::TYPE_DOUBLE_MAT4X2,
glu::TYPE_DOUBLE_MAT4X3,
glu::TYPE_DOUBLE_MAT4,
};
static const struct
{
const std::string name;
deUint32 flags;
} precisionFlags[] =
{
// TODO remove PRECISION_LOW because both PRECISION_LOW and PRECISION_MEDIUM means relaxed precision?
{ "lowp", PRECISION_LOW },
{ "mediump", PRECISION_MEDIUM },
{ "highp", PRECISION_HIGH }
};
const deUint32 defaultFlags = LAYOUT_XFBBUFFER | LAYOUT_XFBOFFSET;
// .2_level_array
{
tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_array", "2-level basic array variable in single buffer");
addChild(nestedArrayGroup);
for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
{
const glu::DataType type = basicTypes[basicTypeNdx];
const char* const typeName = glu::getDataTypeName(type);
const int childSize = 2;
const int parentSize = 2;
const VarType childType (VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH), childSize);
const VarType parentType (childType, parentSize);
createBlockBasicTypeCases(*nestedArrayGroup, m_testCtx, typeName, parentType, defaultFlags);
}
}
// .3_level_array
{
tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "3_level_array", "3-level basic array variable in single buffer");
addChild(nestedArrayGroup);
for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
{
const glu::DataType type = basicTypes[basicTypeNdx];
const char* const typeName = glu::getDataTypeName(type);
const int childSize0 = 2;
const int childSize1 = 2;
const int parentSize = 2;
const VarType childType0 (VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH), childSize0);
const VarType childType1 (childType0, childSize1);
const VarType parentType (childType1, parentSize);
createBlockBasicTypeCases(*nestedArrayGroup, m_testCtx, typeName, parentType, defaultFlags);
}
}
// .2_level_struct_array
{
tcu::TestCaseGroup* structArrayArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_struct_array", "Struct array in one interface block");
addChild(structArrayArrayGroup);
for (int isArray = 0; isArray < 2; isArray++)
{
const std::string baseName = isArray ? "instance_array" : "std";
const int numInstances = isArray ? 2 : 0;
structArrayArrayGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_vertex"), "", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
structArrayArrayGroup->addChild(new Block2LevelStructArrayCase(m_testCtx, (baseName + "_geometry"), "", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
}
}
// .single_basic_type
{
tcu::TestCaseGroup* singleBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_type", "Single basic variable in single buffer");
addChild(singleBasicTypeGroup);
for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
{
glu::DataType type = basicTypes[basicTypeNdx];
const char* const typeName = glu::getDataTypeName(type);
if (!dataTypeSupportsPrecisionModifier(type))
createBlockBasicTypeCases(*singleBasicTypeGroup, m_testCtx, typeName, VarType(type, 0), defaultFlags);
}
for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisionFlags); precNdx++)
{
de::MovePtr<tcu::TestCaseGroup> precGroup(new tcu::TestCaseGroup(m_testCtx, precisionFlags[precNdx].name.c_str(), ""));
for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
{
glu::DataType type = basicTypes[basicTypeNdx];
const char* const typeName = glu::getDataTypeName(type);
if (dataTypeSupportsPrecisionModifier(type))
createBlockBasicTypeCases(*precGroup, m_testCtx, typeName, VarType(type, precisionFlags[precNdx].flags), defaultFlags);
}
singleBasicTypeGroup->addChild(precGroup.release());
}
}
// .single_basic_array
{
tcu::TestCaseGroup* singleBasicArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_basic_array", "Single basic array variable in single buffer");
addChild(singleBasicArrayGroup);
for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
{
glu::DataType type = basicTypes[basicTypeNdx];
const char* const typeName = glu::getDataTypeName(type);
const int arraySize = 3;
createBlockBasicTypeCases(*singleBasicArrayGroup, m_testCtx, typeName,
VarType(VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH), arraySize),
defaultFlags);
}
}
// .single_struct
{
tcu::TestCaseGroup* singleStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct", "Single struct in interface block");
addChild(singleStructGroup);
for (int isArray = 0; isArray < 2; isArray++)
{
const std::string baseName = isArray ? "instance_array" : "std";
const int numInstances = isArray ? 3 : 0;
singleStructGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_vertex", "", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
singleStructGroup->addChild(new BlockSingleStructCase(m_testCtx, baseName + "_geometry", "", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
}
}
// .single_struct_array
{
tcu::TestCaseGroup* singleStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_struct_array", "Struct array in one interface block");
addChild(singleStructArrayGroup);
for (int isArray = 0; isArray < 2; isArray++)
{
const std::string baseName = isArray ? "instance_array" : "std";
const int numInstances = isArray ? 2 : 0;
singleStructArrayGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_vertex", "", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
singleStructArrayGroup->addChild(new BlockSingleStructArrayCase(m_testCtx, baseName + "_geometry", "", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
}
}
// .single_nested_struct
{
tcu::TestCaseGroup* singleNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct", "Nested struct in one interface block");
addChild(singleNestedStructGroup);
for (int isArray = 0; isArray < 2; isArray++)
{
const std::string baseName = isArray ? "instance_array" : "std";
const int numInstances = isArray ? 2 : 0;
singleNestedStructGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_vertex", "", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
singleNestedStructGroup->addChild(new BlockSingleNestedStructCase(m_testCtx, baseName + "_geometry", "", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
}
}
// .single_nested_struct_array
{
tcu::TestCaseGroup* singleNestedStructArrayGroup = new tcu::TestCaseGroup(m_testCtx, "single_nested_struct_array", "Nested struct array in one interface block");
addChild(singleNestedStructArrayGroup);
for (int isArray = 0; isArray < 2; isArray++)
{
const std::string baseName = isArray ? "instance_array" : "std";
const int numInstances = isArray ? 2 : 0;
singleNestedStructArrayGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_vertex", "", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
singleNestedStructArrayGroup->addChild(new BlockSingleNestedStructArrayCase(m_testCtx, baseName + "_geometry", "", defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
}
}
// .instance_array_basic_type
{
tcu::TestCaseGroup* instanceArrayBasicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "instance_array_basic_type", "Single basic variable in instance array");
addChild(instanceArrayBasicTypeGroup);
for (int basicTypeNdx = 0; basicTypeNdx < DE_LENGTH_OF_ARRAY(basicTypes); basicTypeNdx++)
{
glu::DataType type = basicTypes[basicTypeNdx];
const char* const typeName = glu::getDataTypeName(type);
const int numInstances = 3;
createBlockBasicTypeCases(*instanceArrayBasicTypeGroup, m_testCtx, typeName,
VarType(type, !dataTypeSupportsPrecisionModifier(type) ? 0 : PRECISION_HIGH),
defaultFlags, numInstances);
}
}
// .multi_basic_types
{
tcu::TestCaseGroup* multiBasicTypesGroup = new tcu::TestCaseGroup(m_testCtx, "multi_basic_types", "Multiple buffers with basic types");
addChild(multiBasicTypesGroup);
for (int isArray = 0; isArray < 2; isArray++)
{
const std::string baseName = isArray ? "instance_array" : "std";
const int numInstances = isArray ? 2 : 0;
multiBasicTypesGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_vertex", "", defaultFlags, defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
multiBasicTypesGroup->addChild(new BlockMultiBasicTypesCase(m_testCtx, baseName + "_geometry", "", defaultFlags, defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
}
}
// .multi_nested_struct
{
tcu::TestCaseGroup* multiNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "multi_nested_struct", "Multiple buffers with nested structs");
addChild(multiNestedStructGroup);
for (int isArray = 0; isArray < 2; isArray++)
{
const std::string baseName = isArray ? "instance_array" : "std";
const int numInstances = isArray ? 2 : 0;
multiNestedStructGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_vertex", "", defaultFlags, defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
multiNestedStructGroup->addChild(new BlockMultiNestedStructCase(m_testCtx, baseName + "_geometry", "", defaultFlags, defaultFlags, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
}
}
// .various_buffers
{
static const struct
{
const std::string name;
deUint32 bufferA;
deUint32 bufferB;
deUint32 bufferC;
} xfbBufferNumbers[] =
{
{ "000", 0, 0, 0 },
{ "010", 0, 1, 0 },
{ "100", 1, 0, 0 },
{ "110", 1, 1, 0 },
};
tcu::TestCaseGroup* multiNestedStructGroup = new tcu::TestCaseGroup(m_testCtx, "various_buffers", "Output data into several transform feedback buffers");
addChild(multiNestedStructGroup);
for (int xfbBufferNdx = 0; xfbBufferNdx < DE_LENGTH_OF_ARRAY(xfbBufferNumbers); xfbBufferNdx++)
{
const deUint32 bufferA = xfbBufferNumbers[xfbBufferNdx].bufferA;
const deUint32 bufferB = xfbBufferNumbers[xfbBufferNdx].bufferB;
const deUint32 bufferC = xfbBufferNumbers[xfbBufferNdx].bufferC;
for (int isArray = 0; isArray < 2; isArray++)
{
std::string baseName = "buffers" + xfbBufferNumbers[xfbBufferNdx].name;
const int numInstances = isArray ? 2 : 0;
if (isArray)
baseName += "_instance_array";
multiNestedStructGroup->addChild(new BlockVariousBuffersCase(m_testCtx, baseName + "_vertex", "", defaultFlags, bufferA, bufferB, bufferC, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_VERTEX));
multiNestedStructGroup->addChild(new BlockVariousBuffersCase(m_testCtx, baseName + "_geometry", "", defaultFlags, bufferA, bufferB, bufferC, numInstances, LOAD_FULL_MATRIX, TEST_STAGE_GEOMETRY));
}
}
}
// .random
{
static const struct
{
std::string name;
TestStageFlags testStageFlags;
}
stages[] =
{
{ "vertex", TEST_STAGE_VERTEX },
{ "geometry", TEST_STAGE_GEOMETRY },
};
for (size_t stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
{
const std::string groupName = "random_" + stages[stageNdx].name;
const TestStageFlags stage = stages[stageNdx].testStageFlags;
const deUint32 allBasicTypes = FEATURE_VECTORS|FEATURE_MATRICES|FEATURE_DOUBLES;
const deUint32 unused = FEATURE_UNASSIGNED_FIELDS|FEATURE_UNASSIGNED_BLOCK_MEMBERS;
const deUint32 disabled = FEATURE_INSTANCE_ARRAYS|FEATURE_MISSING_BLOCK_MEMBERS|FEATURE_OUT_OF_ORDER_OFFSETS; // OOO & missing offsets handled in a dedicated case group
const deUint32 allFeatures = ~disabled;
const deUint32 numCases = 50;
tcu::TestCaseGroup* group = new tcu::TestCaseGroup(m_testCtx, groupName.c_str(), "Random Interface Block cases");
addChild(group);
createRandomCaseGroup(group, m_testCtx, "scalar_types", "Scalar types only, per-block buffers", numCases, stage, unused );
createRandomCaseGroup(group, m_testCtx, "vector_types", "Scalar and vector types only, per-block buffers", numCases, stage, unused|FEATURE_VECTORS );
createRandomCaseGroup(group, m_testCtx, "basic_types", "All basic types, per-block buffers", numCases, stage, unused|allBasicTypes );
createRandomCaseGroup(group, m_testCtx, "basic_arrays", "Arrays, per-block buffers", numCases, stage, unused|allBasicTypes|FEATURE_ARRAYS);
createRandomCaseGroup(group, m_testCtx, "basic_instance_arrays", "Basic instance arrays, per-block buffers", numCases, stage, unused|allBasicTypes|FEATURE_INSTANCE_ARRAYS );
createRandomCaseGroup(group, m_testCtx, "nested_structs", "Nested structs, per-block buffers", numCases, stage, unused|allBasicTypes|FEATURE_STRUCTS );
createRandomCaseGroup(group, m_testCtx, "nested_structs_arrays", "Nested structs, arrays, per-block buffers", numCases, stage, unused|allBasicTypes|FEATURE_STRUCTS|FEATURE_ARRAYS );
createRandomCaseGroup(group, m_testCtx, "nested_structs_instance_arrays", "Nested structs, instance arrays, per-block buffers", numCases, stage, unused|allBasicTypes|FEATURE_STRUCTS|FEATURE_INSTANCE_ARRAYS );
createRandomCaseGroup(group, m_testCtx, "nested_structs_arrays_instance_arrays", "Nested structs, instance arrays, per-block buffers", numCases, stage, unused|allBasicTypes|FEATURE_STRUCTS|FEATURE_ARRAYS|FEATURE_INSTANCE_ARRAYS);
createRandomCaseGroup(group, m_testCtx, "all_instance_array", "All random features, shared buffer", numCases*2, stage, allFeatures|FEATURE_INSTANCE_ARRAYS);
createRandomCaseGroup(group, m_testCtx, "all_unordered_and_instance_array", "All random features, out of order member offsets", numCases*2, stage, allFeatures|FEATURE_OUT_OF_ORDER_OFFSETS|FEATURE_INSTANCE_ARRAYS);
createRandomCaseGroup(group, m_testCtx, "all_missing", "All random features, missing interface members", numCases*2, stage, allFeatures|FEATURE_MISSING_BLOCK_MEMBERS);
createRandomCaseGroup(group, m_testCtx, "all_unordered_and_missing", "All random features, unordered and missing members", numCases*2, stage, allFeatures|FEATURE_OUT_OF_ORDER_OFFSETS|FEATURE_MISSING_BLOCK_MEMBERS);
}
}
}
} // anonymous
tcu::TestCaseGroup* createTransformFeedbackFuzzLayoutTests (tcu::TestContext& testCtx)
{
return new InterfaceBlockTests(testCtx);
}
} // TransformFeedback
} // vkt