/*------------------------------------------------------------------------ * 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 VarType& type, deUint32 layoutFlags, int numInstances, MatrixLoadFlags matrixLoadFlag, TestStageFlags testStageFlags) : InterfaceBlockCase(testCtx, name, 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 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, deUint32 layoutFlags, int numInstances, MatrixLoadFlags matrixLoadFlag, TestStageFlags testStageFlags) : InterfaceBlockCase (testCtx, name, 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, deUint32 layoutFlags, int numInstances, MatrixLoadFlags matrixLoadFlag, TestStageFlags testStageFlags) : InterfaceBlockCase (testCtx, name, 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, deUint32 layoutFlags, int numInstances, MatrixLoadFlags matrixLoadFlag, TestStageFlags testStageFlags) : InterfaceBlockCase (testCtx, name, 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, deUint32 layoutFlags, int numInstances, MatrixLoadFlags matrixLoadFlag, TestStageFlags testStageFlags) : InterfaceBlockCase (testCtx, name, 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, deUint32 flagsA, deUint32 flagsB, int numInstances, MatrixLoadFlags matrixLoadFlag, TestStageFlags testStageFlags) : InterfaceBlockCase (testCtx, name, 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, deUint32 flagsA, deUint32 flagsB, int numInstances, MatrixLoadFlags matrixLoadFlag, TestStageFlags testStageFlags) : InterfaceBlockCase (testCtx, name, 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, deUint32 flags, deUint32 xfbBufferA, deUint32 xfbBufferB, deUint32 xfbBufferC, int numInstances, MatrixLoadFlags matrixLoadFlag, TestStageFlags testStageFlags) : InterfaceBlockCase (testCtx, name, 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, deUint32 flags, int numInstances, MatrixLoadFlags matrixLoadFlag, TestStageFlags testStageFlags) : InterfaceBlockCase (testCtx, name, 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, deUint32 numCases, TestStageFlags testStageFlags, deUint32 features) { const deUint32 baseSeed = deStringHash(groupName) + static_cast(testCtx.getCommandLine().getBaseSeed()); tcu::TestCaseGroup* group = new tcu::TestCaseGroup(testCtx, groupName); 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") { } 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 { // 2-level basic array variable in single buffer tcu::TestCaseGroup* nestedArrayGroup = new tcu::TestCaseGroup(m_testCtx, "2_level_array"); 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 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); // Scalar types only, per-block buffers createRandomCaseGroup(group, m_testCtx, "scalar_types", numCases, stage, unused ); // Scalar and vector types only, per-block buffers createRandomCaseGroup(group, m_testCtx, "vector_types", numCases, stage, unused|FEATURE_VECTORS ); // All basic types, per-block buffers createRandomCaseGroup(group, m_testCtx, "basic_types", numCases, stage, unused|allBasicTypes ); // Arrays, per-block buffers createRandomCaseGroup(group, m_testCtx, "basic_arrays", numCases, stage, unused|allBasicTypes|FEATURE_ARRAYS); // Basic instance arrays, per-block buffers createRandomCaseGroup(group, m_testCtx, "basic_instance_arrays", numCases, stage, unused|allBasicTypes|FEATURE_INSTANCE_ARRAYS ); // Nested structs, per-block buffers createRandomCaseGroup(group, m_testCtx, "nested_structs", numCases, stage, unused|allBasicTypes|FEATURE_STRUCTS ); // Nested structs, arrays, per-block buffers createRandomCaseGroup(group, m_testCtx, "nested_structs_arrays", numCases, stage, unused|allBasicTypes|FEATURE_STRUCTS|FEATURE_ARRAYS ); // Nested structs, instance arrays, per-block buffers createRandomCaseGroup(group, m_testCtx, "nested_structs_instance_arrays", numCases, stage, unused|allBasicTypes|FEATURE_STRUCTS|FEATURE_INSTANCE_ARRAYS ); // Nested structs, instance arrays, per-block buffers createRandomCaseGroup(group, m_testCtx, "nested_structs_arrays_instance_arrays", numCases, stage, unused|allBasicTypes|FEATURE_STRUCTS|FEATURE_ARRAYS|FEATURE_INSTANCE_ARRAYS); // All random features, shared buffer createRandomCaseGroup(group, m_testCtx, "all_instance_array", numCases*2, stage, allFeatures|FEATURE_INSTANCE_ARRAYS); // All random features, out of order member offsets createRandomCaseGroup(group, m_testCtx, "all_unordered_and_instance_array", numCases*2, stage, allFeatures|FEATURE_OUT_OF_ORDER_OFFSETS|FEATURE_INSTANCE_ARRAYS); // All random features, missing interface members createRandomCaseGroup(group, m_testCtx, "all_missing", numCases*2, stage, allFeatures|FEATURE_MISSING_BLOCK_MEMBERS); // All random features, unordered and missing members createRandomCaseGroup(group, m_testCtx, "all_unordered_and_missing", 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