1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.1 Module
3 * -------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Program interface query tests.
22 *//*--------------------------------------------------------------------*/
24 #include "es31fProgramInterfaceQueryTests.hpp"
25 #include "es31fProgramInterfaceQueryTestCase.hpp"
26 #include "es31fProgramInterfaceDefinition.hpp"
27 #include "es31fProgramInterfaceDefinitionUtil.hpp"
28 #include "tcuTestLog.hpp"
29 #include "gluShaderProgram.hpp"
30 #include "gluVarTypeUtil.hpp"
31 #include "gluStrUtil.hpp"
32 #include "gluContextInfo.hpp"
33 #include "glwFunctions.hpp"
34 #include "glwEnums.hpp"
35 #include "deRandom.hpp"
37 #include "deStringUtil.hpp"
38 #include "deSharedPtr.hpp"
39 #include "deUniquePtr.hpp"
40 #include "deSTLUtil.hpp"
41 #include "deArrayUtil.hpp"
55 static int getTypeSize (glu::DataType type)
57 if (type == glu::TYPE_FLOAT)
59 else if (type == glu::TYPE_INT || type == glu::TYPE_UINT)
61 else if (type == glu::TYPE_BOOL)
68 static int getVarTypeSize (const glu::VarType& type)
70 if (type.isBasicType())
71 return glu::getDataTypeScalarSize(type.getBasicType()) * getTypeSize(glu::getDataTypeScalarType(type.getBasicType()));
72 else if (type.isStructType())
75 for (int ndx = 0; ndx < type.getStructPtr()->getNumMembers(); ++ndx)
76 size += getVarTypeSize(type.getStructPtr()->getMember(ndx).getType());
79 else if (type.isArrayType())
81 if (type.getArraySize() == glu::VarType::UNSIZED_ARRAY)
82 return getVarTypeSize(type.getElementType());
84 return type.getArraySize() * getVarTypeSize(type.getElementType());
93 static std::string convertGLTypeNameToTestName (const char* glName)
95 // vectors and matrices are fine as is
97 if (deStringBeginsWith(glName, "vec") == DE_TRUE ||
98 deStringBeginsWith(glName, "ivec") == DE_TRUE ||
99 deStringBeginsWith(glName, "uvec") == DE_TRUE ||
100 deStringBeginsWith(glName, "bvec") == DE_TRUE ||
101 deStringBeginsWith(glName, "mat") == DE_TRUE)
102 return std::string(glName);
105 // convert camel case to use underscore
107 std::ostringstream buf;
108 std::istringstream name (glName);
109 bool mergeNextToken = false;
110 bool previousTokenWasDigit = false;
114 std::ostringstream token;
116 while (name.peek() != EOF)
118 if ((de::isDigit((char)name.peek()) || de::isUpper((char)name.peek())) && token.tellp())
121 token << de::toLower((char)name.get());
124 if (buf.str().empty() || mergeNextToken)
127 buf << '_' << token.str();
129 // Single char causes next char to be merged (don't split initialisms or acronyms) unless it is 'D' after a number (split to ..._2d_acronym_aa
130 mergeNextToken = false;
131 if (token.tellp() == (std::streamoff)1)
133 if (!previousTokenWasDigit || token.str()[0] != 'd')
134 mergeNextToken = true;
136 previousTokenWasDigit = de::isDigit(token.str()[0]);
139 previousTokenWasDigit = false;
146 static glw::GLenum getProgramInterfaceGLEnum (ProgramInterface interface)
148 static const glw::GLenum s_enums[] =
150 GL_UNIFORM, // PROGRAMINTERFACE_UNIFORM
151 GL_UNIFORM_BLOCK, // PROGRAMINTERFACE_UNIFORM_BLOCK
152 GL_ATOMIC_COUNTER_BUFFER, // PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER
153 GL_PROGRAM_INPUT, // PROGRAMINTERFACE_PROGRAM_INPUT
154 GL_PROGRAM_OUTPUT, // PROGRAMINTERFACE_PROGRAM_OUTPUT
155 GL_TRANSFORM_FEEDBACK_VARYING, // PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING
156 GL_BUFFER_VARIABLE, // PROGRAMINTERFACE_BUFFER_VARIABLE
157 GL_SHADER_STORAGE_BLOCK, // PROGRAMINTERFACE_SHADER_STORAGE_BLOCK
160 return de::getSizedArrayElement<PROGRAMINTERFACE_LAST>(s_enums, interface);
163 static glu::ShaderType getShaderMaskFirstStage (deUint32 mask)
165 if (mask & (1u << glu::SHADERTYPE_COMPUTE))
166 return glu::SHADERTYPE_COMPUTE;
168 if (mask & (1u << glu::SHADERTYPE_VERTEX))
169 return glu::SHADERTYPE_VERTEX;
171 if (mask & (1u << glu::SHADERTYPE_TESSELLATION_CONTROL))
172 return glu::SHADERTYPE_TESSELLATION_CONTROL;
174 if (mask & (1u << glu::SHADERTYPE_TESSELLATION_EVALUATION))
175 return glu::SHADERTYPE_TESSELLATION_EVALUATION;
177 if (mask & (1u << glu::SHADERTYPE_GEOMETRY))
178 return glu::SHADERTYPE_GEOMETRY;
180 if (mask & (1u << glu::SHADERTYPE_FRAGMENT))
181 return glu::SHADERTYPE_FRAGMENT;
184 return glu::SHADERTYPE_LAST;
187 static glu::ShaderType getShaderMaskLastStage (deUint32 mask)
189 if (mask & (1u << glu::SHADERTYPE_FRAGMENT))
190 return glu::SHADERTYPE_FRAGMENT;
192 if (mask & (1u << glu::SHADERTYPE_GEOMETRY))
193 return glu::SHADERTYPE_GEOMETRY;
195 if (mask & (1u << glu::SHADERTYPE_TESSELLATION_EVALUATION))
196 return glu::SHADERTYPE_TESSELLATION_EVALUATION;
198 if (mask & (1u << glu::SHADERTYPE_TESSELLATION_CONTROL))
199 return glu::SHADERTYPE_TESSELLATION_CONTROL;
201 if (mask & (1u << glu::SHADERTYPE_VERTEX))
202 return glu::SHADERTYPE_VERTEX;
204 if (mask & (1u << glu::SHADERTYPE_COMPUTE))
205 return glu::SHADERTYPE_COMPUTE;
208 return glu::SHADERTYPE_LAST;
211 namespace ResourceDefinition
223 TYPE_INTERFACE_BLOCK,
226 TYPE_STORAGE_QUALIFIER,
227 TYPE_LAYOUT_QUALIFIER,
229 TYPE_INTERPOLATION_QUALIFIER,
230 TYPE_TRANSFORM_FEEDBACK_TARGET,
235 typedef de::SharedPtr<const Node> SharedPtr;
237 Node (NodeType type, const SharedPtr& enclosingNode) : m_type(type), m_enclosingNode(enclosingNode) { DE_ASSERT(type < TYPE_LAST); }
238 virtual ~Node (void) { }
240 inline const Node* getEnclosingNode (void) const { return m_enclosingNode.get(); }
241 inline NodeType getType (void) const { return m_type; }
244 const NodeType m_type;
245 const SharedPtr m_enclosingNode;
248 class Program : public Node
251 Program (bool separable = false)
252 : Node (TYPE_PROGRAM, SharedPtr())
253 , m_separable (separable)
257 const bool m_separable;
260 class Shader : public Node
263 Shader (const SharedPtr& enclosingNode, glu::ShaderType type, glu::GLSLVersion version)
264 : Node (TYPE_SHADER, enclosingNode)
266 , m_version (version)
268 DE_ASSERT(enclosingNode->getType() == TYPE_PROGRAM);
269 DE_ASSERT(type < glu::SHADERTYPE_LAST);
272 const glu::ShaderType m_type;
273 const glu::GLSLVersion m_version;
276 class DefaultBlock : public Node
279 DefaultBlock (const SharedPtr& enclosing)
280 : Node(TYPE_DEFAULT_BLOCK, enclosing)
282 // enclosed by the shader
283 DE_ASSERT(enclosing->getType() == TYPE_SHADER ||
284 enclosing->getType() == TYPE_SHADER_SET);
288 class StorageQualifier : public Node
291 StorageQualifier (const SharedPtr& enclosing, glu::Storage storage)
292 : Node (TYPE_STORAGE_QUALIFIER, enclosing)
293 , m_storage (storage)
295 // not a part of any block
296 DE_ASSERT(enclosing->getType() == TYPE_DEFAULT_BLOCK);
299 const glu::Storage m_storage;
302 class Variable : public Node
305 Variable (const SharedPtr& enclosing, glu::DataType dataType)
306 : Node (TYPE_VARIABLE, enclosing)
307 , m_dataType (dataType)
309 DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER ||
310 enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
311 enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER ||
312 enclosing->getType() == TYPE_INTERFACE_BLOCK ||
313 enclosing->getType() == TYPE_ARRAY_ELEMENT ||
314 enclosing->getType() == TYPE_STRUCT_MEMBER ||
315 enclosing->getType() == TYPE_TRANSFORM_FEEDBACK_TARGET);
318 const glu::DataType m_dataType;
321 class InterfaceBlock : public Node
324 InterfaceBlock (const SharedPtr& enclosing, bool named)
325 : Node (TYPE_INTERFACE_BLOCK, enclosing)
328 // Must be storage qualified
329 const Node* storageNode = enclosing.get();
330 while (storageNode->getType() == TYPE_ARRAY_ELEMENT ||
331 storageNode->getType() == TYPE_LAYOUT_QUALIFIER)
333 storageNode = storageNode->getEnclosingNode();
336 DE_ASSERT(storageNode->getType() == TYPE_STORAGE_QUALIFIER);
337 DE_UNREF(storageNode);
343 class ArrayElement : public Node
346 ArrayElement (const SharedPtr& enclosing, int arraySize = DEFAULT_SIZE)
347 : Node (TYPE_ARRAY_ELEMENT, enclosing)
348 , m_arraySize (arraySize)
350 DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER ||
351 enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
352 enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER ||
353 enclosing->getType() == TYPE_INTERFACE_BLOCK ||
354 enclosing->getType() == TYPE_ARRAY_ELEMENT ||
355 enclosing->getType() == TYPE_STRUCT_MEMBER ||
356 enclosing->getType() == TYPE_TRANSFORM_FEEDBACK_TARGET);
359 const int m_arraySize;
368 class StructMember : public Node
371 StructMember (const SharedPtr& enclosing)
372 : Node(TYPE_STRUCT_MEMBER, enclosing)
374 DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER ||
375 enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
376 enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER ||
377 enclosing->getType() == TYPE_INTERFACE_BLOCK ||
378 enclosing->getType() == TYPE_ARRAY_ELEMENT ||
379 enclosing->getType() == TYPE_STRUCT_MEMBER ||
380 enclosing->getType() == TYPE_TRANSFORM_FEEDBACK_TARGET);
384 class LayoutQualifier : public Node
387 LayoutQualifier (const SharedPtr& enclosing, const glu::Layout& layout)
388 : Node (TYPE_LAYOUT_QUALIFIER, enclosing)
391 DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER ||
392 enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
393 enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER ||
394 enclosing->getType() == TYPE_DEFAULT_BLOCK ||
395 enclosing->getType() == TYPE_INTERFACE_BLOCK);
398 const glu::Layout m_layout;
401 class InterpolationQualifier : public Node
404 InterpolationQualifier (const SharedPtr& enclosing, const glu::Interpolation& interpolation)
405 : Node (TYPE_INTERPOLATION_QUALIFIER, enclosing)
406 , m_interpolation (interpolation)
408 DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER ||
409 enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
410 enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER ||
411 enclosing->getType() == TYPE_DEFAULT_BLOCK ||
412 enclosing->getType() == TYPE_INTERFACE_BLOCK);
415 const glu::Interpolation m_interpolation;
418 class ShaderSet : public Node
421 ShaderSet (const SharedPtr& enclosing, glu::GLSLVersion version);
422 ShaderSet (const SharedPtr& enclosing, glu::GLSLVersion version, deUint32 stagesPresentBits, deUint32 stagesReferencingBits);
424 void setStage (glu::ShaderType type, bool referencing);
425 bool isStagePresent (glu::ShaderType stage) const;
426 bool isStageReferencing (glu::ShaderType stage) const;
428 deUint32 getPresentMask (void) const;
429 deUint32 getReferencingMask (void) const;
431 const glu::GLSLVersion m_version;
433 bool m_stagePresent[glu::SHADERTYPE_LAST];
434 bool m_stageReferencing[glu::SHADERTYPE_LAST];
437 ShaderSet::ShaderSet (const SharedPtr& enclosing, glu::GLSLVersion version)
438 : Node (TYPE_SHADER_SET, enclosing)
439 , m_version (version)
441 DE_ASSERT(enclosing->getType() == TYPE_PROGRAM);
443 deMemset(m_stagePresent, 0, sizeof(m_stagePresent));
444 deMemset(m_stageReferencing, 0, sizeof(m_stageReferencing));
447 ShaderSet::ShaderSet (const SharedPtr& enclosing,
448 glu::GLSLVersion version,
449 deUint32 stagesPresentBits,
450 deUint32 stagesReferencingBits)
451 : Node (TYPE_SHADER_SET, enclosing)
452 , m_version (version)
454 for (deUint32 stageNdx = 0; stageNdx < glu::SHADERTYPE_LAST; ++stageNdx)
456 const deUint32 stageMask = (1u << stageNdx);
457 const bool stagePresent = (stagesPresentBits & stageMask) != 0;
458 const bool stageReferencing = (stagesReferencingBits & stageMask) != 0;
460 DE_ASSERT(stagePresent || !stageReferencing);
462 m_stagePresent[stageNdx] = stagePresent;
463 m_stageReferencing[stageNdx] = stageReferencing;
467 void ShaderSet::setStage (glu::ShaderType type, bool referencing)
469 DE_ASSERT(type < glu::SHADERTYPE_LAST);
470 m_stagePresent[type] = true;
471 m_stageReferencing[type] = referencing;
474 bool ShaderSet::isStagePresent (glu::ShaderType stage) const
476 DE_ASSERT(stage < glu::SHADERTYPE_LAST);
477 return m_stagePresent[stage];
480 bool ShaderSet::isStageReferencing (glu::ShaderType stage) const
482 DE_ASSERT(stage < glu::SHADERTYPE_LAST);
483 return m_stageReferencing[stage];
486 deUint32 ShaderSet::getPresentMask (void) const
489 for (deUint32 stage = 0; stage < glu::SHADERTYPE_LAST; ++stage)
491 if (m_stagePresent[stage])
492 mask |= (1u << stage);
497 deUint32 ShaderSet::getReferencingMask (void) const
500 for (deUint32 stage = 0; stage < glu::SHADERTYPE_LAST; ++stage)
502 if (m_stageReferencing[stage])
503 mask |= (1u << stage);
508 class TransformFeedbackTarget : public Node
511 TransformFeedbackTarget (const SharedPtr& enclosing, const char* builtinVarName = DE_NULL)
512 : Node (TYPE_TRANSFORM_FEEDBACK_TARGET, enclosing)
513 , m_builtinVarName (builtinVarName)
517 const char* const m_builtinVarName;
520 } // ResourceDefinition
522 static glu::Precision getDataTypeDefaultPrecision (const glu::DataType& type)
524 if (glu::isDataTypeBoolOrBVec(type))
525 return glu::PRECISION_LAST;
526 else if (glu::isDataTypeScalarOrVector(type) || glu::isDataTypeMatrix(type))
527 return glu::PRECISION_HIGHP;
528 else if (glu::isDataTypeSampler(type))
529 return glu::PRECISION_HIGHP;
530 else if (glu::isDataTypeImage(type))
531 return glu::PRECISION_HIGHP;
532 else if (type == glu::TYPE_UINT_ATOMIC_COUNTER)
533 return glu::PRECISION_HIGHP;
536 return glu::PRECISION_LAST;
539 static de::MovePtr<ProgramInterfaceDefinition::Program> generateProgramDefinitionFromResource (const ResourceDefinition::Node* resource)
541 de::MovePtr<ProgramInterfaceDefinition::Program> program (new ProgramInterfaceDefinition::Program());
542 const ResourceDefinition::Node* head = resource;
544 if (head->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
546 DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));
551 BINDING_INTERFACE_BLOCK,
552 BINDING_DEFAULT_BLOCK
556 int autoAssignArraySize = 0;
557 const glu::DataType basicType = static_cast<const ResourceDefinition::Variable*>(resource)->m_dataType;
558 BindingType boundObject = BINDING_VARIABLE;
559 glu::VariableDeclaration variable (glu::VarType(basicType, getDataTypeDefaultPrecision(basicType)), "target");
560 glu::InterfaceBlock interfaceBlock;
561 ProgramInterfaceDefinition::DefaultBlock defaultBlock;
562 std::vector<std::string> feedbackTargetVaryingPath;
563 bool feedbackTargetSet = false;
566 if (glu::isDataTypeImage(basicType))
568 variable.memoryAccessQualifierBits |= glu::MEMORYACCESSQUALIFIER_READONLY_BIT;
569 variable.layout.binding = 1;
571 if (basicType >= glu::TYPE_IMAGE_2D && basicType <= glu::TYPE_IMAGE_3D)
572 variable.layout.format = glu::FORMATLAYOUT_RGBA8;
573 else if (basicType >= glu::TYPE_INT_IMAGE_2D && basicType <= glu::TYPE_INT_IMAGE_3D)
574 variable.layout.format = glu::FORMATLAYOUT_RGBA8I;
575 else if (basicType >= glu::TYPE_UINT_IMAGE_2D && basicType <= glu::TYPE_UINT_IMAGE_3D)
576 variable.layout.format = glu::FORMATLAYOUT_RGBA8UI;
581 // atomic counter specific
582 if (basicType == glu::TYPE_UINT_ATOMIC_COUNTER)
583 variable.layout.binding = 1;
585 for (head = head->getEnclosingNode(); head; head = head->getEnclosingNode())
587 if (head->getType() == ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER)
589 const ResourceDefinition::StorageQualifier* qualifier = static_cast<const ResourceDefinition::StorageQualifier*>(head);
591 DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(head));
593 if (boundObject == BINDING_VARIABLE)
595 DE_ASSERT(variable.storage == glu::STORAGE_LAST);
596 variable.storage = qualifier->m_storage;
598 else if (boundObject == BINDING_INTERFACE_BLOCK)
600 DE_ASSERT(interfaceBlock.storage == glu::STORAGE_LAST);
601 interfaceBlock.storage = qualifier->m_storage;
606 else if (head->getType() == ResourceDefinition::Node::TYPE_LAYOUT_QUALIFIER)
608 const ResourceDefinition::LayoutQualifier* qualifier = static_cast<const ResourceDefinition::LayoutQualifier*>(head);
609 glu::Layout* targetLayout = DE_NULL;
611 DE_ASSERT(dynamic_cast<const ResourceDefinition::LayoutQualifier*>(head));
613 if (boundObject == BINDING_VARIABLE)
614 targetLayout = &variable.layout;
615 else if (boundObject == BINDING_INTERFACE_BLOCK)
616 targetLayout = &interfaceBlock.layout;
620 if (qualifier->m_layout.location != -1)
621 targetLayout->location = qualifier->m_layout.location;
623 if (qualifier->m_layout.binding != -1)
624 targetLayout->binding = qualifier->m_layout.binding;
626 if (qualifier->m_layout.offset != -1)
627 targetLayout->offset = qualifier->m_layout.offset;
629 if (qualifier->m_layout.format != glu::FORMATLAYOUT_LAST)
630 targetLayout->format = qualifier->m_layout.format;
632 if (qualifier->m_layout.matrixOrder != glu::MATRIXORDER_LAST)
633 targetLayout->matrixOrder = qualifier->m_layout.matrixOrder;
635 else if (head->getType() == ResourceDefinition::Node::TYPE_INTERPOLATION_QUALIFIER)
637 const ResourceDefinition::InterpolationQualifier* qualifier = static_cast<const ResourceDefinition::InterpolationQualifier*>(head);
639 DE_ASSERT(dynamic_cast<const ResourceDefinition::InterpolationQualifier*>(head));
641 if (boundObject == BINDING_VARIABLE)
642 variable.interpolation = qualifier->m_interpolation;
646 else if (head->getType() == ResourceDefinition::Node::TYPE_ARRAY_ELEMENT)
648 DE_ASSERT(dynamic_cast<const ResourceDefinition::ArrayElement*>(head));
650 const ResourceDefinition::ArrayElement* arrayElement = static_cast<const ResourceDefinition::ArrayElement*>(head);
653 // Vary array size per level
654 if (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::DEFAULT_SIZE)
656 if (--autoAssignArraySize <= 1)
657 autoAssignArraySize = 3;
659 arraySize = autoAssignArraySize;
661 else if (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::UNSIZED_ARRAY)
662 arraySize = glu::VarType::UNSIZED_ARRAY;
664 arraySize = arrayElement->m_arraySize;
666 if (boundObject == BINDING_VARIABLE)
667 variable.varType = glu::VarType(variable.varType, arraySize);
668 else if (boundObject == BINDING_INTERFACE_BLOCK)
669 interfaceBlock.dimensions.push_back(arraySize);
673 if (feedbackTargetSet)
674 feedbackTargetVaryingPath.back().append("[0]");
676 else if (head->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER)
678 DE_ASSERT(dynamic_cast<const ResourceDefinition::StructMember*>(head));
679 DE_ASSERT(boundObject == BINDING_VARIABLE);
681 // Struct members cannot contain any qualifiers except precision
682 DE_ASSERT(variable.interpolation == glu::INTERPOLATION_LAST);
683 DE_ASSERT(variable.layout == glu::Layout());
684 DE_ASSERT(variable.memoryAccessQualifierBits == 0);
685 DE_ASSERT(variable.storage == glu::STORAGE_LAST);
688 glu::StructType* structPtr = new glu::StructType(("StructType" + de::toString(structNdx++)).c_str());
689 structPtr->addMember(variable.name.c_str(), variable.varType);
691 variable = glu::VariableDeclaration(glu::VarType(structPtr), "target");
694 if (feedbackTargetSet)
695 feedbackTargetVaryingPath.push_back("target");
697 else if (head->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
699 DE_ASSERT(dynamic_cast<const ResourceDefinition::InterfaceBlock*>(head));
700 DE_ASSERT(boundObject == BINDING_VARIABLE);
702 const bool named = static_cast<const ResourceDefinition::InterfaceBlock*>(head)->m_named;
704 boundObject = BINDING_INTERFACE_BLOCK;
706 interfaceBlock.interfaceName = "TargetInterface";
707 interfaceBlock.instanceName = (named) ? ("targetInstance") : ("");
708 interfaceBlock.variables.push_back(variable);
710 if (feedbackTargetSet && !interfaceBlock.instanceName.empty())
711 feedbackTargetVaryingPath.push_back(interfaceBlock.interfaceName);
713 else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
715 DE_ASSERT(dynamic_cast<const ResourceDefinition::DefaultBlock*>(head));
716 DE_ASSERT(boundObject == BINDING_VARIABLE || boundObject == BINDING_INTERFACE_BLOCK);
718 if (boundObject == BINDING_VARIABLE)
719 defaultBlock.variables.push_back(variable);
720 else if (boundObject == BINDING_INTERFACE_BLOCK)
721 defaultBlock.interfaceBlocks.push_back(interfaceBlock);
725 boundObject = BINDING_DEFAULT_BLOCK;
727 else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER)
729 DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(head));
731 const ResourceDefinition::Shader* shaderDef = static_cast<const ResourceDefinition::Shader*>(head);
732 ProgramInterfaceDefinition::Shader* shader = program->addShader(shaderDef->m_type, shaderDef->m_version);
734 shader->getDefaultBlock() = defaultBlock;
736 else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER_SET)
738 DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(head));
740 const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(head);
742 for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
744 if (shaderDef->isStagePresent((glu::ShaderType)shaderType))
746 ProgramInterfaceDefinition::Shader* shader = program->addShader((glu::ShaderType)shaderType, shaderDef->m_version);
748 if (shaderDef->isStageReferencing((glu::ShaderType)shaderType))
749 shader->getDefaultBlock() = defaultBlock;
753 else if (head->getType() == ResourceDefinition::Node::TYPE_PROGRAM)
755 DE_ASSERT(dynamic_cast<const ResourceDefinition::Program*>(head));
757 const ResourceDefinition::Program* programDef = static_cast<const ResourceDefinition::Program*>(head);
759 program->setSeparable(programDef->m_separable);
761 DE_ASSERT(feedbackTargetSet == !feedbackTargetVaryingPath.empty());
762 if (!feedbackTargetVaryingPath.empty())
764 std::ostringstream buf;
766 for (std::vector<std::string>::reverse_iterator it = feedbackTargetVaryingPath.rbegin(); it != feedbackTargetVaryingPath.rend(); ++it)
768 if (it != feedbackTargetVaryingPath.rbegin())
773 program->addTransformFeedbackVarying(buf.str());
774 program->setTransformFeedbackMode(GL_INTERLEAVED_ATTRIBS);
778 else if (head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
780 DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(head));
782 const ResourceDefinition::TransformFeedbackTarget* feedbackTarget = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(head);
784 DE_ASSERT(feedbackTarget->m_builtinVarName == DE_NULL);
785 DE_UNREF(feedbackTarget);
787 feedbackTargetSet = true;
788 feedbackTargetVaryingPath.push_back(variable.name);
797 else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK ||
798 head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
800 const char* feedbackTargetVaryingName = DE_NULL;
802 // empty default block
804 for (; head; head = head->getEnclosingNode())
806 if (head->getType() == ResourceDefinition::Node::TYPE_SHADER)
808 DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(head));
810 const ResourceDefinition::Shader* shaderDef = static_cast<const ResourceDefinition::Shader*>(head);
812 program->addShader(shaderDef->m_type, shaderDef->m_version);
814 else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER_SET)
816 DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(head));
818 const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(head);
820 for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
821 if (shaderDef->isStagePresent((glu::ShaderType)shaderType))
822 program->addShader((glu::ShaderType)shaderType, shaderDef->m_version);
824 else if (head->getType() == ResourceDefinition::Node::TYPE_PROGRAM)
826 DE_ASSERT(dynamic_cast<const ResourceDefinition::Program*>(head));
828 const ResourceDefinition::Program* programDef = static_cast<const ResourceDefinition::Program*>(head);
830 program->setSeparable(programDef->m_separable);
831 if (feedbackTargetVaryingName)
833 program->addTransformFeedbackVarying(std::string(feedbackTargetVaryingName));
834 program->setTransformFeedbackMode(GL_INTERLEAVED_ATTRIBS);
838 else if (head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
840 DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(head));
842 const ResourceDefinition::TransformFeedbackTarget* feedbackTarget = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(head);
844 DE_ASSERT(feedbackTarget->m_builtinVarName != DE_NULL);
846 feedbackTargetVaryingName = feedbackTarget->m_builtinVarName;
848 else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
859 if (program->hasStage(glu::SHADERTYPE_GEOMETRY))
860 program->setGeometryNumOutputVertices(1);
861 if (program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
862 program->setTessellationNumOutputPatchVertices(1);
867 static void checkAndLogProgram (const glu::ShaderProgram& program, const ProgramInterfaceDefinition::Program* programDefinition, const glw::Functions& gl, tcu::TestLog& log)
869 const tcu::ScopedLogSection section(log, "Program", "Program");
874 log << tcu::TestLog::Message << "Program build failed, checking if program exceeded implementation limits" << tcu::TestLog::EndMessage;
875 checkProgramResourceUsage(programDefinition, gl, log);
878 throw tcu::TestError("could not build program");
882 // Resource list query case
884 class ResourceListTestCase : public TestCase
887 ResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, ProgramInterface interface, const char* name = DE_NULL);
888 ~ResourceListTestCase (void);
893 IterateResult iterate (void);
895 void queryResourceList (std::vector<std::string>& dst, glw::GLuint program);
896 bool verifyResourceList (const std::vector<std::string>& resourceList, const std::vector<std::string>& expectedResources);
897 bool verifyResourceIndexQuery (const std::vector<std::string>& resourceList, const std::vector<std::string>& referenceResources, glw::GLuint program);
898 bool verifyMaxNameLength (const std::vector<std::string>& referenceResourceList, glw::GLuint program);
900 static std::string genTestCaseName (ProgramInterface interface, const ResourceDefinition::Node*);
901 static bool isArrayedInterface (ProgramInterface interface, deUint32 stageBits);
903 const ProgramInterface m_programInterface;
904 ResourceDefinition::Node::SharedPtr m_targetResource;
905 ProgramInterfaceDefinition::Program* m_programDefinition;
908 ResourceListTestCase::ResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, ProgramInterface interface, const char* name)
909 : TestCase (context, (name == DE_NULL) ? (genTestCaseName(interface, targetResource.get()).c_str()) : (name), "")
910 , m_programInterface (interface)
911 , m_targetResource (targetResource)
912 , m_programDefinition (DE_NULL)
914 // GL_ATOMIC_COUNTER_BUFFER: no resource names
915 DE_ASSERT(m_programInterface != PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER);
918 ResourceListTestCase::~ResourceListTestCase (void)
923 void ResourceListTestCase::init (void)
925 m_programDefinition = generateProgramDefinitionFromResource(m_targetResource.get()).release();
927 if ((m_programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION)) &&
928 !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
930 throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
932 if (m_programDefinition->hasStage(glu::SHADERTYPE_GEOMETRY) &&
933 !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
935 throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
937 if (programContainsIOBlocks(m_programDefinition) &&
938 !m_context.getContextInfo().isExtensionSupported("GL_EXT_shader_io_blocks"))
940 throw tcu::NotSupportedError("Test requires GL_EXT_shader_io_blocks extension");
944 void ResourceListTestCase::deinit (void)
946 m_targetResource.clear();
948 delete m_programDefinition;
949 m_programDefinition = DE_NULL;
952 ResourceListTestCase::IterateResult ResourceListTestCase::iterate (void)
954 const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_programDefinition));
956 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
957 checkAndLogProgram(program, m_programDefinition, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
959 // Check resource list
961 const tcu::ScopedLogSection section (m_testCtx.getLog(), "ResourceList", "Resource list");
962 std::vector<std::string> resourceList;
963 std::vector<std::string> expectedResources;
965 queryResourceList(resourceList, program.getProgram());
966 expectedResources = getProgramInterfaceResourceList(m_programDefinition, m_programInterface);
968 // verify the list and the expected list match
970 if (!verifyResourceList(resourceList, expectedResources))
971 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid resource list");
973 // verify GetProgramResourceIndex() matches the indices of the list
975 if (!verifyResourceIndexQuery(resourceList, expectedResources, program.getProgram()))
976 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GetProgramResourceIndex returned unexpected values");
978 // Verify MAX_NAME_LENGTH
979 if (!verifyMaxNameLength(resourceList, program.getProgram()))
980 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "MAX_NAME_LENGTH invalid");
986 void ResourceListTestCase::queryResourceList (std::vector<std::string>& dst, glw::GLuint program)
988 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
989 const glw::GLenum programInterface = getProgramInterfaceGLEnum(m_programInterface);
990 glw::GLint numActiveResources = 0;
991 glw::GLint maxNameLength = 0;
992 std::vector<char> buffer;
994 m_testCtx.getLog() << tcu::TestLog::Message << "Querying " << glu::getProgramInterfaceName(programInterface) << " interface:" << tcu::TestLog::EndMessage;
996 gl.getProgramInterfaceiv(program, programInterface, GL_ACTIVE_RESOURCES, &numActiveResources);
997 gl.getProgramInterfaceiv(program, programInterface, GL_MAX_NAME_LENGTH, &maxNameLength);
998 GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
1000 m_testCtx.getLog() << tcu::TestLog::Message
1001 << "\tGL_ACTIVE_RESOURCES = " << numActiveResources << "\n"
1002 << "\tGL_MAX_NAME_LENGTH = " << maxNameLength
1003 << tcu::TestLog::EndMessage;
1005 m_testCtx.getLog() << tcu::TestLog::Message << "Querying all active resources" << tcu::TestLog::EndMessage;
1007 buffer.resize(maxNameLength+1, '\0');
1009 for (int resourceNdx = 0; resourceNdx < numActiveResources; ++resourceNdx)
1011 glw::GLint written = 0;
1013 gl.getProgramResourceName(program, programInterface, resourceNdx, maxNameLength, &written, &buffer[0]);
1014 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource name");
1016 dst.push_back(std::string(&buffer[0], written));
1020 bool ResourceListTestCase::verifyResourceList (const std::vector<std::string>& resourceList, const std::vector<std::string>& expectedResources)
1024 // Log and compare resource lists
1026 m_testCtx.getLog() << tcu::TestLog::Message << "GL returned resources:" << tcu::TestLog::EndMessage;
1028 for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1030 // dummyZero is a uniform that may be added by
1031 // generateProgramInterfaceProgramSources. Omit it here to avoid
1032 // confusion about the output.
1033 if (resourceList[ndx] != getDummyZeroUniformName())
1034 m_testCtx.getLog() << tcu::TestLog::Message << "\t" << ndx << ": " << resourceList[ndx] << tcu::TestLog::EndMessage;
1037 m_testCtx.getLog() << tcu::TestLog::Message << "Expected list of resources:" << tcu::TestLog::EndMessage;
1039 for (int ndx = 0; ndx < (int)expectedResources.size(); ++ndx)
1040 m_testCtx.getLog() << tcu::TestLog::Message << "\t" << ndx << ": " << expectedResources[ndx] << tcu::TestLog::EndMessage;
1042 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying resource list contents." << tcu::TestLog::EndMessage;
1044 for (int ndx = 0; ndx < (int)expectedResources.size(); ++ndx)
1046 if (!de::contains(resourceList.begin(), resourceList.end(), expectedResources[ndx]))
1048 m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource list did not contain active resource " << expectedResources[ndx] << tcu::TestLog::EndMessage;
1053 for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1055 if (!de::contains(expectedResources.begin(), expectedResources.end(), resourceList[ndx]))
1057 // Ignore all builtin variables or the variable dummyZero,
1058 // mismatch causes errors otherwise. dummyZero is a uniform that
1059 // may be added by generateProgramInterfaceProgramSources.
1060 if (deStringBeginsWith(resourceList[ndx].c_str(), "gl_") == DE_FALSE &&
1061 resourceList[ndx] != getDummyZeroUniformName())
1063 m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource list contains unexpected resource name " << resourceList[ndx] << tcu::TestLog::EndMessage;
1067 m_testCtx.getLog() << tcu::TestLog::Message << "Note, resource list contains unknown built-in " << resourceList[ndx] << ". This variable is ignored." << tcu::TestLog::EndMessage;
1074 bool ResourceListTestCase::verifyResourceIndexQuery (const std::vector<std::string>& resourceList, const std::vector<std::string>& referenceResources, glw::GLuint program)
1076 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1077 const glw::GLenum programInterface = getProgramInterfaceGLEnum(m_programInterface);
1080 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying GetProgramResourceIndex returns correct indices for resource names." << tcu::TestLog::EndMessage;
1082 for (int ndx = 0; ndx < (int)referenceResources.size(); ++ndx)
1084 const glw::GLuint index = gl.getProgramResourceIndex(program, programInterface, referenceResources[ndx].c_str());
1085 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1087 if (index == GL_INVALID_INDEX)
1089 m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx] << "\" got index GL_INVALID_INDEX." << tcu::TestLog::EndMessage;
1092 else if ((int)index >= (int)resourceList.size())
1094 m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx] << "\" got index " << index << " (larger or equal to GL_ACTIVE_RESOURCES)." << tcu::TestLog::EndMessage;
1097 else if (resourceList[index] != referenceResources[ndx])
1099 m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx] << "\" got index (index = " << index << ") of another resource (" << resourceList[index] << ")." << tcu::TestLog::EndMessage;
1104 // Query for "name" should match "name[0]" except for XFB
1106 if (m_programInterface != PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING)
1108 for (int ndx = 0; ndx < (int)referenceResources.size(); ++ndx)
1110 if (de::endsWith(referenceResources[ndx], "[0]"))
1112 const std::string queryString = referenceResources[ndx].substr(0, referenceResources[ndx].length()-3);
1113 const glw::GLuint index = gl.getProgramResourceIndex(program, programInterface, queryString.c_str());
1114 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1116 if (index == GL_INVALID_INDEX)
1118 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" resulted in index GL_INVALID_INDEX." << tcu::TestLog::EndMessage;
1121 else if ((int)index >= (int)resourceList.size())
1123 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" resulted in index " << index << " (larger or equal to GL_ACTIVE_RESOURCES)." << tcu::TestLog::EndMessage;
1126 else if (resourceList[index] != queryString + "[0]")
1128 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" got index (index = " << index << ") of another resource (\"" << resourceList[index] << "\")." << tcu::TestLog::EndMessage;
1138 bool ResourceListTestCase::verifyMaxNameLength (const std::vector<std::string>& resourceList, glw::GLuint program)
1140 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1141 const glw::GLenum programInterface = getProgramInterfaceGLEnum(m_programInterface);
1142 glw::GLint maxNameLength = 0;
1143 glw::GLint expectedMaxNameLength = 0;
1145 gl.getProgramInterfaceiv(program, programInterface, GL_MAX_NAME_LENGTH, &maxNameLength);
1146 GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
1148 for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1149 expectedMaxNameLength = de::max(expectedMaxNameLength, (int)resourceList[ndx].size() + 1);
1151 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying MAX_NAME_LENGTH, expecting " << expectedMaxNameLength << " (i.e. consistent with the queried resource list)" << tcu::TestLog::EndMessage;
1153 if (expectedMaxNameLength != maxNameLength)
1155 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got " << maxNameLength << tcu::TestLog::EndMessage;
1162 std::string ResourceListTestCase::genTestCaseName (ProgramInterface interface, const ResourceDefinition::Node* root)
1164 bool isImplicitlySizedArray = false;
1165 bool hasVariable = false;
1166 bool accumulateName = true;
1167 std::string buf = "var";
1170 for (const ResourceDefinition::Node* node = root; node; node = node->getEnclosingNode())
1172 switch (node->getType())
1174 case ResourceDefinition::Node::TYPE_VARIABLE:
1180 case ResourceDefinition::Node::TYPE_STRUCT_MEMBER:
1187 case ResourceDefinition::Node::TYPE_ARRAY_ELEMENT:
1189 DE_ASSERT(dynamic_cast<const ResourceDefinition::ArrayElement*>(node));
1190 const ResourceDefinition::ArrayElement* arrayElement = static_cast<const ResourceDefinition::ArrayElement*>(node);
1192 isImplicitlySizedArray = (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::UNSIZED_ARRAY);
1199 case ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER:
1201 DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(node));
1202 const ResourceDefinition::StorageQualifier* storageDef = static_cast<const ResourceDefinition::StorageQualifier*>(node);
1204 if (storageDef->m_storage == glu::STORAGE_PATCH_IN ||
1205 storageDef->m_storage == glu::STORAGE_PATCH_OUT)
1213 case ResourceDefinition::Node::TYPE_SHADER:
1214 case ResourceDefinition::Node::TYPE_SHADER_SET:
1216 bool arrayedInterface;
1218 if (node->getType() == ResourceDefinition::Node::TYPE_SHADER)
1220 DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(node));
1221 const ResourceDefinition::Shader* shaderDef = static_cast<const ResourceDefinition::Shader*>(node);
1223 arrayedInterface = isArrayedInterface(interface, (1u << shaderDef->m_type));
1227 DE_ASSERT(node->getType() == ResourceDefinition::Node::TYPE_SHADER_SET);
1228 DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(node));
1229 const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(node);
1231 arrayedInterface = isArrayedInterface(interface, shaderDef->getReferencingMask());
1234 if (arrayedInterface && isImplicitlySizedArray)
1236 // omit implicit arrayness from name, i.e. remove trailing "_array"
1237 DE_ASSERT(de::endsWith(buf, "_array"));
1238 buf = buf.substr(0, buf.length() - 6);
1244 case ResourceDefinition::Node::TYPE_INTERFACE_BLOCK:
1246 accumulateName = false;
1256 return prefix + "empty";
1258 return prefix + buf;
1261 bool ResourceListTestCase::isArrayedInterface (ProgramInterface interface, deUint32 stageBits)
1263 if (interface == PROGRAMINTERFACE_PROGRAM_INPUT)
1265 const glu::ShaderType firstStage = getShaderMaskFirstStage(stageBits);
1266 return firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
1267 firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
1268 firstStage == glu::SHADERTYPE_GEOMETRY;
1270 else if (interface == PROGRAMINTERFACE_PROGRAM_OUTPUT)
1272 const glu::ShaderType lastStage = getShaderMaskLastStage(stageBits);
1273 return lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL;
1278 // Resouce property query case
1280 class ResourceTestCase : public ProgramInterfaceQueryTestCase
1283 ResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, const ProgramResourceQueryTestTarget& queryTarget, const char* name = DE_NULL);
1284 ~ResourceTestCase (void);
1289 const ProgramInterfaceDefinition::Program* getProgramDefinition (void) const;
1290 std::vector<std::string> getQueryTargetResources (void) const;
1292 static std::string genTestCaseName (const ResourceDefinition::Node*);
1293 static std::string genMultilineDescription (const ResourceDefinition::Node*);
1295 ResourceDefinition::Node::SharedPtr m_targetResource;
1296 ProgramInterfaceDefinition::Program* m_program;
1297 std::vector<std::string> m_targetResources;
1300 ResourceTestCase::ResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, const ProgramResourceQueryTestTarget& queryTarget, const char* name)
1301 : ProgramInterfaceQueryTestCase (context, (name == DE_NULL) ? (genTestCaseName(targetResource.get()).c_str()) : (name), "", queryTarget)
1302 , m_targetResource (targetResource)
1303 , m_program (DE_NULL)
1307 ResourceTestCase::~ResourceTestCase (void)
1312 void ResourceTestCase::init (void)
1315 << tcu::TestLog::Message
1316 << genMultilineDescription(m_targetResource.get())
1317 << tcu::TestLog::EndMessage;
1321 // Generate interface with target resource
1322 m_program = generateProgramDefinitionFromResource(m_targetResource.get()).release();
1323 m_targetResources = getProgramInterfaceResourceList(m_program, getTargetInterface());
1327 void ResourceTestCase::deinit (void)
1329 m_targetResource.clear();
1332 m_program = DE_NULL;
1334 m_targetResources = std::vector<std::string>();
1337 const ProgramInterfaceDefinition::Program* ResourceTestCase::getProgramDefinition (void) const
1342 std::vector<std::string> ResourceTestCase::getQueryTargetResources (void) const
1344 return m_targetResources;
1347 std::string ResourceTestCase::genTestCaseName (const ResourceDefinition::Node* resource)
1349 if (resource->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
1351 DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));
1353 const ResourceDefinition::Variable* variable = static_cast<const ResourceDefinition::Variable*>(resource);
1355 return convertGLTypeNameToTestName(glu::getDataTypeName(variable->m_dataType));
1362 std::string ResourceTestCase::genMultilineDescription (const ResourceDefinition::Node* resource)
1364 if (resource->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
1366 DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));
1368 const ResourceDefinition::Variable* varDef = static_cast<const ResourceDefinition::Variable*>(resource);
1369 std::ostringstream buf;
1370 std::ostringstream structureDescriptor;
1371 std::string uniformType;
1373 for (const ResourceDefinition::Node* node = resource; node; node = node->getEnclosingNode())
1375 if (node->getType() == ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER)
1377 DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(node));
1379 const ResourceDefinition::StorageQualifier* storageDef = static_cast<const ResourceDefinition::StorageQualifier*>(node);
1381 uniformType = std::string(" ") + glu::getStorageName(storageDef->m_storage);
1382 structureDescriptor << "\n\tdeclared as \"" << glu::getStorageName(storageDef->m_storage) << "\"";
1385 if (node->getType() == ResourceDefinition::Node::TYPE_ARRAY_ELEMENT)
1386 structureDescriptor << "\n\tarray";
1388 if (node->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER)
1389 structureDescriptor << "\n\tin a struct";
1391 if (node->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
1392 structureDescriptor << "\n\tin the default block";
1394 if (node->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
1395 structureDescriptor << "\n\tin an interface block";
1398 buf << "Querying properties of " << glu::getDataTypeName(varDef->m_dataType) << uniformType << " variable.\n"
1400 << "\t" << glu::getDataTypeName(varDef->m_dataType)
1401 << structureDescriptor.str();
1405 else if (resource->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
1407 DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(resource));
1409 const ResourceDefinition::TransformFeedbackTarget* xfbDef = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(resource);
1411 DE_ASSERT(xfbDef->m_builtinVarName);
1413 return std::string("Querying properties of a builtin variable ") + xfbDef->m_builtinVarName;
1420 class ResourceNameBufferLimitCase : public TestCase
1423 ResourceNameBufferLimitCase (Context& context, const char* name, const char* description);
1424 ~ResourceNameBufferLimitCase (void);
1427 IterateResult iterate (void);
1430 ResourceNameBufferLimitCase::ResourceNameBufferLimitCase (Context& context, const char* name, const char* description)
1431 : TestCase(context, name, description)
1435 ResourceNameBufferLimitCase::~ResourceNameBufferLimitCase (void)
1439 ResourceNameBufferLimitCase::IterateResult ResourceNameBufferLimitCase::iterate (void)
1441 static const char* const computeSource = "#version 310 es\n"
1442 "layout(local_size_x = 1) in;\n"
1443 "uniform highp int u_uniformWithALongName;\n"
1444 "writeonly buffer OutputBufferBlock { highp int b_output_int; };\n"
1447 " b_output_int = u_uniformWithALongName;\n"
1450 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1451 const glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(computeSource));
1452 glw::GLuint uniformIndex;
1454 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1458 const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program", "Program");
1460 m_testCtx.getLog() << program;
1461 if (!program.isOk())
1462 throw tcu::TestError("could not build program");
1465 uniformIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_uniformWithALongName");
1466 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1468 if (uniformIndex == GL_INVALID_INDEX)
1469 throw tcu::TestError("Uniform u_uniformWithALongName resource index was GL_INVALID_INDEX");
1471 // Query with different sized buffers, len("u_uniformWithALongName") == 22
1476 const char* description;
1481 { "Query to larger buffer", 24, true },
1482 { "Query to buffer the same size", 23, true },
1483 { "Query to one byte too small buffer", 22, true },
1484 { "Query to one byte buffer", 1, true },
1485 { "Query to zero sized buffer", 0, true },
1486 { "Query to one byte too small buffer, null length argument", 22, false },
1487 { "Query to one byte buffer, null length argument", 1, false },
1488 { "Query to zero sized buffer, null length argument", 0, false },
1491 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(querySizes); ++ndx)
1493 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Query", querySizes[ndx].description);
1494 const int uniformNameLen = 22;
1495 const int expectedWriteLen = (querySizes[ndx].querySize != 0) ? (de::min(uniformNameLen, (querySizes[ndx].querySize - 1))) : (0);
1497 glw::GLsizei written = -1;
1499 // One byte for guard
1500 DE_ASSERT((int)sizeof(buffer) > querySizes[ndx].querySize);
1502 deMemset(buffer, 'x', sizeof(buffer));
1504 if (querySizes[ndx].querySize)
1506 << tcu::TestLog::Message
1507 << "Querying uniform name to a buffer of size " << querySizes[ndx].querySize
1508 << ", expecting query to write " << expectedWriteLen << " bytes followed by a null terminator"
1509 << tcu::TestLog::EndMessage;
1512 << tcu::TestLog::Message
1513 << "Querying uniform name to a buffer of size " << querySizes[ndx].querySize
1514 << ", expecting query to write 0 bytes"
1515 << tcu::TestLog::EndMessage;
1517 gl.getProgramResourceName(program.getProgram(), GL_UNIFORM, uniformIndex, querySizes[ndx].querySize, (querySizes[ndx].returnLength) ? (&written) : (DE_NULL), buffer);
1518 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource name");
1520 if (querySizes[ndx].returnLength && written != expectedWriteLen)
1522 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected write length of " << expectedWriteLen << ", got " << written << tcu::TestLog::EndMessage;
1523 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected write lenght");
1525 else if (querySizes[ndx].querySize != 0 && buffer[expectedWriteLen] != 0)
1527 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected null terminator at " << expectedWriteLen << ", got dec=" << (int)buffer[expectedWriteLen] << tcu::TestLog::EndMessage;
1528 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Missing null terminator");
1530 else if (querySizes[ndx].querySize != 0 && buffer[expectedWriteLen+1] != 'x')
1532 m_testCtx.getLog() << tcu::TestLog::Message << "Error, guard at index " << (expectedWriteLen+1) << " was modified, got dec=" << (int)buffer[expectedWriteLen+1] << tcu::TestLog::EndMessage;
1533 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrote over buffer size");
1535 else if (querySizes[ndx].querySize == 0 && buffer[0] != 'x')
1537 m_testCtx.getLog() << tcu::TestLog::Message << "Error, buffer size was 0 but buffer contents were modified. At index 0 got dec=" << (int)buffer[0] << tcu::TestLog::EndMessage;
1538 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents were modified");
1546 class ResourceQueryBufferLimitCase : public TestCase
1549 ResourceQueryBufferLimitCase (Context& context, const char* name, const char* description);
1550 ~ResourceQueryBufferLimitCase (void);
1553 IterateResult iterate (void);
1556 ResourceQueryBufferLimitCase::ResourceQueryBufferLimitCase (Context& context, const char* name, const char* description)
1557 : TestCase(context, name, description)
1561 ResourceQueryBufferLimitCase::~ResourceQueryBufferLimitCase (void)
1565 ResourceQueryBufferLimitCase::IterateResult ResourceQueryBufferLimitCase::iterate (void)
1567 static const char* const computeSource = "#version 310 es\n"
1568 "layout(local_size_x = 1) in;\n"
1569 "uniform highp int u_uniform;\n"
1570 "writeonly buffer OutputBufferBlock { highp int b_output_int; };\n"
1573 " b_output_int = u_uniform;\n"
1576 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1577 const glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(computeSource));
1578 glw::GLuint uniformIndex;
1580 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1584 const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program", "Program");
1586 m_testCtx.getLog() << program;
1587 if (!program.isOk())
1588 throw tcu::TestError("could not build program");
1591 uniformIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_uniform");
1592 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1594 if (uniformIndex == GL_INVALID_INDEX)
1595 throw tcu::TestError("Uniform u_uniform resource index was GL_INVALID_INDEX");
1597 // Query uniform properties
1602 const char* description;
1608 { "Query to a larger buffer", 2, 3, true },
1609 { "Query to too small a buffer", 3, 2, true },
1610 { "Query to zero sized buffer", 3, 0, true },
1611 { "Query to a larger buffer, null length argument", 2, 3, false },
1612 { "Query to too small a buffer, null length argument", 3, 2, false },
1613 { "Query to zero sized buffer, null length argument", 3, 0, false },
1616 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(querySizes); ++ndx)
1618 const tcu::ScopedLogSection section (m_testCtx.getLog(), "QueryToLarger", querySizes[ndx].description);
1619 const glw::GLenum props[] = { GL_LOCATION, GL_LOCATION, GL_LOCATION };
1620 const int expectedWriteLen = de::min(querySizes[ndx].bufferSize, querySizes[ndx].numProps);
1621 int params[] = { 255, 255, 255, 255 };
1622 glw::GLsizei written = -1;
1624 DE_ASSERT(querySizes[ndx].numProps <= DE_LENGTH_OF_ARRAY(props));
1625 DE_ASSERT(querySizes[ndx].bufferSize < DE_LENGTH_OF_ARRAY(params)); // leave at least one element for overflow detection
1628 << tcu::TestLog::Message
1629 << "Querying " << querySizes[ndx].numProps << " uniform prop(s) to a buffer with size " << querySizes[ndx].bufferSize << ". Expecting query to return " << expectedWriteLen << " prop(s)"
1630 << tcu::TestLog::EndMessage;
1632 gl.getProgramResourceiv(program.getProgram(), GL_UNIFORM, uniformIndex, querySizes[ndx].numProps, props, querySizes[ndx].bufferSize, (querySizes[ndx].returnLength) ? (&written) : (DE_NULL), params);
1633 GLU_EXPECT_NO_ERROR(gl.getError(), "query program resources");
1635 if (querySizes[ndx].returnLength && written != expectedWriteLen)
1637 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected write length of " << expectedWriteLen << ", got " << written << tcu::TestLog::EndMessage;
1638 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected write lenght");
1640 else if (params[expectedWriteLen] != 255)
1642 m_testCtx.getLog() << tcu::TestLog::Message << "Error, guard at index " << (expectedWriteLen) << " was modified. Was 255 before call, got dec=" << params[expectedWriteLen] << tcu::TestLog::EndMessage;
1643 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrote over buffer size");
1651 class InterfaceBlockBaseCase : public TestCase
1656 CASE_NAMED_BLOCK = 0,
1663 InterfaceBlockBaseCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
1664 ~InterfaceBlockBaseCase (void);
1671 const glu::Storage m_storage;
1672 const CaseType m_caseType;
1673 ProgramInterfaceDefinition::Program* m_program;
1676 InterfaceBlockBaseCase::InterfaceBlockBaseCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
1677 : TestCase (context, name, description)
1678 , m_storage (storage)
1679 , m_caseType (caseType)
1680 , m_program (DE_NULL)
1682 DE_ASSERT(storage == glu::STORAGE_UNIFORM || storage == glu::STORAGE_BUFFER);
1685 InterfaceBlockBaseCase::~InterfaceBlockBaseCase (void)
1690 void InterfaceBlockBaseCase::init (void)
1692 ProgramInterfaceDefinition::Shader* shader;
1694 m_program = new ProgramInterfaceDefinition::Program();
1695 shader = m_program->addShader(glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES);
1697 // PrecedingInterface
1699 glu::InterfaceBlock precedingInterfaceBlock;
1701 precedingInterfaceBlock.interfaceName = "PrecedingInterface";
1702 precedingInterfaceBlock.layout.binding = 0;
1703 precedingInterfaceBlock.storage = m_storage;
1704 precedingInterfaceBlock.instanceName = "precedingInstance";
1706 precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "precedingMember"));
1708 // Unsized array type
1709 if (m_storage == glu::STORAGE_BUFFER)
1710 precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY), "precedingMemberUnsizedArray"));
1712 precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 2), "precedingMemberArray"));
1714 shader->getDefaultBlock().interfaceBlocks.push_back(precedingInterfaceBlock);
1719 glu::InterfaceBlock targetInterfaceBlock;
1721 targetInterfaceBlock.interfaceName = "TargetInterface";
1722 targetInterfaceBlock.layout.binding = 1;
1723 targetInterfaceBlock.storage = m_storage;
1725 if (m_caseType == CASE_UNNAMED_BLOCK)
1726 targetInterfaceBlock.instanceName = "";
1728 targetInterfaceBlock.instanceName = "targetInstance";
1730 if (m_caseType == CASE_BLOCK_ARRAY)
1731 targetInterfaceBlock.dimensions.push_back(2);
1735 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "blockMemberBasic"));
1740 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 3), "blockMemberArray"));
1745 glu::StructType* structPtr = new glu::StructType("StructType");
1746 structPtr->addMember("structMemberBasic", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP));
1747 structPtr->addMember("structMemberArray", glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 2));
1749 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(structPtr), 2), "blockMemberStruct"));
1752 // Unsized array type
1753 if (m_storage == glu::STORAGE_BUFFER)
1754 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY), "blockMemberUnsizedArray"));
1756 shader->getDefaultBlock().interfaceBlocks.push_back(targetInterfaceBlock);
1759 // TrailingInterface
1761 glu::InterfaceBlock trailingInterfaceBlock;
1763 trailingInterfaceBlock.interfaceName = "TrailingInterface";
1764 trailingInterfaceBlock.layout.binding = 3;
1765 trailingInterfaceBlock.storage = m_storage;
1766 trailingInterfaceBlock.instanceName = "trailingInstance";
1767 trailingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "trailingMember"));
1769 shader->getDefaultBlock().interfaceBlocks.push_back(trailingInterfaceBlock);
1772 DE_ASSERT(m_program->isValid());
1775 void InterfaceBlockBaseCase::deinit (void)
1778 m_program = DE_NULL;
1781 class InterfaceBlockActiveVariablesTestCase : public InterfaceBlockBaseCase
1784 InterfaceBlockActiveVariablesTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
1787 IterateResult iterate (void);
1790 InterfaceBlockActiveVariablesTestCase::InterfaceBlockActiveVariablesTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
1791 : InterfaceBlockBaseCase(context, name, description, storage, caseType)
1795 InterfaceBlockActiveVariablesTestCase::IterateResult InterfaceBlockActiveVariablesTestCase::iterate (void)
1797 const ProgramInterface programInterface = (m_storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
1798 (m_storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
1799 (PROGRAMINTERFACE_LAST);
1800 const glw::GLenum programGLInterfaceValue = getProgramInterfaceGLEnum(programInterface);
1801 const glw::GLenum programMemberInterfaceValue = (m_storage == glu::STORAGE_UNIFORM) ? (GL_UNIFORM) :
1802 (m_storage == glu::STORAGE_BUFFER) ? (GL_BUFFER_VARIABLE) :
1804 const std::vector<std::string> blockNames = getProgramInterfaceResourceList(m_program, programInterface);
1805 glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
1806 int expectedMaxNumActiveVariables = 0;
1808 DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
1810 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1811 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1813 // Verify all blocks
1815 for (int blockNdx = 0; blockNdx < (int)blockNames.size(); ++blockNdx)
1817 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Block", "Block \"" + blockNames[blockNdx] + "\"");
1818 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1819 const glw::GLuint resourceNdx = gl.getProgramResourceIndex(program.getProgram(), programGLInterfaceValue, blockNames[blockNdx].c_str());
1820 glw::GLint numActiveResources;
1821 std::vector<std::string> activeResourceNames;
1823 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1825 if (resourceNdx == GL_INVALID_INDEX)
1827 m_testCtx.getLog() << tcu::TestLog::Message << "Error, getProgramResourceIndex returned GL_INVALID_INDEX for \"" << blockNames[blockNdx] << "\"" << tcu::TestLog::EndMessage;
1828 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Resource not found");
1832 // query block information
1835 const glw::GLenum props[] = { GL_NUM_ACTIVE_VARIABLES };
1836 glw::GLint retBuffer[2] = { -1, -1 };
1837 glw::GLint written = -1;
1839 gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, DE_LENGTH_OF_ARRAY(props), props, 1, &written, retBuffer);
1840 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_NUM_ACTIVE_VARIABLES");
1842 numActiveResources = retBuffer[0];
1843 expectedMaxNumActiveVariables = de::max(expectedMaxNumActiveVariables, numActiveResources);
1844 m_testCtx.getLog() << tcu::TestLog::Message << "NUM_ACTIVE_VARIABLES = " << numActiveResources << tcu::TestLog::EndMessage;
1846 if (written == -1 || retBuffer[0] == -1)
1848 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for NUM_ACTIVE_VARIABLES did not return a value" << tcu::TestLog::EndMessage;
1849 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for NUM_ACTIVE_VARIABLES failed");
1852 else if (retBuffer[1] != -1)
1854 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for NUM_ACTIVE_VARIABLES returned too many values" << tcu::TestLog::EndMessage;
1855 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for NUM_ACTIVE_VARIABLES returned too many values");
1858 else if (retBuffer[0] < 0)
1860 m_testCtx.getLog() << tcu::TestLog::Message << "Error, NUM_ACTIVE_VARIABLES < 0" << tcu::TestLog::EndMessage;
1861 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "NUM_ACTIVE_VARIABLES < 0");
1866 // query block variable information
1869 const glw::GLenum props[] = { GL_ACTIVE_VARIABLES };
1870 std::vector<glw::GLint> activeVariableIndices (numActiveResources + 1, -1); // Allocate one extra trailing to detect wrong write lengths
1871 glw::GLint written = -1;
1873 gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, DE_LENGTH_OF_ARRAY(props), props, (glw::GLsizei)activeVariableIndices.size(), &written, &activeVariableIndices[0]);
1874 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_ACTIVE_VARIABLES");
1878 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for GL_ACTIVE_VARIABLES did not return any values" << tcu::TestLog::EndMessage;
1879 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES failed");
1882 else if (written != numActiveResources)
1884 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for GL_ACTIVE_VARIABLES did not return NUM_ACTIVE_VARIABLES values" << tcu::TestLog::EndMessage;
1885 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES returned invalid number of values");
1888 else if (activeVariableIndices.back() != -1)
1890 m_testCtx.getLog() << tcu::TestLog::Message << "Error, GL_ACTIVE_VARIABLES query return buffer trailing guard value was modified, getProgramResourceiv returned more than NUM_ACTIVE_VARIABLES values" << tcu::TestLog::EndMessage;
1891 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES returned too many values");
1897 tcu::MessageBuilder builder(&m_testCtx.getLog());
1899 builder << "Active variable indices: {";
1900 for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1904 builder << activeVariableIndices[varNdx];
1906 builder << "}" << tcu::TestLog::EndMessage;
1911 activeResourceNames.resize(numActiveResources);
1913 for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1915 const glw::GLenum nameProp = GL_NAME_LENGTH;
1916 glw::GLint nameLength = -1;
1917 std::vector<char> nameBuffer;
1920 gl.getProgramResourceiv(program.getProgram(), programMemberInterfaceValue, activeVariableIndices[varNdx], 1, &nameProp, 1, &written, &nameLength);
1921 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_NAME_LENGTH");
1923 if (nameLength <= 0 || written <= 0)
1925 m_testCtx.getLog() << tcu::TestLog::Message << "Error, GL_NAME_LENGTH query failed" << tcu::TestLog::EndMessage;
1926 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GL_NAME_LENGTH query failed");
1930 nameBuffer.resize(nameLength + 2, 'X'); // allocate more than required
1932 gl.getProgramResourceName(program.getProgram(), programMemberInterfaceValue, activeVariableIndices[varNdx], nameLength+1, &written, &nameBuffer[0]);
1933 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramResourceName");
1937 m_testCtx.getLog() << tcu::TestLog::Message << "Error, name query failed, no data written" << tcu::TestLog::EndMessage;
1938 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "name query failed");
1941 else if (written > nameLength)
1943 m_testCtx.getLog() << tcu::TestLog::Message << "Error, name query failed, query returned too much data" << tcu::TestLog::EndMessage;
1944 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "name query failed");
1948 activeResourceNames[varNdx] = std::string(&nameBuffer[0], written);
1951 // log collected names
1953 tcu::MessageBuilder builder(&m_testCtx.getLog());
1955 builder << "Active variables:\n";
1956 for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1957 builder << "\t" << activeResourceNames[varNdx] << "\n";
1958 builder << tcu::TestLog::EndMessage;
1964 glu::InterfaceBlock* block = DE_NULL;
1965 const std::string blockName = glu::parseVariableName(blockNames[blockNdx].c_str());
1966 std::vector<std::string> referenceList;
1968 for (int interfaceNdx = 0; interfaceNdx < (int)m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx)
1970 if (m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].interfaceName == blockName)
1972 block = &m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx];
1978 throw tcu::InternalError("could not find block referenced in the reference resource list");
1980 // generate reference list
1982 referenceList = getProgramInterfaceBlockMemberResourceList(*block);
1984 tcu::MessageBuilder builder(&m_testCtx.getLog());
1986 builder << "Expected variable names:\n";
1987 for (int varNdx = 0; varNdx < (int)referenceList.size(); ++varNdx)
1988 builder << "\t" << referenceList[varNdx] << "\n";
1989 builder << tcu::TestLog::EndMessage;
1994 bool listsIdentical = true;
1996 for (int ndx = 0; ndx < (int)referenceList.size(); ++ndx)
1998 if (!de::contains(activeResourceNames.begin(), activeResourceNames.end(), referenceList[ndx]))
2000 m_testCtx.getLog() << tcu::TestLog::Message << "Error, variable name list did not contain active variable " << referenceList[ndx] << tcu::TestLog::EndMessage;
2001 listsIdentical = false;
2005 for (int ndx = 0; ndx < (int)activeResourceNames.size(); ++ndx)
2007 if (!de::contains(referenceList.begin(), referenceList.end(), activeResourceNames[ndx]))
2009 m_testCtx.getLog() << tcu::TestLog::Message << "Error, variable name list contains unexpected resource \"" << activeResourceNames[ndx] << "\"" << tcu::TestLog::EndMessage;
2010 listsIdentical = false;
2015 m_testCtx.getLog() << tcu::TestLog::Message << "Lists identical" << tcu::TestLog::EndMessage;
2018 m_testCtx.getLog() << tcu::TestLog::Message << "Error, invalid active variable list" << tcu::TestLog::EndMessage;
2019 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid active variable list");
2026 // Max num active variables
2028 const tcu::ScopedLogSection section (m_testCtx.getLog(), "MaxNumActiveVariables", "MAX_NUM_ACTIVE_VARIABLES");
2029 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2030 glw::GLint maxNumActiveVariables = -1;
2032 gl.getProgramInterfaceiv(program.getProgram(), programGLInterfaceValue, GL_MAX_NUM_ACTIVE_VARIABLES, &maxNumActiveVariables);
2033 GLU_EXPECT_NO_ERROR(gl.getError(), "query MAX_NUM_ACTIVE_VARIABLES");
2035 m_testCtx.getLog() << tcu::TestLog::Message << "MAX_NUM_ACTIVE_VARIABLES = " << maxNumActiveVariables << tcu::TestLog::EndMessage;
2037 if (expectedMaxNumActiveVariables != maxNumActiveVariables)
2039 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected MAX_NUM_ACTIVE_VARIABLES" << tcu::TestLog::EndMessage;
2040 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected MAX_NUM_ACTIVE_VARIABLES");
2043 m_testCtx.getLog() << tcu::TestLog::Message << "MAX_NUM_ACTIVE_VARIABLES valid" << tcu::TestLog::EndMessage;
2049 class InterfaceBlockDataSizeTestCase : public InterfaceBlockBaseCase
2052 InterfaceBlockDataSizeTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
2055 IterateResult iterate (void);
2056 int getBlockMinDataSize (const std::string& blockName) const;
2057 int getBlockMinDataSize (const glu::InterfaceBlock& block) const;
2060 InterfaceBlockDataSizeTestCase::InterfaceBlockDataSizeTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
2061 : InterfaceBlockBaseCase(context, name, description, storage, caseType)
2065 InterfaceBlockDataSizeTestCase::IterateResult InterfaceBlockDataSizeTestCase::iterate (void)
2067 const ProgramInterface programInterface = (m_storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
2068 (m_storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
2069 (PROGRAMINTERFACE_LAST);
2070 const glw::GLenum programGLInterfaceValue = getProgramInterfaceGLEnum(programInterface);
2071 const std::vector<std::string> blockNames = getProgramInterfaceResourceList(m_program, programInterface);
2072 glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2074 DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
2076 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2077 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2079 // Verify all blocks
2080 for (int blockNdx = 0; blockNdx < (int)blockNames.size(); ++blockNdx)
2082 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Block", "Block \"" + blockNames[blockNdx] + "\"");
2083 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2084 const glw::GLuint resourceNdx = gl.getProgramResourceIndex(program.getProgram(), programGLInterfaceValue, blockNames[blockNdx].c_str());
2085 const int expectedMinDataSize = getBlockMinDataSize(blockNames[blockNdx]);
2086 glw::GLint queryDataSize = -1;
2088 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
2090 if (resourceNdx == GL_INVALID_INDEX)
2092 m_testCtx.getLog() << tcu::TestLog::Message << "Error, getProgramResourceIndex returned GL_INVALID_INDEX for \"" << blockNames[blockNdx] << "\"" << tcu::TestLog::EndMessage;
2093 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Resource not found");
2099 const glw::GLenum prop = GL_BUFFER_DATA_SIZE;
2101 gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, 1, &prop, 1, DE_NULL, &queryDataSize);
2102 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource BUFFER_DATA_SIZE");
2106 << tcu::TestLog::Message
2107 << "BUFFER_DATA_SIZE = " << queryDataSize << "\n"
2108 << "Buffer data size with tight packing: " << expectedMinDataSize
2109 << tcu::TestLog::EndMessage;
2111 if (queryDataSize < expectedMinDataSize)
2113 m_testCtx.getLog() << tcu::TestLog::Message << "Error, buffer size was less than minimum buffer data size" << tcu::TestLog::EndMessage;
2114 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer data size invalid");
2118 m_testCtx.getLog() << tcu::TestLog::Message << "Buffer size valid" << tcu::TestLog::EndMessage;
2124 int InterfaceBlockDataSizeTestCase::getBlockMinDataSize (const std::string& blockFullName) const
2126 const std::string blockName = glu::parseVariableName(blockFullName.c_str());
2128 for (int interfaceNdx = 0; interfaceNdx < (int)m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx)
2130 if (m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].interfaceName == blockName &&
2131 m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].storage == m_storage)
2132 return getBlockMinDataSize(m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx]);
2139 class AtomicCounterCase : public TestCase
2142 AtomicCounterCase (Context& context, const char* name, const char* description);
2143 ~AtomicCounterCase (void);
2150 int getNumAtomicCounterBuffers (void) const;
2151 int getMaxNumActiveVariables (void) const;
2152 int getBufferVariableCount (int binding) const;
2153 int getBufferMinimumDataSize (int binding) const;
2155 ProgramInterfaceDefinition::Program* m_program;
2158 AtomicCounterCase::AtomicCounterCase (Context& context, const char* name, const char* description)
2159 : TestCase (context, name, description)
2160 , m_program (DE_NULL)
2164 AtomicCounterCase::~AtomicCounterCase (void)
2169 void AtomicCounterCase::init (void)
2171 ProgramInterfaceDefinition::Shader* shader;
2173 m_program = new ProgramInterfaceDefinition::Program();
2174 shader = m_program->addShader(glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES);
2177 glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding1_counter1", glu::STORAGE_UNIFORM);
2178 decl.layout.binding = 1;
2179 shader->getDefaultBlock().variables.push_back(decl);
2182 glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding1_counter2", glu::STORAGE_UNIFORM);
2183 decl.layout.binding = 1;
2184 decl.layout.offset = 8;
2186 shader->getDefaultBlock().variables.push_back(decl);
2189 glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding2_counter1", glu::STORAGE_UNIFORM);
2190 decl.layout.binding = 2;
2191 shader->getDefaultBlock().variables.push_back(decl);
2194 DE_ASSERT(m_program->isValid());
2197 void AtomicCounterCase::deinit (void)
2200 m_program = DE_NULL;
2203 int AtomicCounterCase::getNumAtomicCounterBuffers (void) const
2205 std::set<int> buffers;
2207 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2209 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2210 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()))
2212 buffers.insert(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding);
2216 return (int)buffers.size();
2219 int AtomicCounterCase::getMaxNumActiveVariables (void) const
2222 std::map<int,int> numBufferVars;
2224 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2226 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2227 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()))
2229 const int binding = m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding;
2231 if (numBufferVars.find(binding) == numBufferVars.end())
2232 numBufferVars[binding] = 1;
2234 ++numBufferVars[binding];
2238 for (std::map<int,int>::const_iterator it = numBufferVars.begin(); it != numBufferVars.end(); ++it)
2239 maxVars = de::max(maxVars, it->second);
2244 int AtomicCounterCase::getBufferVariableCount (int binding) const
2248 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2250 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2251 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()) &&
2252 m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding == binding)
2259 int AtomicCounterCase::getBufferMinimumDataSize (int binding) const
2262 int currentOffset = 0;
2264 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2266 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2267 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()) &&
2268 m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding == binding)
2270 const int thisOffset = (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.offset != -1) ? (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.offset) : (currentOffset);
2271 currentOffset = thisOffset + 4;
2273 minSize = de::max(minSize, thisOffset + 4);
2280 class AtomicCounterResourceListCase : public AtomicCounterCase
2283 AtomicCounterResourceListCase (Context& context, const char* name, const char* description);
2286 IterateResult iterate (void);
2289 AtomicCounterResourceListCase::AtomicCounterResourceListCase (Context& context, const char* name, const char* description)
2290 : AtomicCounterCase(context, name, description)
2294 AtomicCounterResourceListCase::IterateResult AtomicCounterResourceListCase::iterate (void)
2296 const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2298 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2299 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2302 const tcu::ScopedLogSection section (m_testCtx.getLog(), "ActiveResources", "ACTIVE_RESOURCES");
2303 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2304 glw::GLint numActiveResources = -1;
2305 const int numExpectedActiveResources = 2; // 2 buffer bindings
2307 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying ACTIVE_RESOURCES, expecting " << numExpectedActiveResources << tcu::TestLog::EndMessage;
2309 gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &numActiveResources);
2310 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_ACTIVE_RESOURCES");
2312 m_testCtx.getLog() << tcu::TestLog::Message << "ACTIVE_RESOURCES = " << numActiveResources << tcu::TestLog::EndMessage;
2314 if (numActiveResources != numExpectedActiveResources)
2316 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected ACTIVE_RESOURCES" << tcu::TestLog::EndMessage;
2317 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected ACTIVE_RESOURCES");
2320 m_testCtx.getLog() << tcu::TestLog::Message << "ACTIVE_RESOURCES valid" << tcu::TestLog::EndMessage;
2326 class AtomicCounterActiveVariablesCase : public AtomicCounterCase
2329 AtomicCounterActiveVariablesCase (Context& context, const char* name, const char* description);
2332 IterateResult iterate (void);
2335 AtomicCounterActiveVariablesCase::AtomicCounterActiveVariablesCase (Context& context, const char* name, const char* description)
2336 : AtomicCounterCase(context, name, description)
2340 AtomicCounterActiveVariablesCase::IterateResult AtomicCounterActiveVariablesCase::iterate (void)
2342 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2343 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2344 const int numAtomicBuffers = getNumAtomicCounterBuffers();
2345 const int expectedMaxNumActiveVariables = getMaxNumActiveVariables();
2347 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2348 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2350 // check active variables
2352 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Interface", "ATOMIC_COUNTER_BUFFER interface");
2353 glw::GLint queryActiveResources = -1;
2354 glw::GLint queryMaxNumActiveVariables = -1;
2356 gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &queryActiveResources);
2357 gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, &queryMaxNumActiveVariables);
2358 GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
2361 << tcu::TestLog::Message
2362 << "GL_ACTIVE_RESOURCES = " << queryActiveResources << "\n"
2363 << "GL_MAX_NUM_ACTIVE_VARIABLES = " << queryMaxNumActiveVariables << "\n"
2364 << tcu::TestLog::EndMessage;
2366 if (queryActiveResources != numAtomicBuffers)
2368 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected GL_ACTIVE_RESOURCES, expected " << numAtomicBuffers << tcu::TestLog::EndMessage;
2369 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected GL_ACTIVE_RESOURCES");
2372 if (queryMaxNumActiveVariables != expectedMaxNumActiveVariables)
2374 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected GL_MAX_NUM_ACTIVE_VARIABLES, expected " << expectedMaxNumActiveVariables << tcu::TestLog::EndMessage;
2375 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected GL_MAX_NUM_ACTIVE_VARIABLES");
2379 // Check each buffer
2380 for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2382 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
2383 std::vector<glw::GLint> activeVariables;
2384 std::vector<std::string> memberNames;
2386 // Find active variables
2388 const glw::GLenum numActiveVariablesProp = GL_NUM_ACTIVE_VARIABLES;
2389 const glw::GLenum activeVariablesProp = GL_ACTIVE_VARIABLES;
2390 glw::GLint numActiveVariables = -2;
2391 glw::GLint written = -1;
2393 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &numActiveVariablesProp, 1, &written, &numActiveVariables);
2394 GLU_EXPECT_NO_ERROR(gl.getError(), "query num active variables");
2396 if (numActiveVariables <= 0)
2398 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected NUM_ACTIVE_VARIABLES: " << numActiveVariables << tcu::TestLog::EndMessage;
2399 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected NUM_ACTIVE_VARIABLES");
2405 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for NUM_ACTIVE_VARIABLES returned no values" << tcu::TestLog::EndMessage;
2406 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "NUM_ACTIVE_VARIABLES query failed");
2410 m_testCtx.getLog() << tcu::TestLog::Message << "GL_NUM_ACTIVE_VARIABLES = " << numActiveVariables << tcu::TestLog::EndMessage;
2413 activeVariables.resize(numActiveVariables + 1, -2);
2415 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &activeVariablesProp, numActiveVariables, &written, &activeVariables[0]);
2416 GLU_EXPECT_NO_ERROR(gl.getError(), "query active variables");
2418 if (written != numActiveVariables)
2420 m_testCtx.getLog() << tcu::TestLog::Message << "Error, unexpected number of ACTIVE_VARIABLES, NUM_ACTIVE_VARIABLES = " << numActiveVariables << ", query returned " << written << " values" << tcu::TestLog::EndMessage;
2421 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected ACTIVE_VARIABLES");
2425 if (activeVariables.back() != -2)
2427 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for ACTIVE_VARIABLES wrote over target buffer bounds" << tcu::TestLog::EndMessage;
2428 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "ACTIVE_VARIABLES query failed");
2432 activeVariables.pop_back();
2437 tcu::MessageBuilder builder(&m_testCtx.getLog());
2439 builder << "Active variable indices: {";
2440 for (int varNdx = 0; varNdx < (int)activeVariables.size(); ++varNdx)
2444 builder << activeVariables[varNdx];
2446 builder << "}" << tcu::TestLog::EndMessage;
2449 // collect member names
2450 for (int ndx = 0; ndx < (int)activeVariables.size(); ++ndx)
2452 const glw::GLenum nameLengthProp = GL_NAME_LENGTH;
2453 glw::GLint nameLength = -1;
2454 glw::GLint written = -1;
2455 std::vector<char> nameBuf;
2457 gl.getProgramResourceiv(program.getProgram(), GL_UNIFORM, activeVariables[ndx], 1, &nameLengthProp, 1, &written, &nameLength);
2458 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer variable name length");
2460 if (written <= 0 || nameLength == -1)
2462 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for GL_NAME_LENGTH returned no values" << tcu::TestLog::EndMessage;
2463 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GL_NAME_LENGTH query failed");
2467 nameBuf.resize(nameLength + 2, 'X'); // +2 to tolerate potential off-by-ones in some implementations, name queries will check these cases better
2470 gl.getProgramResourceName(program.getProgram(), GL_UNIFORM, activeVariables[ndx], (int)nameBuf.size(), &written, &nameBuf[0]);
2471 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer variable name");
2475 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for resource name returned no name" << tcu::TestLog::EndMessage;
2476 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Name query failed");
2480 memberNames.push_back(std::string(&nameBuf[0], written));
2485 tcu::MessageBuilder builder(&m_testCtx.getLog());
2487 builder << "Active variables:\n";
2488 for (int varNdx = 0; varNdx < (int)memberNames.size(); ++varNdx)
2490 builder << "\t" << memberNames[varNdx] << "\n";
2492 builder << tcu::TestLog::EndMessage;
2495 // check names are all in the same buffer
2497 bool bindingsValid = true;
2499 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying names" << tcu::TestLog::EndMessage;
2501 for (int nameNdx = 0; nameNdx < (int)memberNames.size(); ++nameNdx)
2503 int prevBinding = -1;
2505 for (int varNdx = 0; varNdx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++varNdx)
2507 if (m_program->getShaders()[0]->getDefaultBlock().variables[varNdx].name == memberNames[nameNdx])
2509 const int varBinding = m_program->getShaders()[0]->getDefaultBlock().variables[varNdx].layout.binding;
2511 if (prevBinding == -1 || prevBinding == varBinding)
2512 prevBinding = varBinding;
2514 bindingsValid = false;
2518 if (prevBinding == -1)
2520 m_testCtx.getLog() << tcu::TestLog::Message << "Error, could not find variable with name \"" << memberNames[nameNdx] << "\"" << tcu::TestLog::EndMessage;
2521 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Variable name invalid");
2523 else if (getBufferVariableCount(prevBinding) != (int)memberNames.size())
2526 << tcu::TestLog::Message
2527 << "Error, unexpected variable count for binding " << prevBinding
2528 << ". Expected " << getBufferVariableCount(prevBinding) << ", got " << (int)memberNames.size()
2529 << tcu::TestLog::EndMessage;
2530 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Variable names invalid");
2536 m_testCtx.getLog() << tcu::TestLog::Message << "Error, all resource do not share the same buffer" << tcu::TestLog::EndMessage;
2537 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Active variables invalid");
2546 class AtomicCounterBufferBindingCase : public AtomicCounterCase
2549 AtomicCounterBufferBindingCase (Context& context, const char* name, const char* description);
2552 IterateResult iterate (void);
2555 AtomicCounterBufferBindingCase::AtomicCounterBufferBindingCase (Context& context, const char* name, const char* description)
2556 : AtomicCounterCase(context, name, description)
2560 AtomicCounterBufferBindingCase::IterateResult AtomicCounterBufferBindingCase::iterate (void)
2562 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2563 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2564 const int numAtomicBuffers = getNumAtomicCounterBuffers();
2566 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2567 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2569 // check every buffer
2570 for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2572 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
2573 const glw::GLenum bufferBindingProp = GL_BUFFER_BINDING;
2574 glw::GLint bufferBinding = -1;
2575 glw::GLint written = -1;
2577 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &bufferBindingProp, 1, &written, &bufferBinding);
2578 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2582 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for BUFFER_BINDING returned no values." << tcu::TestLog::EndMessage;
2583 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "BUFFER_BINDING query failed");
2586 m_testCtx.getLog() << tcu::TestLog::Message << "GL_BUFFER_BINDING = " << bufferBinding << tcu::TestLog::EndMessage;
2588 // no such buffer binding?
2589 if (getBufferVariableCount(bufferBinding) == 0)
2591 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_BINDING = " << bufferBinding << ", but such buffer does not exist." << tcu::TestLog::EndMessage;
2592 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2599 class AtomicCounterBufferDataSizeCase : public AtomicCounterCase
2602 AtomicCounterBufferDataSizeCase (Context& context, const char* name, const char* description);
2605 IterateResult iterate (void);
2608 AtomicCounterBufferDataSizeCase::AtomicCounterBufferDataSizeCase (Context& context, const char* name, const char* description)
2609 : AtomicCounterCase(context, name, description)
2613 AtomicCounterBufferDataSizeCase::IterateResult AtomicCounterBufferDataSizeCase::iterate (void)
2615 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2616 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2617 const int numAtomicBuffers = getNumAtomicCounterBuffers();
2619 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2620 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2622 // check every buffer
2623 for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2625 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
2626 const glw::GLenum props[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE };
2627 glw::GLint values[] = { -1, -1 };
2628 glw::GLint written = -1;
2629 int bufferMinDataSize;
2631 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, DE_LENGTH_OF_ARRAY(props), props, DE_LENGTH_OF_ARRAY(values), &written, values);
2632 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2636 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for (BUFFER_BINDING, BUFFER_DATA_SIZE) returned " << written << " value(s)." << tcu::TestLog::EndMessage;
2637 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
2642 << tcu::TestLog::Message
2643 << "GL_BUFFER_BINDING = " << values[0] << "\n"
2644 << "GL_BUFFER_DATA_SIZE = " << values[1]
2645 << tcu::TestLog::EndMessage;
2647 bufferMinDataSize = getBufferMinimumDataSize(values[0]);
2648 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying data size, expected greater than or equal to " << bufferMinDataSize << tcu::TestLog::EndMessage;
2650 // no such buffer binding?
2651 if (bufferMinDataSize == -1)
2653 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_BINDING = " << values[0] << ", but such buffer does not exist." << tcu::TestLog::EndMessage;
2654 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2656 else if (values[1] < bufferMinDataSize)
2658 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_DATA_SIZE = " << values[1] << ", expected greater than or equal to " << bufferMinDataSize << tcu::TestLog::EndMessage;
2659 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2662 m_testCtx.getLog() << tcu::TestLog::Message << "Data size valid" << tcu::TestLog::EndMessage;
2668 class AtomicCounterReferencedByCase : public TestCase
2671 AtomicCounterReferencedByCase (Context& context,
2673 const char* description,
2675 deUint32 presentStagesMask,
2676 deUint32 activeStagesMask);
2677 ~AtomicCounterReferencedByCase (void);
2682 IterateResult iterate (void);
2684 const bool m_separable;
2685 const deUint32 m_presentStagesMask;
2686 const deUint32 m_activeStagesMask;
2687 ProgramInterfaceDefinition::Program* m_program;
2690 AtomicCounterReferencedByCase::AtomicCounterReferencedByCase (Context& context,
2692 const char* description,
2694 deUint32 presentStagesMask,
2695 deUint32 activeStagesMask)
2696 : TestCase (context, name, description)
2697 , m_separable (separable)
2698 , m_presentStagesMask (presentStagesMask)
2699 , m_activeStagesMask (activeStagesMask)
2700 , m_program (DE_NULL)
2702 DE_ASSERT((activeStagesMask & presentStagesMask) == activeStagesMask);
2705 AtomicCounterReferencedByCase::~AtomicCounterReferencedByCase (void)
2710 void AtomicCounterReferencedByCase::init (void)
2712 const deUint32 geometryMask = (1 << glu::SHADERTYPE_GEOMETRY);
2713 const deUint32 tessellationMask = (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION);
2714 glu::VariableDeclaration atomicVar (glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "targetCounter", glu::STORAGE_UNIFORM);
2716 if ((m_presentStagesMask & tessellationMask) != 0 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
2717 throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
2718 if ((m_presentStagesMask & geometryMask) != 0 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
2719 throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
2721 atomicVar.layout.binding = 1;
2723 m_program = new ProgramInterfaceDefinition::Program();
2724 m_program->setSeparable(m_separable);
2726 for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
2728 if (m_activeStagesMask & (1 << shaderType))
2729 m_program->addShader((glu::ShaderType)shaderType, glu::GLSL_VERSION_310_ES)->getDefaultBlock().variables.push_back(atomicVar);
2730 else if (m_presentStagesMask & (1 << shaderType))
2731 m_program->addShader((glu::ShaderType)shaderType, glu::GLSL_VERSION_310_ES);
2734 if (m_program->hasStage(glu::SHADERTYPE_GEOMETRY))
2735 m_program->setGeometryNumOutputVertices(1);
2736 if (m_program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
2737 m_program->setTessellationNumOutputPatchVertices(1);
2739 DE_ASSERT(m_program->isValid());
2742 void AtomicCounterReferencedByCase::deinit (void)
2745 m_program = DE_NULL;
2748 AtomicCounterReferencedByCase::IterateResult AtomicCounterReferencedByCase::iterate (void)
2752 glw::GLenum propName;
2753 glu::ShaderType shaderType;
2754 const char* extension;
2757 { GL_REFERENCED_BY_VERTEX_SHADER, glu::SHADERTYPE_VERTEX, DE_NULL },
2758 { GL_REFERENCED_BY_FRAGMENT_SHADER, glu::SHADERTYPE_FRAGMENT, DE_NULL },
2759 { GL_REFERENCED_BY_COMPUTE_SHADER, glu::SHADERTYPE_COMPUTE, DE_NULL },
2760 { GL_REFERENCED_BY_TESS_CONTROL_SHADER, glu::SHADERTYPE_TESSELLATION_CONTROL, "GL_EXT_tessellation_shader" },
2761 { GL_REFERENCED_BY_TESS_EVALUATION_SHADER, glu::SHADERTYPE_TESSELLATION_EVALUATION, "GL_EXT_tessellation_shader" },
2762 { GL_REFERENCED_BY_GEOMETRY_SHADER, glu::SHADERTYPE_GEOMETRY, "GL_EXT_geometry_shader" },
2765 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2766 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2768 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2769 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2772 for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(targetProps); ++propNdx)
2774 if (targetProps[propNdx].extension == DE_NULL || m_context.getContextInfo().isExtensionSupported(targetProps[propNdx].extension))
2776 const glw::GLenum prop = targetProps[propNdx].propName;
2777 const glw::GLint expected = ((m_activeStagesMask & (1 << targetProps[propNdx].shaderType)) != 0) ? (GL_TRUE) : (GL_FALSE);
2778 glw::GLint value = -1;
2779 glw::GLint written = -1;
2781 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying " << glu::getProgramResourcePropertyName(prop) << ", expecting " << glu::getBooleanName(expected) << tcu::TestLog::EndMessage;
2783 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, 0, 1, &prop, 1, &written, &value);
2784 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2788 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for referenced_by_* returned invalid number of values." << tcu::TestLog::EndMessage;
2789 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
2793 m_testCtx.getLog() << tcu::TestLog::Message << glu::getProgramResourcePropertyName(prop) << " = " << glu::getBooleanStr(value) << tcu::TestLog::EndMessage;
2795 if (value != expected)
2797 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected value" << tcu::TestLog::EndMessage;
2798 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected property value");
2807 class ProgramInputOutputReferencedByCase : public TestCase
2812 CASE_VERTEX_FRAGMENT = 0,
2813 CASE_VERTEX_GEO_FRAGMENT,
2814 CASE_VERTEX_TESS_FRAGMENT,
2815 CASE_VERTEX_TESS_GEO_FRAGMENT,
2817 CASE_SEPARABLE_VERTEX,
2818 CASE_SEPARABLE_FRAGMENT,
2819 CASE_SEPARABLE_GEOMETRY,
2820 CASE_SEPARABLE_TESS_CTRL,
2821 CASE_SEPARABLE_TESS_EVAL,
2825 ProgramInputOutputReferencedByCase (Context& context, const char* name, const char* description, glu::Storage targetStorage, CaseType caseType);
2826 ~ProgramInputOutputReferencedByCase (void);
2831 IterateResult iterate (void);
2833 const CaseType m_caseType;
2834 const glu::Storage m_targetStorage;
2835 ProgramInterfaceDefinition::Program* m_program;
2838 ProgramInputOutputReferencedByCase::ProgramInputOutputReferencedByCase (Context& context, const char* name, const char* description, glu::Storage targetStorage, CaseType caseType)
2839 : TestCase (context, name, description)
2840 , m_caseType (caseType)
2841 , m_targetStorage (targetStorage)
2842 , m_program (DE_NULL)
2844 DE_ASSERT(caseType < CASE_LAST);
2847 ProgramInputOutputReferencedByCase::~ProgramInputOutputReferencedByCase (void)
2852 void ProgramInputOutputReferencedByCase::init (void)
2854 const bool hasTessellationShader = (m_caseType == CASE_VERTEX_TESS_FRAGMENT) ||
2855 (m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT) ||
2856 (m_caseType == CASE_SEPARABLE_TESS_CTRL) ||
2857 (m_caseType == CASE_SEPARABLE_TESS_EVAL);
2858 const bool hasGeometryShader = (m_caseType == CASE_VERTEX_GEO_FRAGMENT) ||
2859 (m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT) ||
2860 (m_caseType == CASE_SEPARABLE_GEOMETRY);
2862 if (hasTessellationShader && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
2863 throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
2864 if (hasGeometryShader && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
2865 throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
2867 m_program = new ProgramInterfaceDefinition::Program();
2869 if (m_caseType == CASE_SEPARABLE_VERTEX ||
2870 m_caseType == CASE_SEPARABLE_FRAGMENT ||
2871 m_caseType == CASE_SEPARABLE_GEOMETRY ||
2872 m_caseType == CASE_SEPARABLE_TESS_CTRL ||
2873 m_caseType == CASE_SEPARABLE_TESS_EVAL)
2875 const bool isInputCase = (m_targetStorage == glu::STORAGE_IN || m_targetStorage == glu::STORAGE_PATCH_IN);
2876 const bool perPatchStorage = (m_targetStorage == glu::STORAGE_PATCH_IN || m_targetStorage == glu::STORAGE_PATCH_OUT);
2877 const char* varName = (isInputCase) ? ("shaderInput") : ("shaderOutput");
2878 const glu::VariableDeclaration targetDecl (glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), varName, m_targetStorage);
2879 const glu::ShaderType shaderType = (m_caseType == CASE_SEPARABLE_VERTEX) ? (glu::SHADERTYPE_VERTEX)
2880 : (m_caseType == CASE_SEPARABLE_FRAGMENT) ? (glu::SHADERTYPE_FRAGMENT)
2881 : (m_caseType == CASE_SEPARABLE_GEOMETRY) ? (glu::SHADERTYPE_GEOMETRY)
2882 : (m_caseType == CASE_SEPARABLE_TESS_CTRL) ? (glu::SHADERTYPE_TESSELLATION_CONTROL)
2883 : (m_caseType == CASE_SEPARABLE_TESS_EVAL) ? (glu::SHADERTYPE_TESSELLATION_EVALUATION)
2884 : (glu::SHADERTYPE_LAST);
2885 const bool arrayedInterface = (isInputCase) ? ((shaderType == glu::SHADERTYPE_GEOMETRY) ||
2886 (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL) ||
2887 (shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION))
2888 : (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL);
2890 m_program->setSeparable(true);
2892 if (arrayedInterface && !perPatchStorage)
2894 const glu::VariableDeclaration targetDeclArr(glu::VarType(targetDecl.varType, glu::VarType::UNSIZED_ARRAY), varName, m_targetStorage);
2895 m_program->addShader(shaderType, glu::GLSL_VERSION_310_ES)->getDefaultBlock().variables.push_back(targetDeclArr);
2899 m_program->addShader(shaderType, glu::GLSL_VERSION_310_ES)->getDefaultBlock().variables.push_back(targetDecl);
2902 else if (m_caseType == CASE_VERTEX_FRAGMENT ||
2903 m_caseType == CASE_VERTEX_GEO_FRAGMENT ||
2904 m_caseType == CASE_VERTEX_TESS_FRAGMENT ||
2905 m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
2907 ProgramInterfaceDefinition::Shader* vertex = m_program->addShader(glu::SHADERTYPE_VERTEX, glu::GLSL_VERSION_310_ES);
2908 ProgramInterfaceDefinition::Shader* fragment = m_program->addShader(glu::SHADERTYPE_FRAGMENT, glu::GLSL_VERSION_310_ES);
2910 m_program->setSeparable(false);
2912 vertex->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2915 vertex->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2918 glu::INTERPOLATION_LAST,
2921 fragment->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2924 glu::INTERPOLATION_LAST,
2926 fragment->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2929 glu::INTERPOLATION_LAST,
2932 if (m_caseType == CASE_VERTEX_TESS_FRAGMENT || m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
2934 ProgramInterfaceDefinition::Shader* tessCtrl = m_program->addShader(glu::SHADERTYPE_TESSELLATION_CONTROL, glu::GLSL_VERSION_310_ES);
2935 ProgramInterfaceDefinition::Shader* tessEval = m_program->addShader(glu::SHADERTYPE_TESSELLATION_EVALUATION, glu::GLSL_VERSION_310_ES);
2937 tessCtrl->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2940 glu::INTERPOLATION_LAST,
2942 tessCtrl->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2945 glu::INTERPOLATION_LAST,
2948 tessEval->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2951 glu::INTERPOLATION_LAST,
2953 tessEval->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2956 glu::INTERPOLATION_LAST,
2960 if (m_caseType == CASE_VERTEX_GEO_FRAGMENT || m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
2962 ProgramInterfaceDefinition::Shader* geometry = m_program->addShader(glu::SHADERTYPE_GEOMETRY, glu::GLSL_VERSION_310_ES);
2964 geometry->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2967 glu::INTERPOLATION_LAST,
2969 geometry->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2972 glu::INTERPOLATION_LAST,
2979 if (m_program->hasStage(glu::SHADERTYPE_GEOMETRY))
2980 m_program->setGeometryNumOutputVertices(1);
2981 if (m_program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
2982 m_program->setTessellationNumOutputPatchVertices(1);
2984 DE_ASSERT(m_program->isValid());
2987 void ProgramInputOutputReferencedByCase::deinit (void)
2990 m_program = DE_NULL;
2993 ProgramInputOutputReferencedByCase::IterateResult ProgramInputOutputReferencedByCase::iterate (void)
2997 glw::GLenum propName;
2998 glu::ShaderType shaderType;
2999 const char* extension;
3002 { GL_REFERENCED_BY_VERTEX_SHADER, glu::SHADERTYPE_VERTEX, DE_NULL },
3003 { GL_REFERENCED_BY_FRAGMENT_SHADER, glu::SHADERTYPE_FRAGMENT, DE_NULL },
3004 { GL_REFERENCED_BY_COMPUTE_SHADER, glu::SHADERTYPE_COMPUTE, DE_NULL },
3005 { GL_REFERENCED_BY_TESS_CONTROL_SHADER, glu::SHADERTYPE_TESSELLATION_CONTROL, "GL_EXT_tessellation_shader" },
3006 { GL_REFERENCED_BY_TESS_EVALUATION_SHADER, glu::SHADERTYPE_TESSELLATION_EVALUATION, "GL_EXT_tessellation_shader" },
3007 { GL_REFERENCED_BY_GEOMETRY_SHADER, glu::SHADERTYPE_GEOMETRY, "GL_EXT_geometry_shader" },
3010 const bool isInputCase = (m_targetStorage == glu::STORAGE_IN || m_targetStorage == glu::STORAGE_PATCH_IN);
3011 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3012 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
3013 const std::string targetResourceName = (isInputCase) ? ("shaderInput") : ("shaderOutput");
3014 const glw::GLenum programGLInterface = (isInputCase) ? (GL_PROGRAM_INPUT) : (GL_PROGRAM_OUTPUT);
3015 glw::GLuint resourceIndex;
3017 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3018 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
3020 // find target resource index
3022 resourceIndex = gl.getProgramResourceIndex(program.getProgram(), programGLInterface, targetResourceName.c_str());
3023 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
3025 if (resourceIndex == GL_INVALID_INDEX)
3027 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for resource \"" << targetResourceName << "\" index returned invalid index." << tcu::TestLog::EndMessage;
3028 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "could not find target resource");
3033 for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(targetProps); ++propNdx)
3035 if (targetProps[propNdx].extension == DE_NULL || m_context.getContextInfo().isExtensionSupported(targetProps[propNdx].extension))
3037 const glw::GLenum prop = targetProps[propNdx].propName;
3038 const bool expected = (isInputCase) ? (targetProps[propNdx].shaderType == m_program->getFirstStage()) : (targetProps[propNdx].shaderType == m_program->getLastStage());
3039 glw::GLint value = -1;
3040 glw::GLint written = -1;
3042 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying " << glu::getProgramResourcePropertyName(prop) << ", expecting " << ((expected) ? ("TRUE") : ("FALSE")) << tcu::TestLog::EndMessage;
3044 gl.getProgramResourceiv(program.getProgram(), programGLInterface, resourceIndex, 1, &prop, 1, &written, &value);
3045 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
3049 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for referenced_by_* returned invalid number of values." << tcu::TestLog::EndMessage;
3050 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
3054 m_testCtx.getLog() << tcu::TestLog::Message << glu::getProgramResourcePropertyName(prop) << " = " << glu::getBooleanStr(value) << tcu::TestLog::EndMessage;
3056 if (value != ((expected) ? (GL_TRUE) : (GL_FALSE)))
3058 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected value" << tcu::TestLog::EndMessage;
3059 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected property value");
3068 class FeedbackResourceListTestCase : public ResourceListTestCase
3071 FeedbackResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& resource, const char* name);
3072 ~FeedbackResourceListTestCase (void);
3075 IterateResult iterate (void);
3078 FeedbackResourceListTestCase::FeedbackResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& resource, const char* name)
3079 : ResourceListTestCase(context, resource, PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, name)
3083 FeedbackResourceListTestCase::~FeedbackResourceListTestCase (void)
3088 FeedbackResourceListTestCase::IterateResult FeedbackResourceListTestCase::iterate (void)
3090 const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_programDefinition));
3092 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3094 // Feedback varyings
3096 tcu::MessageBuilder builder(&m_testCtx.getLog());
3097 builder << "Transform feedback varyings: {";
3098 for (int ndx = 0; ndx < (int)m_programDefinition->getTransformFeedbackVaryings().size(); ++ndx)
3102 builder << "\"" << m_programDefinition->getTransformFeedbackVaryings()[ndx] << "\"";
3104 builder << "}" << tcu::TestLog::EndMessage;
3107 checkAndLogProgram(program, m_programDefinition, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
3109 // Check resource list
3111 const tcu::ScopedLogSection section (m_testCtx.getLog(), "ResourceList", "Resource list");
3112 std::vector<std::string> resourceList;
3113 std::vector<std::string> expectedResources;
3115 queryResourceList(resourceList, program.getProgram());
3116 expectedResources = getProgramInterfaceResourceList(m_programDefinition, m_programInterface);
3118 // verify the list and the expected list match
3120 if (!verifyResourceList(resourceList, expectedResources))
3121 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid resource list");
3123 // verify GetProgramResourceIndex() matches the indices of the list
3125 if (!verifyResourceIndexQuery(resourceList, expectedResources, program.getProgram()))
3126 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GetProgramResourceIndex returned unexpected values");
3128 // Verify MAX_NAME_LENGTH
3129 if (!verifyMaxNameLength(resourceList, program.getProgram()))
3130 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "MAX_NAME_LENGTH invalid");
3136 int InterfaceBlockDataSizeTestCase::getBlockMinDataSize (const glu::InterfaceBlock& block) const
3140 for (int ndx = 0; ndx < (int)block.variables.size(); ++ndx)
3141 dataSize += getVarTypeSize(block.variables[ndx].varType);
3146 static bool isDataTypeLayoutQualified (glu::DataType type)
3148 return glu::isDataTypeImage(type) || glu::isDataTypeAtomicCounter(type);
3151 static void generateVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3, bool createTestGroup = true)
3156 glu::DataType dataType;
3159 { 0, glu::TYPE_FLOAT },
3160 { 1, glu::TYPE_INT },
3161 { 1, glu::TYPE_UINT },
3162 { 1, glu::TYPE_BOOL },
3164 { 3, glu::TYPE_FLOAT_VEC2 },
3165 { 1, glu::TYPE_FLOAT_VEC3 },
3166 { 1, glu::TYPE_FLOAT_VEC4 },
3168 { 3, glu::TYPE_INT_VEC2 },
3169 { 2, glu::TYPE_INT_VEC3 },
3170 { 3, glu::TYPE_INT_VEC4 },
3172 { 3, glu::TYPE_UINT_VEC2 },
3173 { 2, glu::TYPE_UINT_VEC3 },
3174 { 3, glu::TYPE_UINT_VEC4 },
3176 { 3, glu::TYPE_BOOL_VEC2 },
3177 { 2, glu::TYPE_BOOL_VEC3 },
3178 { 3, glu::TYPE_BOOL_VEC4 },
3180 { 2, glu::TYPE_FLOAT_MAT2 },
3181 { 3, glu::TYPE_FLOAT_MAT2X3 },
3182 { 3, glu::TYPE_FLOAT_MAT2X4 },
3183 { 2, glu::TYPE_FLOAT_MAT3X2 },
3184 { 2, glu::TYPE_FLOAT_MAT3 },
3185 { 3, glu::TYPE_FLOAT_MAT3X4 },
3186 { 2, glu::TYPE_FLOAT_MAT4X2 },
3187 { 3, glu::TYPE_FLOAT_MAT4X3 },
3188 { 2, glu::TYPE_FLOAT_MAT4 },
3191 tcu::TestCaseGroup* group;
3193 if (createTestGroup)
3195 group = new tcu::TestCaseGroup(context.getTestContext(), "basic_type", "Basic variable");
3196 targetGroup->addChild(group);
3199 group = targetGroup;
3201 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3203 if (variableTypes[ndx].level <= expandLevel)
3205 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
3206 group->addChild(new ResourceTestCase(context, variable, queryTarget));
3211 static void generateOpaqueTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3, bool createTestGroup = true)
3216 glu::DataType dataType;
3219 { 0, glu::TYPE_SAMPLER_2D },
3220 { 2, glu::TYPE_SAMPLER_CUBE },
3221 { 1, glu::TYPE_SAMPLER_2D_ARRAY },
3222 { 1, glu::TYPE_SAMPLER_3D },
3223 { 2, glu::TYPE_SAMPLER_2D_SHADOW },
3224 { 3, glu::TYPE_SAMPLER_CUBE_SHADOW },
3225 { 3, glu::TYPE_SAMPLER_2D_ARRAY_SHADOW },
3226 { 1, glu::TYPE_INT_SAMPLER_2D },
3227 { 3, glu::TYPE_INT_SAMPLER_CUBE },
3228 { 3, glu::TYPE_INT_SAMPLER_2D_ARRAY },
3229 { 3, glu::TYPE_INT_SAMPLER_3D },
3230 { 2, glu::TYPE_UINT_SAMPLER_2D },
3231 { 3, glu::TYPE_UINT_SAMPLER_CUBE },
3232 { 3, glu::TYPE_UINT_SAMPLER_2D_ARRAY },
3233 { 3, glu::TYPE_UINT_SAMPLER_3D },
3234 { 2, glu::TYPE_SAMPLER_2D_MULTISAMPLE },
3235 { 2, glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE },
3236 { 3, glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE },
3237 { 1, glu::TYPE_IMAGE_2D },
3238 { 3, glu::TYPE_IMAGE_CUBE },
3239 { 3, glu::TYPE_IMAGE_2D_ARRAY },
3240 { 3, glu::TYPE_IMAGE_3D },
3241 { 3, glu::TYPE_INT_IMAGE_2D },
3242 { 3, glu::TYPE_INT_IMAGE_CUBE },
3243 { 1, glu::TYPE_INT_IMAGE_2D_ARRAY },
3244 { 3, glu::TYPE_INT_IMAGE_3D },
3245 { 2, glu::TYPE_UINT_IMAGE_2D },
3246 { 3, glu::TYPE_UINT_IMAGE_CUBE },
3247 { 3, glu::TYPE_UINT_IMAGE_2D_ARRAY },
3248 { 3, glu::TYPE_UINT_IMAGE_3D },
3249 { 1, glu::TYPE_UINT_ATOMIC_COUNTER },
3252 bool isStructMember = false;
3255 for (const ResourceDefinition::Node* node = parentStructure.get(); node; node = node->getEnclosingNode())
3257 // Don't insert inside a interface block
3258 if (node->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3261 isStructMember |= (node->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER);
3266 tcu::TestCaseGroup* group;
3268 if (createTestGroup)
3270 group = new tcu::TestCaseGroup(context.getTestContext(), "opaque_type", "Opaque types");
3271 targetGroup->addChild(group);
3274 group = targetGroup;
3276 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3278 if (variableTypes[ndx].level > expandLevel)
3281 // Layout qualifiers are not allowed on struct members
3282 if (isDataTypeLayoutQualified(variableTypes[ndx].dataType) && isStructMember)
3286 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
3287 group->addChild(new ResourceTestCase(context, variable, queryTarget));
3293 static void generateCompoundVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3);
3295 static void generateVariableArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3)
3297 if (expandLevel > 0)
3299 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3300 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3302 targetGroup->addChild(blockGroup);
3304 // Arrays of basic variables
3305 generateVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3307 // Arrays of opaque types
3308 generateOpaqueTypeCases(context, arrayElement, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3311 generateVariableArrayCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3313 // Arrays of structs
3314 generateCompoundVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3318 static void generateCompoundVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
3320 if (expandLevel > 0)
3322 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3323 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "struct", "Structs");
3325 targetGroup->addChild(blockGroup);
3327 // Struct containing basic variable
3328 generateVariableCases(context, structMember, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3330 // Struct containing opaque types
3331 generateOpaqueTypeCases(context, structMember, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3333 // Struct containing arrays
3334 generateVariableArrayCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3336 // Struct containing struct
3337 generateCompoundVariableCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3341 // Resource list cases
3345 BLOCKFLAG_DEFAULT = 0x01,
3346 BLOCKFLAG_NAMED = 0x02,
3347 BLOCKFLAG_UNNAMED = 0x04,
3348 BLOCKFLAG_ARRAY = 0x08,
3350 BLOCKFLAG_ALL = 0x0F
3353 static void generateUniformCaseBlocks (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, deUint32 blockFlags, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup* const))
3355 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
3356 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
3359 if (blockFlags & BLOCKFLAG_DEFAULT)
3361 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "default_block", "Default block");
3362 targetGroup->addChild(blockGroup);
3364 blockContentGenerator(context, uniform, blockGroup);
3368 if (blockFlags & BLOCKFLAG_NAMED)
3370 const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(uniform, true));
3372 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "named_block", "Named uniform block");
3373 targetGroup->addChild(blockGroup);
3375 blockContentGenerator(context, block, blockGroup);
3379 if (blockFlags & BLOCKFLAG_UNNAMED)
3381 const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(uniform, false));
3383 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "unnamed_block", "Unnamed uniform block");
3384 targetGroup->addChild(blockGroup);
3386 blockContentGenerator(context, block, blockGroup);
3390 if (blockFlags & BLOCKFLAG_ARRAY)
3392 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(uniform));
3393 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
3395 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "block_array", "Uniform block array");
3396 targetGroup->addChild(blockGroup);
3398 blockContentGenerator(context, block, blockGroup);
3402 static void generateBufferBackedResourceListBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, int depth)
3406 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, glu::TYPE_FLOAT_VEC4));
3407 targetGroup->addChild(new ResourceListTestCase(context, variable, interface));
3413 const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
3414 generateBufferBackedResourceListBlockContentCases(context, structMember, targetGroup, interface, depth - 1);
3420 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
3421 generateBufferBackedResourceListBlockContentCases(context, arrayElement, targetGroup, interface, depth - 1);
3425 static void generateBufferBackedVariableAggregateTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, ProgramResourcePropFlags targetProp, glu::DataType dataType, const std::string& nameSuffix, int depth)
3429 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, dataType));
3430 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, targetProp), ("var" + nameSuffix).c_str()));
3436 const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
3437 generateBufferBackedVariableAggregateTypeCases(context, structMember, targetGroup, interface, targetProp, dataType, "_struct" + nameSuffix, depth - 1);
3443 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
3444 generateBufferBackedVariableAggregateTypeCases(context, arrayElement, targetGroup, interface, targetProp, dataType, "_array" + nameSuffix, depth - 1);
3448 static void generateUniformResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3450 generateBufferBackedResourceListBlockContentCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, 4);
3453 static void generateUniformBlockArraySizeContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3455 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ARRAY_SIZE);
3456 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3457 const bool namedNonArrayBlock = isInterfaceBlock &&
3458 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3459 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3461 if (!isInterfaceBlock || namedNonArrayBlock)
3465 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3466 targetGroup->addChild(blockGroup);
3468 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3469 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3474 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3475 targetGroup->addChild(blockGroup);
3477 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_ARRAY_SIZE, glu::TYPE_FLOAT, "", 3);
3483 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, queryTarget.interface, PROGRAMRESOURCEPROP_ARRAY_SIZE, glu::TYPE_FLOAT, "", 2);
3487 static void generateBufferBackedArrayStrideTypeAggregateSubCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const std::string& namePrefix, ProgramInterface interface, glu::DataType type, int expandLevel)
3491 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, type));
3492 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_ARRAY_STRIDE), namePrefix.c_str()));
3495 if (expandLevel > 0)
3497 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3498 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3501 generateBufferBackedArrayStrideTypeAggregateSubCases(context, structMember, targetGroup, namePrefix + "_struct", interface, type, expandLevel - 1);
3504 generateBufferBackedArrayStrideTypeAggregateSubCases(context, arrayElement, targetGroup, namePrefix + "_array", interface, type, expandLevel - 1);
3508 static void generateBufferBackedArrayStrideTypeAggregateCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, glu::DataType type, int expandLevel, bool includeBaseCase)
3510 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3511 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3512 const std::string namePrefix = glu::getDataTypeName(type);
3514 if (expandLevel == 0 || includeBaseCase)
3516 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, type));
3517 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_ARRAY_STRIDE), namePrefix.c_str()));
3519 if (expandLevel >= 1)
3522 if (!glu::isDataTypeAtomicCounter(type))
3523 generateBufferBackedArrayStrideTypeAggregateSubCases(context, structMember, targetGroup, namePrefix + "_struct", interface, type, expandLevel - 1);
3526 generateBufferBackedArrayStrideTypeAggregateSubCases(context, arrayElement, targetGroup, namePrefix + "_array", interface, type, expandLevel - 1);
3530 static void generateUniformBlockArrayStrideContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3532 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ARRAY_STRIDE);
3533 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3534 const bool namedNonArrayBlock = isInterfaceBlock &&
3535 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3536 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3538 if (!isInterfaceBlock || namedNonArrayBlock)
3542 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3543 targetGroup->addChild(blockGroup);
3545 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3546 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3551 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3552 targetGroup->addChild(blockGroup);
3555 if (!isInterfaceBlock)
3556 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_SAMPLER_2D, 1, false);
3558 // .atomic_counter_*
3559 if (!isInterfaceBlock)
3561 const ResourceDefinition::Node::SharedPtr layout(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
3562 generateBufferBackedArrayStrideTypeAggregateCases(context, layout, blockGroup, queryTarget.interface, glu::TYPE_UINT_ATOMIC_COUNTER, 1, false);
3566 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_FLOAT, 2, false);
3569 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_BOOL, 1, false);
3572 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_BOOL_VEC3, 2, false);
3575 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_FLOAT_VEC3, 2, false);
3578 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_INT_VEC3, 2, false);
3583 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3584 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3585 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3589 static void generateUniformBlockLocationContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3591 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_LOCATION);
3592 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3594 if (!isInterfaceBlock)
3596 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 3);
3597 generateOpaqueTypeCases(context, parentStructure, targetGroup, queryTarget, 3);
3598 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 2);
3599 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 2);
3602 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1, false);
3605 static void generateUniformBlockBlockIndexContents (Context& context, tcu::TestCaseGroup* const targetGroup)
3607 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
3608 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
3609 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
3610 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
3611 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(uniform, glu::Layout(-1, 0)));
3615 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(uniform, glu::TYPE_FLOAT_VEC4));
3617 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "default_block"));
3622 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, true));
3623 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3625 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "named_block"));
3630 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, false));
3631 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3633 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "unnamed_block"));
3638 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding));
3639 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
3640 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3642 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "block_array"));
3646 static void generateUniformBlockAtomicCounterBufferIndexContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3648 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ATOMIC_COUNTER_BUFFER_INDEX);
3649 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3651 if (!isInterfaceBlock)
3653 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 3);
3654 generateOpaqueTypeCases(context, parentStructure, targetGroup, queryTarget, 3);
3658 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3659 const ResourceDefinition::Node::SharedPtr arrayArrayElement (new ResourceDefinition::ArrayElement(arrayElement));
3660 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3661 const ResourceDefinition::Node::SharedPtr elementvariable (new ResourceDefinition::Variable(arrayArrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3662 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3664 targetGroup->addChild(blockGroup);
3666 blockGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "var_array"));
3667 blockGroup->addChild(new ResourceTestCase(context, elementvariable, queryTarget, "var_array_array"));
3671 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1, false);
3674 static void generateUniformBlockNameLengthContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3676 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3677 const bool namedNonArrayBlock = isInterfaceBlock &&
3678 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3679 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3681 if (!isInterfaceBlock || namedNonArrayBlock)
3682 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 2);
3684 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 1);
3687 static void generateUniformBlockTypeContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3689 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_TYPE);
3690 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3691 const bool namedNonArrayBlock = isInterfaceBlock &&
3692 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3693 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3695 if (!isInterfaceBlock || namedNonArrayBlock)
3699 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3700 targetGroup->addChild(blockGroup);
3702 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3703 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3706 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3707 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3712 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3713 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3714 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3718 static void generateUniformBlockOffsetContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3720 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_OFFSET);
3721 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3722 const bool namedNonArrayBlock = isInterfaceBlock &&
3723 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3724 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3726 if (!isInterfaceBlock)
3730 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3731 targetGroup->addChild(blockGroup);
3733 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3734 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3739 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3740 targetGroup->addChild(blockGroup);
3742 // .atomic_uint_struct
3743 // .atomic_uint_array
3745 const ResourceDefinition::Node::SharedPtr offset (new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, 4)));
3746 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(offset));
3747 const ResourceDefinition::Node::SharedPtr elementVariable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3749 blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "atomic_uint_array"));
3755 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3756 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3757 const ResourceDefinition::Node::SharedPtr memberVariable (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
3758 const ResourceDefinition::Node::SharedPtr elementVariable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
3760 blockGroup->addChild(new ResourceTestCase(context, memberVariable, queryTarget, "float_struct"));
3761 blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "float_array"));
3765 else if (namedNonArrayBlock)
3769 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3770 targetGroup->addChild(blockGroup);
3772 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3773 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3778 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3779 targetGroup->addChild(blockGroup);
3784 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3785 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::StructMember(parentStructure));
3786 const ResourceDefinition::Node::SharedPtr memberVariable (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
3787 const ResourceDefinition::Node::SharedPtr elementVariable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
3789 blockGroup->addChild(new ResourceTestCase(context, memberVariable, queryTarget, "float_struct"));
3790 blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "float_array"));
3796 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3797 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3798 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3802 static void generateMatrixVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, bool createTestGroup = true, int expandLevel = 2)
3810 { 0, glu::TYPE_FLOAT_MAT2 },
3811 { 1, glu::TYPE_FLOAT_MAT2X3 },
3812 { 2, glu::TYPE_FLOAT_MAT2X4 },
3813 { 2, glu::TYPE_FLOAT_MAT3X2 },
3814 { 1, glu::TYPE_FLOAT_MAT3 },
3815 { 0, glu::TYPE_FLOAT_MAT3X4 },
3816 { 2, glu::TYPE_FLOAT_MAT4X2 },
3817 { 1, glu::TYPE_FLOAT_MAT4X3 },
3818 { 0, glu::TYPE_FLOAT_MAT4 },
3821 tcu::TestCaseGroup* group;
3823 if (createTestGroup)
3825 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "matrix", "Basic matrix type");
3826 targetGroup->addChild(blockGroup);
3830 group = targetGroup;
3832 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3834 if (variableTypes[ndx].priority < expandLevel)
3836 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
3837 group->addChild(new ResourceTestCase(context, variable, queryTarget));
3842 static void generateMatrixStructCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel);
3844 static void generateMatrixArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
3846 if (expandLevel > 0)
3848 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3849 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3851 targetGroup->addChild(blockGroup);
3853 // Arrays of basic variables
3854 generateMatrixVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel != 1, expandLevel);
3857 generateMatrixArrayCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3859 // Arrays of structs
3860 generateMatrixStructCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3864 static void generateMatrixStructCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
3866 if (expandLevel > 0)
3868 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3869 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "struct", "Structs");
3871 targetGroup->addChild(blockGroup);
3873 // Struct containing basic variable
3874 generateMatrixVariableCases(context, structMember, blockGroup, queryTarget, expandLevel != 1, expandLevel);
3876 // Struct containing arrays
3877 generateMatrixArrayCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3879 // Struct containing struct
3880 generateMatrixStructCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3884 static void generateUniformMatrixOrderCaseBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, bool extendedBasicTypeCases, bool opaqueCases)
3889 glu::MatrixOrder order;
3892 { "no_qualifier", glu::MATRIXORDER_LAST },
3893 { "row_major", glu::MATRIXORDER_ROW_MAJOR },
3894 { "column_major", glu::MATRIXORDER_COLUMN_MAJOR },
3897 const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR);
3899 for (int qualifierNdx = 0; qualifierNdx < DE_LENGTH_OF_ARRAY(qualifiers); ++qualifierNdx)
3901 // Add layout qualifiers only for block members
3902 if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST || parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3904 ResourceDefinition::Node::SharedPtr subStructure = parentStructure;
3905 tcu::TestCaseGroup* const qualifierGroup = new tcu::TestCaseGroup(context.getTestContext(), qualifiers[qualifierNdx].name, "");
3907 targetGroup->addChild(qualifierGroup);
3909 if (qualifiers[qualifierNdx].order != glu::MATRIXORDER_LAST)
3912 layout.matrixOrder = qualifiers[qualifierNdx].order;
3913 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
3916 if (extendedBasicTypeCases && qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST)
3920 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "");
3921 qualifierGroup->addChild(blockGroup);
3923 generateVariableCases(context, subStructure, blockGroup, queryTarget, 1, false);
3924 generateMatrixVariableCases(context, subStructure, blockGroup, queryTarget, false);
3926 generateOpaqueTypeCases(context, subStructure, blockGroup, queryTarget, 2, false);
3931 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "");
3932 qualifierGroup->addChild(blockGroup);
3934 generateBufferBackedVariableAggregateTypeCases(context, subStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
3939 generateBufferBackedVariableAggregateTypeCases(context, subStructure, qualifierGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
3945 static void generateUniformMatrixStrideCaseBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, bool extendedBasicTypeCases, bool opaqueCases)
3950 glu::MatrixOrder order;
3953 { "no_qualifier", glu::MATRIXORDER_LAST },
3954 { "row_major", glu::MATRIXORDER_ROW_MAJOR },
3955 { "column_major", glu::MATRIXORDER_COLUMN_MAJOR },
3958 const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_MATRIX_STRIDE);
3960 for (int qualifierNdx = 0; qualifierNdx < DE_LENGTH_OF_ARRAY(qualifiers); ++qualifierNdx)
3962 // Add layout qualifiers only for block members
3963 if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST || parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3965 ResourceDefinition::Node::SharedPtr subStructure = parentStructure;
3966 tcu::TestCaseGroup* const qualifierGroup = new tcu::TestCaseGroup(context.getTestContext(), qualifiers[qualifierNdx].name, "");
3968 targetGroup->addChild(qualifierGroup);
3970 if (qualifiers[qualifierNdx].order != glu::MATRIXORDER_LAST)
3973 layout.matrixOrder = qualifiers[qualifierNdx].order;
3974 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
3977 if (extendedBasicTypeCases)
3981 if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST)
3983 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "");
3984 qualifierGroup->addChild(blockGroup);
3986 generateVariableCases(context, subStructure, blockGroup, queryTarget, 1, false);
3987 generateMatrixVariableCases(context, subStructure, blockGroup, queryTarget, false);
3989 generateOpaqueTypeCases(context, subStructure, blockGroup, queryTarget, 2, false);
3992 generateMatrixVariableCases(context, subStructure, qualifierGroup, queryTarget);
3996 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "");
3997 qualifierGroup->addChild(blockGroup);
3999 generateBufferBackedVariableAggregateTypeCases(context, subStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
4003 generateBufferBackedVariableAggregateTypeCases(context, subStructure, qualifierGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
4008 static void generateUniformMatrixCaseBlocks (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup* const, bool, bool))
4013 const char* description;
4016 bool extendedBasicTypeCases;
4017 glu::MatrixOrder order;
4020 { "default_block", "Default block", false, true, true, glu::MATRIXORDER_LAST },
4021 { "named_block", "Named uniform block", true, true, true, glu::MATRIXORDER_LAST },
4022 { "named_block_row_major", "Named uniform block", true, true, false, glu::MATRIXORDER_ROW_MAJOR },
4023 { "named_block_col_major", "Named uniform block", true, true, false, glu::MATRIXORDER_COLUMN_MAJOR },
4024 { "unnamed_block", "Unnamed uniform block", true, false, false, glu::MATRIXORDER_LAST },
4025 { "unnamed_block_row_major", "Unnamed uniform block", true, false, false, glu::MATRIXORDER_ROW_MAJOR },
4026 { "unnamed_block_col_major", "Unnamed uniform block", true, false, false, glu::MATRIXORDER_COLUMN_MAJOR },
4029 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
4030 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4032 for (int childNdx = 0; childNdx < (int)DE_LENGTH_OF_ARRAY(children); ++childNdx)
4034 ResourceDefinition::Node::SharedPtr subStructure = uniform;
4035 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), children[childNdx].name, children[childNdx].description);
4036 const bool addOpaqueCases = children[childNdx].extendedBasicTypeCases && !children[childNdx].block;
4038 targetGroup->addChild(blockGroup);
4040 if (children[childNdx].order != glu::MATRIXORDER_LAST)
4043 layout.matrixOrder = children[childNdx].order;
4044 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
4047 if (children[childNdx].block)
4048 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(subStructure, children[childNdx].namedBlock));
4050 blockContentGenerator(context, subStructure, blockGroup, children[childNdx].extendedBasicTypeCases, addOpaqueCases);
4054 static void generateBufferReferencedByShaderInterfaceBlockCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, bool extendedCases)
4056 const bool isDefaultBlock = (parentStructure->getType() != ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
4062 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(parentStructure, glu::TYPE_FLOAT));
4063 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
4064 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4065 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4066 const ResourceDefinition::Node::SharedPtr variableStruct (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
4068 targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "float"));
4069 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_array"));
4070 targetGroup->addChild(new ResourceTestCase(context, variableStruct, queryTarget, "float_struct"));
4078 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
4079 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_SAMPLER_2D));
4080 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(layout));
4081 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4082 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_SAMPLER_2D));
4083 const ResourceDefinition::Node::SharedPtr variableStruct (new ResourceDefinition::Variable(structMember, glu::TYPE_SAMPLER_2D));
4085 targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "sampler"));
4086 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "sampler_array"));
4087 targetGroup->addChild(new ResourceTestCase(context, variableStruct, queryTarget, "sampler_struct"));
4091 // .atomic_uint_array
4094 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
4095 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_UINT_ATOMIC_COUNTER));
4096 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(layout));
4097 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
4099 targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "atomic_uint"));
4100 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "atomic_uint_array"));
4105 // .float_array_struct
4107 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4108 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(structMember));
4109 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4111 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_array_struct"));
4114 // .float_struct_array
4116 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
4117 const ResourceDefinition::Node::SharedPtr arrayStructMember (new ResourceDefinition::StructMember(arrayElement));
4118 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(arrayStructMember, glu::TYPE_FLOAT));
4120 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_struct_array"));
4123 // .float_array_array
4125 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
4126 const ResourceDefinition::Node::SharedPtr subArrayElement (new ResourceDefinition::ArrayElement(arrayElement));
4127 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(subArrayElement, glu::TYPE_FLOAT));
4129 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_array_array"));
4132 // .float_struct_struct
4134 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4135 const ResourceDefinition::Node::SharedPtr subStructMember (new ResourceDefinition::StructMember(structMember));
4136 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(subStructMember, glu::TYPE_FLOAT));
4138 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_struct_struct"));
4141 if (queryTarget.interface == PROGRAMINTERFACE_BUFFER_VARIABLE)
4143 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
4145 // .float_unsized_array
4147 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4149 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_unsized_array"));
4152 // .float_unsized_struct_array
4154 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(arrayElement));
4155 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
4157 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_unsized_struct_array"));
4163 static void generateUniformReferencedByShaderSingleBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, int expandLevel)
4165 DE_UNREF(expandLevel);
4167 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
4168 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4169 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER);
4170 const bool singleShaderCase = parentStructure->getType() == ResourceDefinition::Node::TYPE_SHADER;
4174 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "default_block", "");
4175 targetGroup->addChild(blockGroup);
4177 generateBufferReferencedByShaderInterfaceBlockCases(context, uniform, blockGroup, queryTarget, singleShaderCase);
4182 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(uniform, true));
4183 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "uniform_block", "");
4185 targetGroup->addChild(blockGroup);
4187 generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, singleShaderCase);
4192 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(uniform, false));
4193 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "");
4195 targetGroup->addChild(blockGroup);
4197 generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, false);
4202 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(uniform));
4203 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4204 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "");
4206 targetGroup->addChild(blockGroup);
4208 generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, false);
4212 static void generateReferencedByShaderCaseBlocks (Context& context, tcu::TestCaseGroup* const targetGroup, void (*generateBlockContent)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, int expandLevel))
4217 glu::ShaderType stage;
4219 } singleStageCases[] =
4221 { "compute", glu::SHADERTYPE_COMPUTE, 3 },
4222 { "separable_vertex", glu::SHADERTYPE_VERTEX, 2 },
4223 { "separable_fragment", glu::SHADERTYPE_FRAGMENT, 2 },
4224 { "separable_tess_ctrl", glu::SHADERTYPE_TESSELLATION_CONTROL, 2 },
4225 { "separable_tess_eval", glu::SHADERTYPE_TESSELLATION_EVALUATION, 2 },
4226 { "separable_geometry", glu::SHADERTYPE_GEOMETRY, 2 },
4238 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT),
4243 "vertex_tess_fragment",
4244 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
4249 "vertex_geo_fragment",
4250 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY),
4255 "vertex_tess_geo_fragment",
4256 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
4262 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
4264 TestCaseGroup* const blockGroup = new TestCaseGroup(context, singleStageCases[ndx].name, "");
4265 const bool programSeparable = (singleStageCases[ndx].stage != glu::SHADERTYPE_COMPUTE);
4266 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(programSeparable));
4267 const ResourceDefinition::Node::SharedPtr stage (new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glu::GLSL_VERSION_310_ES));
4269 targetGroup->addChild(blockGroup);
4271 generateBlockContent(context, stage, blockGroup, singleStageCases[ndx].expandLevel);
4274 for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
4278 TestCaseGroup* const blockGroup = new TestCaseGroup(context, pipelines[pipelineNdx].name, "");
4279 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4280 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program,
4281 glu::GLSL_VERSION_310_ES,
4282 pipelines[pipelineNdx].flags,
4283 pipelines[pipelineNdx].flags);
4284 targetGroup->addChild(blockGroup);
4287 const ResourceDefinition::Node::SharedPtr shaders(shaderSet);
4288 generateBlockContent(context, shaders, blockGroup, pipelines[pipelineNdx].expandLevel);
4293 for (int selectedStageBit = 0; selectedStageBit < glu::SHADERTYPE_LAST; ++selectedStageBit)
4295 if (pipelines[pipelineNdx].flags & (1 << selectedStageBit))
4297 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4298 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program,
4299 glu::GLSL_VERSION_310_ES,
4300 pipelines[pipelineNdx].flags,
4301 (1u << selectedStageBit));
4302 const char* stageName = (selectedStageBit == glu::SHADERTYPE_VERTEX) ? ("vertex")
4303 : (selectedStageBit == glu::SHADERTYPE_FRAGMENT) ? ("fragment")
4304 : (selectedStageBit == glu::SHADERTYPE_GEOMETRY) ? ("geo")
4305 : (selectedStageBit == glu::SHADERTYPE_TESSELLATION_CONTROL) ? ("tess_ctrl")
4306 : (selectedStageBit == glu::SHADERTYPE_TESSELLATION_EVALUATION) ? ("tess_eval")
4308 const std::string setName = std::string() + pipelines[pipelineNdx].name + "_only_" + stageName;
4309 TestCaseGroup* const blockGroup = new TestCaseGroup(context, setName.c_str(), "");
4310 const ResourceDefinition::Node::SharedPtr shaders (shaderSet);
4312 generateBlockContent(context, shaders, blockGroup, pipelines[pipelineNdx].subExpandLevel);
4313 targetGroup->addChild(blockGroup);
4319 static glu::DataType generateRandomDataType (de::Random& rnd, bool excludeOpaqueTypes)
4321 static const glu::DataType s_types[] =
4327 glu::TYPE_FLOAT_VEC2,
4328 glu::TYPE_FLOAT_VEC3,
4329 glu::TYPE_FLOAT_VEC4,
4333 glu::TYPE_UINT_VEC2,
4334 glu::TYPE_UINT_VEC3,
4335 glu::TYPE_UINT_VEC4,
4336 glu::TYPE_BOOL_VEC2,
4337 glu::TYPE_BOOL_VEC3,
4338 glu::TYPE_BOOL_VEC4,
4339 glu::TYPE_FLOAT_MAT2,
4340 glu::TYPE_FLOAT_MAT2X3,
4341 glu::TYPE_FLOAT_MAT2X4,
4342 glu::TYPE_FLOAT_MAT3X2,
4343 glu::TYPE_FLOAT_MAT3,
4344 glu::TYPE_FLOAT_MAT3X4,
4345 glu::TYPE_FLOAT_MAT4X2,
4346 glu::TYPE_FLOAT_MAT4X3,
4347 glu::TYPE_FLOAT_MAT4,
4349 glu::TYPE_SAMPLER_2D,
4350 glu::TYPE_SAMPLER_CUBE,
4351 glu::TYPE_SAMPLER_2D_ARRAY,
4352 glu::TYPE_SAMPLER_3D,
4353 glu::TYPE_SAMPLER_2D_SHADOW,
4354 glu::TYPE_SAMPLER_CUBE_SHADOW,
4355 glu::TYPE_SAMPLER_2D_ARRAY_SHADOW,
4356 glu::TYPE_INT_SAMPLER_2D,
4357 glu::TYPE_INT_SAMPLER_CUBE,
4358 glu::TYPE_INT_SAMPLER_2D_ARRAY,
4359 glu::TYPE_INT_SAMPLER_3D,
4360 glu::TYPE_UINT_SAMPLER_2D,
4361 glu::TYPE_UINT_SAMPLER_CUBE,
4362 glu::TYPE_UINT_SAMPLER_2D_ARRAY,
4363 glu::TYPE_UINT_SAMPLER_3D,
4364 glu::TYPE_SAMPLER_2D_MULTISAMPLE,
4365 glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE,
4366 glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE,
4368 glu::TYPE_IMAGE_CUBE,
4369 glu::TYPE_IMAGE_2D_ARRAY,
4371 glu::TYPE_INT_IMAGE_2D,
4372 glu::TYPE_INT_IMAGE_CUBE,
4373 glu::TYPE_INT_IMAGE_2D_ARRAY,
4374 glu::TYPE_INT_IMAGE_3D,
4375 glu::TYPE_UINT_IMAGE_2D,
4376 glu::TYPE_UINT_IMAGE_CUBE,
4377 glu::TYPE_UINT_IMAGE_2D_ARRAY,
4378 glu::TYPE_UINT_IMAGE_3D,
4379 glu::TYPE_UINT_ATOMIC_COUNTER
4384 const glu::DataType type = s_types[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_types)-1)];
4386 if (!excludeOpaqueTypes ||
4387 glu::isDataTypeScalarOrVector(type) ||
4388 glu::isDataTypeMatrix(type))
4393 static ResourceDefinition::Node::SharedPtr generateRandomVariableDefinition (de::Random& rnd,
4394 const ResourceDefinition::Node::SharedPtr& parentStructure,
4395 glu::DataType baseType,
4396 const glu::Layout& layout,
4399 const int maxNesting = 4;
4400 ResourceDefinition::Node::SharedPtr currentStructure = parentStructure;
4401 const bool canBeInsideAStruct = layout.binding == -1 && !isDataTypeLayoutQualified(baseType);
4403 for (int nestNdx = 0; nestNdx < maxNesting; ++nestNdx)
4405 if (allowUnsized && nestNdx == 0 && rnd.getFloat() < 0.2)
4406 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
4407 else if (rnd.getFloat() < 0.3 && canBeInsideAStruct)
4408 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StructMember(currentStructure));
4409 else if (rnd.getFloat() < 0.3)
4410 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
4415 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Variable(currentStructure, baseType));
4418 static ResourceDefinition::Node::SharedPtr generateRandomCoreShaderSet (de::Random& rnd)
4420 if (rnd.getFloat() < 0.5f)
4423 const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
4424 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
4426 else if (rnd.getFloat() < 0.5f)
4428 // vertex and fragment
4429 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4430 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program, glu::GLSL_VERSION_310_ES);
4434 shaderSet->setStage(glu::SHADERTYPE_VERTEX, true);
4435 shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, rnd.getBool());
4439 shaderSet->setStage(glu::SHADERTYPE_VERTEX, rnd.getBool());
4440 shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, true);
4443 return ResourceDefinition::Node::SharedPtr(shaderSet);
4447 // separate vertex or fragment
4448 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
4449 const glu::ShaderType shaderType = (rnd.getBool()) ? (glu::SHADERTYPE_VERTEX) : (glu::SHADERTYPE_FRAGMENT);
4451 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, shaderType, glu::GLSL_VERSION_310_ES));
4455 static ResourceDefinition::Node::SharedPtr generateRandomExtShaderSet (de::Random& rnd)
4457 if (rnd.getFloat() < 0.5f)
4460 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4461 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program, glu::GLSL_VERSION_310_ES);
4463 shaderSet->setStage(glu::SHADERTYPE_VERTEX, rnd.getBool());
4464 shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, rnd.getBool());
4466 // tess shader are either both or neither present. Make cases interesting
4467 // by forcing one extended shader to always have reference
4470 shaderSet->setStage(glu::SHADERTYPE_GEOMETRY, true);
4474 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, rnd.getBool());
4475 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, rnd.getBool());
4480 shaderSet->setStage(glu::SHADERTYPE_GEOMETRY, rnd.getBool());
4484 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, true);
4485 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, rnd.getBool());
4489 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, rnd.getBool());
4490 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, true);
4494 return ResourceDefinition::Node::SharedPtr(shaderSet);
4499 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
4500 const int selector = rnd.getInt(0, 2);
4501 const glu::ShaderType shaderType = (selector == 0) ? (glu::SHADERTYPE_GEOMETRY)
4502 : (selector == 1) ? (glu::SHADERTYPE_TESSELLATION_CONTROL)
4503 : (selector == 2) ? (glu::SHADERTYPE_TESSELLATION_EVALUATION)
4504 : (glu::SHADERTYPE_LAST);
4506 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, shaderType, glu::GLSL_VERSION_310_ES));
4510 static ResourceDefinition::Node::SharedPtr generateRandomShaderSet (de::Random& rnd, bool onlyExtensionStages)
4512 if (!onlyExtensionStages)
4513 return generateRandomCoreShaderSet(rnd);
4515 return generateRandomExtShaderSet(rnd);
4518 static glu::Layout generateRandomUniformBlockLayout (de::Random& rnd)
4523 layout.binding = rnd.getInt(0, 5);
4526 layout.matrixOrder = (rnd.getBool()) ? (glu::MATRIXORDER_COLUMN_MAJOR) : (glu::MATRIXORDER_ROW_MAJOR);
4531 static glu::Layout generateRandomBufferBlockLayout (de::Random& rnd)
4533 return generateRandomUniformBlockLayout(rnd);
4536 static glu::Layout generateRandomVariableLayout (de::Random& rnd, glu::DataType type, bool interfaceBlockMember)
4540 if ((glu::isDataTypeAtomicCounter(type) || glu::isDataTypeImage(type) || glu::isDataTypeSampler(type)) && rnd.getBool())
4541 layout.binding = rnd.getInt(0, 5);
4543 if (glu::isDataTypeAtomicCounter(type) && rnd.getBool())
4544 layout.offset = rnd.getInt(0, 3) * 4;
4546 if (glu::isDataTypeMatrix(type) && interfaceBlockMember && rnd.getBool())
4547 layout.matrixOrder = (rnd.getBool()) ? (glu::MATRIXORDER_COLUMN_MAJOR) : (glu::MATRIXORDER_ROW_MAJOR);
4552 static void generateUniformRandomCase (Context& context, tcu::TestCaseGroup* const targetGroup, int index, bool onlyExtensionStages)
4554 de::Random rnd (index * 0x12345);
4555 const ResourceDefinition::Node::SharedPtr shader = generateRandomShaderSet(rnd, onlyExtensionStages);
4556 const bool interfaceBlock = rnd.getBool();
4557 const glu::DataType type = generateRandomDataType(rnd, interfaceBlock);
4558 const glu::Layout layout = generateRandomVariableLayout(rnd, type, interfaceBlock);
4559 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
4560 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4561 ResourceDefinition::Node::SharedPtr currentStructure = uniform;
4565 const bool namedBlock = rnd.getBool();
4567 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, generateRandomUniformBlockLayout(rnd)));
4569 if (namedBlock && rnd.getBool())
4570 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
4572 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(currentStructure, namedBlock));
4575 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, layout));
4576 currentStructure = generateRandomVariableDefinition(rnd, currentStructure, type, layout, false);
4578 targetGroup->addChild(new ResourceTestCase(context, currentStructure, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_UNIFORM_INTERFACE_MASK), de::toString(index).c_str()));
4581 static void generateUniformCaseRandomCases (Context& context, tcu::TestCaseGroup* const targetGroup)
4583 const int numBasicCases = 40;
4584 const int numTessGeoCases = 40;
4586 for (int ndx = 0; ndx < numBasicCases; ++ndx)
4587 generateUniformRandomCase(context, targetGroup, ndx, false);
4588 for (int ndx = 0; ndx < numTessGeoCases; ++ndx)
4589 generateUniformRandomCase(context, targetGroup, numBasicCases + ndx, true);
4592 class UniformInterfaceTestGroup : public TestCaseGroup
4595 UniformInterfaceTestGroup (Context& context);
4599 UniformInterfaceTestGroup::UniformInterfaceTestGroup (Context& context)
4600 : TestCaseGroup(context, "uniform", "Uniform interace")
4604 void UniformInterfaceTestGroup::init (void)
4606 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4607 const ResourceDefinition::Node::SharedPtr computeShader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
4611 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
4612 addChild(blockGroup);
4613 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformResourceListBlockContents);
4618 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Query array size");
4619 addChild(blockGroup);
4620 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockArraySizeContents);
4625 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_stride", "Query array stride");
4626 addChild(blockGroup);
4627 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockArrayStrideContents);
4630 // .atomic_counter_buffer_index
4632 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "atomic_counter_buffer_index", "Query atomic counter buffer index");
4633 addChild(blockGroup);
4634 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_DEFAULT | BLOCKFLAG_NAMED, generateUniformBlockAtomicCounterBufferIndexContents);
4639 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "block_index", "Query block index");
4640 addChild(blockGroup);
4641 generateUniformBlockBlockIndexContents(m_context, blockGroup);
4646 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Query location");
4647 addChild(blockGroup);
4648 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_DEFAULT | BLOCKFLAG_NAMED | BLOCKFLAG_UNNAMED, generateUniformBlockLocationContents);
4651 // .matrix_row_major
4653 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "matrix_row_major", "Query matrix row_major");
4654 addChild(blockGroup);
4655 generateUniformMatrixCaseBlocks(m_context, computeShader, blockGroup, generateUniformMatrixOrderCaseBlockContentCases);
4660 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "matrix_stride", "Query matrix stride");
4661 addChild(blockGroup);
4662 generateUniformMatrixCaseBlocks(m_context, computeShader, blockGroup, generateUniformMatrixStrideCaseBlockContentCases);
4667 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Query name length");
4668 addChild(blockGroup);
4669 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockNameLengthContents);
4674 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "offset", "Query offset");
4675 addChild(blockGroup);
4676 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockOffsetContents);
4679 // .referenced_by_shader
4681 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by_shader", "Query referenced by shader");
4682 addChild(blockGroup);
4683 generateReferencedByShaderCaseBlocks(m_context, blockGroup, generateUniformReferencedByShaderSingleBlockContentCases);
4688 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Query type");
4689 addChild(blockGroup);
4690 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockTypeContents);
4695 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random");
4696 addChild(blockGroup);
4697 generateUniformCaseRandomCases(m_context, blockGroup);
4701 static void generateBufferBackedInterfaceResourceListCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, const char* blockName)
4703 targetGroup->addChild(new ResourceListTestCase(context, targetResource, interface, blockName));
4706 static void generateBufferBackedInterfaceNameLengthCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, const char* blockName)
4708 targetGroup->addChild(new ResourceTestCase(context, targetResource, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_NAME_LENGTH), blockName));
4711 static void generateBufferBackedInterfaceResourceBasicBlockTypes (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup* const, ProgramInterface interface, const char* blockName))
4713 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4714 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
4715 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
4716 const ResourceDefinition::Node::SharedPtr storageQualifier (new ResourceDefinition::StorageQualifier(defaultBlock, storage));
4717 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(storageQualifier, glu::Layout(-1, 1)));
4718 const ProgramInterface programInterface = (storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) : (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK);
4722 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, true));
4723 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4725 blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "named_block");
4730 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, false));
4731 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4733 blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "unnamed_block");
4738 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding, 3));
4739 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4740 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4742 blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "block_array");
4745 // .block_array_single_element
4747 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding, 1));
4748 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4749 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4751 blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "block_array_single_element");
4755 static void generateBufferBackedInterfaceResourceBufferBindingCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
4757 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4758 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
4759 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
4760 const ResourceDefinition::Node::SharedPtr storageQualifier (new ResourceDefinition::StorageQualifier(defaultBlock, storage));
4762 for (int ndx = 0; ndx < 2; ++ndx)
4764 const bool explicitBinding = (ndx == 1);
4765 const int bindingNdx = (explicitBinding) ? (1) : (-1);
4766 const std::string nameSuffix = (explicitBinding) ? ("_explicit_binding") : ("");
4767 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(storageQualifier, glu::Layout(-1, bindingNdx)));
4768 const ProgramInterface programInterface = (storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) : (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK);
4772 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, true));
4773 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4775 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("named_block" + nameSuffix).c_str()));
4780 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, false));
4781 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4783 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("unnamed_block" + nameSuffix).c_str()));
4788 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding, 3));
4789 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4790 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4792 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("block_array" + nameSuffix).c_str()));
4797 template <glu::Storage Storage>
4798 static void generateBufferBlockReferencedByShaderSingleBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
4800 const ProgramInterface programInterface = (Storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
4801 (Storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
4802 (PROGRAMINTERFACE_LAST);
4803 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
4804 const ResourceDefinition::Node::SharedPtr storage (new ResourceDefinition::StorageQualifier(defaultBlock, Storage));
4806 DE_UNREF(expandLevel);
4808 DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
4812 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, true));
4813 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4815 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "named_block"));
4820 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, false));
4821 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4823 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "unnamed_block"));
4828 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(storage, 3));
4829 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4830 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4832 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "block_array"));
4836 static void generateBufferBackedInterfaceResourceActiveVariablesCase (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
4838 targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "named_block", "Named block", storage, InterfaceBlockActiveVariablesTestCase::CASE_NAMED_BLOCK));
4839 targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "unnamed_block", "Unnamed block", storage, InterfaceBlockActiveVariablesTestCase::CASE_UNNAMED_BLOCK));
4840 targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "block_array", "Block array", storage, InterfaceBlockActiveVariablesTestCase::CASE_BLOCK_ARRAY));
4843 static void generateBufferBackedInterfaceResourceBufferDataSizeCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
4845 targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "named_block", "Named block", storage, InterfaceBlockDataSizeTestCase::CASE_NAMED_BLOCK));
4846 targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "unnamed_block", "Unnamed block", storage, InterfaceBlockDataSizeTestCase::CASE_UNNAMED_BLOCK));
4847 targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "block_array", "Block array", storage, InterfaceBlockDataSizeTestCase::CASE_BLOCK_ARRAY));
4850 class BufferBackedBlockInterfaceTestGroup : public TestCaseGroup
4853 BufferBackedBlockInterfaceTestGroup (Context& context, glu::Storage interfaceBlockStorage);
4857 static const char* getGroupName (glu::Storage storage);
4858 static const char* getGroupDescription (glu::Storage storage);
4860 const glu::Storage m_storage;
4863 BufferBackedBlockInterfaceTestGroup::BufferBackedBlockInterfaceTestGroup(Context& context, glu::Storage storage)
4864 : TestCaseGroup (context, getGroupName(storage), getGroupDescription(storage))
4865 , m_storage (storage)
4867 DE_ASSERT(storage == glu::STORAGE_BUFFER || storage == glu::STORAGE_UNIFORM);
4870 void BufferBackedBlockInterfaceTestGroup::init (void)
4874 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
4875 addChild(blockGroup);
4876 generateBufferBackedInterfaceResourceBasicBlockTypes(m_context, blockGroup, m_storage, generateBufferBackedInterfaceResourceListCase);
4879 // .active_variables
4881 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "active_variables", "Active variables");
4882 addChild(blockGroup);
4883 generateBufferBackedInterfaceResourceActiveVariablesCase(m_context, blockGroup, m_storage);
4888 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "buffer_binding", "Buffer binding");
4889 addChild(blockGroup);
4890 generateBufferBackedInterfaceResourceBufferBindingCases(m_context, blockGroup, m_storage);
4893 // .buffer_data_size
4895 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "buffer_data_size", "Buffer data size");
4896 addChild(blockGroup);
4897 generateBufferBackedInterfaceResourceBufferDataSizeCases(m_context, blockGroup, m_storage);
4902 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
4903 addChild(blockGroup);
4904 generateBufferBackedInterfaceResourceBasicBlockTypes(m_context, blockGroup, m_storage, generateBufferBackedInterfaceNameLengthCase);
4909 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Referenced by shader");
4910 addChild(blockGroup);
4912 if (m_storage == glu::STORAGE_UNIFORM)
4913 generateReferencedByShaderCaseBlocks(m_context, blockGroup, generateBufferBlockReferencedByShaderSingleBlockContentCases<glu::STORAGE_UNIFORM>);
4914 else if (m_storage == glu::STORAGE_BUFFER)
4915 generateReferencedByShaderCaseBlocks(m_context, blockGroup, generateBufferBlockReferencedByShaderSingleBlockContentCases<glu::STORAGE_BUFFER>);
4921 const char* BufferBackedBlockInterfaceTestGroup::getGroupName (glu::Storage storage)
4925 case glu::STORAGE_UNIFORM: return "uniform_block";
4926 case glu::STORAGE_BUFFER: return "shader_storage_block";
4933 const char* BufferBackedBlockInterfaceTestGroup::getGroupDescription (glu::Storage storage)
4937 case glu::STORAGE_UNIFORM: return "Uniform block interface";
4938 case glu::STORAGE_BUFFER: return "Shader storage block interface";
4945 class AtomicCounterTestGroup : public TestCaseGroup
4948 AtomicCounterTestGroup (Context& context);
4952 AtomicCounterTestGroup::AtomicCounterTestGroup (Context& context)
4953 : TestCaseGroup(context, "atomic_counter_buffer", "Atomic counter buffer")
4957 void AtomicCounterTestGroup::init (void)
4967 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT)
4970 "vertex_tess_fragment",
4971 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION)
4974 "vertex_geo_fragment",
4975 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY)
4978 "vertex_tess_geo_fragment",
4979 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
4984 addChild(new AtomicCounterResourceListCase(m_context, "resource_list", "Resource list"));
4986 // .active_variables
4987 addChild(new AtomicCounterActiveVariablesCase(m_context, "active_variables", "Active variables"));
4990 addChild(new AtomicCounterBufferBindingCase(m_context, "buffer_binding", "Buffer binding"));
4992 // .buffer_data_size
4993 addChild(new AtomicCounterBufferDataSizeCase(m_context, "buffer_data_size", "Buffer binding"));
4996 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_compute", "", false, (1 << glu::SHADERTYPE_COMPUTE), (1 << glu::SHADERTYPE_COMPUTE)));
4997 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_vertex", "", true, (1 << glu::SHADERTYPE_VERTEX), (1 << glu::SHADERTYPE_VERTEX)));
4998 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_fragment", "", true, (1 << glu::SHADERTYPE_FRAGMENT), (1 << glu::SHADERTYPE_FRAGMENT)));
4999 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_geometry", "", true, (1 << glu::SHADERTYPE_GEOMETRY), (1 << glu::SHADERTYPE_GEOMETRY)));
5000 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_tess_ctrl", "", true, (1 << glu::SHADERTYPE_TESSELLATION_CONTROL), (1 << glu::SHADERTYPE_TESSELLATION_CONTROL)));
5001 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_tess_eval", "", true, (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION), (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION)));
5003 for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
5005 addChild(new AtomicCounterReferencedByCase(m_context, (std::string() + "referenced_by_" + pipelines[pipelineNdx].name).c_str(), "", false, pipelines[pipelineNdx].flags, pipelines[pipelineNdx].flags));
5007 for (deUint32 stageNdx = 0; stageNdx < glu::SHADERTYPE_LAST; ++stageNdx)
5009 const deUint32 currentBit = (1u << stageNdx);
5010 if (currentBit > pipelines[pipelineNdx].flags)
5012 if (currentBit & pipelines[pipelineNdx].flags)
5014 const char* stageName = (stageNdx == glu::SHADERTYPE_VERTEX) ? ("vertex")
5015 : (stageNdx == glu::SHADERTYPE_FRAGMENT) ? ("fragment")
5016 : (stageNdx == glu::SHADERTYPE_GEOMETRY) ? ("geo")
5017 : (stageNdx == glu::SHADERTYPE_TESSELLATION_CONTROL) ? ("tess_ctrl")
5018 : (stageNdx == glu::SHADERTYPE_TESSELLATION_EVALUATION) ? ("tess_eval")
5020 const std::string name = std::string() + "referenced_by_" + pipelines[pipelineNdx].name + "_only_" + stageName;
5022 addChild(new AtomicCounterReferencedByCase(m_context, name.c_str(), "", false, pipelines[pipelineNdx].flags, currentBit));
5028 static void generateProgramInputOutputShaderCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, bool withCompute, bool inputCase, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, deUint32))
5033 glu::ShaderType stage;
5034 } singleStageCases[] =
5036 { "separable_vertex", glu::SHADERTYPE_VERTEX },
5037 { "separable_fragment", glu::SHADERTYPE_FRAGMENT },
5038 { "separable_tess_ctrl", glu::SHADERTYPE_TESSELLATION_CONTROL },
5039 { "separable_tess_eval", glu::SHADERTYPE_TESSELLATION_EVALUATION },
5040 { "separable_geometry", glu::SHADERTYPE_GEOMETRY },
5045 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "vertex_fragment", "Vertex and fragment");
5046 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(false));
5047 ResourceDefinition::ShaderSet* shaderSetPtr = new ResourceDefinition::ShaderSet(program, glu::GLSL_VERSION_310_ES);
5048 const ResourceDefinition::Node::SharedPtr shaderSet (shaderSetPtr);
5049 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shaderSet));
5051 shaderSetPtr->setStage(glu::SHADERTYPE_VERTEX, inputCase);
5052 shaderSetPtr->setStage(glu::SHADERTYPE_FRAGMENT, !inputCase);
5054 targetGroup->addChild(blockGroup);
5056 blockContentGenerator(context, defaultBlock, blockGroup, (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT));
5060 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
5062 TestCaseGroup* const blockGroup = new TestCaseGroup(context, singleStageCases[ndx].name, "");
5063 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
5064 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glu::GLSL_VERSION_310_ES));
5065 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
5067 targetGroup->addChild(blockGroup);
5068 blockContentGenerator(context, defaultBlock, blockGroup, (1 << singleStageCases[ndx].stage));
5074 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "compute", "Compute");
5075 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
5076 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
5077 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
5079 targetGroup->addChild(blockGroup);
5081 blockContentGenerator(context, defaultBlock, blockGroup, (1 << glu::SHADERTYPE_COMPUTE));
5084 // .interface_blocks
5088 const char* inputName;
5089 glu::ShaderType inputStage;
5090 glu::Storage inputStorage;
5091 const char* outputName;
5092 glu::ShaderType outputStage;
5093 glu::Storage outputStorage;
5098 glu::SHADERTYPE_FRAGMENT,
5101 glu::SHADERTYPE_VERTEX,
5106 glu::SHADERTYPE_TESSELLATION_EVALUATION,
5107 glu::STORAGE_PATCH_IN,
5109 glu::SHADERTYPE_TESSELLATION_CONTROL,
5110 glu::STORAGE_PATCH_OUT,
5114 tcu::TestCaseGroup* const ioBlocksGroup = new TestCaseGroup(context, "interface_blocks", "Interface blocks");
5115 targetGroup->addChild(ioBlocksGroup);
5120 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(ioBlockTypes); ++ndx)
5122 const char* const name = (inputCase) ? (ioBlockTypes[ndx].inputName) : (ioBlockTypes[ndx].outputName);
5123 const glu::ShaderType shaderType = (inputCase) ? (ioBlockTypes[ndx].inputStage) : (ioBlockTypes[ndx].outputStage);
5124 const glu::Storage storageType = (inputCase) ? (ioBlockTypes[ndx].inputStorage) : (ioBlockTypes[ndx].outputStorage);
5125 tcu::TestCaseGroup* const ioBlockGroup = new TestCaseGroup(context, name, "");
5126 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
5127 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, shaderType, glu::GLSL_VERSION_310_ES));
5128 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
5129 const ResourceDefinition::Node::SharedPtr storage (new ResourceDefinition::StorageQualifier(defaultBlock, storageType));
5131 ioBlocksGroup->addChild(ioBlockGroup);
5135 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, true));
5136 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block", "Named block");
5138 ioBlockGroup->addChild(blockGroup);
5140 blockContentGenerator(context, block, blockGroup, (1 << shaderType));
5143 // .named_block_explicit_location
5145 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(storage, glu::Layout(3)));
5146 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(layout, true));
5147 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block_explicit_location", "Named block with explicit location");
5149 ioBlockGroup->addChild(blockGroup);
5151 blockContentGenerator(context, block, blockGroup, (1 << shaderType));
5156 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, false));
5157 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "Unnamed block");
5159 ioBlockGroup->addChild(blockGroup);
5161 blockContentGenerator(context, block, blockGroup, (1 << shaderType));
5166 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(storage));
5167 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
5168 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "Block array");
5170 ioBlockGroup->addChild(blockGroup);
5172 blockContentGenerator(context, block, blockGroup, (1 << shaderType));
5178 static void generateProgramInputBlockContents (Context& context,
5179 const ResourceDefinition::Node::SharedPtr& parentStructure,
5180 tcu::TestCaseGroup* targetGroup,
5181 deUint32 presentShadersMask,
5183 void (*genCase)(Context& context,
5184 const ResourceDefinition::Node::SharedPtr& parentStructure,
5185 tcu::TestCaseGroup* targetGroup,
5186 ProgramInterface interface,
5189 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5190 const ResourceDefinition::Node::SharedPtr input = (inDefaultBlock)
5191 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
5192 : (parentStructure);
5193 const glu::ShaderType firstStage = getShaderMaskFirstStage(presentShadersMask);
5196 if (includeEmpty && inDefaultBlock)
5197 genCase(context, parentStructure, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "empty");
5199 if (firstStage == glu::SHADERTYPE_VERTEX)
5202 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5203 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5205 else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5209 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5210 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5214 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(input));
5215 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5216 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var_struct");
5220 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input));
5221 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5222 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var_array");
5225 else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
5226 firstStage == glu::SHADERTYPE_GEOMETRY)
5228 // arrayed interface
5232 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5233 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5234 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5236 // extension forbids use arrays of structs
5237 // extension forbids use arrays of arrays
5239 else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5241 // arrayed interface
5242 const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5246 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5247 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5248 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5250 // extension forbids use arrays of structs
5251 // extension forbids use arrays of arrays
5255 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchInput, glu::TYPE_FLOAT_VEC4));
5256 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var");
5258 // .patch_var_struct
5260 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchInput));
5261 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5262 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var_struct");
5266 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchInput));
5267 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5268 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var_array");
5271 else if (firstStage == glu::SHADERTYPE_COMPUTE)
5279 static void generateProgramOutputBlockContents (Context& context,
5280 const ResourceDefinition::Node::SharedPtr& parentStructure,
5281 tcu::TestCaseGroup* targetGroup,
5282 deUint32 presentShadersMask,
5284 void (*genCase)(Context& context,
5285 const ResourceDefinition::Node::SharedPtr& parentStructure,
5286 tcu::TestCaseGroup* targetGroup,
5287 ProgramInterface interface,
5290 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5291 const ResourceDefinition::Node::SharedPtr output = (inDefaultBlock)
5292 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
5293 : (parentStructure);
5294 const glu::ShaderType lastStage = getShaderMaskLastStage(presentShadersMask);
5297 if (includeEmpty && inDefaultBlock)
5298 genCase(context, parentStructure, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "empty");
5300 if (lastStage == glu::SHADERTYPE_VERTEX ||
5301 lastStage == glu::SHADERTYPE_GEOMETRY ||
5302 lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
5307 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5308 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5312 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
5313 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5314 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_struct");
5318 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5319 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5320 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_array");
5323 else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5327 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5328 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5332 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5333 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5334 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_array");
5337 else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5339 // arrayed interface
5340 const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5344 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5345 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5346 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5348 // extension forbids use arrays of structs
5349 // extension forbids use array of arrays
5353 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchOutput, glu::TYPE_FLOAT_VEC4));
5354 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var");
5356 // .patch_var_struct
5358 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchOutput));
5359 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5360 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var_struct");
5364 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchOutput));
5365 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5366 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var_array");
5369 else if (lastStage == glu::SHADERTYPE_COMPUTE)
5377 static void addProgramInputOutputResourceListCase (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramInterface programInterface, const char* name)
5379 ResourceListTestCase* const resourceListCase = new ResourceListTestCase(context, parentStructure, programInterface);
5381 DE_ASSERT(deStringEqual(name, resourceListCase->getName()));
5383 targetGroup->addChild(resourceListCase);
5386 static void generateProgramInputResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5388 generateProgramInputBlockContents(context, parentStructure, targetGroup, presentShadersMask, true, addProgramInputOutputResourceListCase);
5391 static void generateProgramOutputResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5393 generateProgramOutputBlockContents(context, parentStructure, targetGroup, presentShadersMask, true, addProgramInputOutputResourceListCase);
5396 template <ProgramResourcePropFlags TargetProp>
5397 static void addProgramInputOutputResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramInterface programInterface, const char* name)
5399 ResourceTestCase* const resourceTestCase = new ResourceTestCase(context, parentStructure, ProgramResourceQueryTestTarget(programInterface, TargetProp), name);
5400 targetGroup->addChild(resourceTestCase);
5403 template <ProgramResourcePropFlags TargetProp>
5404 static void generateProgramInputBasicBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5406 generateProgramInputBlockContents(context, parentStructure, targetGroup, presentShadersMask, false, addProgramInputOutputResourceTestCase<TargetProp>);
5409 template <ProgramResourcePropFlags TargetProp>
5410 static void generateProgramOutputBasicBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5412 generateProgramOutputBlockContents(context, parentStructure, targetGroup, presentShadersMask, false, addProgramInputOutputResourceTestCase<TargetProp>);
5415 static void generateProgramInputLocationBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5417 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5418 const ResourceDefinition::Node::SharedPtr input = (inDefaultBlock)
5419 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
5420 : (parentStructure);
5421 const glu::ShaderType firstStage = getShaderMaskFirstStage(presentShadersMask);
5423 if (firstStage == glu::SHADERTYPE_VERTEX)
5427 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5428 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5430 // .var_explicit_location
5432 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5433 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5434 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5437 else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5441 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5442 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5444 // .var_explicit_location
5446 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5447 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5448 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5452 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(input));
5453 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5454 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct"));
5456 // .var_struct_explicit_location
5458 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5459 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5460 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5461 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct_explicit_location"));
5465 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input));
5466 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5467 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
5469 // .var_array_explicit_location
5471 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5472 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5473 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5474 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
5477 else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
5478 firstStage == glu::SHADERTYPE_GEOMETRY)
5480 // arrayed interface
5484 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5485 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5486 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5488 // .var_explicit_location
5490 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5491 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5492 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5493 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5495 // extension forbids use arrays of structs
5496 // extension forbids use arrays of arrays
5498 else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5500 // arrayed interface
5501 const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5505 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5506 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5507 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5509 // .var_explicit_location
5511 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5512 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5513 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5514 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5516 // extension forbids use arrays of structs
5517 // extension forbids use arrays of arrays
5521 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchInput, glu::TYPE_FLOAT_VEC4));
5522 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var"));
5524 // .patch_var_explicit_location
5526 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
5527 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5528 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_explicit_location"));
5530 // .patch_var_struct
5532 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchInput));
5533 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5534 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct"));
5536 // .patch_var_struct_explicit_location
5538 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
5539 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5540 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5541 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct_explicit_location"));
5545 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchInput));
5546 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5547 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array"));
5549 // .patch_var_array_explicit_location
5551 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
5552 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5553 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5554 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array_explicit_location"));
5557 else if (firstStage == glu::SHADERTYPE_COMPUTE)
5565 static void generateProgramOutputLocationBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5567 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5568 const ResourceDefinition::Node::SharedPtr output = (inDefaultBlock)
5569 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
5570 : (parentStructure);
5571 const glu::ShaderType lastStage = getShaderMaskLastStage(presentShadersMask);
5573 if (lastStage == glu::SHADERTYPE_VERTEX ||
5574 lastStage == glu::SHADERTYPE_GEOMETRY ||
5575 lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
5580 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5581 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5583 // .var_explicit_location
5585 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5586 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5587 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5591 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
5592 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5593 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct"));
5595 // .var_struct_explicit_location
5597 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5598 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5599 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5600 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct_explicit_location"));
5604 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5605 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5606 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
5608 // .var_array_explicit_location
5610 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5611 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5612 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5613 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
5616 else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5620 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5621 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5623 // .var_explicit_location
5625 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5626 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5627 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5631 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5632 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5633 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
5635 // .var_array_explicit_location
5637 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(1)));
5638 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5639 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5640 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
5643 else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5645 // arrayed interface
5646 const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5650 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5651 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5652 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5654 // .var_explicit_location
5656 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5657 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5658 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5659 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5661 // extension forbids use arrays of structs
5662 // extension forbids use array of arrays
5666 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchOutput, glu::TYPE_FLOAT_VEC4));
5667 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var"));
5669 // .patch_var_explicit_location
5671 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
5672 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5673 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_explicit_location"));
5675 // .patch_var_struct
5677 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchOutput));
5678 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5679 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct"));
5681 // .patch_var_struct_explicit_location
5683 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
5684 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5685 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5686 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct_explicit_location"));
5690 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchOutput));
5691 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5692 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array"));
5694 // .patch_var_array_explicit_location
5696 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
5697 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5698 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5699 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array_explicit_location"));
5702 else if (lastStage == glu::SHADERTYPE_COMPUTE)
5710 static void generateProgramInputOutputReferencedByCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
5712 // all whole pipelines
5713 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_FRAGMENT));
5714 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_tess_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_TESS_FRAGMENT));
5715 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_geo_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_GEO_FRAGMENT));
5716 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_tess_geo_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_TESS_GEO_FRAGMENT));
5718 // all partial pipelines
5719 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_vertex", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_VERTEX));
5720 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_FRAGMENT));
5721 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_geometry", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_GEOMETRY));
5722 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_eval", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_EVAL));
5723 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_ctrl", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_CTRL));
5726 if (storage == glu::STORAGE_IN)
5727 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_eval_patch_in", "", glu::STORAGE_PATCH_IN, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_EVAL));
5728 else if (storage == glu::STORAGE_OUT)
5729 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_ctrl_patch_out", "", glu::STORAGE_PATCH_OUT, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_CTRL));
5734 template <ProgramInterface interface>
5735 static void generateProgramInputOutputTypeBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool allowMatrixCases, int expandLevel)
5744 { glu::TYPE_FLOAT, false, 0 },
5745 { glu::TYPE_INT, false, 1 },
5746 { glu::TYPE_UINT, false, 1 },
5747 { glu::TYPE_FLOAT_VEC2, false, 2 },
5748 { glu::TYPE_FLOAT_VEC3, false, 1 },
5749 { glu::TYPE_FLOAT_VEC4, false, 2 },
5750 { glu::TYPE_INT_VEC2, false, 0 },
5751 { glu::TYPE_INT_VEC3, false, 2 },
5752 { glu::TYPE_INT_VEC4, false, 2 },
5753 { glu::TYPE_UINT_VEC2, false, 2 },
5754 { glu::TYPE_UINT_VEC3, false, 2 },
5755 { glu::TYPE_UINT_VEC4, false, 0 },
5756 { glu::TYPE_FLOAT_MAT2, true, 2 },
5757 { glu::TYPE_FLOAT_MAT2X3, true, 2 },
5758 { glu::TYPE_FLOAT_MAT2X4, true, 2 },
5759 { glu::TYPE_FLOAT_MAT3X2, true, 0 },
5760 { glu::TYPE_FLOAT_MAT3, true, 2 },
5761 { glu::TYPE_FLOAT_MAT3X4, true, 2 },
5762 { glu::TYPE_FLOAT_MAT4X2, true, 2 },
5763 { glu::TYPE_FLOAT_MAT4X3, true, 2 },
5764 { glu::TYPE_FLOAT_MAT4, true, 2 },
5767 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
5769 if (!allowMatrixCases && variableTypes[ndx].isMatrix)
5772 if (variableTypes[ndx].level <= expandLevel)
5774 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
5775 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_TYPE)));
5780 static void generateProgramInputTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5782 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5783 const ResourceDefinition::Node::SharedPtr input = (inDefaultBlock)
5784 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
5785 : (parentStructure);
5786 const glu::ShaderType firstStage = getShaderMaskFirstStage(presentShadersMask);
5787 const int interfaceBlockExpansionReducement = (!inDefaultBlock) ? (1) : (0); // lesser expansions on block members to keep test counts reasonable
5789 if (firstStage == glu::SHADERTYPE_VERTEX)
5791 // Only basic types (and no booleans)
5792 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, input, targetGroup, true, 2 - interfaceBlockExpansionReducement);
5794 else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5796 const ResourceDefinition::Node::SharedPtr flatShading(new ResourceDefinition::InterpolationQualifier(input, glu::INTERPOLATION_FLAT));
5798 // Only basic types, arrays of basic types, struct of basic types (and no booleans)
5800 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5801 targetGroup->addChild(blockGroup);
5802 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, flatShading, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5805 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(flatShading));
5806 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
5808 targetGroup->addChild(blockGroup);
5809 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElement, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5812 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(flatShading));
5813 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Struct types");
5815 targetGroup->addChild(blockGroup);
5816 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, structMember, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5819 else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
5820 firstStage == glu::SHADERTYPE_GEOMETRY)
5822 // arrayed interface
5824 // Only basic types (and no booleans)
5825 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5826 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElement, targetGroup, true, 2);
5828 else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5830 // arrayed interface
5831 const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5835 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5836 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5838 targetGroup->addChild(blockGroup);
5839 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElem, blockGroup, true, 2);
5841 // extension forbids use arrays of structs
5842 // extension forbids use arrays of arrays
5846 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var", "Basic types, per-patch");
5848 targetGroup->addChild(blockGroup);
5849 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, patchInput, blockGroup, true, 1);
5851 // .patch_var_struct
5853 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchInput));
5854 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_struct", "Struct types, per-patch");
5856 targetGroup->addChild(blockGroup);
5857 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, structMbr, blockGroup, true, 1);
5861 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchInput));
5862 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_array", "Array types, per-patch");
5864 targetGroup->addChild(blockGroup);
5865 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElem, blockGroup, true, 1);
5868 else if (firstStage == glu::SHADERTYPE_COMPUTE)
5876 static void generateProgramOutputTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5878 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5879 const ResourceDefinition::Node::SharedPtr output = (inDefaultBlock)
5880 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
5881 : (parentStructure);
5882 const glu::ShaderType lastStage = getShaderMaskLastStage(presentShadersMask);
5883 const int interfaceBlockExpansionReducement = (!inDefaultBlock) ? (1) : (0); // lesser expansions on block members to keep test counts reasonable
5885 if (lastStage == glu::SHADERTYPE_VERTEX ||
5886 lastStage == glu::SHADERTYPE_GEOMETRY ||
5887 lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
5890 const ResourceDefinition::Node::SharedPtr flatShading(new ResourceDefinition::InterpolationQualifier(output, glu::INTERPOLATION_FLAT));
5892 // Only basic types, arrays of basic types, struct of basic types (and no booleans)
5894 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5895 targetGroup->addChild(blockGroup);
5896 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, flatShading, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5899 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(flatShading));
5900 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
5901 const int typeExpansionReducement = (lastStage != glu::SHADERTYPE_VERTEX) ? (1) : (0); // lesser expansions on other stages
5902 const int expansionLevel = 2 - interfaceBlockExpansionReducement - typeExpansionReducement;
5904 targetGroup->addChild(blockGroup);
5905 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElement, blockGroup, true, expansionLevel);
5908 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(flatShading));
5909 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Struct types");
5910 const int typeExpansionReducement = (lastStage != glu::SHADERTYPE_VERTEX) ? (1) : (0); // lesser expansions on other stages
5911 const int expansionLevel = 2 - interfaceBlockExpansionReducement - typeExpansionReducement;
5913 targetGroup->addChild(blockGroup);
5914 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, structMember, blockGroup, true, expansionLevel);
5917 else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5919 // only basic type and basic type array (and no booleans or matrices)
5921 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5922 targetGroup->addChild(blockGroup);
5923 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, output, blockGroup, false, 2);
5926 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(output));
5927 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
5929 targetGroup->addChild(blockGroup);
5930 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElement, blockGroup, false, 2);
5933 else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5935 // arrayed interface
5936 const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5940 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5941 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5943 targetGroup->addChild(blockGroup);
5944 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElem, blockGroup, true, 2);
5946 // extension forbids use arrays of structs
5947 // extension forbids use arrays of arrays
5951 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var", "Basic types, per-patch");
5953 targetGroup->addChild(blockGroup);
5954 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, patchOutput, blockGroup, true, 1);
5956 // .patch_var_struct
5958 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchOutput));
5959 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_struct", "Struct types, per-patch");
5961 targetGroup->addChild(blockGroup);
5962 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, structMbr, blockGroup, true, 1);
5966 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchOutput));
5967 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_array", "Array types, per-patch");
5969 targetGroup->addChild(blockGroup);
5970 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElem, blockGroup, true, 1);
5973 else if (lastStage == glu::SHADERTYPE_COMPUTE)
5981 class ProgramInputTestGroup : public TestCaseGroup
5984 ProgramInputTestGroup (Context& context);
5988 ProgramInputTestGroup::ProgramInputTestGroup (Context& context)
5989 : TestCaseGroup(context, "program_input", "Program input")
5993 void ProgramInputTestGroup::init (void)
5997 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
5998 addChild(blockGroup);
5999 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, true, true, generateProgramInputResourceListBlockContents);
6004 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Array size");
6005 addChild(blockGroup);
6006 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6011 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Location");
6012 addChild(blockGroup);
6013 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputLocationBlockContents);
6018 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
6019 addChild(blockGroup);
6020 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6025 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Reference by shader");
6026 addChild(blockGroup);
6027 generateProgramInputOutputReferencedByCases(m_context, blockGroup, glu::STORAGE_IN);
6032 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Type");
6033 addChild(blockGroup);
6034 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputTypeBlockContents);
6039 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "is_per_patch", "Is per patch");
6040 addChild(blockGroup);
6041 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
6045 class ProgramOutputTestGroup : public TestCaseGroup
6048 ProgramOutputTestGroup (Context& context);
6052 ProgramOutputTestGroup::ProgramOutputTestGroup (Context& context)
6053 : TestCaseGroup(context, "program_output", "Program output")
6057 void ProgramOutputTestGroup::init (void)
6061 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
6062 addChild(blockGroup);
6063 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, true, false, generateProgramOutputResourceListBlockContents);
6068 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Array size");
6069 addChild(blockGroup);
6070 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6075 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Location");
6076 addChild(blockGroup);
6077 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputLocationBlockContents);
6082 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
6083 addChild(blockGroup);
6084 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6089 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Reference by shader");
6090 addChild(blockGroup);
6091 generateProgramInputOutputReferencedByCases(m_context, blockGroup, glu::STORAGE_OUT);
6096 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Type");
6097 addChild(blockGroup);
6098 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputTypeBlockContents);
6103 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "is_per_patch", "Is per patch");
6104 addChild(blockGroup);
6105 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
6109 static void generateTransformFeedbackShaderCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, bool))
6115 deUint32 lastStageBit;
6121 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT),
6122 (1 << glu::SHADERTYPE_VERTEX),
6126 "vertex_tess_fragment",
6127 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
6128 (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
6132 "vertex_geo_fragment",
6133 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY),
6134 (1 << glu::SHADERTYPE_GEOMETRY),
6138 "vertex_tess_geo_fragment",
6139 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
6140 (1 << glu::SHADERTYPE_GEOMETRY),
6147 glu::ShaderType stage;
6149 } singleStageCases[] =
6151 { "separable_vertex", glu::SHADERTYPE_VERTEX, false },
6152 { "separable_tess_eval", glu::SHADERTYPE_TESSELLATION_EVALUATION, true },
6153 { "separable_geometry", glu::SHADERTYPE_GEOMETRY, true },
6156 // monolithic pipeline
6157 for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
6159 TestCaseGroup* const blockGroup = new TestCaseGroup(context, pipelines[pipelineNdx].name, "");
6160 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6161 const ResourceDefinition::Node::SharedPtr shaderSet (new ResourceDefinition::ShaderSet(program,
6162 glu::GLSL_VERSION_310_ES,
6163 pipelines[pipelineNdx].stageBits,
6164 pipelines[pipelineNdx].lastStageBit));
6166 targetGroup->addChild(blockGroup);
6167 blockContentGenerator(context, shaderSet, blockGroup, pipelines[pipelineNdx].reducedSet);
6170 // separable pipeline
6171 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
6173 TestCaseGroup* const blockGroup = new TestCaseGroup(context, singleStageCases[ndx].name, "");
6174 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
6175 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glu::GLSL_VERSION_310_ES));
6177 targetGroup->addChild(blockGroup);
6178 blockContentGenerator(context, shader, blockGroup, singleStageCases[ndx].reducedSet);
6182 static void generateTransformFeedbackResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6184 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6185 const ResourceDefinition::Node::SharedPtr output (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6187 DE_UNREF(reducedSet);
6189 // .builtin_gl_position
6191 const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6192 targetGroup->addChild(new FeedbackResourceListTestCase(context, xfbTarget, "builtin_gl_position"));
6194 // .default_block_basic_type
6196 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6197 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6198 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_basic_type"));
6200 // .default_block_struct_member
6202 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
6203 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(structMbr));
6204 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6205 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_struct_member"));
6207 // .default_block_array
6209 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6210 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(xfbTarget));
6211 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6212 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_array"));
6214 // .default_block_array_element
6216 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
6217 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(arrayElem));
6218 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6219 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_array_element"));
6223 template <ProgramResourcePropFlags TargetProp>
6224 static void generateTransformFeedbackVariableBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6226 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6227 const ResourceDefinition::Node::SharedPtr output (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6229 DE_UNREF(reducedSet);
6231 // .builtin_gl_position
6233 const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6234 targetGroup->addChild(new ResourceTestCase(context, xfbTarget, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "builtin_gl_position"));
6236 // .default_block_basic_type
6238 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6239 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6240 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_basic_type"));
6242 // .default_block_struct_member
6244 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
6245 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(structMbr));
6246 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6247 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_struct_member"));
6249 // .default_block_array
6251 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6252 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(xfbTarget));
6253 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6254 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_array"));
6256 // .default_block_array_element
6258 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
6259 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(arrayElem));
6260 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6261 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_array_element"));
6265 static void generateTransformFeedbackVariableBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6273 { glu::TYPE_FLOAT, true },
6274 { glu::TYPE_INT, true },
6275 { glu::TYPE_UINT, true },
6277 { glu::TYPE_FLOAT_VEC2, false },
6278 { glu::TYPE_FLOAT_VEC3, true },
6279 { glu::TYPE_FLOAT_VEC4, false },
6281 { glu::TYPE_INT_VEC2, false },
6282 { glu::TYPE_INT_VEC3, true },
6283 { glu::TYPE_INT_VEC4, false },
6285 { glu::TYPE_UINT_VEC2, true },
6286 { glu::TYPE_UINT_VEC3, false },
6287 { glu::TYPE_UINT_VEC4, false },
6289 { glu::TYPE_FLOAT_MAT2, false },
6290 { glu::TYPE_FLOAT_MAT2X3, false },
6291 { glu::TYPE_FLOAT_MAT2X4, false },
6292 { glu::TYPE_FLOAT_MAT3X2, false },
6293 { glu::TYPE_FLOAT_MAT3, false },
6294 { glu::TYPE_FLOAT_MAT3X4, true },
6295 { glu::TYPE_FLOAT_MAT4X2, false },
6296 { glu::TYPE_FLOAT_MAT4X3, false },
6297 { glu::TYPE_FLOAT_MAT4, false },
6300 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6302 if (variableTypes[ndx].important || !reducedSet)
6304 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
6305 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, PROGRAMRESOURCEPROP_TYPE)));
6310 static void generateTransformFeedbackVariableTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6312 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6313 const ResourceDefinition::Node::SharedPtr output (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6314 const ResourceDefinition::Node::SharedPtr flatShading (new ResourceDefinition::InterpolationQualifier(output, glu::INTERPOLATION_FLAT));
6316 // Only builtins, basic types, arrays of basic types, struct of basic types (and no booleans)
6318 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6319 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "builtin", "Built-in outputs");
6321 targetGroup->addChild(blockGroup);
6322 blockGroup->addChild(new ResourceTestCase(context, xfbTarget, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, PROGRAMRESOURCEPROP_TYPE), "gl_position"));
6325 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(flatShading));
6326 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
6328 targetGroup->addChild(blockGroup);
6329 generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
6332 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(flatShading));
6333 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(arrayElement));
6334 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
6336 targetGroup->addChild(blockGroup);
6337 generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
6340 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(flatShading));
6341 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(xfbTarget));
6342 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "whole_array", "Whole array");
6344 targetGroup->addChild(blockGroup);
6345 generateTransformFeedbackVariableBasicTypeCases(context, arrayElement, blockGroup, reducedSet);
6348 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(flatShading));
6349 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(structMember));
6350 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Struct types");
6352 targetGroup->addChild(blockGroup);
6353 generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
6357 class TransformFeedbackVaryingTestGroup : public TestCaseGroup
6360 TransformFeedbackVaryingTestGroup (Context& context);
6364 TransformFeedbackVaryingTestGroup::TransformFeedbackVaryingTestGroup (Context& context)
6365 : TestCaseGroup(context, "transform_feedback_varying", "Transform feedback varyings")
6369 void TransformFeedbackVaryingTestGroup::init (void)
6373 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "resource_list", "Resource list");
6374 addChild(blockGroup);
6375 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, generateTransformFeedbackResourceListBlockContents);
6380 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_size", "Array size");
6381 addChild(blockGroup);
6382 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, generateTransformFeedbackVariableBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6387 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "name_length", "Name length");
6388 addChild(blockGroup);
6389 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, generateTransformFeedbackVariableBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6394 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "type", "Type");
6395 addChild(blockGroup);
6396 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, generateTransformFeedbackVariableTypeBlockContents);
6400 static void generateBufferVariableBufferCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*))
6402 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6403 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
6404 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6405 const ResourceDefinition::Node::SharedPtr bufferStorage (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6406 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(bufferStorage, glu::Layout(-1, 0)));
6410 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, true));
6411 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block", "Named block");
6413 targetGroup->addChild(blockGroup);
6415 blockContentGenerator(context, buffer, blockGroup);
6420 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, false));
6421 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "Unnamed block");
6423 targetGroup->addChild(blockGroup);
6425 blockContentGenerator(context, buffer, blockGroup);
6430 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding));
6431 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
6432 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "Block array");
6434 targetGroup->addChild(blockGroup);
6436 blockContentGenerator(context, buffer, blockGroup);
6440 static void generateBufferVariableResourceListBlockContentsProxy (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
6442 generateBufferBackedResourceListBlockContentCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, 4);
6445 static void generateBufferVariableArraySizeSubCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramResourcePropFlags targetProp, bool sizedArray, bool extendedCases)
6447 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp);
6448 tcu::TestCaseGroup* aggregateGroup;
6453 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
6454 targetGroup->addChild(blockGroup);
6456 generateVariableCases(context, parentStructure, blockGroup, queryTarget, (sizedArray) ? (2) : (1), false);
6462 aggregateGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
6463 targetGroup->addChild(aggregateGroup);
6466 aggregateGroup = targetGroup;
6469 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_FLOAT, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6472 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_BOOL, (extendedCases && sizedArray) ? (1) : (0), !extendedCases);
6475 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_BOOL_VEC3, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6478 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_FLOAT_VEC4, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6481 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_INT_VEC2, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6484 template <ProgramResourcePropFlags TargetProp>
6485 static void generateBufferVariableArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
6487 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp);
6488 const bool namedNonArrayBlock = static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named && parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
6491 if (namedNonArrayBlock)
6493 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "non_array", "Non-array target");
6494 targetGroup->addChild(blockGroup);
6496 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 1, false);
6501 const ResourceDefinition::Node::SharedPtr sized (new ResourceDefinition::ArrayElement(parentStructure));
6502 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
6503 targetGroup->addChild(blockGroup);
6505 generateBufferVariableArraySizeSubCases(context, sized, blockGroup, TargetProp, true, namedNonArrayBlock);
6510 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6511 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unsized", "Unsized target");
6512 targetGroup->addChild(blockGroup);
6514 generateBufferVariableArraySizeSubCases(context, unsized, blockGroup, TargetProp, false, namedNonArrayBlock);
6518 static void generateBufferVariableBlockIndexCases (Context& context, tcu::TestCaseGroup* const targetGroup)
6520 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6521 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
6522 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6523 const ResourceDefinition::Node::SharedPtr bufferStorage (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6524 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(bufferStorage, glu::Layout(-1, 0)));
6528 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, true));
6529 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
6531 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "named_block"));
6536 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, false));
6537 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
6539 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "unnamed_block"));
6544 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding));
6545 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
6546 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
6548 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "block_array"));
6552 static void generateBufferVariableMatrixCaseBlocks (Context& context, tcu::TestCaseGroup* const targetGroup, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, bool))
6557 const char* description;
6559 bool extendedBasicTypeCases;
6560 glu::MatrixOrder order;
6563 { "named_block", "Named uniform block", true, true, glu::MATRIXORDER_LAST },
6564 { "named_block_row_major", "Named uniform block", true, false, glu::MATRIXORDER_ROW_MAJOR },
6565 { "named_block_col_major", "Named uniform block", true, false, glu::MATRIXORDER_COLUMN_MAJOR },
6566 { "unnamed_block", "Unnamed uniform block", false, false, glu::MATRIXORDER_LAST },
6567 { "unnamed_block_row_major", "Unnamed uniform block", false, false, glu::MATRIXORDER_ROW_MAJOR },
6568 { "unnamed_block_col_major", "Unnamed uniform block", false, false, glu::MATRIXORDER_COLUMN_MAJOR },
6571 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6572 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
6573 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6574 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6576 for (int childNdx = 0; childNdx < (int)DE_LENGTH_OF_ARRAY(children); ++childNdx)
6578 ResourceDefinition::Node::SharedPtr parentStructure = buffer;
6579 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, children[childNdx].name, children[childNdx].description);
6581 targetGroup->addChild(blockGroup);
6583 if (children[childNdx].order != glu::MATRIXORDER_LAST)
6586 layout.matrixOrder = children[childNdx].order;
6587 parentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(parentStructure, layout));
6590 parentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(parentStructure, children[childNdx].namedBlock));
6592 blockContentGenerator(context, parentStructure, blockGroup, children[childNdx].extendedBasicTypeCases);
6596 static void generateBufferVariableMatrixVariableBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramResourcePropFlags targetProp)
6598 // all matrix types and some non-matrix
6600 static const glu::DataType variableTypes[] =
6604 glu::TYPE_FLOAT_MAT2,
6605 glu::TYPE_FLOAT_MAT2X3,
6606 glu::TYPE_FLOAT_MAT2X4,
6607 glu::TYPE_FLOAT_MAT3X2,
6608 glu::TYPE_FLOAT_MAT3,
6609 glu::TYPE_FLOAT_MAT3X4,
6610 glu::TYPE_FLOAT_MAT4X2,
6611 glu::TYPE_FLOAT_MAT4X3,
6612 glu::TYPE_FLOAT_MAT4,
6615 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6617 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx]));
6618 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp)));
6622 static void generateBufferVariableMatrixVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramResourcePropFlags targetProp)
6625 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp, glu::TYPE_FLOAT_MAT3X2, "", 2);
6629 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6630 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(unsized, glu::TYPE_FLOAT_MAT3X2));
6632 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp), "var_unsized_array"));
6636 template <ProgramResourcePropFlags TargetProp>
6637 static void generateBufferVariableMatrixCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool extendedTypeCases)
6640 if (extendedTypeCases)
6642 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "types", "Types");
6643 targetGroup->addChild(blockGroup);
6644 generateBufferVariableMatrixVariableBasicTypeCases(context, parentStructure, blockGroup, TargetProp);
6649 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "no_qualifier", "No qualifier");
6650 targetGroup->addChild(blockGroup);
6651 generateBufferVariableMatrixVariableCases(context, parentStructure, blockGroup, TargetProp);
6656 const ResourceDefinition::Node::SharedPtr matrixOrder(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, -1, glu::FORMATLAYOUT_LAST, glu::MATRIXORDER_COLUMN_MAJOR)));
6658 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "column_major", "Column major qualifier");
6659 targetGroup->addChild(blockGroup);
6660 generateBufferVariableMatrixVariableCases(context, matrixOrder, blockGroup, TargetProp);
6665 const ResourceDefinition::Node::SharedPtr matrixOrder(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, -1, glu::FORMATLAYOUT_LAST, glu::MATRIXORDER_ROW_MAJOR)));
6667 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "row_major", "Row major qualifier");
6668 targetGroup->addChild(blockGroup);
6669 generateBufferVariableMatrixVariableCases(context, matrixOrder, blockGroup, TargetProp);
6673 static void generateBufferVariableNameLengthCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
6677 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
6678 targetGroup->addChild(blockGroup);
6680 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 3);
6685 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6686 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unsized", "Unsized target");
6687 targetGroup->addChild(blockGroup);
6689 generateBufferBackedVariableAggregateTypeCases(context, unsized, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 2);
6693 static void generateBufferVariableOffsetCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
6697 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
6698 targetGroup->addChild(blockGroup);
6700 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_OFFSET, glu::TYPE_FLOAT, "", 3);
6705 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6706 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unsized", "Unsized target");
6707 targetGroup->addChild(blockGroup);
6709 generateBufferBackedVariableAggregateTypeCases(context, unsized, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_OFFSET, glu::TYPE_FLOAT, "", 2);
6713 static void generateBufferVariableReferencedByBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
6715 DE_UNREF(expandLevel);
6717 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER);
6718 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6719 const ResourceDefinition::Node::SharedPtr storage (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6720 const bool singleShaderCase = parentStructure->getType() == ResourceDefinition::Node::TYPE_SHADER;
6724 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(storage, true));
6725 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block", "Named block");
6727 targetGroup->addChild(blockGroup);
6729 generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, singleShaderCase);
6734 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(storage, false));
6735 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "Unnamed block");
6737 targetGroup->addChild(blockGroup);
6739 generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, false);
6744 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(storage));
6745 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
6746 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "Block array");
6748 targetGroup->addChild(blockGroup);
6750 generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, false);
6754 template <ProgramResourcePropFlags TargetProp>
6755 static void generateBufferVariableTopLevelCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
6757 // basic and aggregate types
6758 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp, glu::TYPE_FLOAT_VEC4, "", 3);
6760 // basic and aggregate types in an unsized array
6762 const ResourceDefinition::Node::SharedPtr unsized(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6764 generateBufferBackedVariableAggregateTypeCases(context, unsized, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp, glu::TYPE_FLOAT_VEC4, "_unsized_array", 2);
6768 static void generateBufferVariableTypeBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
6773 glu::DataType dataType;
6776 { 0, glu::TYPE_FLOAT },
6777 { 1, glu::TYPE_INT },
6778 { 1, glu::TYPE_UINT },
6779 { 1, glu::TYPE_BOOL },
6781 { 3, glu::TYPE_FLOAT_VEC2 },
6782 { 1, glu::TYPE_FLOAT_VEC3 },
6783 { 1, glu::TYPE_FLOAT_VEC4 },
6785 { 3, glu::TYPE_INT_VEC2 },
6786 { 2, glu::TYPE_INT_VEC3 },
6787 { 3, glu::TYPE_INT_VEC4 },
6789 { 3, glu::TYPE_UINT_VEC2 },
6790 { 2, glu::TYPE_UINT_VEC3 },
6791 { 3, glu::TYPE_UINT_VEC4 },
6793 { 3, glu::TYPE_BOOL_VEC2 },
6794 { 2, glu::TYPE_BOOL_VEC3 },
6795 { 3, glu::TYPE_BOOL_VEC4 },
6797 { 2, glu::TYPE_FLOAT_MAT2 },
6798 { 3, glu::TYPE_FLOAT_MAT2X3 },
6799 { 3, glu::TYPE_FLOAT_MAT2X4 },
6800 { 2, glu::TYPE_FLOAT_MAT3X2 },
6801 { 2, glu::TYPE_FLOAT_MAT3 },
6802 { 3, glu::TYPE_FLOAT_MAT3X4 },
6803 { 2, glu::TYPE_FLOAT_MAT4X2 },
6804 { 3, glu::TYPE_FLOAT_MAT4X3 },
6805 { 2, glu::TYPE_FLOAT_MAT4 },
6808 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6810 if (variableTypes[ndx].level <= expandLevel)
6812 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
6813 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_TYPE)));
6818 static void generateBufferVariableTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int depth = 3)
6823 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic type");
6824 targetGroup->addChild(blockGroup);
6825 generateBufferVariableTypeBasicTypeCases(context, parentStructure, blockGroup, depth);
6829 // flatten bottom-level
6830 generateBufferVariableTypeBasicTypeCases(context, parentStructure, targetGroup, depth);
6836 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
6837 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Arrays");
6839 targetGroup->addChild(blockGroup);
6840 generateBufferVariableTypeCases(context, arrayElement, blockGroup, depth-1);
6846 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
6847 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Structs");
6849 targetGroup->addChild(blockGroup);
6850 generateBufferVariableTypeCases(context, structMember, blockGroup, depth-1);
6854 static void generateBufferVariableTypeBlock (Context& context, tcu::TestCaseGroup* targetGroup)
6856 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6857 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
6858 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6859 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6860 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(buffer, true));
6862 generateBufferVariableTypeCases(context, block, targetGroup);
6865 static void generateBufferVariableRandomCase (Context& context, tcu::TestCaseGroup* const targetGroup, int index, bool onlyExtensionStages)
6867 de::Random rnd (index * 0x12345);
6868 const ResourceDefinition::Node::SharedPtr shader = generateRandomShaderSet(rnd, onlyExtensionStages);
6869 const glu::DataType type = generateRandomDataType(rnd, true);
6870 const glu::Layout layout = generateRandomVariableLayout(rnd, type, true);
6871 const bool namedBlock = rnd.getBool();
6872 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6873 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6874 ResourceDefinition::Node::SharedPtr currentStructure (new ResourceDefinition::LayoutQualifier(buffer, generateRandomBufferBlockLayout(rnd)));
6876 if (namedBlock && rnd.getBool())
6877 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
6878 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(currentStructure, namedBlock));
6880 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, layout));
6881 currentStructure = generateRandomVariableDefinition(rnd, currentStructure, type, layout, true);
6883 targetGroup->addChild(new ResourceTestCase(context, currentStructure, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BUFFER_VARIABLE_MASK), de::toString(index).c_str()));
6886 static void generateBufferVariableRandomCases (Context& context, tcu::TestCaseGroup* const targetGroup)
6888 const int numBasicCases = 40;
6889 const int numTessGeoCases = 40;
6891 for (int ndx = 0; ndx < numBasicCases; ++ndx)
6892 generateBufferVariableRandomCase(context, targetGroup, ndx, false);
6893 for (int ndx = 0; ndx < numTessGeoCases; ++ndx)
6894 generateBufferVariableRandomCase(context, targetGroup, numBasicCases + ndx, true);
6897 class BufferVariableTestGroup : public TestCaseGroup
6900 BufferVariableTestGroup (Context& context);
6904 BufferVariableTestGroup::BufferVariableTestGroup (Context& context)
6905 : TestCaseGroup(context, "buffer_variable", "Buffer variable")
6909 void BufferVariableTestGroup::init (void)
6913 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "resource_list", "Resource list");
6914 addChild(blockGroup);
6915 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableResourceListBlockContentsProxy);
6920 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_size", "Array size");
6921 addChild(blockGroup);
6922 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableArrayCases<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6927 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_stride", "Array stride");
6928 addChild(blockGroup);
6929 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableArrayCases<PROGRAMRESOURCEPROP_ARRAY_STRIDE>);
6934 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "block_index", "Block index");
6935 addChild(blockGroup);
6936 generateBufferVariableBlockIndexCases(m_context, blockGroup);
6941 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "is_row_major", "Is row major");
6942 addChild(blockGroup);
6943 generateBufferVariableMatrixCaseBlocks(m_context, blockGroup, generateBufferVariableMatrixCases<PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR>);
6948 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "matrix_stride", "Matrix stride");
6949 addChild(blockGroup);
6950 generateBufferVariableMatrixCaseBlocks(m_context, blockGroup, generateBufferVariableMatrixCases<PROGRAMRESOURCEPROP_MATRIX_STRIDE>);
6955 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "name_length", "Name length");
6956 addChild(blockGroup);
6957 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableNameLengthCases);
6962 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "offset", "Offset");
6963 addChild(blockGroup);
6964 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableOffsetCases);
6969 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "referenced_by", "Referenced by");
6970 addChild(blockGroup);
6971 generateReferencedByShaderCaseBlocks(m_context, blockGroup, generateBufferVariableReferencedByBlockContents);
6974 // .top_level_array_size
6976 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "top_level_array_size", "Top-level array size");
6977 addChild(blockGroup);
6978 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableTopLevelCases<PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_SIZE>);
6981 // .top_level_array_stride
6983 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "top_level_array_stride", "Top-level array stride");
6984 addChild(blockGroup);
6985 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableTopLevelCases<PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_STRIDE>);
6990 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "type", "Type");
6991 addChild(blockGroup);
6992 generateBufferVariableTypeBlock(m_context, blockGroup);
6997 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "random", "Random");
6998 addChild(blockGroup);
6999 generateBufferVariableRandomCases(m_context, blockGroup);
7005 ProgramInterfaceQueryTests::ProgramInterfaceQueryTests (Context& context)
7006 : TestCaseGroup(context, "program_interface_query", "Program interface query tests")
7010 ProgramInterfaceQueryTests::~ProgramInterfaceQueryTests (void)
7014 void ProgramInterfaceQueryTests::init (void)
7018 // .buffer_limited_query
7020 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "buffer_limited_query", "Queries limited by the buffer size");
7024 group->addChild(new ResourceNameBufferLimitCase(m_context, "resource_name_query", "Test GetProgramResourceName with too small a buffer"));
7025 group->addChild(new ResourceQueryBufferLimitCase(m_context, "resource_query", "Test GetProgramResourceiv with too small a buffer"));
7031 addChild(new UniformInterfaceTestGroup(m_context));
7034 addChild(new BufferBackedBlockInterfaceTestGroup(m_context, glu::STORAGE_UNIFORM));
7036 // .atomic_counter_buffer
7037 addChild(new AtomicCounterTestGroup(m_context));
7040 addChild(new ProgramInputTestGroup(m_context));
7043 addChild(new ProgramOutputTestGroup(m_context));
7045 // .transform_feedback_varying
7046 addChild(new TransformFeedbackVaryingTestGroup(m_context));
7049 addChild(new BufferVariableTestGroup(m_context));
7051 // .shader_storage_block
7052 addChild(new BufferBackedBlockInterfaceTestGroup(m_context, glu::STORAGE_BUFFER));