Add test: UBO out of order block member offsets
authorMaciej Jesionowski <maciej.jesionowski@mobica.com>
Tue, 11 Oct 2016 09:35:24 +0000 (11:35 +0200)
committerPyry Haulos <phaulos@google.com>
Fri, 18 Nov 2016 18:10:28 +0000 (13:10 -0500)
New tests:
- dEQP-VK.ubo.random.all_out_of_order_offsets.*

Modified tests:
- dEQP-VK.ubo.* - changed GLSL version from '310 es' to '450'
- dEQP-VK.ubo.random.all_* - include arrays of arrays

Version change is required to support 'offset' layout in GLSL.

Fixes #490

Change-Id: I0c07dcebd85874d64146e48db8fefe8ad9f88877

android/cts/master/vk-master.txt
external/vulkancts/modules/vulkan/ubo/vktRandomUniformBlockCase.cpp
external/vulkancts/modules/vulkan/ubo/vktRandomUniformBlockCase.hpp
external/vulkancts/modules/vulkan/ubo/vktUniformBlockCase.cpp
external/vulkancts/modules/vulkan/ubo/vktUniformBlockCase.hpp
external/vulkancts/modules/vulkan/ubo/vktUniformBlockTests.cpp
external/vulkancts/mustpass/1.0.2/vk-default.txt

index 0a21070..e63885b 100644 (file)
@@ -102796,6 +102796,56 @@ dEQP-VK.ubo.random.all_shared_buffer.46
 dEQP-VK.ubo.random.all_shared_buffer.47
 dEQP-VK.ubo.random.all_shared_buffer.48
 dEQP-VK.ubo.random.all_shared_buffer.49
+dEQP-VK.ubo.random.all_out_of_order_offsets.0
+dEQP-VK.ubo.random.all_out_of_order_offsets.1
+dEQP-VK.ubo.random.all_out_of_order_offsets.2
+dEQP-VK.ubo.random.all_out_of_order_offsets.3
+dEQP-VK.ubo.random.all_out_of_order_offsets.4
+dEQP-VK.ubo.random.all_out_of_order_offsets.5
+dEQP-VK.ubo.random.all_out_of_order_offsets.6
+dEQP-VK.ubo.random.all_out_of_order_offsets.7
+dEQP-VK.ubo.random.all_out_of_order_offsets.8
+dEQP-VK.ubo.random.all_out_of_order_offsets.9
+dEQP-VK.ubo.random.all_out_of_order_offsets.10
+dEQP-VK.ubo.random.all_out_of_order_offsets.11
+dEQP-VK.ubo.random.all_out_of_order_offsets.12
+dEQP-VK.ubo.random.all_out_of_order_offsets.13
+dEQP-VK.ubo.random.all_out_of_order_offsets.14
+dEQP-VK.ubo.random.all_out_of_order_offsets.15
+dEQP-VK.ubo.random.all_out_of_order_offsets.16
+dEQP-VK.ubo.random.all_out_of_order_offsets.17
+dEQP-VK.ubo.random.all_out_of_order_offsets.18
+dEQP-VK.ubo.random.all_out_of_order_offsets.19
+dEQP-VK.ubo.random.all_out_of_order_offsets.20
+dEQP-VK.ubo.random.all_out_of_order_offsets.21
+dEQP-VK.ubo.random.all_out_of_order_offsets.22
+dEQP-VK.ubo.random.all_out_of_order_offsets.23
+dEQP-VK.ubo.random.all_out_of_order_offsets.24
+dEQP-VK.ubo.random.all_out_of_order_offsets.25
+dEQP-VK.ubo.random.all_out_of_order_offsets.26
+dEQP-VK.ubo.random.all_out_of_order_offsets.27
+dEQP-VK.ubo.random.all_out_of_order_offsets.28
+dEQP-VK.ubo.random.all_out_of_order_offsets.29
+dEQP-VK.ubo.random.all_out_of_order_offsets.30
+dEQP-VK.ubo.random.all_out_of_order_offsets.31
+dEQP-VK.ubo.random.all_out_of_order_offsets.32
+dEQP-VK.ubo.random.all_out_of_order_offsets.33
+dEQP-VK.ubo.random.all_out_of_order_offsets.34
+dEQP-VK.ubo.random.all_out_of_order_offsets.35
+dEQP-VK.ubo.random.all_out_of_order_offsets.36
+dEQP-VK.ubo.random.all_out_of_order_offsets.37
+dEQP-VK.ubo.random.all_out_of_order_offsets.38
+dEQP-VK.ubo.random.all_out_of_order_offsets.39
+dEQP-VK.ubo.random.all_out_of_order_offsets.40
+dEQP-VK.ubo.random.all_out_of_order_offsets.41
+dEQP-VK.ubo.random.all_out_of_order_offsets.42
+dEQP-VK.ubo.random.all_out_of_order_offsets.43
+dEQP-VK.ubo.random.all_out_of_order_offsets.44
+dEQP-VK.ubo.random.all_out_of_order_offsets.45
+dEQP-VK.ubo.random.all_out_of_order_offsets.46
+dEQP-VK.ubo.random.all_out_of_order_offsets.47
+dEQP-VK.ubo.random.all_out_of_order_offsets.48
+dEQP-VK.ubo.random.all_out_of_order_offsets.49
 dEQP-VK.dynamic_state.vp_state.viewport
 dEQP-VK.dynamic_state.vp_state.scissor
 dEQP-VK.dynamic_state.vp_state.viewport_array
index 4e91553..49824f5 100644 (file)
@@ -58,7 +58,7 @@ RandomUniformBlockCase::RandomUniformBlockCase (tcu::TestContext&     testCtx,
                                                                                                BufferMode                      bufferMode,
                                                                                                deUint32                        features,
                                                                                                deUint32                        seed)
-       : UniformBlockCase              (testCtx, name, description, bufferMode, LOAD_FULL_MATRIX)
+       : UniformBlockCase              (testCtx, name, description, bufferMode, LOAD_FULL_MATRIX, (features & FEATURE_OUT_OF_ORDER_OFFSETS) != 0u)
        , m_features                    (features)
        , m_maxVertexBlocks             ((features & FEATURE_VERTEX_BLOCKS)             ? 4 : 0)
        , m_maxFragmentBlocks   ((features & FEATURE_FRAGMENT_BLOCKS)   ? 4 : 0)
@@ -177,7 +177,7 @@ VarType RandomUniformBlockCase::generateType (de::Random& rnd, int typeDepth, bo
                        structType.addMember(std::string("m") + (char)('A' + ndx), memberTypes[ndx], flags);
                }
 
-               return VarType(&structType);
+               return VarType(&structType, m_shuffleUniformMembers ? static_cast<deUint32>(LAYOUT_OFFSET) : 0u);
        }
        else if (m_maxArrayLength > 0 && arrayOk && rnd.getFloat() < arrayWeight)
        {
@@ -224,7 +224,7 @@ VarType RandomUniformBlockCase::generateType (de::Random& rnd, int typeDepth, bo
                }
 
                glu::DataType   type    = rnd.choose<glu::DataType>(typeCandidates.begin(), typeCandidates.end());
-               deUint32                flags   = 0;
+               deUint32                flags   = (m_shuffleUniformMembers ? static_cast<deUint32>(LAYOUT_OFFSET) : 0u);
 
                if (!glu::isDataTypeBoolOrBVec(type))
                {
index 5030fb4..5d7559d 100644 (file)
@@ -38,22 +38,23 @@ namespace ubo
 
 enum FeatureBits
 {
-       FEATURE_VECTORS                         = (1<<0),
-       FEATURE_MATRICES                        = (1<<1),
-       FEATURE_ARRAYS                          = (1<<2),
-       FEATURE_STRUCTS                         = (1<<3),
-       FEATURE_NESTED_STRUCTS          = (1<<4),
-       FEATURE_INSTANCE_ARRAYS         = (1<<5),
-       FEATURE_VERTEX_BLOCKS           = (1<<6),
-       FEATURE_FRAGMENT_BLOCKS         = (1<<7),
-       FEATURE_SHARED_BLOCKS           = (1<<8),
-       FEATURE_UNUSED_UNIFORMS         = (1<<9),
-       FEATURE_UNUSED_MEMBERS          = (1<<10),
-       FEATURE_PACKED_LAYOUT           = (1<<12),
-       FEATURE_SHARED_LAYOUT           = (1<<13),
-       FEATURE_STD140_LAYOUT           = (1<<14),
-       FEATURE_MATRIX_LAYOUT           = (1<<15),      //!< Matrix layout flags.
-       FEATURE_ARRAYS_OF_ARRAYS        = (1<<16)
+       FEATURE_VECTORS                                 = (1<<0),
+       FEATURE_MATRICES                                = (1<<1),
+       FEATURE_ARRAYS                                  = (1<<2),
+       FEATURE_STRUCTS                                 = (1<<3),
+       FEATURE_NESTED_STRUCTS                  = (1<<4),
+       FEATURE_INSTANCE_ARRAYS                 = (1<<5),
+       FEATURE_VERTEX_BLOCKS                   = (1<<6),
+       FEATURE_FRAGMENT_BLOCKS                 = (1<<7),
+       FEATURE_SHARED_BLOCKS                   = (1<<8),
+       FEATURE_UNUSED_UNIFORMS                 = (1<<9),
+       FEATURE_UNUSED_MEMBERS                  = (1<<10),
+       FEATURE_PACKED_LAYOUT                   = (1<<12),
+       FEATURE_SHARED_LAYOUT                   = (1<<13),
+       FEATURE_STD140_LAYOUT                   = (1<<14),
+       FEATURE_MATRIX_LAYOUT                   = (1<<15),      //!< Matrix layout flags.
+       FEATURE_ARRAYS_OF_ARRAYS                = (1<<16),
+       FEATURE_OUT_OF_ORDER_OFFSETS    = (1<<17),
 };
 
 class RandomUniformBlockCase : public UniformBlockCase
index 5a5db75..a9ee588 100644 (file)
@@ -83,9 +83,9 @@ VarType::VarType (const VarType& elementType, int arraySize)
        m_data.array.elementType        = new VarType(elementType);
 }
 
-VarType::VarType (const StructType* structPtr)
+VarType::VarType (const StructType* structPtr, deUint32 flags)
        : m_type        (TYPE_STRUCT)
-       , m_flags       (0)
+       , m_flags       (flags)
 {
        m_data.structPtr = structPtr;
 }
@@ -263,7 +263,8 @@ std::ostream& operator<< (std::ostream& str, const PrecisionFlagsFmt& fmt)
 struct LayoutFlagsFmt
 {
        deUint32 flags;
-       LayoutFlagsFmt (deUint32 flags_) : flags(flags_) {}
+       deUint32 offset;
+       LayoutFlagsFmt (deUint32 flags_, deUint32 offset_ = 0u) : flags(flags_), offset(offset_) {}
 };
 
 std::ostream& operator<< (std::ostream& str, const LayoutFlagsFmt& fmt)
@@ -276,7 +277,8 @@ std::ostream& operator<< (std::ostream& str, const LayoutFlagsFmt& fmt)
        {
                { LAYOUT_STD140,                "std140"                },
                { LAYOUT_ROW_MAJOR,             "row_major"             },
-               { LAYOUT_COLUMN_MAJOR,  "column_major"  }
+               { LAYOUT_COLUMN_MAJOR,  "column_major"  },
+               { LAYOUT_OFFSET,                "offset"                },
        };
 
        deUint32 remBits = fmt.flags;
@@ -287,6 +289,8 @@ std::ostream& operator<< (std::ostream& str, const LayoutFlagsFmt& fmt)
                        if (remBits != fmt.flags)
                                str << ", ";
                        str << bitDesc[descNdx].token;
+                       if (bitDesc[descNdx].bit == LAYOUT_OFFSET)
+                               str << " = " << fmt.offset;
                        remBits &= ~bitDesc[descNdx].bit;
                }
        }
@@ -756,8 +760,8 @@ std::ostream& operator<< (std::ostream& str, const Indent& indent)
        return str;
 }
 
-void           generateDeclaration                     (std::ostringstream& src, const VarType& type, const std::string& name, int indentLevel, deUint32 unusedHints);
-void           generateDeclaration                     (std::ostringstream& src, const Uniform& uniform, int indentLevel);
+void           generateDeclaration                     (std::ostringstream& src, const VarType& type, const std::string& name, int indentLevel, deUint32 unusedHints, deUint32 flagsMask, deUint32 offset);
+void           generateDeclaration                     (std::ostringstream& src, const Uniform& uniform, int indentLevel, deUint32 offset);
 void           generateDeclaration                     (std::ostringstream& src, const StructType& structType, int indentLevel);
 
 void           generateLocalDeclaration        (std::ostringstream& src, const StructType& structType, int indentLevel);
@@ -780,7 +784,7 @@ void generateFullDeclaration (std::ostringstream& src, const StructType& structT
        for (StructType::ConstIterator memberIter = structType.begin(); memberIter != structType.end(); memberIter++)
        {
                src << Indent(indentLevel + 1);
-               generateDeclaration(src, memberIter->getType(), memberIter->getName(), indentLevel + 1, memberIter->getFlags() & UNUSED_BOTH);
+               generateDeclaration(src, memberIter->getType(), memberIter->getName(), indentLevel + 1, memberIter->getFlags() & UNUSED_BOTH, ~LAYOUT_OFFSET, 0u);
        }
 
        src << Indent(indentLevel) << "}";
@@ -791,15 +795,18 @@ void generateLocalDeclaration (std::ostringstream& src, const StructType& struct
        src << structType.getTypeName();
 }
 
-void generateDeclaration (std::ostringstream& src, const VarType& type, const std::string& name, int indentLevel, deUint32 unusedHints)
+void generateLayoutAndPrecisionDeclaration (std::ostringstream& src, deUint32 flags, deUint32 offset)
 {
-       deUint32 flags = type.getFlags();
-
        if ((flags & LAYOUT_MASK) != 0)
-               src << "layout(" << LayoutFlagsFmt(flags & LAYOUT_MASK) << ") ";
+               src << "layout(" << LayoutFlagsFmt(flags & LAYOUT_MASK, offset) << ") ";
 
        if ((flags & PRECISION_MASK) != 0)
                src << PrecisionFlagsFmt(flags & PRECISION_MASK) << " ";
+}
+
+void generateDeclaration (std::ostringstream& src, const VarType& type, const std::string& name, int indentLevel, deUint32 unusedHints, deUint32 flagsMask, deUint32 offset)
+{
+       generateLayoutAndPrecisionDeclaration(src, type.getFlags() & flagsMask, offset);
 
        if (type.isBasicType())
                src << glu::getDataTypeName(type.getBasicType()) << " " << name;
@@ -813,12 +820,10 @@ void generateDeclaration (std::ostringstream& src, const VarType& type, const st
                        curType = &curType->getElementType();
                }
 
+               generateLayoutAndPrecisionDeclaration(src, curType->getFlags() & flagsMask, offset);
+
                if (curType->isBasicType())
-               {
-                       if ((curType->getFlags() & PRECISION_MASK) != 0)
-                               src << PrecisionFlagsFmt(curType->getFlags() & PRECISION_MASK) << " ";
                        src << glu::getDataTypeName(curType->getBasicType());
-               }
                else
                {
                        DE_ASSERT(curType->isStructType());
@@ -847,15 +852,94 @@ void generateDeclaration (std::ostringstream& src, const VarType& type, const st
        src << "\n";
 }
 
-void generateDeclaration (std::ostringstream& src, const Uniform& uniform, int indentLevel)
+void generateDeclaration (std::ostringstream& src, const Uniform& uniform, int indentLevel, deUint32 offset)
 {
        if ((uniform.getFlags() & LAYOUT_MASK) != 0)
                src << "layout(" << LayoutFlagsFmt(uniform.getFlags() & LAYOUT_MASK) << ") ";
 
-       generateDeclaration(src, uniform.getType(), uniform.getName(), indentLevel, uniform.getFlags() & UNUSED_BOTH);
+       generateDeclaration(src, uniform.getType(), uniform.getName(), indentLevel, uniform.getFlags() & UNUSED_BOTH, ~0u, offset);
+}
+
+deUint32 getBlockMemberOffset (int blockNdx, const UniformBlock& block, const Uniform& uniform, const UniformLayout& layout)
+{
+       std::ostringstream      name;
+       const VarType*          curType = &uniform.getType();
+
+       if (block.getInstanceName().length() != 0)
+               name << block.getBlockName() << ".";    // \note UniformLayoutEntry uses block name rather than instance name
+
+       name << uniform.getName();
+
+       while (!curType->isBasicType())
+       {
+               if (curType->isArrayType())
+               {
+                       name << "[0]";
+                       curType = &curType->getElementType();
+               }
+
+               if (curType->isStructType())
+               {
+                       const StructType::ConstIterator firstMember = curType->getStruct().begin();
+                       name << "." << firstMember->getName();
+                       curType = &firstMember->getType();
+               }
+       }
+
+       const int uniformNdx = layout.getUniformLayoutIndex(blockNdx, name.str());
+       DE_ASSERT(uniformNdx >= 0);
+
+       return layout.uniforms[uniformNdx].offset;
 }
 
-void generateDeclaration (std::ostringstream& src, int blockNdx, const UniformBlock& block)
+template<typename T>
+void semiShuffle (std::vector<T>& v)
+{
+       const std::vector<T>    src     = v;
+       int                                             i       = -1;
+       int                                             n       = static_cast<int>(src.size());
+
+       v.clear();
+
+       while (n)
+       {
+               i += n;
+               v.push_back(src[i]);
+               n = (n > 0 ? 1 - n : -1 - n);
+       }
+}
+
+template<typename T>
+//! \note Stores pointers to original elements
+class Traverser
+{
+public:
+       template<typename Iter>
+       Traverser (const Iter beg, const Iter end, const bool shuffled)
+       {
+               for (Iter it = beg; it != end; ++it)
+                       m_elements.push_back(&(*it));
+
+               if (shuffled)
+                       semiShuffle(m_elements);
+
+               m_next = m_elements.begin();
+       }
+
+       T* next (void)
+       {
+               if (m_next != m_elements.end())
+                       return *m_next++;
+               else
+                       return DE_NULL;
+       }
+
+private:
+       typename std::vector<T*>                                        m_elements;
+       typename std::vector<T*>::const_iterator        m_next;
+};
+
+void generateDeclaration (std::ostringstream& src, int blockNdx, const UniformBlock& block, const UniformLayout& layout, bool shuffleUniformMembers)
 {
        src << "layout(set = 0, binding = " << blockNdx;
        if ((block.getFlags() & LAYOUT_MASK) != 0)
@@ -865,10 +949,12 @@ void generateDeclaration (std::ostringstream& src, int blockNdx, const UniformBl
        src << "uniform " << block.getBlockName();
        src << "\n{\n";
 
-       for (UniformBlock::ConstIterator uniformIter = block.begin(); uniformIter != block.end(); uniformIter++)
+       Traverser<const Uniform> uniforms(block.begin(), block.end(), shuffleUniformMembers);
+
+       while (const Uniform* pUniform = uniforms.next())
        {
                src << Indent(1);
-               generateDeclaration(src, *uniformIter, 1 /* indent level */);
+               generateDeclaration(src, *pUniform, 1 /* indent level */, getBlockMemberOffset(blockNdx, block, *pUniform, layout));
        }
 
        src << "}";
@@ -1240,10 +1326,10 @@ void generateCompareSrc (std::ostringstream& src,
        }
 }
 
-std::string generateVertexShader (const ShaderInterface& interface, const UniformLayout& layout, const std::map<int, void*>& blockPointers, MatrixLoadFlags matrixLoadFlag)
+std::string generateVertexShader (const ShaderInterface& interface, const UniformLayout& layout, const std::map<int, void*>& blockPointers, MatrixLoadFlags matrixLoadFlag, bool shuffleUniformMembers)
 {
        std::ostringstream src;
-       src << "#version 310 es\n";
+       src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n";
 
        src << "layout(location = 0) in highp vec4 a_position;\n";
        src << "layout(location = 0) out mediump float v_vtxResult;\n";
@@ -1258,7 +1344,7 @@ std::string generateVertexShader (const ShaderInterface& interface, const Unifor
        {
                const UniformBlock& block = interface.getUniformBlock(blockNdx);
                if (block.getFlags() & DECLARE_VERTEX)
-                       generateDeclaration(src, blockNdx, block);
+                       generateDeclaration(src, blockNdx, block, layout, shuffleUniformMembers);
        }
 
        // Comparison utilities.
@@ -1280,10 +1366,10 @@ std::string generateVertexShader (const ShaderInterface& interface, const Unifor
        return src.str();
 }
 
-std::string generateFragmentShader (const ShaderInterface& interface, const UniformLayout& layout, const std::map<int, void*>& blockPointers, MatrixLoadFlags matrixLoadFlag)
+std::string generateFragmentShader (const ShaderInterface& interface, const UniformLayout& layout, const std::map<int, void*>& blockPointers, MatrixLoadFlags matrixLoadFlag, bool shuffleUniformMembers)
 {
        std::ostringstream src;
-       src << "#version 310 es\n";
+       src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n";
 
        src << "layout(location = 0) in mediump float v_vtxResult;\n";
        src << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n";
@@ -1298,7 +1384,7 @@ std::string generateFragmentShader (const ShaderInterface& interface, const Unif
        {
                const UniformBlock& block = interface.getUniformBlock(blockNdx);
                if (block.getFlags() & DECLARE_FRAGMENT)
-                       generateDeclaration(src, blockNdx, block);
+                       generateDeclaration(src, blockNdx, block, layout, shuffleUniformMembers);
        }
 
        // Comparison utilities.
@@ -2170,10 +2256,11 @@ vk::Move<VkPipeline> UniformBlockCaseInstance::createPipeline (vk::VkShaderModul
 
 // UniformBlockCase.
 
-UniformBlockCase::UniformBlockCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, BufferMode bufferMode, MatrixLoadFlags matrixLoadFlag)
-       : TestCase                      (testCtx, name, description)
-       , m_bufferMode          (bufferMode)
-       , m_matrixLoadFlag      (matrixLoadFlag)
+UniformBlockCase::UniformBlockCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, BufferMode bufferMode, MatrixLoadFlags matrixLoadFlag, bool shuffleUniformMembers)
+       : TestCase                                      (testCtx, name, description)
+       , m_bufferMode                          (bufferMode)
+       , m_matrixLoadFlag                      (matrixLoadFlag)
+       , m_shuffleUniformMembers       (shuffleUniformMembers)
 {
 }
 
@@ -2220,8 +2307,8 @@ void UniformBlockCase::init (void)
        generateValues(m_uniformLayout, m_blockPointers, 1 /* seed */);
 
        // Generate shaders.
-       m_vertShaderSource = generateVertexShader(m_interface, m_uniformLayout, m_blockPointers, m_matrixLoadFlag);
-       m_fragShaderSource = generateFragmentShader(m_interface, m_uniformLayout, m_blockPointers, m_matrixLoadFlag);
+       m_vertShaderSource = generateVertexShader(m_interface, m_uniformLayout, m_blockPointers, m_matrixLoadFlag, m_shuffleUniformMembers);
+       m_fragShaderSource = generateFragmentShader(m_interface, m_uniformLayout, m_blockPointers, m_matrixLoadFlag, m_shuffleUniformMembers);
 }
 
 } // ubo
index 4f70d73..415ff5b 100644 (file)
@@ -50,14 +50,15 @@ enum UniformFlags
        LAYOUT_STD140           = (1<<5),
        LAYOUT_ROW_MAJOR        = (1<<6),
        LAYOUT_COLUMN_MAJOR     = (1<<7),       //!< \note Lack of both flags means column-major matrix.
-       LAYOUT_MASK                     = LAYOUT_SHARED|LAYOUT_PACKED|LAYOUT_STD140|LAYOUT_ROW_MAJOR|LAYOUT_COLUMN_MAJOR,
+       LAYOUT_OFFSET           = (1<<8),
+       LAYOUT_MASK                     = LAYOUT_SHARED|LAYOUT_PACKED|LAYOUT_STD140|LAYOUT_ROW_MAJOR|LAYOUT_COLUMN_MAJOR|LAYOUT_OFFSET,
 
-       DECLARE_VERTEX          = (1<<8),
-       DECLARE_FRAGMENT        = (1<<9),
+       DECLARE_VERTEX          = (1<<9),
+       DECLARE_FRAGMENT        = (1<<10),
        DECLARE_BOTH            = DECLARE_VERTEX|DECLARE_FRAGMENT,
 
-       UNUSED_VERTEX           = (1<<10),      //!< Uniform or struct member is not read in vertex shader.
-       UNUSED_FRAGMENT         = (1<<11),      //!< Uniform or struct member is not read in fragment shader.
+       UNUSED_VERTEX           = (1<<11),      //!< Uniform or struct member is not read in vertex shader.
+       UNUSED_FRAGMENT         = (1<<12),      //!< Uniform or struct member is not read in fragment shader.
        UNUSED_BOTH                     = UNUSED_VERTEX|UNUSED_FRAGMENT
 };
 
@@ -76,7 +77,7 @@ public:
                                                VarType                 (const VarType& other);
                                                VarType                 (glu::DataType basicType, deUint32 flags);
                                                VarType                 (const VarType& elementType, int arraySize);
-       explicit                        VarType                 (const StructType* structPtr);
+       explicit                        VarType                 (const StructType* structPtr, deUint32 flags = 0u);
                                                ~VarType                (void);
 
        bool                            isBasicType             (void) const    { return m_type == TYPE_BASIC;  }
@@ -305,7 +306,8 @@ public:
                                                                                                                         const std::string&     name,
                                                                                                                         const std::string&     description,
                                                                                                                         BufferMode                     bufferMode,
-                                                                                                                        MatrixLoadFlags        matrixLoadFlag);
+                                                                                                                        MatrixLoadFlags        matrixLoadFlag,
+                                                                                                                        bool                           shuffleUniformMembers = false);
                                                                ~UniformBlockCase                       (void);
 
        virtual void                            initPrograms                            (vk::SourceCollections& programCollection) const;
@@ -317,14 +319,15 @@ protected:
        BufferMode                                      m_bufferMode;
        ShaderInterface                         m_interface;
        MatrixLoadFlags                         m_matrixLoadFlag;
+       const bool                                      m_shuffleUniformMembers;        //!< Used with explicit offsets to test out of order member offsets
 
 private:
        std::string                                     m_vertShaderSource;
        std::string                                     m_fragShaderSource;
 
-       std::vector<deUint8>            m_data;                         //!< Data.
-       std::map<int, void*>            m_blockPointers;        //!< Reference block pointers.
-       UniformLayout                           m_uniformLayout;        //!< std140 layout.
+       std::vector<deUint8>            m_data;                                         //!< Data.
+       std::map<int, void*>            m_blockPointers;                        //!< Reference block pointers.
+       UniformLayout                           m_uniformLayout;                        //!< std140 layout.
 };
 
 } // ubo
index ed97d01..d37e3b9 100644 (file)
@@ -845,7 +845,7 @@ void UniformBlockTests::init (void)
                const deUint32  allBasicTypes   = FEATURE_VECTORS|FEATURE_MATRICES;
                const deUint32  unused                  = FEATURE_UNUSED_MEMBERS|FEATURE_UNUSED_UNIFORMS;
                const deUint32  matFlags                = FEATURE_MATRIX_LAYOUT;
-               const deUint32  allFeatures             = ~FEATURE_ARRAYS_OF_ARRAYS;
+               const deUint32  allFeatures             = ~FEATURE_OUT_OF_ORDER_OFFSETS;  // OOO offsets handled in a dedicated case group
 
                tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random Uniform Block cases");
                addChild(randomGroup);
@@ -864,6 +864,8 @@ void UniformBlockTests::init (void)
 
                createRandomCaseGroup(randomGroup, m_testCtx, "all_per_block_buffers",  "All random features, per-block buffers",       UniformBlockCase::BUFFERMODE_PER_BLOCK, allFeatures,    50, 200);
                createRandomCaseGroup(randomGroup, m_testCtx, "all_shared_buffer",              "All random features, shared buffer",           UniformBlockCase::BUFFERMODE_SINGLE,    allFeatures,    50, 250);
+
+               createRandomCaseGroup(randomGroup, m_testCtx, "all_out_of_order_offsets",       "All random features, out of order member offsets",             UniformBlockCase::BUFFERMODE_PER_BLOCK, allFeatures | FEATURE_OUT_OF_ORDER_OFFSETS,     50, 300);
        }
 }
 
index c32c208..0a5ec67 100644 (file)
@@ -96410,6 +96410,56 @@ dEQP-VK.ubo.random.all_shared_buffer.46
 dEQP-VK.ubo.random.all_shared_buffer.47
 dEQP-VK.ubo.random.all_shared_buffer.48
 dEQP-VK.ubo.random.all_shared_buffer.49
+dEQP-VK.ubo.random.all_out_of_order_offsets.0
+dEQP-VK.ubo.random.all_out_of_order_offsets.1
+dEQP-VK.ubo.random.all_out_of_order_offsets.2
+dEQP-VK.ubo.random.all_out_of_order_offsets.3
+dEQP-VK.ubo.random.all_out_of_order_offsets.4
+dEQP-VK.ubo.random.all_out_of_order_offsets.5
+dEQP-VK.ubo.random.all_out_of_order_offsets.6
+dEQP-VK.ubo.random.all_out_of_order_offsets.7
+dEQP-VK.ubo.random.all_out_of_order_offsets.8
+dEQP-VK.ubo.random.all_out_of_order_offsets.9
+dEQP-VK.ubo.random.all_out_of_order_offsets.10
+dEQP-VK.ubo.random.all_out_of_order_offsets.11
+dEQP-VK.ubo.random.all_out_of_order_offsets.12
+dEQP-VK.ubo.random.all_out_of_order_offsets.13
+dEQP-VK.ubo.random.all_out_of_order_offsets.14
+dEQP-VK.ubo.random.all_out_of_order_offsets.15
+dEQP-VK.ubo.random.all_out_of_order_offsets.16
+dEQP-VK.ubo.random.all_out_of_order_offsets.17
+dEQP-VK.ubo.random.all_out_of_order_offsets.18
+dEQP-VK.ubo.random.all_out_of_order_offsets.19
+dEQP-VK.ubo.random.all_out_of_order_offsets.20
+dEQP-VK.ubo.random.all_out_of_order_offsets.21
+dEQP-VK.ubo.random.all_out_of_order_offsets.22
+dEQP-VK.ubo.random.all_out_of_order_offsets.23
+dEQP-VK.ubo.random.all_out_of_order_offsets.24
+dEQP-VK.ubo.random.all_out_of_order_offsets.25
+dEQP-VK.ubo.random.all_out_of_order_offsets.26
+dEQP-VK.ubo.random.all_out_of_order_offsets.27
+dEQP-VK.ubo.random.all_out_of_order_offsets.28
+dEQP-VK.ubo.random.all_out_of_order_offsets.29
+dEQP-VK.ubo.random.all_out_of_order_offsets.30
+dEQP-VK.ubo.random.all_out_of_order_offsets.31
+dEQP-VK.ubo.random.all_out_of_order_offsets.32
+dEQP-VK.ubo.random.all_out_of_order_offsets.33
+dEQP-VK.ubo.random.all_out_of_order_offsets.34
+dEQP-VK.ubo.random.all_out_of_order_offsets.35
+dEQP-VK.ubo.random.all_out_of_order_offsets.36
+dEQP-VK.ubo.random.all_out_of_order_offsets.37
+dEQP-VK.ubo.random.all_out_of_order_offsets.38
+dEQP-VK.ubo.random.all_out_of_order_offsets.39
+dEQP-VK.ubo.random.all_out_of_order_offsets.40
+dEQP-VK.ubo.random.all_out_of_order_offsets.41
+dEQP-VK.ubo.random.all_out_of_order_offsets.42
+dEQP-VK.ubo.random.all_out_of_order_offsets.43
+dEQP-VK.ubo.random.all_out_of_order_offsets.44
+dEQP-VK.ubo.random.all_out_of_order_offsets.45
+dEQP-VK.ubo.random.all_out_of_order_offsets.46
+dEQP-VK.ubo.random.all_out_of_order_offsets.47
+dEQP-VK.ubo.random.all_out_of_order_offsets.48
+dEQP-VK.ubo.random.all_out_of_order_offsets.49
 dEQP-VK.dynamic_state.vp_state.viewport
 dEQP-VK.dynamic_state.vp_state.scissor
 dEQP-VK.dynamic_state.vp_state.viewport_array