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)
1029 m_testCtx.getLog() << tcu::TestLog::Message << "\t" << ndx << ": " << resourceList[ndx] << tcu::TestLog::EndMessage;
1031 m_testCtx.getLog() << tcu::TestLog::Message << "Expected list of resources:" << tcu::TestLog::EndMessage;
1033 for (int ndx = 0; ndx < (int)expectedResources.size(); ++ndx)
1034 m_testCtx.getLog() << tcu::TestLog::Message << "\t" << ndx << ": " << expectedResources[ndx] << tcu::TestLog::EndMessage;
1036 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying resource list contents." << tcu::TestLog::EndMessage;
1038 for (int ndx = 0; ndx < (int)expectedResources.size(); ++ndx)
1040 if (!de::contains(resourceList.begin(), resourceList.end(), expectedResources[ndx]))
1042 m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource list did not contain active resource " << expectedResources[ndx] << tcu::TestLog::EndMessage;
1047 for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1049 if (!de::contains(expectedResources.begin(), expectedResources.end(), resourceList[ndx]))
1051 // Ignore all builtin variables, mismatch causes errors otherwise
1052 if (deStringBeginsWith(resourceList[ndx].c_str(), "gl_") == DE_FALSE)
1054 m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource list contains unexpected resource name " << resourceList[ndx] << tcu::TestLog::EndMessage;
1058 m_testCtx.getLog() << tcu::TestLog::Message << "Note, resource list contains unknown built-in " << resourceList[ndx] << ". This variable is ignored." << tcu::TestLog::EndMessage;
1065 bool ResourceListTestCase::verifyResourceIndexQuery (const std::vector<std::string>& resourceList, const std::vector<std::string>& referenceResources, glw::GLuint program)
1067 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1068 const glw::GLenum programInterface = getProgramInterfaceGLEnum(m_programInterface);
1071 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying GetProgramResourceIndex returns correct indices for resource names." << tcu::TestLog::EndMessage;
1073 for (int ndx = 0; ndx < (int)referenceResources.size(); ++ndx)
1075 const glw::GLuint index = gl.getProgramResourceIndex(program, programInterface, referenceResources[ndx].c_str());
1076 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1078 if (index == GL_INVALID_INDEX)
1080 m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx] << "\" got index GL_INVALID_INDEX." << tcu::TestLog::EndMessage;
1083 else if ((int)index >= (int)resourceList.size())
1085 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;
1088 else if (resourceList[index] != referenceResources[ndx])
1090 m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx] << "\" got index (index = " << index << ") of another resource (" << resourceList[index] << ")." << tcu::TestLog::EndMessage;
1095 // Query for "name" should match "name[0]" except for XFB
1097 if (m_programInterface != PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING)
1099 for (int ndx = 0; ndx < (int)referenceResources.size(); ++ndx)
1101 if (de::endsWith(referenceResources[ndx], "[0]"))
1103 const std::string queryString = referenceResources[ndx].substr(0, referenceResources[ndx].length()-3);
1104 const glw::GLuint index = gl.getProgramResourceIndex(program, programInterface, queryString.c_str());
1105 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1107 if (index == GL_INVALID_INDEX)
1109 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" resulted in index GL_INVALID_INDEX." << tcu::TestLog::EndMessage;
1112 else if ((int)index >= (int)resourceList.size())
1114 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" resulted in index " << index << " (larger or equal to GL_ACTIVE_RESOURCES)." << tcu::TestLog::EndMessage;
1117 else if (resourceList[index] != queryString + "[0]")
1119 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" got index (index = " << index << ") of another resource (\"" << resourceList[index] << "\")." << tcu::TestLog::EndMessage;
1129 bool ResourceListTestCase::verifyMaxNameLength (const std::vector<std::string>& resourceList, glw::GLuint program)
1131 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1132 const glw::GLenum programInterface = getProgramInterfaceGLEnum(m_programInterface);
1133 glw::GLint maxNameLength = 0;
1134 glw::GLint expectedMaxNameLength = 0;
1136 gl.getProgramInterfaceiv(program, programInterface, GL_MAX_NAME_LENGTH, &maxNameLength);
1137 GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
1139 for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1140 expectedMaxNameLength = de::max(expectedMaxNameLength, (int)resourceList[ndx].size() + 1);
1142 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying MAX_NAME_LENGTH, expecting " << expectedMaxNameLength << " (i.e. consistent with the queried resource list)" << tcu::TestLog::EndMessage;
1144 if (expectedMaxNameLength != maxNameLength)
1146 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got " << maxNameLength << tcu::TestLog::EndMessage;
1153 std::string ResourceListTestCase::genTestCaseName (ProgramInterface interface, const ResourceDefinition::Node* root)
1155 bool isImplicitlySizedArray = false;
1156 bool hasVariable = false;
1157 bool accumulateName = true;
1158 std::string buf = "var";
1161 for (const ResourceDefinition::Node* node = root; node; node = node->getEnclosingNode())
1163 switch (node->getType())
1165 case ResourceDefinition::Node::TYPE_VARIABLE:
1171 case ResourceDefinition::Node::TYPE_STRUCT_MEMBER:
1178 case ResourceDefinition::Node::TYPE_ARRAY_ELEMENT:
1180 DE_ASSERT(dynamic_cast<const ResourceDefinition::ArrayElement*>(node));
1181 const ResourceDefinition::ArrayElement* arrayElement = static_cast<const ResourceDefinition::ArrayElement*>(node);
1183 isImplicitlySizedArray = (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::UNSIZED_ARRAY);
1190 case ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER:
1192 DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(node));
1193 const ResourceDefinition::StorageQualifier* storageDef = static_cast<const ResourceDefinition::StorageQualifier*>(node);
1195 if (storageDef->m_storage == glu::STORAGE_PATCH_IN ||
1196 storageDef->m_storage == glu::STORAGE_PATCH_OUT)
1204 case ResourceDefinition::Node::TYPE_SHADER:
1205 case ResourceDefinition::Node::TYPE_SHADER_SET:
1207 bool arrayedInterface;
1209 if (node->getType() == ResourceDefinition::Node::TYPE_SHADER)
1211 DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(node));
1212 const ResourceDefinition::Shader* shaderDef = static_cast<const ResourceDefinition::Shader*>(node);
1214 arrayedInterface = isArrayedInterface(interface, (1u << shaderDef->m_type));
1218 DE_ASSERT(node->getType() == ResourceDefinition::Node::TYPE_SHADER_SET);
1219 DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(node));
1220 const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(node);
1222 arrayedInterface = isArrayedInterface(interface, shaderDef->getReferencingMask());
1225 if (arrayedInterface && isImplicitlySizedArray)
1227 // omit implicit arrayness from name, i.e. remove trailing "_array"
1228 DE_ASSERT(de::endsWith(buf, "_array"));
1229 buf = buf.substr(0, buf.length() - 6);
1235 case ResourceDefinition::Node::TYPE_INTERFACE_BLOCK:
1237 accumulateName = false;
1247 return prefix + "empty";
1249 return prefix + buf;
1252 bool ResourceListTestCase::isArrayedInterface (ProgramInterface interface, deUint32 stageBits)
1254 if (interface == PROGRAMINTERFACE_PROGRAM_INPUT)
1256 const glu::ShaderType firstStage = getShaderMaskFirstStage(stageBits);
1257 return firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
1258 firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
1259 firstStage == glu::SHADERTYPE_GEOMETRY;
1261 else if (interface == PROGRAMINTERFACE_PROGRAM_OUTPUT)
1263 const glu::ShaderType lastStage = getShaderMaskLastStage(stageBits);
1264 return lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL;
1269 // Resouce property query case
1271 class ResourceTestCase : public ProgramInterfaceQueryTestCase
1274 ResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, const ProgramResourceQueryTestTarget& queryTarget, const char* name = DE_NULL);
1275 ~ResourceTestCase (void);
1280 const ProgramInterfaceDefinition::Program* getProgramDefinition (void) const;
1281 std::vector<std::string> getQueryTargetResources (void) const;
1283 static std::string genTestCaseName (const ResourceDefinition::Node*);
1284 static std::string genMultilineDescription (const ResourceDefinition::Node*);
1286 ResourceDefinition::Node::SharedPtr m_targetResource;
1287 ProgramInterfaceDefinition::Program* m_program;
1288 std::vector<std::string> m_targetResources;
1291 ResourceTestCase::ResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, const ProgramResourceQueryTestTarget& queryTarget, const char* name)
1292 : ProgramInterfaceQueryTestCase (context, (name == DE_NULL) ? (genTestCaseName(targetResource.get()).c_str()) : (name), "", queryTarget)
1293 , m_targetResource (targetResource)
1294 , m_program (DE_NULL)
1298 ResourceTestCase::~ResourceTestCase (void)
1303 void ResourceTestCase::init (void)
1306 << tcu::TestLog::Message
1307 << genMultilineDescription(m_targetResource.get())
1308 << tcu::TestLog::EndMessage;
1312 // Generate interface with target resource
1313 m_program = generateProgramDefinitionFromResource(m_targetResource.get()).release();
1314 m_targetResources = getProgramInterfaceResourceList(m_program, getTargetInterface());
1318 void ResourceTestCase::deinit (void)
1320 m_targetResource.clear();
1323 m_program = DE_NULL;
1325 m_targetResources = std::vector<std::string>();
1328 const ProgramInterfaceDefinition::Program* ResourceTestCase::getProgramDefinition (void) const
1333 std::vector<std::string> ResourceTestCase::getQueryTargetResources (void) const
1335 return m_targetResources;
1338 std::string ResourceTestCase::genTestCaseName (const ResourceDefinition::Node* resource)
1340 if (resource->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
1342 DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));
1344 const ResourceDefinition::Variable* variable = static_cast<const ResourceDefinition::Variable*>(resource);
1346 return convertGLTypeNameToTestName(glu::getDataTypeName(variable->m_dataType));
1353 std::string ResourceTestCase::genMultilineDescription (const ResourceDefinition::Node* resource)
1355 if (resource->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
1357 DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));
1359 const ResourceDefinition::Variable* varDef = static_cast<const ResourceDefinition::Variable*>(resource);
1360 std::ostringstream buf;
1361 std::ostringstream structureDescriptor;
1362 std::string uniformType;
1364 for (const ResourceDefinition::Node* node = resource; node; node = node->getEnclosingNode())
1366 if (node->getType() == ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER)
1368 DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(node));
1370 const ResourceDefinition::StorageQualifier* storageDef = static_cast<const ResourceDefinition::StorageQualifier*>(node);
1372 uniformType = std::string(" ") + glu::getStorageName(storageDef->m_storage);
1373 structureDescriptor << "\n\tdeclared as \"" << glu::getStorageName(storageDef->m_storage) << "\"";
1376 if (node->getType() == ResourceDefinition::Node::TYPE_ARRAY_ELEMENT)
1377 structureDescriptor << "\n\tarray";
1379 if (node->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER)
1380 structureDescriptor << "\n\tin a struct";
1382 if (node->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
1383 structureDescriptor << "\n\tin the default block";
1385 if (node->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
1386 structureDescriptor << "\n\tin an interface block";
1389 buf << "Querying properties of " << glu::getDataTypeName(varDef->m_dataType) << uniformType << " variable.\n"
1391 << "\t" << glu::getDataTypeName(varDef->m_dataType)
1392 << structureDescriptor.str();
1396 else if (resource->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
1398 DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(resource));
1400 const ResourceDefinition::TransformFeedbackTarget* xfbDef = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(resource);
1402 DE_ASSERT(xfbDef->m_builtinVarName);
1404 return std::string("Querying properties of a builtin variable ") + xfbDef->m_builtinVarName;
1411 class ResourceNameBufferLimitCase : public TestCase
1414 ResourceNameBufferLimitCase (Context& context, const char* name, const char* description);
1415 ~ResourceNameBufferLimitCase (void);
1418 IterateResult iterate (void);
1421 ResourceNameBufferLimitCase::ResourceNameBufferLimitCase (Context& context, const char* name, const char* description)
1422 : TestCase(context, name, description)
1426 ResourceNameBufferLimitCase::~ResourceNameBufferLimitCase (void)
1430 ResourceNameBufferLimitCase::IterateResult ResourceNameBufferLimitCase::iterate (void)
1432 static const char* const computeSource = "#version 310 es\n"
1433 "layout(local_size_x = 1) in;\n"
1434 "uniform highp int u_uniformWithALongName;\n"
1435 "writeonly buffer OutputBufferBlock { highp int b_output_int; };\n"
1438 " b_output_int = u_uniformWithALongName;\n"
1441 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1442 const glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(computeSource));
1443 glw::GLuint uniformIndex;
1445 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1449 const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program", "Program");
1451 m_testCtx.getLog() << program;
1452 if (!program.isOk())
1453 throw tcu::TestError("could not build program");
1456 uniformIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_uniformWithALongName");
1457 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1459 if (uniformIndex == GL_INVALID_INDEX)
1460 throw tcu::TestError("Uniform u_uniformWithALongName resource index was GL_INVALID_INDEX");
1462 // Query with different sized buffers, len("u_uniformWithALongName") == 22
1467 const char* description;
1472 { "Query to larger buffer", 24, true },
1473 { "Query to buffer the same size", 23, true },
1474 { "Query to one byte too small buffer", 22, true },
1475 { "Query to one byte buffer", 1, true },
1476 { "Query to zero sized buffer", 0, true },
1477 { "Query to one byte too small buffer, null length argument", 22, false },
1478 { "Query to one byte buffer, null length argument", 1, false },
1479 { "Query to zero sized buffer, null length argument", 0, false },
1482 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(querySizes); ++ndx)
1484 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Query", querySizes[ndx].description);
1485 const int uniformNameLen = 22;
1486 const int expectedWriteLen = (querySizes[ndx].querySize != 0) ? (de::min(uniformNameLen, (querySizes[ndx].querySize - 1))) : (0);
1488 glw::GLsizei written = -1;
1490 // One byte for guard
1491 DE_ASSERT((int)sizeof(buffer) > querySizes[ndx].querySize);
1493 deMemset(buffer, 'x', sizeof(buffer));
1495 if (querySizes[ndx].querySize)
1497 << tcu::TestLog::Message
1498 << "Querying uniform name to a buffer of size " << querySizes[ndx].querySize
1499 << ", expecting query to write " << expectedWriteLen << " bytes followed by a null terminator"
1500 << tcu::TestLog::EndMessage;
1503 << tcu::TestLog::Message
1504 << "Querying uniform name to a buffer of size " << querySizes[ndx].querySize
1505 << ", expecting query to write 0 bytes"
1506 << tcu::TestLog::EndMessage;
1508 gl.getProgramResourceName(program.getProgram(), GL_UNIFORM, uniformIndex, querySizes[ndx].querySize, (querySizes[ndx].returnLength) ? (&written) : (DE_NULL), buffer);
1509 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource name");
1511 if (querySizes[ndx].returnLength && written != expectedWriteLen)
1513 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected write length of " << expectedWriteLen << ", got " << written << tcu::TestLog::EndMessage;
1514 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected write lenght");
1516 else if (querySizes[ndx].querySize != 0 && buffer[expectedWriteLen] != 0)
1518 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected null terminator at " << expectedWriteLen << ", got dec=" << (int)buffer[expectedWriteLen] << tcu::TestLog::EndMessage;
1519 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Missing null terminator");
1521 else if (querySizes[ndx].querySize != 0 && buffer[expectedWriteLen+1] != 'x')
1523 m_testCtx.getLog() << tcu::TestLog::Message << "Error, guard at index " << (expectedWriteLen+1) << " was modified, got dec=" << (int)buffer[expectedWriteLen+1] << tcu::TestLog::EndMessage;
1524 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrote over buffer size");
1526 else if (querySizes[ndx].querySize == 0 && buffer[0] != 'x')
1528 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;
1529 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents were modified");
1537 class ResourceQueryBufferLimitCase : public TestCase
1540 ResourceQueryBufferLimitCase (Context& context, const char* name, const char* description);
1541 ~ResourceQueryBufferLimitCase (void);
1544 IterateResult iterate (void);
1547 ResourceQueryBufferLimitCase::ResourceQueryBufferLimitCase (Context& context, const char* name, const char* description)
1548 : TestCase(context, name, description)
1552 ResourceQueryBufferLimitCase::~ResourceQueryBufferLimitCase (void)
1556 ResourceQueryBufferLimitCase::IterateResult ResourceQueryBufferLimitCase::iterate (void)
1558 static const char* const computeSource = "#version 310 es\n"
1559 "layout(local_size_x = 1) in;\n"
1560 "uniform highp int u_uniform;\n"
1561 "writeonly buffer OutputBufferBlock { highp int b_output_int; };\n"
1564 " b_output_int = u_uniform;\n"
1567 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1568 const glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(computeSource));
1569 glw::GLuint uniformIndex;
1571 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1575 const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program", "Program");
1577 m_testCtx.getLog() << program;
1578 if (!program.isOk())
1579 throw tcu::TestError("could not build program");
1582 uniformIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_uniform");
1583 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1585 if (uniformIndex == GL_INVALID_INDEX)
1586 throw tcu::TestError("Uniform u_uniform resource index was GL_INVALID_INDEX");
1588 // Query uniform properties
1593 const char* description;
1599 { "Query to a larger buffer", 2, 3, true },
1600 { "Query to too small a buffer", 3, 2, true },
1601 { "Query to zero sized buffer", 3, 0, true },
1602 { "Query to a larger buffer, null length argument", 2, 3, false },
1603 { "Query to too small a buffer, null length argument", 3, 2, false },
1604 { "Query to zero sized buffer, null length argument", 3, 0, false },
1607 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(querySizes); ++ndx)
1609 const tcu::ScopedLogSection section (m_testCtx.getLog(), "QueryToLarger", querySizes[ndx].description);
1610 const glw::GLenum props[] = { GL_LOCATION, GL_LOCATION, GL_LOCATION };
1611 const int expectedWriteLen = de::min(querySizes[ndx].bufferSize, querySizes[ndx].numProps);
1612 int params[] = { 255, 255, 255, 255 };
1613 glw::GLsizei written = -1;
1615 DE_ASSERT(querySizes[ndx].numProps <= DE_LENGTH_OF_ARRAY(props));
1616 DE_ASSERT(querySizes[ndx].bufferSize < DE_LENGTH_OF_ARRAY(params)); // leave at least one element for overflow detection
1619 << tcu::TestLog::Message
1620 << "Querying " << querySizes[ndx].numProps << " uniform prop(s) to a buffer with size " << querySizes[ndx].bufferSize << ". Expecting query to return " << expectedWriteLen << " prop(s)"
1621 << tcu::TestLog::EndMessage;
1623 gl.getProgramResourceiv(program.getProgram(), GL_UNIFORM, uniformIndex, querySizes[ndx].numProps, props, querySizes[ndx].bufferSize, (querySizes[ndx].returnLength) ? (&written) : (DE_NULL), params);
1624 GLU_EXPECT_NO_ERROR(gl.getError(), "query program resources");
1626 if (querySizes[ndx].returnLength && written != expectedWriteLen)
1628 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected write length of " << expectedWriteLen << ", got " << written << tcu::TestLog::EndMessage;
1629 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected write lenght");
1631 else if (params[expectedWriteLen] != 255)
1633 m_testCtx.getLog() << tcu::TestLog::Message << "Error, guard at index " << (expectedWriteLen) << " was modified. Was 255 before call, got dec=" << params[expectedWriteLen] << tcu::TestLog::EndMessage;
1634 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrote over buffer size");
1642 class InterfaceBlockBaseCase : public TestCase
1647 CASE_NAMED_BLOCK = 0,
1654 InterfaceBlockBaseCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
1655 ~InterfaceBlockBaseCase (void);
1662 const glu::Storage m_storage;
1663 const CaseType m_caseType;
1664 ProgramInterfaceDefinition::Program* m_program;
1667 InterfaceBlockBaseCase::InterfaceBlockBaseCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
1668 : TestCase (context, name, description)
1669 , m_storage (storage)
1670 , m_caseType (caseType)
1671 , m_program (DE_NULL)
1673 DE_ASSERT(storage == glu::STORAGE_UNIFORM || storage == glu::STORAGE_BUFFER);
1676 InterfaceBlockBaseCase::~InterfaceBlockBaseCase (void)
1681 void InterfaceBlockBaseCase::init (void)
1683 ProgramInterfaceDefinition::Shader* shader;
1685 m_program = new ProgramInterfaceDefinition::Program();
1686 shader = m_program->addShader(glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES);
1688 // PrecedingInterface
1690 glu::InterfaceBlock precedingInterfaceBlock;
1692 precedingInterfaceBlock.interfaceName = "PrecedingInterface";
1693 precedingInterfaceBlock.layout.binding = 0;
1694 precedingInterfaceBlock.storage = m_storage;
1695 precedingInterfaceBlock.instanceName = "precedingInstance";
1697 precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "precedingMember"));
1699 // Unsized array type
1700 if (m_storage == glu::STORAGE_BUFFER)
1701 precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY), "precedingMemberUnsizedArray"));
1703 precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 2), "precedingMemberArray"));
1705 shader->getDefaultBlock().interfaceBlocks.push_back(precedingInterfaceBlock);
1710 glu::InterfaceBlock targetInterfaceBlock;
1712 targetInterfaceBlock.interfaceName = "TargetInterface";
1713 targetInterfaceBlock.layout.binding = 1;
1714 targetInterfaceBlock.storage = m_storage;
1716 if (m_caseType == CASE_UNNAMED_BLOCK)
1717 targetInterfaceBlock.instanceName = "";
1719 targetInterfaceBlock.instanceName = "targetInstance";
1721 if (m_caseType == CASE_BLOCK_ARRAY)
1722 targetInterfaceBlock.dimensions.push_back(2);
1726 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "blockMemberBasic"));
1731 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 3), "blockMemberArray"));
1736 glu::StructType* structPtr = new glu::StructType("StructType");
1737 structPtr->addMember("structMemberBasic", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP));
1738 structPtr->addMember("structMemberArray", glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 2));
1740 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(structPtr), 2), "blockMemberStruct"));
1743 // Unsized array type
1744 if (m_storage == glu::STORAGE_BUFFER)
1745 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY), "blockMemberUnsizedArray"));
1747 shader->getDefaultBlock().interfaceBlocks.push_back(targetInterfaceBlock);
1750 // TrailingInterface
1752 glu::InterfaceBlock trailingInterfaceBlock;
1754 trailingInterfaceBlock.interfaceName = "TrailingInterface";
1755 trailingInterfaceBlock.layout.binding = 3;
1756 trailingInterfaceBlock.storage = m_storage;
1757 trailingInterfaceBlock.instanceName = "trailingInstance";
1758 trailingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "trailingMember"));
1760 shader->getDefaultBlock().interfaceBlocks.push_back(trailingInterfaceBlock);
1763 DE_ASSERT(m_program->isValid());
1766 void InterfaceBlockBaseCase::deinit (void)
1769 m_program = DE_NULL;
1772 class InterfaceBlockActiveVariablesTestCase : public InterfaceBlockBaseCase
1775 InterfaceBlockActiveVariablesTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
1778 IterateResult iterate (void);
1781 InterfaceBlockActiveVariablesTestCase::InterfaceBlockActiveVariablesTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
1782 : InterfaceBlockBaseCase(context, name, description, storage, caseType)
1786 InterfaceBlockActiveVariablesTestCase::IterateResult InterfaceBlockActiveVariablesTestCase::iterate (void)
1788 const ProgramInterface programInterface = (m_storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
1789 (m_storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
1790 (PROGRAMINTERFACE_LAST);
1791 const glw::GLenum programGLInterfaceValue = getProgramInterfaceGLEnum(programInterface);
1792 const glw::GLenum programMemberInterfaceValue = (m_storage == glu::STORAGE_UNIFORM) ? (GL_UNIFORM) :
1793 (m_storage == glu::STORAGE_BUFFER) ? (GL_BUFFER_VARIABLE) :
1795 const std::vector<std::string> blockNames = getProgramInterfaceResourceList(m_program, programInterface);
1796 glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
1797 int expectedMaxNumActiveVariables = 0;
1799 DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
1801 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1802 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1804 // Verify all blocks
1806 for (int blockNdx = 0; blockNdx < (int)blockNames.size(); ++blockNdx)
1808 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Block", "Block \"" + blockNames[blockNdx] + "\"");
1809 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1810 const glw::GLuint resourceNdx = gl.getProgramResourceIndex(program.getProgram(), programGLInterfaceValue, blockNames[blockNdx].c_str());
1811 glw::GLint numActiveResources;
1812 std::vector<std::string> activeResourceNames;
1814 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1816 if (resourceNdx == GL_INVALID_INDEX)
1818 m_testCtx.getLog() << tcu::TestLog::Message << "Error, getProgramResourceIndex returned GL_INVALID_INDEX for \"" << blockNames[blockNdx] << "\"" << tcu::TestLog::EndMessage;
1819 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Resource not found");
1823 // query block information
1826 const glw::GLenum props[] = { GL_NUM_ACTIVE_VARIABLES };
1827 glw::GLint retBuffer[2] = { -1, -1 };
1828 glw::GLint written = -1;
1830 gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, DE_LENGTH_OF_ARRAY(props), props, 1, &written, retBuffer);
1831 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_NUM_ACTIVE_VARIABLES");
1833 numActiveResources = retBuffer[0];
1834 expectedMaxNumActiveVariables = de::max(expectedMaxNumActiveVariables, numActiveResources);
1835 m_testCtx.getLog() << tcu::TestLog::Message << "NUM_ACTIVE_VARIABLES = " << numActiveResources << tcu::TestLog::EndMessage;
1837 if (written == -1 || retBuffer[0] == -1)
1839 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for NUM_ACTIVE_VARIABLES did not return a value" << tcu::TestLog::EndMessage;
1840 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for NUM_ACTIVE_VARIABLES failed");
1843 else if (retBuffer[1] != -1)
1845 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for NUM_ACTIVE_VARIABLES returned too many values" << tcu::TestLog::EndMessage;
1846 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for NUM_ACTIVE_VARIABLES returned too many values");
1849 else if (retBuffer[0] < 0)
1851 m_testCtx.getLog() << tcu::TestLog::Message << "Error, NUM_ACTIVE_VARIABLES < 0" << tcu::TestLog::EndMessage;
1852 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "NUM_ACTIVE_VARIABLES < 0");
1857 // query block variable information
1860 const glw::GLenum props[] = { GL_ACTIVE_VARIABLES };
1861 std::vector<glw::GLint> activeVariableIndices (numActiveResources + 1, -1); // Allocate one extra trailing to detect wrong write lengths
1862 glw::GLint written = -1;
1864 gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, DE_LENGTH_OF_ARRAY(props), props, (glw::GLsizei)activeVariableIndices.size(), &written, &activeVariableIndices[0]);
1865 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_ACTIVE_VARIABLES");
1869 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for GL_ACTIVE_VARIABLES did not return any values" << tcu::TestLog::EndMessage;
1870 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES failed");
1873 else if (written != numActiveResources)
1875 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for GL_ACTIVE_VARIABLES did not return NUM_ACTIVE_VARIABLES values" << tcu::TestLog::EndMessage;
1876 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES returned invalid number of values");
1879 else if (activeVariableIndices.back() != -1)
1881 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;
1882 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES returned too many values");
1888 tcu::MessageBuilder builder(&m_testCtx.getLog());
1890 builder << "Active variable indices: {";
1891 for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1895 builder << activeVariableIndices[varNdx];
1897 builder << "}" << tcu::TestLog::EndMessage;
1902 activeResourceNames.resize(numActiveResources);
1904 for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1906 const glw::GLenum nameProp = GL_NAME_LENGTH;
1907 glw::GLint nameLength = -1;
1908 std::vector<char> nameBuffer;
1911 gl.getProgramResourceiv(program.getProgram(), programMemberInterfaceValue, activeVariableIndices[varNdx], 1, &nameProp, 1, &written, &nameLength);
1912 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_NAME_LENGTH");
1914 if (nameLength <= 0 || written <= 0)
1916 m_testCtx.getLog() << tcu::TestLog::Message << "Error, GL_NAME_LENGTH query failed" << tcu::TestLog::EndMessage;
1917 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GL_NAME_LENGTH query failed");
1921 nameBuffer.resize(nameLength + 2, 'X'); // allocate more than required
1923 gl.getProgramResourceName(program.getProgram(), programMemberInterfaceValue, activeVariableIndices[varNdx], nameLength+1, &written, &nameBuffer[0]);
1924 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramResourceName");
1928 m_testCtx.getLog() << tcu::TestLog::Message << "Error, name query failed, no data written" << tcu::TestLog::EndMessage;
1929 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "name query failed");
1932 else if (written > nameLength)
1934 m_testCtx.getLog() << tcu::TestLog::Message << "Error, name query failed, query returned too much data" << tcu::TestLog::EndMessage;
1935 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "name query failed");
1939 activeResourceNames[varNdx] = std::string(&nameBuffer[0], written);
1942 // log collected names
1944 tcu::MessageBuilder builder(&m_testCtx.getLog());
1946 builder << "Active variables:\n";
1947 for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1948 builder << "\t" << activeResourceNames[varNdx] << "\n";
1949 builder << tcu::TestLog::EndMessage;
1955 glu::InterfaceBlock* block = DE_NULL;
1956 const std::string blockName = glu::parseVariableName(blockNames[blockNdx].c_str());
1957 std::vector<std::string> referenceList;
1959 for (int interfaceNdx = 0; interfaceNdx < (int)m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx)
1961 if (m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].interfaceName == blockName)
1963 block = &m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx];
1969 throw tcu::InternalError("could not find block referenced in the reference resource list");
1971 // generate reference list
1973 referenceList = getProgramInterfaceBlockMemberResourceList(*block);
1975 tcu::MessageBuilder builder(&m_testCtx.getLog());
1977 builder << "Expected variable names:\n";
1978 for (int varNdx = 0; varNdx < (int)referenceList.size(); ++varNdx)
1979 builder << "\t" << referenceList[varNdx] << "\n";
1980 builder << tcu::TestLog::EndMessage;
1985 bool listsIdentical = true;
1987 for (int ndx = 0; ndx < (int)referenceList.size(); ++ndx)
1989 if (!de::contains(activeResourceNames.begin(), activeResourceNames.end(), referenceList[ndx]))
1991 m_testCtx.getLog() << tcu::TestLog::Message << "Error, variable name list did not contain active variable " << referenceList[ndx] << tcu::TestLog::EndMessage;
1992 listsIdentical = false;
1996 for (int ndx = 0; ndx < (int)activeResourceNames.size(); ++ndx)
1998 if (!de::contains(referenceList.begin(), referenceList.end(), activeResourceNames[ndx]))
2000 m_testCtx.getLog() << tcu::TestLog::Message << "Error, variable name list contains unexpected resource \"" << activeResourceNames[ndx] << "\"" << tcu::TestLog::EndMessage;
2001 listsIdentical = false;
2006 m_testCtx.getLog() << tcu::TestLog::Message << "Lists identical" << tcu::TestLog::EndMessage;
2009 m_testCtx.getLog() << tcu::TestLog::Message << "Error, invalid active variable list" << tcu::TestLog::EndMessage;
2010 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid active variable list");
2017 // Max num active variables
2019 const tcu::ScopedLogSection section (m_testCtx.getLog(), "MaxNumActiveVariables", "MAX_NUM_ACTIVE_VARIABLES");
2020 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2021 glw::GLint maxNumActiveVariables = -1;
2023 gl.getProgramInterfaceiv(program.getProgram(), programGLInterfaceValue, GL_MAX_NUM_ACTIVE_VARIABLES, &maxNumActiveVariables);
2024 GLU_EXPECT_NO_ERROR(gl.getError(), "query MAX_NUM_ACTIVE_VARIABLES");
2026 m_testCtx.getLog() << tcu::TestLog::Message << "MAX_NUM_ACTIVE_VARIABLES = " << maxNumActiveVariables << tcu::TestLog::EndMessage;
2028 if (expectedMaxNumActiveVariables != maxNumActiveVariables)
2030 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected MAX_NUM_ACTIVE_VARIABLES" << tcu::TestLog::EndMessage;
2031 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected MAX_NUM_ACTIVE_VARIABLES");
2034 m_testCtx.getLog() << tcu::TestLog::Message << "MAX_NUM_ACTIVE_VARIABLES valid" << tcu::TestLog::EndMessage;
2040 class InterfaceBlockDataSizeTestCase : public InterfaceBlockBaseCase
2043 InterfaceBlockDataSizeTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
2046 IterateResult iterate (void);
2047 int getBlockMinDataSize (const std::string& blockName) const;
2048 int getBlockMinDataSize (const glu::InterfaceBlock& block) const;
2051 InterfaceBlockDataSizeTestCase::InterfaceBlockDataSizeTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
2052 : InterfaceBlockBaseCase(context, name, description, storage, caseType)
2056 InterfaceBlockDataSizeTestCase::IterateResult InterfaceBlockDataSizeTestCase::iterate (void)
2058 const ProgramInterface programInterface = (m_storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
2059 (m_storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
2060 (PROGRAMINTERFACE_LAST);
2061 const glw::GLenum programGLInterfaceValue = getProgramInterfaceGLEnum(programInterface);
2062 const std::vector<std::string> blockNames = getProgramInterfaceResourceList(m_program, programInterface);
2063 glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2065 DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
2067 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2068 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2070 // Verify all blocks
2071 for (int blockNdx = 0; blockNdx < (int)blockNames.size(); ++blockNdx)
2073 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Block", "Block \"" + blockNames[blockNdx] + "\"");
2074 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2075 const glw::GLuint resourceNdx = gl.getProgramResourceIndex(program.getProgram(), programGLInterfaceValue, blockNames[blockNdx].c_str());
2076 const int expectedMinDataSize = getBlockMinDataSize(blockNames[blockNdx]);
2077 glw::GLint queryDataSize = -1;
2079 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
2081 if (resourceNdx == GL_INVALID_INDEX)
2083 m_testCtx.getLog() << tcu::TestLog::Message << "Error, getProgramResourceIndex returned GL_INVALID_INDEX for \"" << blockNames[blockNdx] << "\"" << tcu::TestLog::EndMessage;
2084 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Resource not found");
2090 const glw::GLenum prop = GL_BUFFER_DATA_SIZE;
2092 gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, 1, &prop, 1, DE_NULL, &queryDataSize);
2093 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource BUFFER_DATA_SIZE");
2097 << tcu::TestLog::Message
2098 << "BUFFER_DATA_SIZE = " << queryDataSize << "\n"
2099 << "Buffer data size with tight packing: " << expectedMinDataSize
2100 << tcu::TestLog::EndMessage;
2102 if (queryDataSize < expectedMinDataSize)
2104 m_testCtx.getLog() << tcu::TestLog::Message << "Error, buffer size was less than minimum buffer data size" << tcu::TestLog::EndMessage;
2105 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer data size invalid");
2109 m_testCtx.getLog() << tcu::TestLog::Message << "Buffer size valid" << tcu::TestLog::EndMessage;
2115 int InterfaceBlockDataSizeTestCase::getBlockMinDataSize (const std::string& blockFullName) const
2117 const std::string blockName = glu::parseVariableName(blockFullName.c_str());
2119 for (int interfaceNdx = 0; interfaceNdx < (int)m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx)
2121 if (m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].interfaceName == blockName &&
2122 m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].storage == m_storage)
2123 return getBlockMinDataSize(m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx]);
2130 class AtomicCounterCase : public TestCase
2133 AtomicCounterCase (Context& context, const char* name, const char* description);
2134 ~AtomicCounterCase (void);
2141 int getNumAtomicCounterBuffers (void) const;
2142 int getMaxNumActiveVariables (void) const;
2143 int getBufferVariableCount (int binding) const;
2144 int getBufferMinimumDataSize (int binding) const;
2146 ProgramInterfaceDefinition::Program* m_program;
2149 AtomicCounterCase::AtomicCounterCase (Context& context, const char* name, const char* description)
2150 : TestCase (context, name, description)
2151 , m_program (DE_NULL)
2155 AtomicCounterCase::~AtomicCounterCase (void)
2160 void AtomicCounterCase::init (void)
2162 ProgramInterfaceDefinition::Shader* shader;
2164 m_program = new ProgramInterfaceDefinition::Program();
2165 shader = m_program->addShader(glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES);
2168 glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding1_counter1", glu::STORAGE_UNIFORM);
2169 decl.layout.binding = 1;
2170 shader->getDefaultBlock().variables.push_back(decl);
2173 glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding1_counter2", glu::STORAGE_UNIFORM);
2174 decl.layout.binding = 1;
2175 decl.layout.offset = 8;
2177 shader->getDefaultBlock().variables.push_back(decl);
2180 glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding2_counter1", glu::STORAGE_UNIFORM);
2181 decl.layout.binding = 2;
2182 shader->getDefaultBlock().variables.push_back(decl);
2185 DE_ASSERT(m_program->isValid());
2188 void AtomicCounterCase::deinit (void)
2191 m_program = DE_NULL;
2194 int AtomicCounterCase::getNumAtomicCounterBuffers (void) const
2196 std::set<int> buffers;
2198 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2200 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2201 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()))
2203 buffers.insert(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding);
2207 return (int)buffers.size();
2210 int AtomicCounterCase::getMaxNumActiveVariables (void) const
2213 std::map<int,int> numBufferVars;
2215 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2217 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2218 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()))
2220 const int binding = m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding;
2222 if (numBufferVars.find(binding) == numBufferVars.end())
2223 numBufferVars[binding] = 1;
2225 ++numBufferVars[binding];
2229 for (std::map<int,int>::const_iterator it = numBufferVars.begin(); it != numBufferVars.end(); ++it)
2230 maxVars = de::max(maxVars, it->second);
2235 int AtomicCounterCase::getBufferVariableCount (int binding) const
2239 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2241 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2242 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()) &&
2243 m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding == binding)
2250 int AtomicCounterCase::getBufferMinimumDataSize (int binding) const
2253 int currentOffset = 0;
2255 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2257 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2258 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()) &&
2259 m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding == binding)
2261 const int thisOffset = (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.offset != -1) ? (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.offset) : (currentOffset);
2262 currentOffset = thisOffset + 4;
2264 minSize = de::max(minSize, thisOffset + 4);
2271 class AtomicCounterResourceListCase : public AtomicCounterCase
2274 AtomicCounterResourceListCase (Context& context, const char* name, const char* description);
2277 IterateResult iterate (void);
2280 AtomicCounterResourceListCase::AtomicCounterResourceListCase (Context& context, const char* name, const char* description)
2281 : AtomicCounterCase(context, name, description)
2285 AtomicCounterResourceListCase::IterateResult AtomicCounterResourceListCase::iterate (void)
2287 const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2289 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2290 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2293 const tcu::ScopedLogSection section (m_testCtx.getLog(), "ActiveResources", "ACTIVE_RESOURCES");
2294 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2295 glw::GLint numActiveResources = -1;
2296 const int numExpectedActiveResources = 2; // 2 buffer bindings
2298 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying ACTIVE_RESOURCES, expecting " << numExpectedActiveResources << tcu::TestLog::EndMessage;
2300 gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &numActiveResources);
2301 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_ACTIVE_RESOURCES");
2303 m_testCtx.getLog() << tcu::TestLog::Message << "ACTIVE_RESOURCES = " << numActiveResources << tcu::TestLog::EndMessage;
2305 if (numActiveResources != numExpectedActiveResources)
2307 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected ACTIVE_RESOURCES" << tcu::TestLog::EndMessage;
2308 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected ACTIVE_RESOURCES");
2311 m_testCtx.getLog() << tcu::TestLog::Message << "ACTIVE_RESOURCES valid" << tcu::TestLog::EndMessage;
2317 class AtomicCounterActiveVariablesCase : public AtomicCounterCase
2320 AtomicCounterActiveVariablesCase (Context& context, const char* name, const char* description);
2323 IterateResult iterate (void);
2326 AtomicCounterActiveVariablesCase::AtomicCounterActiveVariablesCase (Context& context, const char* name, const char* description)
2327 : AtomicCounterCase(context, name, description)
2331 AtomicCounterActiveVariablesCase::IterateResult AtomicCounterActiveVariablesCase::iterate (void)
2333 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2334 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2335 const int numAtomicBuffers = getNumAtomicCounterBuffers();
2336 const int expectedMaxNumActiveVariables = getMaxNumActiveVariables();
2338 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2339 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2341 // check active variables
2343 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Interface", "ATOMIC_COUNTER_BUFFER interface");
2344 glw::GLint queryActiveResources = -1;
2345 glw::GLint queryMaxNumActiveVariables = -1;
2347 gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &queryActiveResources);
2348 gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, &queryMaxNumActiveVariables);
2349 GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
2352 << tcu::TestLog::Message
2353 << "GL_ACTIVE_RESOURCES = " << queryActiveResources << "\n"
2354 << "GL_MAX_NUM_ACTIVE_VARIABLES = " << queryMaxNumActiveVariables << "\n"
2355 << tcu::TestLog::EndMessage;
2357 if (queryActiveResources != numAtomicBuffers)
2359 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected GL_ACTIVE_RESOURCES, expected " << numAtomicBuffers << tcu::TestLog::EndMessage;
2360 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected GL_ACTIVE_RESOURCES");
2363 if (queryMaxNumActiveVariables != expectedMaxNumActiveVariables)
2365 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected GL_MAX_NUM_ACTIVE_VARIABLES, expected " << expectedMaxNumActiveVariables << tcu::TestLog::EndMessage;
2366 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected GL_MAX_NUM_ACTIVE_VARIABLES");
2370 // Check each buffer
2371 for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2373 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
2374 std::vector<glw::GLint> activeVariables;
2375 std::vector<std::string> memberNames;
2377 // Find active variables
2379 const glw::GLenum numActiveVariablesProp = GL_NUM_ACTIVE_VARIABLES;
2380 const glw::GLenum activeVariablesProp = GL_ACTIVE_VARIABLES;
2381 glw::GLint numActiveVariables = -2;
2382 glw::GLint written = -1;
2384 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &numActiveVariablesProp, 1, &written, &numActiveVariables);
2385 GLU_EXPECT_NO_ERROR(gl.getError(), "query num active variables");
2387 if (numActiveVariables <= 0)
2389 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected NUM_ACTIVE_VARIABLES: " << numActiveVariables << tcu::TestLog::EndMessage;
2390 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected NUM_ACTIVE_VARIABLES");
2396 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for NUM_ACTIVE_VARIABLES returned no values" << tcu::TestLog::EndMessage;
2397 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "NUM_ACTIVE_VARIABLES query failed");
2401 m_testCtx.getLog() << tcu::TestLog::Message << "GL_NUM_ACTIVE_VARIABLES = " << numActiveVariables << tcu::TestLog::EndMessage;
2404 activeVariables.resize(numActiveVariables + 1, -2);
2406 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &activeVariablesProp, numActiveVariables, &written, &activeVariables[0]);
2407 GLU_EXPECT_NO_ERROR(gl.getError(), "query active variables");
2409 if (written != numActiveVariables)
2411 m_testCtx.getLog() << tcu::TestLog::Message << "Error, unexpected number of ACTIVE_VARIABLES, NUM_ACTIVE_VARIABLES = " << numActiveVariables << ", query returned " << written << " values" << tcu::TestLog::EndMessage;
2412 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected ACTIVE_VARIABLES");
2416 if (activeVariables.back() != -2)
2418 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for ACTIVE_VARIABLES wrote over target buffer bounds" << tcu::TestLog::EndMessage;
2419 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "ACTIVE_VARIABLES query failed");
2423 activeVariables.pop_back();
2428 tcu::MessageBuilder builder(&m_testCtx.getLog());
2430 builder << "Active variable indices: {";
2431 for (int varNdx = 0; varNdx < (int)activeVariables.size(); ++varNdx)
2435 builder << activeVariables[varNdx];
2437 builder << "}" << tcu::TestLog::EndMessage;
2440 // collect member names
2441 for (int ndx = 0; ndx < (int)activeVariables.size(); ++ndx)
2443 const glw::GLenum nameLengthProp = GL_NAME_LENGTH;
2444 glw::GLint nameLength = -1;
2445 glw::GLint written = -1;
2446 std::vector<char> nameBuf;
2448 gl.getProgramResourceiv(program.getProgram(), GL_UNIFORM, activeVariables[ndx], 1, &nameLengthProp, 1, &written, &nameLength);
2449 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer variable name length");
2451 if (written <= 0 || nameLength == -1)
2453 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for GL_NAME_LENGTH returned no values" << tcu::TestLog::EndMessage;
2454 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GL_NAME_LENGTH query failed");
2458 nameBuf.resize(nameLength + 2, 'X'); // +2 to tolerate potential off-by-ones in some implementations, name queries will check these cases better
2461 gl.getProgramResourceName(program.getProgram(), GL_UNIFORM, activeVariables[ndx], (int)nameBuf.size(), &written, &nameBuf[0]);
2462 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer variable name");
2466 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for resource name returned no name" << tcu::TestLog::EndMessage;
2467 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Name query failed");
2471 memberNames.push_back(std::string(&nameBuf[0], written));
2476 tcu::MessageBuilder builder(&m_testCtx.getLog());
2478 builder << "Active variables:\n";
2479 for (int varNdx = 0; varNdx < (int)memberNames.size(); ++varNdx)
2481 builder << "\t" << memberNames[varNdx] << "\n";
2483 builder << tcu::TestLog::EndMessage;
2486 // check names are all in the same buffer
2488 bool bindingsValid = true;
2490 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying names" << tcu::TestLog::EndMessage;
2492 for (int nameNdx = 0; nameNdx < (int)memberNames.size(); ++nameNdx)
2494 int prevBinding = -1;
2496 for (int varNdx = 0; varNdx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++varNdx)
2498 if (m_program->getShaders()[0]->getDefaultBlock().variables[varNdx].name == memberNames[nameNdx])
2500 const int varBinding = m_program->getShaders()[0]->getDefaultBlock().variables[varNdx].layout.binding;
2502 if (prevBinding == -1 || prevBinding == varBinding)
2503 prevBinding = varBinding;
2505 bindingsValid = false;
2509 if (prevBinding == -1)
2511 m_testCtx.getLog() << tcu::TestLog::Message << "Error, could not find variable with name \"" << memberNames[nameNdx] << "\"" << tcu::TestLog::EndMessage;
2512 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Variable name invalid");
2514 else if (getBufferVariableCount(prevBinding) != (int)memberNames.size())
2517 << tcu::TestLog::Message
2518 << "Error, unexpected variable count for binding " << prevBinding
2519 << ". Expected " << getBufferVariableCount(prevBinding) << ", got " << (int)memberNames.size()
2520 << tcu::TestLog::EndMessage;
2521 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Variable names invalid");
2527 m_testCtx.getLog() << tcu::TestLog::Message << "Error, all resource do not share the same buffer" << tcu::TestLog::EndMessage;
2528 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Active variables invalid");
2537 class AtomicCounterBufferBindingCase : public AtomicCounterCase
2540 AtomicCounterBufferBindingCase (Context& context, const char* name, const char* description);
2543 IterateResult iterate (void);
2546 AtomicCounterBufferBindingCase::AtomicCounterBufferBindingCase (Context& context, const char* name, const char* description)
2547 : AtomicCounterCase(context, name, description)
2551 AtomicCounterBufferBindingCase::IterateResult AtomicCounterBufferBindingCase::iterate (void)
2553 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2554 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2555 const int numAtomicBuffers = getNumAtomicCounterBuffers();
2557 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2558 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2560 // check every buffer
2561 for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2563 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
2564 const glw::GLenum bufferBindingProp = GL_BUFFER_BINDING;
2565 glw::GLint bufferBinding = -1;
2566 glw::GLint written = -1;
2568 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &bufferBindingProp, 1, &written, &bufferBinding);
2569 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2573 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for BUFFER_BINDING returned no values." << tcu::TestLog::EndMessage;
2574 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "BUFFER_BINDING query failed");
2577 m_testCtx.getLog() << tcu::TestLog::Message << "GL_BUFFER_BINDING = " << bufferBinding << tcu::TestLog::EndMessage;
2579 // no such buffer binding?
2580 if (getBufferVariableCount(bufferBinding) == 0)
2582 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_BINDING = " << bufferBinding << ", but such buffer does not exist." << tcu::TestLog::EndMessage;
2583 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2590 class AtomicCounterBufferDataSizeCase : public AtomicCounterCase
2593 AtomicCounterBufferDataSizeCase (Context& context, const char* name, const char* description);
2596 IterateResult iterate (void);
2599 AtomicCounterBufferDataSizeCase::AtomicCounterBufferDataSizeCase (Context& context, const char* name, const char* description)
2600 : AtomicCounterCase(context, name, description)
2604 AtomicCounterBufferDataSizeCase::IterateResult AtomicCounterBufferDataSizeCase::iterate (void)
2606 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2607 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2608 const int numAtomicBuffers = getNumAtomicCounterBuffers();
2610 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2611 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2613 // check every buffer
2614 for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2616 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
2617 const glw::GLenum props[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE };
2618 glw::GLint values[] = { -1, -1 };
2619 glw::GLint written = -1;
2620 int bufferMinDataSize;
2622 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, DE_LENGTH_OF_ARRAY(props), props, DE_LENGTH_OF_ARRAY(values), &written, values);
2623 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2627 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for (BUFFER_BINDING, BUFFER_DATA_SIZE) returned " << written << " value(s)." << tcu::TestLog::EndMessage;
2628 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
2633 << tcu::TestLog::Message
2634 << "GL_BUFFER_BINDING = " << values[0] << "\n"
2635 << "GL_BUFFER_DATA_SIZE = " << values[1]
2636 << tcu::TestLog::EndMessage;
2638 bufferMinDataSize = getBufferMinimumDataSize(values[0]);
2639 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying data size, expected greater than or equal to " << bufferMinDataSize << tcu::TestLog::EndMessage;
2641 // no such buffer binding?
2642 if (bufferMinDataSize == -1)
2644 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_BINDING = " << values[0] << ", but such buffer does not exist." << tcu::TestLog::EndMessage;
2645 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2647 else if (values[1] < bufferMinDataSize)
2649 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;
2650 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2653 m_testCtx.getLog() << tcu::TestLog::Message << "Data size valid" << tcu::TestLog::EndMessage;
2659 class AtomicCounterReferencedByCase : public TestCase
2662 AtomicCounterReferencedByCase (Context& context,
2664 const char* description,
2666 deUint32 presentStagesMask,
2667 deUint32 activeStagesMask);
2668 ~AtomicCounterReferencedByCase (void);
2673 IterateResult iterate (void);
2675 const bool m_separable;
2676 const deUint32 m_presentStagesMask;
2677 const deUint32 m_activeStagesMask;
2678 ProgramInterfaceDefinition::Program* m_program;
2681 AtomicCounterReferencedByCase::AtomicCounterReferencedByCase (Context& context,
2683 const char* description,
2685 deUint32 presentStagesMask,
2686 deUint32 activeStagesMask)
2687 : TestCase (context, name, description)
2688 , m_separable (separable)
2689 , m_presentStagesMask (presentStagesMask)
2690 , m_activeStagesMask (activeStagesMask)
2691 , m_program (DE_NULL)
2693 DE_ASSERT((activeStagesMask & presentStagesMask) == activeStagesMask);
2696 AtomicCounterReferencedByCase::~AtomicCounterReferencedByCase (void)
2701 void AtomicCounterReferencedByCase::init (void)
2703 const deUint32 geometryMask = (1 << glu::SHADERTYPE_GEOMETRY);
2704 const deUint32 tessellationMask = (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION);
2705 glu::VariableDeclaration atomicVar (glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "targetCounter", glu::STORAGE_UNIFORM);
2707 if ((m_presentStagesMask & tessellationMask) != 0 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
2708 throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
2709 if ((m_presentStagesMask & geometryMask) != 0 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
2710 throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
2712 atomicVar.layout.binding = 1;
2714 m_program = new ProgramInterfaceDefinition::Program();
2715 m_program->setSeparable(m_separable);
2717 for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
2719 if (m_activeStagesMask & (1 << shaderType))
2720 m_program->addShader((glu::ShaderType)shaderType, glu::GLSL_VERSION_310_ES)->getDefaultBlock().variables.push_back(atomicVar);
2721 else if (m_presentStagesMask & (1 << shaderType))
2722 m_program->addShader((glu::ShaderType)shaderType, glu::GLSL_VERSION_310_ES);
2725 if (m_program->hasStage(glu::SHADERTYPE_GEOMETRY))
2726 m_program->setGeometryNumOutputVertices(1);
2727 if (m_program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
2728 m_program->setTessellationNumOutputPatchVertices(1);
2730 DE_ASSERT(m_program->isValid());
2733 void AtomicCounterReferencedByCase::deinit (void)
2736 m_program = DE_NULL;
2739 AtomicCounterReferencedByCase::IterateResult AtomicCounterReferencedByCase::iterate (void)
2743 glw::GLenum propName;
2744 glu::ShaderType shaderType;
2745 const char* extension;
2748 { GL_REFERENCED_BY_VERTEX_SHADER, glu::SHADERTYPE_VERTEX, DE_NULL },
2749 { GL_REFERENCED_BY_FRAGMENT_SHADER, glu::SHADERTYPE_FRAGMENT, DE_NULL },
2750 { GL_REFERENCED_BY_COMPUTE_SHADER, glu::SHADERTYPE_COMPUTE, DE_NULL },
2751 { GL_REFERENCED_BY_TESS_CONTROL_SHADER, glu::SHADERTYPE_TESSELLATION_CONTROL, "GL_EXT_tessellation_shader" },
2752 { GL_REFERENCED_BY_TESS_EVALUATION_SHADER, glu::SHADERTYPE_TESSELLATION_EVALUATION, "GL_EXT_tessellation_shader" },
2753 { GL_REFERENCED_BY_GEOMETRY_SHADER, glu::SHADERTYPE_GEOMETRY, "GL_EXT_geometry_shader" },
2756 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2757 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2759 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2760 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2763 for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(targetProps); ++propNdx)
2765 if (targetProps[propNdx].extension == DE_NULL || m_context.getContextInfo().isExtensionSupported(targetProps[propNdx].extension))
2767 const glw::GLenum prop = targetProps[propNdx].propName;
2768 const glw::GLint expected = ((m_activeStagesMask & (1 << targetProps[propNdx].shaderType)) != 0) ? (GL_TRUE) : (GL_FALSE);
2769 glw::GLint value = -1;
2770 glw::GLint written = -1;
2772 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying " << glu::getProgramResourcePropertyName(prop) << ", expecting " << glu::getBooleanName(expected) << tcu::TestLog::EndMessage;
2774 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, 0, 1, &prop, 1, &written, &value);
2775 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2779 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for referenced_by_* returned invalid number of values." << tcu::TestLog::EndMessage;
2780 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
2784 m_testCtx.getLog() << tcu::TestLog::Message << glu::getProgramResourcePropertyName(prop) << " = " << glu::getBooleanStr(value) << tcu::TestLog::EndMessage;
2786 if (value != expected)
2788 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected value" << tcu::TestLog::EndMessage;
2789 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected property value");
2798 class ProgramInputOutputReferencedByCase : public TestCase
2803 CASE_VERTEX_FRAGMENT = 0,
2804 CASE_VERTEX_GEO_FRAGMENT,
2805 CASE_VERTEX_TESS_FRAGMENT,
2806 CASE_VERTEX_TESS_GEO_FRAGMENT,
2808 CASE_SEPARABLE_VERTEX,
2809 CASE_SEPARABLE_FRAGMENT,
2810 CASE_SEPARABLE_GEOMETRY,
2811 CASE_SEPARABLE_TESS_CTRL,
2812 CASE_SEPARABLE_TESS_EVAL,
2816 ProgramInputOutputReferencedByCase (Context& context, const char* name, const char* description, glu::Storage targetStorage, CaseType caseType);
2817 ~ProgramInputOutputReferencedByCase (void);
2822 IterateResult iterate (void);
2824 const CaseType m_caseType;
2825 const glu::Storage m_targetStorage;
2826 ProgramInterfaceDefinition::Program* m_program;
2829 ProgramInputOutputReferencedByCase::ProgramInputOutputReferencedByCase (Context& context, const char* name, const char* description, glu::Storage targetStorage, CaseType caseType)
2830 : TestCase (context, name, description)
2831 , m_caseType (caseType)
2832 , m_targetStorage (targetStorage)
2833 , m_program (DE_NULL)
2835 DE_ASSERT(caseType < CASE_LAST);
2838 ProgramInputOutputReferencedByCase::~ProgramInputOutputReferencedByCase (void)
2843 void ProgramInputOutputReferencedByCase::init (void)
2845 const bool hasTessellationShader = (m_caseType == CASE_VERTEX_TESS_FRAGMENT) ||
2846 (m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT) ||
2847 (m_caseType == CASE_SEPARABLE_TESS_CTRL) ||
2848 (m_caseType == CASE_SEPARABLE_TESS_EVAL);
2849 const bool hasGeometryShader = (m_caseType == CASE_VERTEX_GEO_FRAGMENT) ||
2850 (m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT) ||
2851 (m_caseType == CASE_SEPARABLE_GEOMETRY);
2853 if (hasTessellationShader && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
2854 throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
2855 if (hasGeometryShader && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
2856 throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
2858 m_program = new ProgramInterfaceDefinition::Program();
2860 if (m_caseType == CASE_SEPARABLE_VERTEX ||
2861 m_caseType == CASE_SEPARABLE_FRAGMENT ||
2862 m_caseType == CASE_SEPARABLE_GEOMETRY ||
2863 m_caseType == CASE_SEPARABLE_TESS_CTRL ||
2864 m_caseType == CASE_SEPARABLE_TESS_EVAL)
2866 const bool isInputCase = (m_targetStorage == glu::STORAGE_IN || m_targetStorage == glu::STORAGE_PATCH_IN);
2867 const bool perPatchStorage = (m_targetStorage == glu::STORAGE_PATCH_IN || m_targetStorage == glu::STORAGE_PATCH_OUT);
2868 const char* varName = (isInputCase) ? ("shaderInput") : ("shaderOutput");
2869 const glu::VariableDeclaration targetDecl (glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), varName, m_targetStorage);
2870 const glu::ShaderType shaderType = (m_caseType == CASE_SEPARABLE_VERTEX) ? (glu::SHADERTYPE_VERTEX)
2871 : (m_caseType == CASE_SEPARABLE_FRAGMENT) ? (glu::SHADERTYPE_FRAGMENT)
2872 : (m_caseType == CASE_SEPARABLE_GEOMETRY) ? (glu::SHADERTYPE_GEOMETRY)
2873 : (m_caseType == CASE_SEPARABLE_TESS_CTRL) ? (glu::SHADERTYPE_TESSELLATION_CONTROL)
2874 : (m_caseType == CASE_SEPARABLE_TESS_EVAL) ? (glu::SHADERTYPE_TESSELLATION_EVALUATION)
2875 : (glu::SHADERTYPE_LAST);
2876 const bool arrayedInterface = (isInputCase) ? ((shaderType == glu::SHADERTYPE_GEOMETRY) ||
2877 (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL) ||
2878 (shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION))
2879 : (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL);
2881 m_program->setSeparable(true);
2883 if (arrayedInterface && !perPatchStorage)
2885 const glu::VariableDeclaration targetDeclArr(glu::VarType(targetDecl.varType, glu::VarType::UNSIZED_ARRAY), varName, m_targetStorage);
2886 m_program->addShader(shaderType, glu::GLSL_VERSION_310_ES)->getDefaultBlock().variables.push_back(targetDeclArr);
2890 m_program->addShader(shaderType, glu::GLSL_VERSION_310_ES)->getDefaultBlock().variables.push_back(targetDecl);
2893 else if (m_caseType == CASE_VERTEX_FRAGMENT ||
2894 m_caseType == CASE_VERTEX_GEO_FRAGMENT ||
2895 m_caseType == CASE_VERTEX_TESS_FRAGMENT ||
2896 m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
2898 ProgramInterfaceDefinition::Shader* vertex = m_program->addShader(glu::SHADERTYPE_VERTEX, glu::GLSL_VERSION_310_ES);
2899 ProgramInterfaceDefinition::Shader* fragment = m_program->addShader(glu::SHADERTYPE_FRAGMENT, glu::GLSL_VERSION_310_ES);
2901 m_program->setSeparable(false);
2903 vertex->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2906 vertex->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2909 glu::INTERPOLATION_LAST,
2912 fragment->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2915 glu::INTERPOLATION_LAST,
2917 fragment->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2920 glu::INTERPOLATION_LAST,
2923 if (m_caseType == CASE_VERTEX_TESS_FRAGMENT || m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
2925 ProgramInterfaceDefinition::Shader* tessCtrl = m_program->addShader(glu::SHADERTYPE_TESSELLATION_CONTROL, glu::GLSL_VERSION_310_ES);
2926 ProgramInterfaceDefinition::Shader* tessEval = m_program->addShader(glu::SHADERTYPE_TESSELLATION_EVALUATION, glu::GLSL_VERSION_310_ES);
2928 tessCtrl->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2931 glu::INTERPOLATION_LAST,
2933 tessCtrl->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2936 glu::INTERPOLATION_LAST,
2939 tessEval->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2942 glu::INTERPOLATION_LAST,
2944 tessEval->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2947 glu::INTERPOLATION_LAST,
2951 if (m_caseType == CASE_VERTEX_GEO_FRAGMENT || m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
2953 ProgramInterfaceDefinition::Shader* geometry = m_program->addShader(glu::SHADERTYPE_GEOMETRY, glu::GLSL_VERSION_310_ES);
2955 geometry->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2958 glu::INTERPOLATION_LAST,
2960 geometry->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2963 glu::INTERPOLATION_LAST,
2970 if (m_program->hasStage(glu::SHADERTYPE_GEOMETRY))
2971 m_program->setGeometryNumOutputVertices(1);
2972 if (m_program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
2973 m_program->setTessellationNumOutputPatchVertices(1);
2975 DE_ASSERT(m_program->isValid());
2978 void ProgramInputOutputReferencedByCase::deinit (void)
2981 m_program = DE_NULL;
2984 ProgramInputOutputReferencedByCase::IterateResult ProgramInputOutputReferencedByCase::iterate (void)
2988 glw::GLenum propName;
2989 glu::ShaderType shaderType;
2990 const char* extension;
2993 { GL_REFERENCED_BY_VERTEX_SHADER, glu::SHADERTYPE_VERTEX, DE_NULL },
2994 { GL_REFERENCED_BY_FRAGMENT_SHADER, glu::SHADERTYPE_FRAGMENT, DE_NULL },
2995 { GL_REFERENCED_BY_COMPUTE_SHADER, glu::SHADERTYPE_COMPUTE, DE_NULL },
2996 { GL_REFERENCED_BY_TESS_CONTROL_SHADER, glu::SHADERTYPE_TESSELLATION_CONTROL, "GL_EXT_tessellation_shader" },
2997 { GL_REFERENCED_BY_TESS_EVALUATION_SHADER, glu::SHADERTYPE_TESSELLATION_EVALUATION, "GL_EXT_tessellation_shader" },
2998 { GL_REFERENCED_BY_GEOMETRY_SHADER, glu::SHADERTYPE_GEOMETRY, "GL_EXT_geometry_shader" },
3001 const bool isInputCase = (m_targetStorage == glu::STORAGE_IN || m_targetStorage == glu::STORAGE_PATCH_IN);
3002 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3003 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
3004 const std::string targetResourceName = (isInputCase) ? ("shaderInput") : ("shaderOutput");
3005 const glw::GLenum programGLInterface = (isInputCase) ? (GL_PROGRAM_INPUT) : (GL_PROGRAM_OUTPUT);
3006 glw::GLuint resourceIndex;
3008 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3009 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
3011 // find target resource index
3013 resourceIndex = gl.getProgramResourceIndex(program.getProgram(), programGLInterface, targetResourceName.c_str());
3014 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
3016 if (resourceIndex == GL_INVALID_INDEX)
3018 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for resource \"" << targetResourceName << "\" index returned invalid index." << tcu::TestLog::EndMessage;
3019 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "could not find target resource");
3024 for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(targetProps); ++propNdx)
3026 if (targetProps[propNdx].extension == DE_NULL || m_context.getContextInfo().isExtensionSupported(targetProps[propNdx].extension))
3028 const glw::GLenum prop = targetProps[propNdx].propName;
3029 const bool expected = (isInputCase) ? (targetProps[propNdx].shaderType == m_program->getFirstStage()) : (targetProps[propNdx].shaderType == m_program->getLastStage());
3030 glw::GLint value = -1;
3031 glw::GLint written = -1;
3033 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying " << glu::getProgramResourcePropertyName(prop) << ", expecting " << ((expected) ? ("TRUE") : ("FALSE")) << tcu::TestLog::EndMessage;
3035 gl.getProgramResourceiv(program.getProgram(), programGLInterface, resourceIndex, 1, &prop, 1, &written, &value);
3036 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
3040 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for referenced_by_* returned invalid number of values." << tcu::TestLog::EndMessage;
3041 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
3045 m_testCtx.getLog() << tcu::TestLog::Message << glu::getProgramResourcePropertyName(prop) << " = " << glu::getBooleanStr(value) << tcu::TestLog::EndMessage;
3047 if (value != ((expected) ? (GL_TRUE) : (GL_FALSE)))
3049 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected value" << tcu::TestLog::EndMessage;
3050 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected property value");
3059 class FeedbackResourceListTestCase : public ResourceListTestCase
3062 FeedbackResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& resource, const char* name);
3063 ~FeedbackResourceListTestCase (void);
3066 IterateResult iterate (void);
3069 FeedbackResourceListTestCase::FeedbackResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& resource, const char* name)
3070 : ResourceListTestCase(context, resource, PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, name)
3074 FeedbackResourceListTestCase::~FeedbackResourceListTestCase (void)
3079 FeedbackResourceListTestCase::IterateResult FeedbackResourceListTestCase::iterate (void)
3081 const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_programDefinition));
3083 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3085 // Feedback varyings
3087 tcu::MessageBuilder builder(&m_testCtx.getLog());
3088 builder << "Transform feedback varyings: {";
3089 for (int ndx = 0; ndx < (int)m_programDefinition->getTransformFeedbackVaryings().size(); ++ndx)
3093 builder << "\"" << m_programDefinition->getTransformFeedbackVaryings()[ndx] << "\"";
3095 builder << "}" << tcu::TestLog::EndMessage;
3098 checkAndLogProgram(program, m_programDefinition, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
3100 // Check resource list
3102 const tcu::ScopedLogSection section (m_testCtx.getLog(), "ResourceList", "Resource list");
3103 std::vector<std::string> resourceList;
3104 std::vector<std::string> expectedResources;
3106 queryResourceList(resourceList, program.getProgram());
3107 expectedResources = getProgramInterfaceResourceList(m_programDefinition, m_programInterface);
3109 // verify the list and the expected list match
3111 if (!verifyResourceList(resourceList, expectedResources))
3112 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid resource list");
3114 // verify GetProgramResourceIndex() matches the indices of the list
3116 if (!verifyResourceIndexQuery(resourceList, expectedResources, program.getProgram()))
3117 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GetProgramResourceIndex returned unexpected values");
3119 // Verify MAX_NAME_LENGTH
3120 if (!verifyMaxNameLength(resourceList, program.getProgram()))
3121 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "MAX_NAME_LENGTH invalid");
3127 int InterfaceBlockDataSizeTestCase::getBlockMinDataSize (const glu::InterfaceBlock& block) const
3131 for (int ndx = 0; ndx < (int)block.variables.size(); ++ndx)
3132 dataSize += getVarTypeSize(block.variables[ndx].varType);
3137 static bool isDataTypeLayoutQualified (glu::DataType type)
3139 return glu::isDataTypeImage(type) || glu::isDataTypeAtomicCounter(type);
3142 static void generateVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3, bool createTestGroup = true)
3147 glu::DataType dataType;
3150 { 0, glu::TYPE_FLOAT },
3151 { 1, glu::TYPE_INT },
3152 { 1, glu::TYPE_UINT },
3153 { 1, glu::TYPE_BOOL },
3155 { 3, glu::TYPE_FLOAT_VEC2 },
3156 { 1, glu::TYPE_FLOAT_VEC3 },
3157 { 1, glu::TYPE_FLOAT_VEC4 },
3159 { 3, glu::TYPE_INT_VEC2 },
3160 { 2, glu::TYPE_INT_VEC3 },
3161 { 3, glu::TYPE_INT_VEC4 },
3163 { 3, glu::TYPE_UINT_VEC2 },
3164 { 2, glu::TYPE_UINT_VEC3 },
3165 { 3, glu::TYPE_UINT_VEC4 },
3167 { 3, glu::TYPE_BOOL_VEC2 },
3168 { 2, glu::TYPE_BOOL_VEC3 },
3169 { 3, glu::TYPE_BOOL_VEC4 },
3171 { 2, glu::TYPE_FLOAT_MAT2 },
3172 { 3, glu::TYPE_FLOAT_MAT2X3 },
3173 { 3, glu::TYPE_FLOAT_MAT2X4 },
3174 { 2, glu::TYPE_FLOAT_MAT3X2 },
3175 { 2, glu::TYPE_FLOAT_MAT3 },
3176 { 3, glu::TYPE_FLOAT_MAT3X4 },
3177 { 2, glu::TYPE_FLOAT_MAT4X2 },
3178 { 3, glu::TYPE_FLOAT_MAT4X3 },
3179 { 2, glu::TYPE_FLOAT_MAT4 },
3182 tcu::TestCaseGroup* group;
3184 if (createTestGroup)
3186 group = new tcu::TestCaseGroup(context.getTestContext(), "basic_type", "Basic variable");
3187 targetGroup->addChild(group);
3190 group = targetGroup;
3192 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3194 if (variableTypes[ndx].level <= expandLevel)
3196 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
3197 group->addChild(new ResourceTestCase(context, variable, queryTarget));
3202 static void generateOpaqueTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3, bool createTestGroup = true)
3207 glu::DataType dataType;
3210 { 0, glu::TYPE_SAMPLER_2D },
3211 { 2, glu::TYPE_SAMPLER_CUBE },
3212 { 1, glu::TYPE_SAMPLER_2D_ARRAY },
3213 { 1, glu::TYPE_SAMPLER_3D },
3214 { 2, glu::TYPE_SAMPLER_2D_SHADOW },
3215 { 3, glu::TYPE_SAMPLER_CUBE_SHADOW },
3216 { 3, glu::TYPE_SAMPLER_2D_ARRAY_SHADOW },
3217 { 1, glu::TYPE_INT_SAMPLER_2D },
3218 { 3, glu::TYPE_INT_SAMPLER_CUBE },
3219 { 3, glu::TYPE_INT_SAMPLER_2D_ARRAY },
3220 { 3, glu::TYPE_INT_SAMPLER_3D },
3221 { 2, glu::TYPE_UINT_SAMPLER_2D },
3222 { 3, glu::TYPE_UINT_SAMPLER_CUBE },
3223 { 3, glu::TYPE_UINT_SAMPLER_2D_ARRAY },
3224 { 3, glu::TYPE_UINT_SAMPLER_3D },
3225 { 2, glu::TYPE_SAMPLER_2D_MULTISAMPLE },
3226 { 2, glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE },
3227 { 3, glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE },
3228 { 1, glu::TYPE_IMAGE_2D },
3229 { 3, glu::TYPE_IMAGE_CUBE },
3230 { 3, glu::TYPE_IMAGE_2D_ARRAY },
3231 { 3, glu::TYPE_IMAGE_3D },
3232 { 3, glu::TYPE_INT_IMAGE_2D },
3233 { 3, glu::TYPE_INT_IMAGE_CUBE },
3234 { 1, glu::TYPE_INT_IMAGE_2D_ARRAY },
3235 { 3, glu::TYPE_INT_IMAGE_3D },
3236 { 2, glu::TYPE_UINT_IMAGE_2D },
3237 { 3, glu::TYPE_UINT_IMAGE_CUBE },
3238 { 3, glu::TYPE_UINT_IMAGE_2D_ARRAY },
3239 { 3, glu::TYPE_UINT_IMAGE_3D },
3240 { 1, glu::TYPE_UINT_ATOMIC_COUNTER },
3243 bool isStructMember = false;
3246 for (const ResourceDefinition::Node* node = parentStructure.get(); node; node = node->getEnclosingNode())
3248 // Don't insert inside a interface block
3249 if (node->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3252 isStructMember |= (node->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER);
3257 tcu::TestCaseGroup* group;
3259 if (createTestGroup)
3261 group = new tcu::TestCaseGroup(context.getTestContext(), "opaque_type", "Opaque types");
3262 targetGroup->addChild(group);
3265 group = targetGroup;
3267 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3269 if (variableTypes[ndx].level > expandLevel)
3272 // Layout qualifiers are not allowed on struct members
3273 if (isDataTypeLayoutQualified(variableTypes[ndx].dataType) && isStructMember)
3277 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
3278 group->addChild(new ResourceTestCase(context, variable, queryTarget));
3284 static void generateCompoundVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3);
3286 static void generateVariableArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3)
3288 if (expandLevel > 0)
3290 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3291 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3293 targetGroup->addChild(blockGroup);
3295 // Arrays of basic variables
3296 generateVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3298 // Arrays of opaque types
3299 generateOpaqueTypeCases(context, arrayElement, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3302 generateVariableArrayCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3304 // Arrays of structs
3305 generateCompoundVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3309 static void generateCompoundVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
3311 if (expandLevel > 0)
3313 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3314 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "struct", "Structs");
3316 targetGroup->addChild(blockGroup);
3318 // Struct containing basic variable
3319 generateVariableCases(context, structMember, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3321 // Struct containing opaque types
3322 generateOpaqueTypeCases(context, structMember, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3324 // Struct containing arrays
3325 generateVariableArrayCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3327 // Struct containing struct
3328 generateCompoundVariableCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3332 // Resource list cases
3336 BLOCKFLAG_DEFAULT = 0x01,
3337 BLOCKFLAG_NAMED = 0x02,
3338 BLOCKFLAG_UNNAMED = 0x04,
3339 BLOCKFLAG_ARRAY = 0x08,
3341 BLOCKFLAG_ALL = 0x0F
3344 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))
3346 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
3347 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
3350 if (blockFlags & BLOCKFLAG_DEFAULT)
3352 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "default_block", "Default block");
3353 targetGroup->addChild(blockGroup);
3355 blockContentGenerator(context, uniform, blockGroup);
3359 if (blockFlags & BLOCKFLAG_NAMED)
3361 const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(uniform, true));
3363 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "named_block", "Named uniform block");
3364 targetGroup->addChild(blockGroup);
3366 blockContentGenerator(context, block, blockGroup);
3370 if (blockFlags & BLOCKFLAG_UNNAMED)
3372 const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(uniform, false));
3374 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "unnamed_block", "Unnamed uniform block");
3375 targetGroup->addChild(blockGroup);
3377 blockContentGenerator(context, block, blockGroup);
3381 if (blockFlags & BLOCKFLAG_ARRAY)
3383 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(uniform));
3384 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
3386 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "block_array", "Uniform block array");
3387 targetGroup->addChild(blockGroup);
3389 blockContentGenerator(context, block, blockGroup);
3393 static void generateBufferBackedResourceListBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, int depth)
3397 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, glu::TYPE_FLOAT_VEC4));
3398 targetGroup->addChild(new ResourceListTestCase(context, variable, interface));
3404 const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
3405 generateBufferBackedResourceListBlockContentCases(context, structMember, targetGroup, interface, depth - 1);
3411 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
3412 generateBufferBackedResourceListBlockContentCases(context, arrayElement, targetGroup, interface, depth - 1);
3416 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)
3420 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, dataType));
3421 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, targetProp), ("var" + nameSuffix).c_str()));
3427 const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
3428 generateBufferBackedVariableAggregateTypeCases(context, structMember, targetGroup, interface, targetProp, dataType, "_struct" + nameSuffix, depth - 1);
3434 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
3435 generateBufferBackedVariableAggregateTypeCases(context, arrayElement, targetGroup, interface, targetProp, dataType, "_array" + nameSuffix, depth - 1);
3439 static void generateUniformResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3441 generateBufferBackedResourceListBlockContentCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, 4);
3444 static void generateUniformBlockArraySizeContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3446 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ARRAY_SIZE);
3447 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3448 const bool namedNonArrayBlock = isInterfaceBlock &&
3449 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3450 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3452 if (!isInterfaceBlock || namedNonArrayBlock)
3456 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3457 targetGroup->addChild(blockGroup);
3459 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3460 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3465 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3466 targetGroup->addChild(blockGroup);
3468 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_ARRAY_SIZE, glu::TYPE_FLOAT, "", 3);
3474 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, queryTarget.interface, PROGRAMRESOURCEPROP_ARRAY_SIZE, glu::TYPE_FLOAT, "", 2);
3478 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)
3482 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, type));
3483 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_ARRAY_STRIDE), namePrefix.c_str()));
3486 if (expandLevel > 0)
3488 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3489 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3492 generateBufferBackedArrayStrideTypeAggregateSubCases(context, structMember, targetGroup, namePrefix + "_struct", interface, type, expandLevel - 1);
3495 generateBufferBackedArrayStrideTypeAggregateSubCases(context, arrayElement, targetGroup, namePrefix + "_array", interface, type, expandLevel - 1);
3499 static void generateBufferBackedArrayStrideTypeAggregateCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, glu::DataType type, int expandLevel, bool includeBaseCase)
3501 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3502 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3503 const std::string namePrefix = glu::getDataTypeName(type);
3505 if (expandLevel == 0 || includeBaseCase)
3507 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, type));
3508 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_ARRAY_STRIDE), namePrefix.c_str()));
3510 if (expandLevel >= 1)
3513 if (!glu::isDataTypeAtomicCounter(type))
3514 generateBufferBackedArrayStrideTypeAggregateSubCases(context, structMember, targetGroup, namePrefix + "_struct", interface, type, expandLevel - 1);
3517 generateBufferBackedArrayStrideTypeAggregateSubCases(context, arrayElement, targetGroup, namePrefix + "_array", interface, type, expandLevel - 1);
3521 static void generateUniformBlockArrayStrideContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3523 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ARRAY_STRIDE);
3524 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3525 const bool namedNonArrayBlock = isInterfaceBlock &&
3526 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3527 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3529 if (!isInterfaceBlock || namedNonArrayBlock)
3533 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3534 targetGroup->addChild(blockGroup);
3536 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3537 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3542 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3543 targetGroup->addChild(blockGroup);
3546 if (!isInterfaceBlock)
3547 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_SAMPLER_2D, 1, false);
3549 // .atomic_counter_*
3550 if (!isInterfaceBlock)
3552 const ResourceDefinition::Node::SharedPtr layout(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
3553 generateBufferBackedArrayStrideTypeAggregateCases(context, layout, blockGroup, queryTarget.interface, glu::TYPE_UINT_ATOMIC_COUNTER, 1, false);
3557 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_FLOAT, 2, false);
3560 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_BOOL, 1, false);
3563 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_BOOL_VEC3, 2, false);
3566 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_FLOAT_VEC3, 2, false);
3569 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_INT_VEC3, 2, false);
3574 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3575 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3576 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3580 static void generateUniformBlockLocationContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3582 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_LOCATION);
3583 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3585 if (!isInterfaceBlock)
3587 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 3);
3588 generateOpaqueTypeCases(context, parentStructure, targetGroup, queryTarget, 3);
3589 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 2);
3590 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 2);
3593 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1, false);
3596 static void generateUniformBlockBlockIndexContents (Context& context, tcu::TestCaseGroup* const targetGroup)
3598 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
3599 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
3600 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
3601 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
3602 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(uniform, glu::Layout(-1, 0)));
3606 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(uniform, glu::TYPE_FLOAT_VEC4));
3608 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "default_block"));
3613 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, true));
3614 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3616 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "named_block"));
3621 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, false));
3622 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3624 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "unnamed_block"));
3629 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding));
3630 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
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), "block_array"));
3637 static void generateUniformBlockAtomicCounterBufferIndexContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3639 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ATOMIC_COUNTER_BUFFER_INDEX);
3640 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3642 if (!isInterfaceBlock)
3644 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 3);
3645 generateOpaqueTypeCases(context, parentStructure, targetGroup, queryTarget, 3);
3649 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3650 const ResourceDefinition::Node::SharedPtr arrayArrayElement (new ResourceDefinition::ArrayElement(arrayElement));
3651 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3652 const ResourceDefinition::Node::SharedPtr elementvariable (new ResourceDefinition::Variable(arrayArrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3653 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3655 targetGroup->addChild(blockGroup);
3657 blockGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "var_array"));
3658 blockGroup->addChild(new ResourceTestCase(context, elementvariable, queryTarget, "var_array_array"));
3662 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1, false);
3665 static void generateUniformBlockNameLengthContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3667 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3668 const bool namedNonArrayBlock = isInterfaceBlock &&
3669 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3670 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3672 if (!isInterfaceBlock || namedNonArrayBlock)
3673 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 2);
3675 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 1);
3678 static void generateUniformBlockTypeContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3680 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_TYPE);
3681 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3682 const bool namedNonArrayBlock = isInterfaceBlock &&
3683 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3684 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3686 if (!isInterfaceBlock || namedNonArrayBlock)
3690 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3691 targetGroup->addChild(blockGroup);
3693 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3694 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3697 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3698 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3703 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3704 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3705 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3709 static void generateUniformBlockOffsetContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3711 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_OFFSET);
3712 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3713 const bool namedNonArrayBlock = isInterfaceBlock &&
3714 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3715 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3717 if (!isInterfaceBlock)
3721 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3722 targetGroup->addChild(blockGroup);
3724 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3725 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3730 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3731 targetGroup->addChild(blockGroup);
3733 // .atomic_uint_struct
3734 // .atomic_uint_array
3736 const ResourceDefinition::Node::SharedPtr offset (new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, 4)));
3737 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(offset));
3738 const ResourceDefinition::Node::SharedPtr elementVariable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3740 blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "atomic_uint_array"));
3746 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3747 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3748 const ResourceDefinition::Node::SharedPtr memberVariable (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
3749 const ResourceDefinition::Node::SharedPtr elementVariable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
3751 blockGroup->addChild(new ResourceTestCase(context, memberVariable, queryTarget, "float_struct"));
3752 blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "float_array"));
3756 else if (namedNonArrayBlock)
3760 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3761 targetGroup->addChild(blockGroup);
3763 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3764 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3769 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3770 targetGroup->addChild(blockGroup);
3775 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3776 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::StructMember(parentStructure));
3777 const ResourceDefinition::Node::SharedPtr memberVariable (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
3778 const ResourceDefinition::Node::SharedPtr elementVariable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
3780 blockGroup->addChild(new ResourceTestCase(context, memberVariable, queryTarget, "float_struct"));
3781 blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "float_array"));
3787 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3788 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3789 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3793 static void generateMatrixVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, bool createTestGroup = true, int expandLevel = 2)
3801 { 0, glu::TYPE_FLOAT_MAT2 },
3802 { 1, glu::TYPE_FLOAT_MAT2X3 },
3803 { 2, glu::TYPE_FLOAT_MAT2X4 },
3804 { 2, glu::TYPE_FLOAT_MAT3X2 },
3805 { 1, glu::TYPE_FLOAT_MAT3 },
3806 { 0, glu::TYPE_FLOAT_MAT3X4 },
3807 { 2, glu::TYPE_FLOAT_MAT4X2 },
3808 { 1, glu::TYPE_FLOAT_MAT4X3 },
3809 { 0, glu::TYPE_FLOAT_MAT4 },
3812 tcu::TestCaseGroup* group;
3814 if (createTestGroup)
3816 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "matrix", "Basic matrix type");
3817 targetGroup->addChild(blockGroup);
3821 group = targetGroup;
3823 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3825 if (variableTypes[ndx].priority < expandLevel)
3827 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
3828 group->addChild(new ResourceTestCase(context, variable, queryTarget));
3833 static void generateMatrixStructCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel);
3835 static void generateMatrixArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
3837 if (expandLevel > 0)
3839 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3840 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3842 targetGroup->addChild(blockGroup);
3844 // Arrays of basic variables
3845 generateMatrixVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel != 1, expandLevel);
3848 generateMatrixArrayCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3850 // Arrays of structs
3851 generateMatrixStructCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3855 static void generateMatrixStructCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
3857 if (expandLevel > 0)
3859 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3860 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "struct", "Structs");
3862 targetGroup->addChild(blockGroup);
3864 // Struct containing basic variable
3865 generateMatrixVariableCases(context, structMember, blockGroup, queryTarget, expandLevel != 1, expandLevel);
3867 // Struct containing arrays
3868 generateMatrixArrayCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3870 // Struct containing struct
3871 generateMatrixStructCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3875 static void generateUniformMatrixOrderCaseBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, bool extendedBasicTypeCases, bool opaqueCases)
3880 glu::MatrixOrder order;
3883 { "no_qualifier", glu::MATRIXORDER_LAST },
3884 { "row_major", glu::MATRIXORDER_ROW_MAJOR },
3885 { "column_major", glu::MATRIXORDER_COLUMN_MAJOR },
3888 const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR);
3890 for (int qualifierNdx = 0; qualifierNdx < DE_LENGTH_OF_ARRAY(qualifiers); ++qualifierNdx)
3892 // Add layout qualifiers only for block members
3893 if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST || parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3895 ResourceDefinition::Node::SharedPtr subStructure = parentStructure;
3896 tcu::TestCaseGroup* const qualifierGroup = new tcu::TestCaseGroup(context.getTestContext(), qualifiers[qualifierNdx].name, "");
3898 targetGroup->addChild(qualifierGroup);
3900 if (qualifiers[qualifierNdx].order != glu::MATRIXORDER_LAST)
3903 layout.matrixOrder = qualifiers[qualifierNdx].order;
3904 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
3907 if (extendedBasicTypeCases && qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST)
3911 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "");
3912 qualifierGroup->addChild(blockGroup);
3914 generateVariableCases(context, subStructure, blockGroup, queryTarget, 1, false);
3915 generateMatrixVariableCases(context, subStructure, blockGroup, queryTarget, false);
3917 generateOpaqueTypeCases(context, subStructure, blockGroup, queryTarget, 2, false);
3922 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "");
3923 qualifierGroup->addChild(blockGroup);
3925 generateBufferBackedVariableAggregateTypeCases(context, subStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
3930 generateBufferBackedVariableAggregateTypeCases(context, subStructure, qualifierGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
3936 static void generateUniformMatrixStrideCaseBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, bool extendedBasicTypeCases, bool opaqueCases)
3941 glu::MatrixOrder order;
3944 { "no_qualifier", glu::MATRIXORDER_LAST },
3945 { "row_major", glu::MATRIXORDER_ROW_MAJOR },
3946 { "column_major", glu::MATRIXORDER_COLUMN_MAJOR },
3949 const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_MATRIX_STRIDE);
3951 for (int qualifierNdx = 0; qualifierNdx < DE_LENGTH_OF_ARRAY(qualifiers); ++qualifierNdx)
3953 // Add layout qualifiers only for block members
3954 if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST || parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3956 ResourceDefinition::Node::SharedPtr subStructure = parentStructure;
3957 tcu::TestCaseGroup* const qualifierGroup = new tcu::TestCaseGroup(context.getTestContext(), qualifiers[qualifierNdx].name, "");
3959 targetGroup->addChild(qualifierGroup);
3961 if (qualifiers[qualifierNdx].order != glu::MATRIXORDER_LAST)
3964 layout.matrixOrder = qualifiers[qualifierNdx].order;
3965 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
3968 if (extendedBasicTypeCases)
3972 if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST)
3974 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "");
3975 qualifierGroup->addChild(blockGroup);
3977 generateVariableCases(context, subStructure, blockGroup, queryTarget, 1, false);
3978 generateMatrixVariableCases(context, subStructure, blockGroup, queryTarget, false);
3980 generateOpaqueTypeCases(context, subStructure, blockGroup, queryTarget, 2, false);
3983 generateMatrixVariableCases(context, subStructure, qualifierGroup, queryTarget);
3987 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "");
3988 qualifierGroup->addChild(blockGroup);
3990 generateBufferBackedVariableAggregateTypeCases(context, subStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
3994 generateBufferBackedVariableAggregateTypeCases(context, subStructure, qualifierGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
3999 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))
4004 const char* description;
4007 bool extendedBasicTypeCases;
4008 glu::MatrixOrder order;
4011 { "default_block", "Default block", false, true, true, glu::MATRIXORDER_LAST },
4012 { "named_block", "Named uniform block", true, true, true, glu::MATRIXORDER_LAST },
4013 { "named_block_row_major", "Named uniform block", true, true, false, glu::MATRIXORDER_ROW_MAJOR },
4014 { "named_block_col_major", "Named uniform block", true, true, false, glu::MATRIXORDER_COLUMN_MAJOR },
4015 { "unnamed_block", "Unnamed uniform block", true, false, false, glu::MATRIXORDER_LAST },
4016 { "unnamed_block_row_major", "Unnamed uniform block", true, false, false, glu::MATRIXORDER_ROW_MAJOR },
4017 { "unnamed_block_col_major", "Unnamed uniform block", true, false, false, glu::MATRIXORDER_COLUMN_MAJOR },
4020 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
4021 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4023 for (int childNdx = 0; childNdx < (int)DE_LENGTH_OF_ARRAY(children); ++childNdx)
4025 ResourceDefinition::Node::SharedPtr subStructure = uniform;
4026 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), children[childNdx].name, children[childNdx].description);
4027 const bool addOpaqueCases = children[childNdx].extendedBasicTypeCases && !children[childNdx].block;
4029 targetGroup->addChild(blockGroup);
4031 if (children[childNdx].order != glu::MATRIXORDER_LAST)
4034 layout.matrixOrder = children[childNdx].order;
4035 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
4038 if (children[childNdx].block)
4039 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(subStructure, children[childNdx].namedBlock));
4041 blockContentGenerator(context, subStructure, blockGroup, children[childNdx].extendedBasicTypeCases, addOpaqueCases);
4045 static void generateBufferReferencedByShaderInterfaceBlockCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, bool extendedCases)
4047 const bool isDefaultBlock = (parentStructure->getType() != ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
4053 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(parentStructure, glu::TYPE_FLOAT));
4054 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
4055 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4056 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4057 const ResourceDefinition::Node::SharedPtr variableStruct (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
4059 targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "float"));
4060 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_array"));
4061 targetGroup->addChild(new ResourceTestCase(context, variableStruct, queryTarget, "float_struct"));
4069 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
4070 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_SAMPLER_2D));
4071 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(layout));
4072 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4073 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_SAMPLER_2D));
4074 const ResourceDefinition::Node::SharedPtr variableStruct (new ResourceDefinition::Variable(structMember, glu::TYPE_SAMPLER_2D));
4076 targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "sampler"));
4077 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "sampler_array"));
4078 targetGroup->addChild(new ResourceTestCase(context, variableStruct, queryTarget, "sampler_struct"));
4082 // .atomic_uint_array
4085 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
4086 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_UINT_ATOMIC_COUNTER));
4087 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(layout));
4088 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
4090 targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "atomic_uint"));
4091 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "atomic_uint_array"));
4096 // .float_array_struct
4098 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4099 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(structMember));
4100 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4102 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_array_struct"));
4105 // .float_struct_array
4107 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
4108 const ResourceDefinition::Node::SharedPtr arrayStructMember (new ResourceDefinition::StructMember(arrayElement));
4109 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(arrayStructMember, glu::TYPE_FLOAT));
4111 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_struct_array"));
4114 // .float_array_array
4116 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
4117 const ResourceDefinition::Node::SharedPtr subArrayElement (new ResourceDefinition::ArrayElement(arrayElement));
4118 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(subArrayElement, glu::TYPE_FLOAT));
4120 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_array_array"));
4123 // .float_struct_struct
4125 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4126 const ResourceDefinition::Node::SharedPtr subStructMember (new ResourceDefinition::StructMember(structMember));
4127 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(subStructMember, glu::TYPE_FLOAT));
4129 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_struct_struct"));
4132 if (queryTarget.interface == PROGRAMINTERFACE_BUFFER_VARIABLE)
4134 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
4136 // .float_unsized_array
4138 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4140 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_unsized_array"));
4143 // .float_unsized_struct_array
4145 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(arrayElement));
4146 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
4148 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_unsized_struct_array"));
4154 static void generateUniformReferencedByShaderSingleBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, int expandLevel)
4156 DE_UNREF(expandLevel);
4158 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
4159 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4160 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER);
4161 const bool singleShaderCase = parentStructure->getType() == ResourceDefinition::Node::TYPE_SHADER;
4165 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "default_block", "");
4166 targetGroup->addChild(blockGroup);
4168 generateBufferReferencedByShaderInterfaceBlockCases(context, uniform, blockGroup, queryTarget, singleShaderCase);
4173 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(uniform, true));
4174 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "uniform_block", "");
4176 targetGroup->addChild(blockGroup);
4178 generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, singleShaderCase);
4183 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(uniform, false));
4184 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "");
4186 targetGroup->addChild(blockGroup);
4188 generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, false);
4193 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(uniform));
4194 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4195 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "");
4197 targetGroup->addChild(blockGroup);
4199 generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, false);
4203 static void generateReferencedByShaderCaseBlocks (Context& context, tcu::TestCaseGroup* const targetGroup, void (*generateBlockContent)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, int expandLevel))
4208 glu::ShaderType stage;
4210 } singleStageCases[] =
4212 { "compute", glu::SHADERTYPE_COMPUTE, 3 },
4213 { "separable_vertex", glu::SHADERTYPE_VERTEX, 2 },
4214 { "separable_fragment", glu::SHADERTYPE_FRAGMENT, 2 },
4215 { "separable_tess_ctrl", glu::SHADERTYPE_TESSELLATION_CONTROL, 2 },
4216 { "separable_tess_eval", glu::SHADERTYPE_TESSELLATION_EVALUATION, 2 },
4217 { "separable_geometry", glu::SHADERTYPE_GEOMETRY, 2 },
4229 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT),
4234 "vertex_tess_fragment",
4235 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
4240 "vertex_geo_fragment",
4241 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY),
4246 "vertex_tess_geo_fragment",
4247 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
4253 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
4255 TestCaseGroup* const blockGroup = new TestCaseGroup(context, singleStageCases[ndx].name, "");
4256 const bool programSeparable = (singleStageCases[ndx].stage != glu::SHADERTYPE_COMPUTE);
4257 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(programSeparable));
4258 const ResourceDefinition::Node::SharedPtr stage (new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glu::GLSL_VERSION_310_ES));
4260 targetGroup->addChild(blockGroup);
4262 generateBlockContent(context, stage, blockGroup, singleStageCases[ndx].expandLevel);
4265 for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
4269 TestCaseGroup* const blockGroup = new TestCaseGroup(context, pipelines[pipelineNdx].name, "");
4270 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4271 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program,
4272 glu::GLSL_VERSION_310_ES,
4273 pipelines[pipelineNdx].flags,
4274 pipelines[pipelineNdx].flags);
4275 targetGroup->addChild(blockGroup);
4278 const ResourceDefinition::Node::SharedPtr shaders(shaderSet);
4279 generateBlockContent(context, shaders, blockGroup, pipelines[pipelineNdx].expandLevel);
4284 for (int selectedStageBit = 0; selectedStageBit < glu::SHADERTYPE_LAST; ++selectedStageBit)
4286 if (pipelines[pipelineNdx].flags & (1 << selectedStageBit))
4288 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4289 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program,
4290 glu::GLSL_VERSION_310_ES,
4291 pipelines[pipelineNdx].flags,
4292 (1u << selectedStageBit));
4293 const char* stageName = (selectedStageBit == glu::SHADERTYPE_VERTEX) ? ("vertex")
4294 : (selectedStageBit == glu::SHADERTYPE_FRAGMENT) ? ("fragment")
4295 : (selectedStageBit == glu::SHADERTYPE_GEOMETRY) ? ("geo")
4296 : (selectedStageBit == glu::SHADERTYPE_TESSELLATION_CONTROL) ? ("tess_ctrl")
4297 : (selectedStageBit == glu::SHADERTYPE_TESSELLATION_EVALUATION) ? ("tess_eval")
4299 const std::string setName = std::string() + pipelines[pipelineNdx].name + "_only_" + stageName;
4300 TestCaseGroup* const blockGroup = new TestCaseGroup(context, setName.c_str(), "");
4301 const ResourceDefinition::Node::SharedPtr shaders (shaderSet);
4303 generateBlockContent(context, shaders, blockGroup, pipelines[pipelineNdx].subExpandLevel);
4304 targetGroup->addChild(blockGroup);
4310 static glu::DataType generateRandomDataType (de::Random& rnd, bool excludeOpaqueTypes)
4312 static const glu::DataType s_types[] =
4318 glu::TYPE_FLOAT_VEC2,
4319 glu::TYPE_FLOAT_VEC3,
4320 glu::TYPE_FLOAT_VEC4,
4324 glu::TYPE_UINT_VEC2,
4325 glu::TYPE_UINT_VEC3,
4326 glu::TYPE_UINT_VEC4,
4327 glu::TYPE_BOOL_VEC2,
4328 glu::TYPE_BOOL_VEC3,
4329 glu::TYPE_BOOL_VEC4,
4330 glu::TYPE_FLOAT_MAT2,
4331 glu::TYPE_FLOAT_MAT2X3,
4332 glu::TYPE_FLOAT_MAT2X4,
4333 glu::TYPE_FLOAT_MAT3X2,
4334 glu::TYPE_FLOAT_MAT3,
4335 glu::TYPE_FLOAT_MAT3X4,
4336 glu::TYPE_FLOAT_MAT4X2,
4337 glu::TYPE_FLOAT_MAT4X3,
4338 glu::TYPE_FLOAT_MAT4,
4340 glu::TYPE_SAMPLER_2D,
4341 glu::TYPE_SAMPLER_CUBE,
4342 glu::TYPE_SAMPLER_2D_ARRAY,
4343 glu::TYPE_SAMPLER_3D,
4344 glu::TYPE_SAMPLER_2D_SHADOW,
4345 glu::TYPE_SAMPLER_CUBE_SHADOW,
4346 glu::TYPE_SAMPLER_2D_ARRAY_SHADOW,
4347 glu::TYPE_INT_SAMPLER_2D,
4348 glu::TYPE_INT_SAMPLER_CUBE,
4349 glu::TYPE_INT_SAMPLER_2D_ARRAY,
4350 glu::TYPE_INT_SAMPLER_3D,
4351 glu::TYPE_UINT_SAMPLER_2D,
4352 glu::TYPE_UINT_SAMPLER_CUBE,
4353 glu::TYPE_UINT_SAMPLER_2D_ARRAY,
4354 glu::TYPE_UINT_SAMPLER_3D,
4355 glu::TYPE_SAMPLER_2D_MULTISAMPLE,
4356 glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE,
4357 glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE,
4359 glu::TYPE_IMAGE_CUBE,
4360 glu::TYPE_IMAGE_2D_ARRAY,
4362 glu::TYPE_INT_IMAGE_2D,
4363 glu::TYPE_INT_IMAGE_CUBE,
4364 glu::TYPE_INT_IMAGE_2D_ARRAY,
4365 glu::TYPE_INT_IMAGE_3D,
4366 glu::TYPE_UINT_IMAGE_2D,
4367 glu::TYPE_UINT_IMAGE_CUBE,
4368 glu::TYPE_UINT_IMAGE_2D_ARRAY,
4369 glu::TYPE_UINT_IMAGE_3D,
4370 glu::TYPE_UINT_ATOMIC_COUNTER
4375 const glu::DataType type = s_types[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_types)-1)];
4377 if (!excludeOpaqueTypes ||
4378 glu::isDataTypeScalarOrVector(type) ||
4379 glu::isDataTypeMatrix(type))
4384 static ResourceDefinition::Node::SharedPtr generateRandomVariableDefinition (de::Random& rnd,
4385 const ResourceDefinition::Node::SharedPtr& parentStructure,
4386 glu::DataType baseType,
4387 const glu::Layout& layout,
4390 const int maxNesting = 4;
4391 ResourceDefinition::Node::SharedPtr currentStructure = parentStructure;
4392 const bool canBeInsideAStruct = layout.binding == -1 && !isDataTypeLayoutQualified(baseType);
4394 for (int nestNdx = 0; nestNdx < maxNesting; ++nestNdx)
4396 if (allowUnsized && nestNdx == 0 && rnd.getFloat() < 0.2)
4397 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
4398 else if (rnd.getFloat() < 0.3 && canBeInsideAStruct)
4399 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StructMember(currentStructure));
4400 else if (rnd.getFloat() < 0.3)
4401 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
4406 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Variable(currentStructure, baseType));
4409 static ResourceDefinition::Node::SharedPtr generateRandomCoreShaderSet (de::Random& rnd)
4411 if (rnd.getFloat() < 0.5f)
4414 const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
4415 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
4417 else if (rnd.getFloat() < 0.5f)
4419 // vertex and fragment
4420 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4421 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program, glu::GLSL_VERSION_310_ES);
4425 shaderSet->setStage(glu::SHADERTYPE_VERTEX, true);
4426 shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, rnd.getBool());
4430 shaderSet->setStage(glu::SHADERTYPE_VERTEX, rnd.getBool());
4431 shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, true);
4434 return ResourceDefinition::Node::SharedPtr(shaderSet);
4438 // separate vertex or fragment
4439 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
4440 const glu::ShaderType shaderType = (rnd.getBool()) ? (glu::SHADERTYPE_VERTEX) : (glu::SHADERTYPE_FRAGMENT);
4442 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, shaderType, glu::GLSL_VERSION_310_ES));
4446 static ResourceDefinition::Node::SharedPtr generateRandomExtShaderSet (de::Random& rnd)
4448 if (rnd.getFloat() < 0.5f)
4451 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4452 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program, glu::GLSL_VERSION_310_ES);
4454 shaderSet->setStage(glu::SHADERTYPE_VERTEX, rnd.getBool());
4455 shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, rnd.getBool());
4457 // tess shader are either both or neither present. Make cases interesting
4458 // by forcing one extended shader to always have reference
4461 shaderSet->setStage(glu::SHADERTYPE_GEOMETRY, true);
4465 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, rnd.getBool());
4466 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, rnd.getBool());
4471 shaderSet->setStage(glu::SHADERTYPE_GEOMETRY, rnd.getBool());
4475 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, true);
4476 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, rnd.getBool());
4480 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, rnd.getBool());
4481 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, true);
4485 return ResourceDefinition::Node::SharedPtr(shaderSet);
4490 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
4491 const int selector = rnd.getInt(0, 2);
4492 const glu::ShaderType shaderType = (selector == 0) ? (glu::SHADERTYPE_GEOMETRY)
4493 : (selector == 1) ? (glu::SHADERTYPE_TESSELLATION_CONTROL)
4494 : (selector == 2) ? (glu::SHADERTYPE_TESSELLATION_EVALUATION)
4495 : (glu::SHADERTYPE_LAST);
4497 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, shaderType, glu::GLSL_VERSION_310_ES));
4501 static ResourceDefinition::Node::SharedPtr generateRandomShaderSet (de::Random& rnd, bool onlyExtensionStages)
4503 if (!onlyExtensionStages)
4504 return generateRandomCoreShaderSet(rnd);
4506 return generateRandomExtShaderSet(rnd);
4509 static glu::Layout generateRandomUniformBlockLayout (de::Random& rnd)
4514 layout.binding = rnd.getInt(0, 5);
4517 layout.matrixOrder = (rnd.getBool()) ? (glu::MATRIXORDER_COLUMN_MAJOR) : (glu::MATRIXORDER_ROW_MAJOR);
4522 static glu::Layout generateRandomBufferBlockLayout (de::Random& rnd)
4524 return generateRandomUniformBlockLayout(rnd);
4527 static glu::Layout generateRandomVariableLayout (de::Random& rnd, glu::DataType type, bool interfaceBlockMember)
4531 if ((glu::isDataTypeAtomicCounter(type) || glu::isDataTypeImage(type) || glu::isDataTypeSampler(type)) && rnd.getBool())
4532 layout.binding = rnd.getInt(0, 5);
4534 if (glu::isDataTypeAtomicCounter(type) && rnd.getBool())
4535 layout.offset = rnd.getInt(0, 3) * 4;
4537 if (glu::isDataTypeMatrix(type) && interfaceBlockMember && rnd.getBool())
4538 layout.matrixOrder = (rnd.getBool()) ? (glu::MATRIXORDER_COLUMN_MAJOR) : (glu::MATRIXORDER_ROW_MAJOR);
4543 static void generateUniformRandomCase (Context& context, tcu::TestCaseGroup* const targetGroup, int index, bool onlyExtensionStages)
4545 de::Random rnd (index * 0x12345);
4546 const ResourceDefinition::Node::SharedPtr shader = generateRandomShaderSet(rnd, onlyExtensionStages);
4547 const bool interfaceBlock = rnd.getBool();
4548 const glu::DataType type = generateRandomDataType(rnd, interfaceBlock);
4549 const glu::Layout layout = generateRandomVariableLayout(rnd, type, interfaceBlock);
4550 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
4551 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4552 ResourceDefinition::Node::SharedPtr currentStructure = uniform;
4556 const bool namedBlock = rnd.getBool();
4558 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, generateRandomUniformBlockLayout(rnd)));
4560 if (namedBlock && rnd.getBool())
4561 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
4563 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(currentStructure, namedBlock));
4566 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, layout));
4567 currentStructure = generateRandomVariableDefinition(rnd, currentStructure, type, layout, false);
4569 targetGroup->addChild(new ResourceTestCase(context, currentStructure, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_UNIFORM_INTERFACE_MASK), de::toString(index).c_str()));
4572 static void generateUniformCaseRandomCases (Context& context, tcu::TestCaseGroup* const targetGroup)
4574 const int numBasicCases = 40;
4575 const int numTessGeoCases = 40;
4577 for (int ndx = 0; ndx < numBasicCases; ++ndx)
4578 generateUniformRandomCase(context, targetGroup, ndx, false);
4579 for (int ndx = 0; ndx < numTessGeoCases; ++ndx)
4580 generateUniformRandomCase(context, targetGroup, numBasicCases + ndx, true);
4583 class UniformInterfaceTestGroup : public TestCaseGroup
4586 UniformInterfaceTestGroup (Context& context);
4590 UniformInterfaceTestGroup::UniformInterfaceTestGroup (Context& context)
4591 : TestCaseGroup(context, "uniform", "Uniform interace")
4595 void UniformInterfaceTestGroup::init (void)
4597 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4598 const ResourceDefinition::Node::SharedPtr computeShader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
4602 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
4603 addChild(blockGroup);
4604 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformResourceListBlockContents);
4609 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Query array size");
4610 addChild(blockGroup);
4611 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockArraySizeContents);
4616 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_stride", "Query array stride");
4617 addChild(blockGroup);
4618 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockArrayStrideContents);
4621 // .atomic_counter_buffer_index
4623 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "atomic_counter_buffer_index", "Query atomic counter buffer index");
4624 addChild(blockGroup);
4625 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_DEFAULT | BLOCKFLAG_NAMED, generateUniformBlockAtomicCounterBufferIndexContents);
4630 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "block_index", "Query block index");
4631 addChild(blockGroup);
4632 generateUniformBlockBlockIndexContents(m_context, blockGroup);
4637 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Query location");
4638 addChild(blockGroup);
4639 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_DEFAULT | BLOCKFLAG_NAMED | BLOCKFLAG_UNNAMED, generateUniformBlockLocationContents);
4642 // .matrix_row_major
4644 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "matrix_row_major", "Query matrix row_major");
4645 addChild(blockGroup);
4646 generateUniformMatrixCaseBlocks(m_context, computeShader, blockGroup, generateUniformMatrixOrderCaseBlockContentCases);
4651 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "matrix_stride", "Query matrix stride");
4652 addChild(blockGroup);
4653 generateUniformMatrixCaseBlocks(m_context, computeShader, blockGroup, generateUniformMatrixStrideCaseBlockContentCases);
4658 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Query name length");
4659 addChild(blockGroup);
4660 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockNameLengthContents);
4665 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "offset", "Query offset");
4666 addChild(blockGroup);
4667 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockOffsetContents);
4670 // .referenced_by_shader
4672 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by_shader", "Query referenced by shader");
4673 addChild(blockGroup);
4674 generateReferencedByShaderCaseBlocks(m_context, blockGroup, generateUniformReferencedByShaderSingleBlockContentCases);
4679 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Query type");
4680 addChild(blockGroup);
4681 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockTypeContents);
4686 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random");
4687 addChild(blockGroup);
4688 generateUniformCaseRandomCases(m_context, blockGroup);
4692 static void generateBufferBackedInterfaceResourceListCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, const char* blockName)
4694 targetGroup->addChild(new ResourceListTestCase(context, targetResource, interface, blockName));
4697 static void generateBufferBackedInterfaceNameLengthCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, const char* blockName)
4699 targetGroup->addChild(new ResourceTestCase(context, targetResource, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_NAME_LENGTH), blockName));
4702 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))
4704 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4705 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
4706 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
4707 const ResourceDefinition::Node::SharedPtr storageQualifier (new ResourceDefinition::StorageQualifier(defaultBlock, storage));
4708 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(storageQualifier, glu::Layout(-1, 1)));
4709 const ProgramInterface programInterface = (storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) : (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK);
4713 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, true));
4714 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4716 blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "named_block");
4721 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, false));
4722 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4724 blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "unnamed_block");
4729 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding, 3));
4730 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4731 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4733 blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "block_array");
4736 // .block_array_single_element
4738 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding, 1));
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_single_element");
4746 static void generateBufferBackedInterfaceResourceBufferBindingCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
4748 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4749 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
4750 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
4751 const ResourceDefinition::Node::SharedPtr storageQualifier (new ResourceDefinition::StorageQualifier(defaultBlock, storage));
4753 for (int ndx = 0; ndx < 2; ++ndx)
4755 const bool explicitBinding = (ndx == 1);
4756 const int bindingNdx = (explicitBinding) ? (1) : (-1);
4757 const std::string nameSuffix = (explicitBinding) ? ("_explicit_binding") : ("");
4758 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(storageQualifier, glu::Layout(-1, bindingNdx)));
4759 const ProgramInterface programInterface = (storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) : (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK);
4763 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, true));
4764 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4766 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("named_block" + nameSuffix).c_str()));
4771 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, false));
4772 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4774 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("unnamed_block" + nameSuffix).c_str()));
4779 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding, 3));
4780 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
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), ("block_array" + nameSuffix).c_str()));
4788 template <glu::Storage Storage>
4789 static void generateBufferBlockReferencedByShaderSingleBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
4791 const ProgramInterface programInterface = (Storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
4792 (Storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
4793 (PROGRAMINTERFACE_LAST);
4794 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
4795 const ResourceDefinition::Node::SharedPtr storage (new ResourceDefinition::StorageQualifier(defaultBlock, Storage));
4797 DE_UNREF(expandLevel);
4799 DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
4803 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, true));
4804 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4806 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "named_block"));
4811 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, false));
4812 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4814 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "unnamed_block"));
4819 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(storage, 3));
4820 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
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), "block_array"));
4827 static void generateBufferBackedInterfaceResourceActiveVariablesCase (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
4829 targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "named_block", "Named block", storage, InterfaceBlockActiveVariablesTestCase::CASE_NAMED_BLOCK));
4830 targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "unnamed_block", "Unnamed block", storage, InterfaceBlockActiveVariablesTestCase::CASE_UNNAMED_BLOCK));
4831 targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "block_array", "Block array", storage, InterfaceBlockActiveVariablesTestCase::CASE_BLOCK_ARRAY));
4834 static void generateBufferBackedInterfaceResourceBufferDataSizeCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
4836 targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "named_block", "Named block", storage, InterfaceBlockDataSizeTestCase::CASE_NAMED_BLOCK));
4837 targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "unnamed_block", "Unnamed block", storage, InterfaceBlockDataSizeTestCase::CASE_UNNAMED_BLOCK));
4838 targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "block_array", "Block array", storage, InterfaceBlockDataSizeTestCase::CASE_BLOCK_ARRAY));
4841 class BufferBackedBlockInterfaceTestGroup : public TestCaseGroup
4844 BufferBackedBlockInterfaceTestGroup (Context& context, glu::Storage interfaceBlockStorage);
4848 static const char* getGroupName (glu::Storage storage);
4849 static const char* getGroupDescription (glu::Storage storage);
4851 const glu::Storage m_storage;
4854 BufferBackedBlockInterfaceTestGroup::BufferBackedBlockInterfaceTestGroup(Context& context, glu::Storage storage)
4855 : TestCaseGroup (context, getGroupName(storage), getGroupDescription(storage))
4856 , m_storage (storage)
4858 DE_ASSERT(storage == glu::STORAGE_BUFFER || storage == glu::STORAGE_UNIFORM);
4861 void BufferBackedBlockInterfaceTestGroup::init (void)
4865 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
4866 addChild(blockGroup);
4867 generateBufferBackedInterfaceResourceBasicBlockTypes(m_context, blockGroup, m_storage, generateBufferBackedInterfaceResourceListCase);
4870 // .active_variables
4872 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "active_variables", "Active variables");
4873 addChild(blockGroup);
4874 generateBufferBackedInterfaceResourceActiveVariablesCase(m_context, blockGroup, m_storage);
4879 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "buffer_binding", "Buffer binding");
4880 addChild(blockGroup);
4881 generateBufferBackedInterfaceResourceBufferBindingCases(m_context, blockGroup, m_storage);
4884 // .buffer_data_size
4886 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "buffer_data_size", "Buffer data size");
4887 addChild(blockGroup);
4888 generateBufferBackedInterfaceResourceBufferDataSizeCases(m_context, blockGroup, m_storage);
4893 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
4894 addChild(blockGroup);
4895 generateBufferBackedInterfaceResourceBasicBlockTypes(m_context, blockGroup, m_storage, generateBufferBackedInterfaceNameLengthCase);
4900 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Referenced by shader");
4901 addChild(blockGroup);
4903 if (m_storage == glu::STORAGE_UNIFORM)
4904 generateReferencedByShaderCaseBlocks(m_context, blockGroup, generateBufferBlockReferencedByShaderSingleBlockContentCases<glu::STORAGE_UNIFORM>);
4905 else if (m_storage == glu::STORAGE_BUFFER)
4906 generateReferencedByShaderCaseBlocks(m_context, blockGroup, generateBufferBlockReferencedByShaderSingleBlockContentCases<glu::STORAGE_BUFFER>);
4912 const char* BufferBackedBlockInterfaceTestGroup::getGroupName (glu::Storage storage)
4916 case glu::STORAGE_UNIFORM: return "uniform_block";
4917 case glu::STORAGE_BUFFER: return "shader_storage_block";
4924 const char* BufferBackedBlockInterfaceTestGroup::getGroupDescription (glu::Storage storage)
4928 case glu::STORAGE_UNIFORM: return "Uniform block interface";
4929 case glu::STORAGE_BUFFER: return "Shader storage block interface";
4936 class AtomicCounterTestGroup : public TestCaseGroup
4939 AtomicCounterTestGroup (Context& context);
4943 AtomicCounterTestGroup::AtomicCounterTestGroup (Context& context)
4944 : TestCaseGroup(context, "atomic_counter_buffer", "Atomic counter buffer")
4948 void AtomicCounterTestGroup::init (void)
4958 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT)
4961 "vertex_tess_fragment",
4962 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION)
4965 "vertex_geo_fragment",
4966 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY)
4969 "vertex_tess_geo_fragment",
4970 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
4975 addChild(new AtomicCounterResourceListCase(m_context, "resource_list", "Resource list"));
4977 // .active_variables
4978 addChild(new AtomicCounterActiveVariablesCase(m_context, "active_variables", "Active variables"));
4981 addChild(new AtomicCounterBufferBindingCase(m_context, "buffer_binding", "Buffer binding"));
4983 // .buffer_data_size
4984 addChild(new AtomicCounterBufferDataSizeCase(m_context, "buffer_data_size", "Buffer binding"));
4987 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_compute", "", false, (1 << glu::SHADERTYPE_COMPUTE), (1 << glu::SHADERTYPE_COMPUTE)));
4988 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_vertex", "", true, (1 << glu::SHADERTYPE_VERTEX), (1 << glu::SHADERTYPE_VERTEX)));
4989 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_fragment", "", true, (1 << glu::SHADERTYPE_FRAGMENT), (1 << glu::SHADERTYPE_FRAGMENT)));
4990 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_geometry", "", true, (1 << glu::SHADERTYPE_GEOMETRY), (1 << glu::SHADERTYPE_GEOMETRY)));
4991 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_tess_ctrl", "", true, (1 << glu::SHADERTYPE_TESSELLATION_CONTROL), (1 << glu::SHADERTYPE_TESSELLATION_CONTROL)));
4992 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_tess_eval", "", true, (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION), (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION)));
4994 for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
4996 addChild(new AtomicCounterReferencedByCase(m_context, (std::string() + "referenced_by_" + pipelines[pipelineNdx].name).c_str(), "", false, pipelines[pipelineNdx].flags, pipelines[pipelineNdx].flags));
4998 for (deUint32 stageNdx = 0; stageNdx < glu::SHADERTYPE_LAST; ++stageNdx)
5000 const deUint32 currentBit = (1u << stageNdx);
5001 if (currentBit > pipelines[pipelineNdx].flags)
5003 if (currentBit & pipelines[pipelineNdx].flags)
5005 const char* stageName = (stageNdx == glu::SHADERTYPE_VERTEX) ? ("vertex")
5006 : (stageNdx == glu::SHADERTYPE_FRAGMENT) ? ("fragment")
5007 : (stageNdx == glu::SHADERTYPE_GEOMETRY) ? ("geo")
5008 : (stageNdx == glu::SHADERTYPE_TESSELLATION_CONTROL) ? ("tess_ctrl")
5009 : (stageNdx == glu::SHADERTYPE_TESSELLATION_EVALUATION) ? ("tess_eval")
5011 const std::string name = std::string() + "referenced_by_" + pipelines[pipelineNdx].name + "_only_" + stageName;
5013 addChild(new AtomicCounterReferencedByCase(m_context, name.c_str(), "", false, pipelines[pipelineNdx].flags, currentBit));
5019 static void generateProgramInputOutputShaderCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, bool withCompute, bool inputCase, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, deUint32))
5024 glu::ShaderType stage;
5025 } singleStageCases[] =
5027 { "separable_vertex", glu::SHADERTYPE_VERTEX },
5028 { "separable_fragment", glu::SHADERTYPE_FRAGMENT },
5029 { "separable_tess_ctrl", glu::SHADERTYPE_TESSELLATION_CONTROL },
5030 { "separable_tess_eval", glu::SHADERTYPE_TESSELLATION_EVALUATION },
5031 { "separable_geometry", glu::SHADERTYPE_GEOMETRY },
5036 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "vertex_fragment", "Vertex and fragment");
5037 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(false));
5038 ResourceDefinition::ShaderSet* shaderSetPtr = new ResourceDefinition::ShaderSet(program, glu::GLSL_VERSION_310_ES);
5039 const ResourceDefinition::Node::SharedPtr shaderSet (shaderSetPtr);
5040 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shaderSet));
5042 shaderSetPtr->setStage(glu::SHADERTYPE_VERTEX, inputCase);
5043 shaderSetPtr->setStage(glu::SHADERTYPE_FRAGMENT, !inputCase);
5045 targetGroup->addChild(blockGroup);
5047 blockContentGenerator(context, defaultBlock, blockGroup, (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT));
5051 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
5053 TestCaseGroup* const blockGroup = new TestCaseGroup(context, singleStageCases[ndx].name, "");
5054 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
5055 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glu::GLSL_VERSION_310_ES));
5056 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
5058 targetGroup->addChild(blockGroup);
5059 blockContentGenerator(context, defaultBlock, blockGroup, (1 << singleStageCases[ndx].stage));
5065 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "compute", "Compute");
5066 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
5067 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
5068 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
5070 targetGroup->addChild(blockGroup);
5072 blockContentGenerator(context, defaultBlock, blockGroup, (1 << glu::SHADERTYPE_COMPUTE));
5075 // .interface_blocks
5079 const char* inputName;
5080 glu::ShaderType inputStage;
5081 glu::Storage inputStorage;
5082 const char* outputName;
5083 glu::ShaderType outputStage;
5084 glu::Storage outputStorage;
5089 glu::SHADERTYPE_FRAGMENT,
5092 glu::SHADERTYPE_VERTEX,
5097 glu::SHADERTYPE_TESSELLATION_EVALUATION,
5098 glu::STORAGE_PATCH_IN,
5100 glu::SHADERTYPE_TESSELLATION_CONTROL,
5101 glu::STORAGE_PATCH_OUT,
5105 tcu::TestCaseGroup* const ioBlocksGroup = new TestCaseGroup(context, "interface_blocks", "Interface blocks");
5106 targetGroup->addChild(ioBlocksGroup);
5111 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(ioBlockTypes); ++ndx)
5113 const char* const name = (inputCase) ? (ioBlockTypes[ndx].inputName) : (ioBlockTypes[ndx].outputName);
5114 const glu::ShaderType shaderType = (inputCase) ? (ioBlockTypes[ndx].inputStage) : (ioBlockTypes[ndx].outputStage);
5115 const glu::Storage storageType = (inputCase) ? (ioBlockTypes[ndx].inputStorage) : (ioBlockTypes[ndx].outputStorage);
5116 tcu::TestCaseGroup* const ioBlockGroup = new TestCaseGroup(context, name, "");
5117 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
5118 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, shaderType, glu::GLSL_VERSION_310_ES));
5119 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
5120 const ResourceDefinition::Node::SharedPtr storage (new ResourceDefinition::StorageQualifier(defaultBlock, storageType));
5122 ioBlocksGroup->addChild(ioBlockGroup);
5126 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, true));
5127 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block", "Named block");
5129 ioBlockGroup->addChild(blockGroup);
5131 blockContentGenerator(context, block, blockGroup, (1 << shaderType));
5134 // .named_block_explicit_location
5136 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(storage, glu::Layout(3)));
5137 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(layout, true));
5138 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block_explicit_location", "Named block with explicit location");
5140 ioBlockGroup->addChild(blockGroup);
5142 blockContentGenerator(context, block, blockGroup, (1 << shaderType));
5147 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, false));
5148 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "Unnamed block");
5150 ioBlockGroup->addChild(blockGroup);
5152 blockContentGenerator(context, block, blockGroup, (1 << shaderType));
5157 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(storage));
5158 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
5159 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "Block array");
5161 ioBlockGroup->addChild(blockGroup);
5163 blockContentGenerator(context, block, blockGroup, (1 << shaderType));
5169 static void generateProgramInputBlockContents (Context& context,
5170 const ResourceDefinition::Node::SharedPtr& parentStructure,
5171 tcu::TestCaseGroup* targetGroup,
5172 deUint32 presentShadersMask,
5174 void (*genCase)(Context& context,
5175 const ResourceDefinition::Node::SharedPtr& parentStructure,
5176 tcu::TestCaseGroup* targetGroup,
5177 ProgramInterface interface,
5180 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5181 const ResourceDefinition::Node::SharedPtr input = (inDefaultBlock)
5182 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
5183 : (parentStructure);
5184 const glu::ShaderType firstStage = getShaderMaskFirstStage(presentShadersMask);
5187 if (includeEmpty && inDefaultBlock)
5188 genCase(context, parentStructure, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "empty");
5190 if (firstStage == glu::SHADERTYPE_VERTEX)
5193 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5194 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5196 else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5200 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5201 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5205 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(input));
5206 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5207 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var_struct");
5211 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input));
5212 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5213 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var_array");
5216 else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
5217 firstStage == glu::SHADERTYPE_GEOMETRY)
5219 // arrayed interface
5223 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5224 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5225 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5227 // extension forbids use arrays of structs
5228 // extension forbids use arrays of arrays
5230 else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5232 // arrayed interface
5233 const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5237 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5238 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5239 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5241 // extension forbids use arrays of structs
5242 // extension forbids use arrays of arrays
5246 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchInput, glu::TYPE_FLOAT_VEC4));
5247 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var");
5249 // .patch_var_struct
5251 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchInput));
5252 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5253 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var_struct");
5257 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchInput));
5258 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5259 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var_array");
5262 else if (firstStage == glu::SHADERTYPE_COMPUTE)
5270 static void generateProgramOutputBlockContents (Context& context,
5271 const ResourceDefinition::Node::SharedPtr& parentStructure,
5272 tcu::TestCaseGroup* targetGroup,
5273 deUint32 presentShadersMask,
5275 void (*genCase)(Context& context,
5276 const ResourceDefinition::Node::SharedPtr& parentStructure,
5277 tcu::TestCaseGroup* targetGroup,
5278 ProgramInterface interface,
5281 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5282 const ResourceDefinition::Node::SharedPtr output = (inDefaultBlock)
5283 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
5284 : (parentStructure);
5285 const glu::ShaderType lastStage = getShaderMaskLastStage(presentShadersMask);
5288 if (includeEmpty && inDefaultBlock)
5289 genCase(context, parentStructure, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "empty");
5291 if (lastStage == glu::SHADERTYPE_VERTEX ||
5292 lastStage == glu::SHADERTYPE_GEOMETRY ||
5293 lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
5298 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5299 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5303 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
5304 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5305 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_struct");
5309 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5310 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5311 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_array");
5314 else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5318 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5319 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5323 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5324 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5325 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_array");
5328 else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5330 // arrayed interface
5331 const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5335 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5336 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5337 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5339 // extension forbids use arrays of structs
5340 // extension forbids use array of arrays
5344 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchOutput, glu::TYPE_FLOAT_VEC4));
5345 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var");
5347 // .patch_var_struct
5349 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchOutput));
5350 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5351 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var_struct");
5355 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchOutput));
5356 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5357 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var_array");
5360 else if (lastStage == glu::SHADERTYPE_COMPUTE)
5368 static void addProgramInputOutputResourceListCase (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramInterface programInterface, const char* name)
5370 ResourceListTestCase* const resourceListCase = new ResourceListTestCase(context, parentStructure, programInterface);
5372 DE_ASSERT(deStringEqual(name, resourceListCase->getName()));
5374 targetGroup->addChild(resourceListCase);
5377 static void generateProgramInputResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5379 generateProgramInputBlockContents(context, parentStructure, targetGroup, presentShadersMask, true, addProgramInputOutputResourceListCase);
5382 static void generateProgramOutputResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5384 generateProgramOutputBlockContents(context, parentStructure, targetGroup, presentShadersMask, true, addProgramInputOutputResourceListCase);
5387 template <ProgramResourcePropFlags TargetProp>
5388 static void addProgramInputOutputResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramInterface programInterface, const char* name)
5390 ResourceTestCase* const resourceTestCase = new ResourceTestCase(context, parentStructure, ProgramResourceQueryTestTarget(programInterface, TargetProp), name);
5391 targetGroup->addChild(resourceTestCase);
5394 template <ProgramResourcePropFlags TargetProp>
5395 static void generateProgramInputBasicBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5397 generateProgramInputBlockContents(context, parentStructure, targetGroup, presentShadersMask, false, addProgramInputOutputResourceTestCase<TargetProp>);
5400 template <ProgramResourcePropFlags TargetProp>
5401 static void generateProgramOutputBasicBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5403 generateProgramOutputBlockContents(context, parentStructure, targetGroup, presentShadersMask, false, addProgramInputOutputResourceTestCase<TargetProp>);
5406 static void generateProgramInputLocationBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5408 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5409 const ResourceDefinition::Node::SharedPtr input = (inDefaultBlock)
5410 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
5411 : (parentStructure);
5412 const glu::ShaderType firstStage = getShaderMaskFirstStage(presentShadersMask);
5414 if (firstStage == glu::SHADERTYPE_VERTEX)
5418 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5419 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5421 // .var_explicit_location
5423 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5424 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5425 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5428 else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5432 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5433 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5435 // .var_explicit_location
5437 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5438 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5439 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5443 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(input));
5444 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5445 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct"));
5447 // .var_struct_explicit_location
5449 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5450 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5451 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5452 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct_explicit_location"));
5456 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input));
5457 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5458 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
5460 // .var_array_explicit_location
5462 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5463 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5464 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5465 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
5468 else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
5469 firstStage == glu::SHADERTYPE_GEOMETRY)
5471 // arrayed interface
5475 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5476 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5477 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5479 // .var_explicit_location
5481 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5482 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5483 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5484 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5486 // extension forbids use arrays of structs
5487 // extension forbids use arrays of arrays
5489 else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5491 // arrayed interface
5492 const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5496 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5497 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5498 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5500 // .var_explicit_location
5502 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5503 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5504 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5505 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5507 // extension forbids use arrays of structs
5508 // extension forbids use arrays of arrays
5512 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchInput, glu::TYPE_FLOAT_VEC4));
5513 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var"));
5515 // .patch_var_explicit_location
5517 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
5518 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5519 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_explicit_location"));
5521 // .patch_var_struct
5523 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchInput));
5524 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5525 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct"));
5527 // .patch_var_struct_explicit_location
5529 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
5530 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5531 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5532 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct_explicit_location"));
5536 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchInput));
5537 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5538 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array"));
5540 // .patch_var_array_explicit_location
5542 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
5543 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5544 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5545 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array_explicit_location"));
5548 else if (firstStage == glu::SHADERTYPE_COMPUTE)
5556 static void generateProgramOutputLocationBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5558 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5559 const ResourceDefinition::Node::SharedPtr output = (inDefaultBlock)
5560 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
5561 : (parentStructure);
5562 const glu::ShaderType lastStage = getShaderMaskLastStage(presentShadersMask);
5564 if (lastStage == glu::SHADERTYPE_VERTEX ||
5565 lastStage == glu::SHADERTYPE_GEOMETRY ||
5566 lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
5571 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5572 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5574 // .var_explicit_location
5576 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5577 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5578 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5582 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
5583 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5584 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct"));
5586 // .var_struct_explicit_location
5588 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5589 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5590 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5591 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct_explicit_location"));
5595 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5596 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5597 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
5599 // .var_array_explicit_location
5601 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5602 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5603 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5604 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
5607 else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5611 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5612 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5614 // .var_explicit_location
5616 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5617 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5618 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5622 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5623 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5624 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
5626 // .var_array_explicit_location
5628 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(1)));
5629 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5630 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5631 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
5634 else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5636 // arrayed interface
5637 const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5641 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5642 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5643 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5645 // .var_explicit_location
5647 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5648 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5649 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5650 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5652 // extension forbids use arrays of structs
5653 // extension forbids use array of arrays
5657 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchOutput, glu::TYPE_FLOAT_VEC4));
5658 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var"));
5660 // .patch_var_explicit_location
5662 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
5663 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5664 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_explicit_location"));
5666 // .patch_var_struct
5668 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchOutput));
5669 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5670 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct"));
5672 // .patch_var_struct_explicit_location
5674 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
5675 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5676 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5677 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct_explicit_location"));
5681 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchOutput));
5682 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5683 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array"));
5685 // .patch_var_array_explicit_location
5687 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
5688 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5689 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5690 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array_explicit_location"));
5693 else if (lastStage == glu::SHADERTYPE_COMPUTE)
5701 static void generateProgramInputOutputReferencedByCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
5703 // all whole pipelines
5704 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_FRAGMENT));
5705 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_tess_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_TESS_FRAGMENT));
5706 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_geo_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_GEO_FRAGMENT));
5707 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_tess_geo_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_TESS_GEO_FRAGMENT));
5709 // all partial pipelines
5710 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_vertex", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_VERTEX));
5711 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_FRAGMENT));
5712 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_geometry", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_GEOMETRY));
5713 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_eval", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_EVAL));
5714 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_ctrl", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_CTRL));
5717 if (storage == glu::STORAGE_IN)
5718 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_eval_patch_in", "", glu::STORAGE_PATCH_IN, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_EVAL));
5719 else if (storage == glu::STORAGE_OUT)
5720 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_ctrl_patch_out", "", glu::STORAGE_PATCH_OUT, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_CTRL));
5725 template <ProgramInterface interface>
5726 static void generateProgramInputOutputTypeBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool allowMatrixCases, int expandLevel)
5735 { glu::TYPE_FLOAT, false, 0 },
5736 { glu::TYPE_INT, false, 1 },
5737 { glu::TYPE_UINT, false, 1 },
5738 { glu::TYPE_FLOAT_VEC2, false, 2 },
5739 { glu::TYPE_FLOAT_VEC3, false, 1 },
5740 { glu::TYPE_FLOAT_VEC4, false, 2 },
5741 { glu::TYPE_INT_VEC2, false, 0 },
5742 { glu::TYPE_INT_VEC3, false, 2 },
5743 { glu::TYPE_INT_VEC4, false, 2 },
5744 { glu::TYPE_UINT_VEC2, false, 2 },
5745 { glu::TYPE_UINT_VEC3, false, 2 },
5746 { glu::TYPE_UINT_VEC4, false, 0 },
5747 { glu::TYPE_FLOAT_MAT2, true, 2 },
5748 { glu::TYPE_FLOAT_MAT2X3, true, 2 },
5749 { glu::TYPE_FLOAT_MAT2X4, true, 2 },
5750 { glu::TYPE_FLOAT_MAT3X2, true, 0 },
5751 { glu::TYPE_FLOAT_MAT3, true, 2 },
5752 { glu::TYPE_FLOAT_MAT3X4, true, 2 },
5753 { glu::TYPE_FLOAT_MAT4X2, true, 2 },
5754 { glu::TYPE_FLOAT_MAT4X3, true, 2 },
5755 { glu::TYPE_FLOAT_MAT4, true, 2 },
5758 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
5760 if (!allowMatrixCases && variableTypes[ndx].isMatrix)
5763 if (variableTypes[ndx].level <= expandLevel)
5765 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
5766 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_TYPE)));
5771 static void generateProgramInputTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5773 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5774 const ResourceDefinition::Node::SharedPtr input = (inDefaultBlock)
5775 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
5776 : (parentStructure);
5777 const glu::ShaderType firstStage = getShaderMaskFirstStage(presentShadersMask);
5778 const int interfaceBlockExpansionReducement = (!inDefaultBlock) ? (1) : (0); // lesser expansions on block members to keep test counts reasonable
5780 if (firstStage == glu::SHADERTYPE_VERTEX)
5782 // Only basic types (and no booleans)
5783 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, input, targetGroup, true, 2 - interfaceBlockExpansionReducement);
5785 else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5787 const ResourceDefinition::Node::SharedPtr flatShading(new ResourceDefinition::InterpolationQualifier(input, glu::INTERPOLATION_FLAT));
5789 // Only basic types, arrays of basic types, struct of basic types (and no booleans)
5791 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5792 targetGroup->addChild(blockGroup);
5793 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, flatShading, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5796 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(flatShading));
5797 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
5799 targetGroup->addChild(blockGroup);
5800 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElement, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5803 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(flatShading));
5804 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Struct types");
5806 targetGroup->addChild(blockGroup);
5807 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, structMember, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5810 else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
5811 firstStage == glu::SHADERTYPE_GEOMETRY)
5813 // arrayed interface
5815 // Only basic types (and no booleans)
5816 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5817 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElement, targetGroup, true, 2);
5819 else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5821 // arrayed interface
5822 const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5826 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5827 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5829 targetGroup->addChild(blockGroup);
5830 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElem, blockGroup, true, 2);
5832 // extension forbids use arrays of structs
5833 // extension forbids use arrays of arrays
5837 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var", "Basic types, per-patch");
5839 targetGroup->addChild(blockGroup);
5840 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, patchInput, blockGroup, true, 1);
5842 // .patch_var_struct
5844 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchInput));
5845 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_struct", "Struct types, per-patch");
5847 targetGroup->addChild(blockGroup);
5848 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, structMbr, blockGroup, true, 1);
5852 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchInput));
5853 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_array", "Array types, per-patch");
5855 targetGroup->addChild(blockGroup);
5856 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElem, blockGroup, true, 1);
5859 else if (firstStage == glu::SHADERTYPE_COMPUTE)
5867 static void generateProgramOutputTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5869 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5870 const ResourceDefinition::Node::SharedPtr output = (inDefaultBlock)
5871 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
5872 : (parentStructure);
5873 const glu::ShaderType lastStage = getShaderMaskLastStage(presentShadersMask);
5874 const int interfaceBlockExpansionReducement = (!inDefaultBlock) ? (1) : (0); // lesser expansions on block members to keep test counts reasonable
5876 if (lastStage == glu::SHADERTYPE_VERTEX ||
5877 lastStage == glu::SHADERTYPE_GEOMETRY ||
5878 lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
5881 const ResourceDefinition::Node::SharedPtr flatShading(new ResourceDefinition::InterpolationQualifier(output, glu::INTERPOLATION_FLAT));
5883 // Only basic types, arrays of basic types, struct of basic types (and no booleans)
5885 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5886 targetGroup->addChild(blockGroup);
5887 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, flatShading, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5890 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(flatShading));
5891 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
5892 const int typeExpansionReducement = (lastStage != glu::SHADERTYPE_VERTEX) ? (1) : (0); // lesser expansions on other stages
5893 const int expansionLevel = 2 - interfaceBlockExpansionReducement - typeExpansionReducement;
5895 targetGroup->addChild(blockGroup);
5896 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElement, blockGroup, true, expansionLevel);
5899 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(flatShading));
5900 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Struct 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, structMember, blockGroup, true, expansionLevel);
5908 else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5910 // only basic type and basic type array (and no booleans or matrices)
5912 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5913 targetGroup->addChild(blockGroup);
5914 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, output, blockGroup, false, 2);
5917 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(output));
5918 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
5920 targetGroup->addChild(blockGroup);
5921 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElement, blockGroup, false, 2);
5924 else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5926 // arrayed interface
5927 const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5931 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5932 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5934 targetGroup->addChild(blockGroup);
5935 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElem, blockGroup, true, 2);
5937 // extension forbids use arrays of structs
5938 // extension forbids use arrays of arrays
5942 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var", "Basic types, per-patch");
5944 targetGroup->addChild(blockGroup);
5945 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, patchOutput, blockGroup, true, 1);
5947 // .patch_var_struct
5949 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchOutput));
5950 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_struct", "Struct types, per-patch");
5952 targetGroup->addChild(blockGroup);
5953 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, structMbr, blockGroup, true, 1);
5957 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchOutput));
5958 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_array", "Array types, per-patch");
5960 targetGroup->addChild(blockGroup);
5961 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElem, blockGroup, true, 1);
5964 else if (lastStage == glu::SHADERTYPE_COMPUTE)
5972 class ProgramInputTestGroup : public TestCaseGroup
5975 ProgramInputTestGroup (Context& context);
5979 ProgramInputTestGroup::ProgramInputTestGroup (Context& context)
5980 : TestCaseGroup(context, "program_input", "Program input")
5984 void ProgramInputTestGroup::init (void)
5988 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
5989 addChild(blockGroup);
5990 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, true, true, generateProgramInputResourceListBlockContents);
5995 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Array size");
5996 addChild(blockGroup);
5997 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6002 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Location");
6003 addChild(blockGroup);
6004 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputLocationBlockContents);
6009 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
6010 addChild(blockGroup);
6011 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6016 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Reference by shader");
6017 addChild(blockGroup);
6018 generateProgramInputOutputReferencedByCases(m_context, blockGroup, glu::STORAGE_IN);
6023 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Type");
6024 addChild(blockGroup);
6025 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputTypeBlockContents);
6030 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "is_per_patch", "Is per patch");
6031 addChild(blockGroup);
6032 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
6036 class ProgramOutputTestGroup : public TestCaseGroup
6039 ProgramOutputTestGroup (Context& context);
6043 ProgramOutputTestGroup::ProgramOutputTestGroup (Context& context)
6044 : TestCaseGroup(context, "program_output", "Program output")
6048 void ProgramOutputTestGroup::init (void)
6052 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
6053 addChild(blockGroup);
6054 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, true, false, generateProgramOutputResourceListBlockContents);
6059 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Array size");
6060 addChild(blockGroup);
6061 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6066 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Location");
6067 addChild(blockGroup);
6068 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputLocationBlockContents);
6073 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
6074 addChild(blockGroup);
6075 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6080 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Reference by shader");
6081 addChild(blockGroup);
6082 generateProgramInputOutputReferencedByCases(m_context, blockGroup, glu::STORAGE_OUT);
6087 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Type");
6088 addChild(blockGroup);
6089 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputTypeBlockContents);
6094 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "is_per_patch", "Is per patch");
6095 addChild(blockGroup);
6096 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
6100 static void generateTransformFeedbackShaderCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, bool))
6106 deUint32 lastStageBit;
6112 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT),
6113 (1 << glu::SHADERTYPE_VERTEX),
6117 "vertex_tess_fragment",
6118 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
6119 (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
6123 "vertex_geo_fragment",
6124 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY),
6125 (1 << glu::SHADERTYPE_GEOMETRY),
6129 "vertex_tess_geo_fragment",
6130 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
6131 (1 << glu::SHADERTYPE_GEOMETRY),
6138 glu::ShaderType stage;
6140 } singleStageCases[] =
6142 { "separable_vertex", glu::SHADERTYPE_VERTEX, false },
6143 { "separable_tess_eval", glu::SHADERTYPE_TESSELLATION_EVALUATION, true },
6144 { "separable_geometry", glu::SHADERTYPE_GEOMETRY, true },
6147 // monolithic pipeline
6148 for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
6150 TestCaseGroup* const blockGroup = new TestCaseGroup(context, pipelines[pipelineNdx].name, "");
6151 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6152 const ResourceDefinition::Node::SharedPtr shaderSet (new ResourceDefinition::ShaderSet(program,
6153 glu::GLSL_VERSION_310_ES,
6154 pipelines[pipelineNdx].stageBits,
6155 pipelines[pipelineNdx].lastStageBit));
6157 targetGroup->addChild(blockGroup);
6158 blockContentGenerator(context, shaderSet, blockGroup, pipelines[pipelineNdx].reducedSet);
6161 // separable pipeline
6162 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
6164 TestCaseGroup* const blockGroup = new TestCaseGroup(context, singleStageCases[ndx].name, "");
6165 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
6166 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glu::GLSL_VERSION_310_ES));
6168 targetGroup->addChild(blockGroup);
6169 blockContentGenerator(context, shader, blockGroup, singleStageCases[ndx].reducedSet);
6173 static void generateTransformFeedbackResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6175 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6176 const ResourceDefinition::Node::SharedPtr output (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6178 DE_UNREF(reducedSet);
6180 // .builtin_gl_position
6182 const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6183 targetGroup->addChild(new FeedbackResourceListTestCase(context, xfbTarget, "builtin_gl_position"));
6185 // .default_block_basic_type
6187 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6188 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6189 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_basic_type"));
6191 // .default_block_struct_member
6193 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
6194 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(structMbr));
6195 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6196 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_struct_member"));
6198 // .default_block_array
6200 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6201 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(xfbTarget));
6202 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6203 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_array"));
6205 // .default_block_array_element
6207 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
6208 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(arrayElem));
6209 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6210 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_array_element"));
6214 template <ProgramResourcePropFlags TargetProp>
6215 static void generateTransformFeedbackVariableBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6217 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6218 const ResourceDefinition::Node::SharedPtr output (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6220 DE_UNREF(reducedSet);
6222 // .builtin_gl_position
6224 const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6225 targetGroup->addChild(new ResourceTestCase(context, xfbTarget, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "builtin_gl_position"));
6227 // .default_block_basic_type
6229 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6230 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6231 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_basic_type"));
6233 // .default_block_struct_member
6235 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
6236 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(structMbr));
6237 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6238 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_struct_member"));
6240 // .default_block_array
6242 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6243 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(xfbTarget));
6244 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6245 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_array"));
6247 // .default_block_array_element
6249 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
6250 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(arrayElem));
6251 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6252 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_array_element"));
6256 static void generateTransformFeedbackVariableBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6264 { glu::TYPE_FLOAT, true },
6265 { glu::TYPE_INT, true },
6266 { glu::TYPE_UINT, true },
6268 { glu::TYPE_FLOAT_VEC2, false },
6269 { glu::TYPE_FLOAT_VEC3, true },
6270 { glu::TYPE_FLOAT_VEC4, false },
6272 { glu::TYPE_INT_VEC2, false },
6273 { glu::TYPE_INT_VEC3, true },
6274 { glu::TYPE_INT_VEC4, false },
6276 { glu::TYPE_UINT_VEC2, true },
6277 { glu::TYPE_UINT_VEC3, false },
6278 { glu::TYPE_UINT_VEC4, false },
6280 { glu::TYPE_FLOAT_MAT2, false },
6281 { glu::TYPE_FLOAT_MAT2X3, false },
6282 { glu::TYPE_FLOAT_MAT2X4, false },
6283 { glu::TYPE_FLOAT_MAT3X2, false },
6284 { glu::TYPE_FLOAT_MAT3, false },
6285 { glu::TYPE_FLOAT_MAT3X4, true },
6286 { glu::TYPE_FLOAT_MAT4X2, false },
6287 { glu::TYPE_FLOAT_MAT4X3, false },
6288 { glu::TYPE_FLOAT_MAT4, false },
6291 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6293 if (variableTypes[ndx].important || !reducedSet)
6295 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
6296 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, PROGRAMRESOURCEPROP_TYPE)));
6301 static void generateTransformFeedbackVariableTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6303 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6304 const ResourceDefinition::Node::SharedPtr output (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6305 const ResourceDefinition::Node::SharedPtr flatShading (new ResourceDefinition::InterpolationQualifier(output, glu::INTERPOLATION_FLAT));
6307 // Only builtins, basic types, arrays of basic types, struct of basic types (and no booleans)
6309 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6310 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "builtin", "Built-in outputs");
6312 targetGroup->addChild(blockGroup);
6313 blockGroup->addChild(new ResourceTestCase(context, xfbTarget, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, PROGRAMRESOURCEPROP_TYPE), "gl_position"));
6316 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(flatShading));
6317 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
6319 targetGroup->addChild(blockGroup);
6320 generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
6323 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(flatShading));
6324 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(arrayElement));
6325 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
6327 targetGroup->addChild(blockGroup);
6328 generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
6331 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(flatShading));
6332 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(xfbTarget));
6333 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "whole_array", "Whole array");
6335 targetGroup->addChild(blockGroup);
6336 generateTransformFeedbackVariableBasicTypeCases(context, arrayElement, blockGroup, reducedSet);
6339 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(flatShading));
6340 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(structMember));
6341 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Struct types");
6343 targetGroup->addChild(blockGroup);
6344 generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
6348 class TransformFeedbackVaryingTestGroup : public TestCaseGroup
6351 TransformFeedbackVaryingTestGroup (Context& context);
6355 TransformFeedbackVaryingTestGroup::TransformFeedbackVaryingTestGroup (Context& context)
6356 : TestCaseGroup(context, "transform_feedback_varying", "Transform feedback varyings")
6360 void TransformFeedbackVaryingTestGroup::init (void)
6364 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "resource_list", "Resource list");
6365 addChild(blockGroup);
6366 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, generateTransformFeedbackResourceListBlockContents);
6371 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_size", "Array size");
6372 addChild(blockGroup);
6373 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, generateTransformFeedbackVariableBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6378 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "name_length", "Name length");
6379 addChild(blockGroup);
6380 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, generateTransformFeedbackVariableBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6385 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "type", "Type");
6386 addChild(blockGroup);
6387 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, generateTransformFeedbackVariableTypeBlockContents);
6391 static void generateBufferVariableBufferCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*))
6393 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6394 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
6395 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6396 const ResourceDefinition::Node::SharedPtr bufferStorage (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6397 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(bufferStorage, glu::Layout(-1, 0)));
6401 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, true));
6402 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block", "Named block");
6404 targetGroup->addChild(blockGroup);
6406 blockContentGenerator(context, buffer, blockGroup);
6411 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, false));
6412 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "Unnamed block");
6414 targetGroup->addChild(blockGroup);
6416 blockContentGenerator(context, buffer, blockGroup);
6421 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding));
6422 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
6423 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "Block array");
6425 targetGroup->addChild(blockGroup);
6427 blockContentGenerator(context, buffer, blockGroup);
6431 static void generateBufferVariableResourceListBlockContentsProxy (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
6433 generateBufferBackedResourceListBlockContentCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, 4);
6436 static void generateBufferVariableArraySizeSubCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramResourcePropFlags targetProp, bool sizedArray, bool extendedCases)
6438 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp);
6439 tcu::TestCaseGroup* aggregateGroup;
6444 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
6445 targetGroup->addChild(blockGroup);
6447 generateVariableCases(context, parentStructure, blockGroup, queryTarget, (sizedArray) ? (2) : (1), false);
6453 aggregateGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
6454 targetGroup->addChild(aggregateGroup);
6457 aggregateGroup = targetGroup;
6460 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_FLOAT, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6463 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_BOOL, (extendedCases && sizedArray) ? (1) : (0), !extendedCases);
6466 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_BOOL_VEC3, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6469 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_FLOAT_VEC4, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6472 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_INT_VEC2, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6475 template <ProgramResourcePropFlags TargetProp>
6476 static void generateBufferVariableArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
6478 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp);
6479 const bool namedNonArrayBlock = static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named && parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
6482 if (namedNonArrayBlock)
6484 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "non_array", "Non-array target");
6485 targetGroup->addChild(blockGroup);
6487 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 1, false);
6492 const ResourceDefinition::Node::SharedPtr sized (new ResourceDefinition::ArrayElement(parentStructure));
6493 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
6494 targetGroup->addChild(blockGroup);
6496 generateBufferVariableArraySizeSubCases(context, sized, blockGroup, TargetProp, true, namedNonArrayBlock);
6501 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6502 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unsized", "Unsized target");
6503 targetGroup->addChild(blockGroup);
6505 generateBufferVariableArraySizeSubCases(context, unsized, blockGroup, TargetProp, false, namedNonArrayBlock);
6509 static void generateBufferVariableBlockIndexCases (Context& context, tcu::TestCaseGroup* const targetGroup)
6511 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6512 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
6513 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6514 const ResourceDefinition::Node::SharedPtr bufferStorage (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6515 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(bufferStorage, glu::Layout(-1, 0)));
6519 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, true));
6520 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
6522 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "named_block"));
6527 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, false));
6528 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
6530 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "unnamed_block"));
6535 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding));
6536 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
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), "block_array"));
6543 static void generateBufferVariableMatrixCaseBlocks (Context& context, tcu::TestCaseGroup* const targetGroup, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, bool))
6548 const char* description;
6550 bool extendedBasicTypeCases;
6551 glu::MatrixOrder order;
6554 { "named_block", "Named uniform block", true, true, glu::MATRIXORDER_LAST },
6555 { "named_block_row_major", "Named uniform block", true, false, glu::MATRIXORDER_ROW_MAJOR },
6556 { "named_block_col_major", "Named uniform block", true, false, glu::MATRIXORDER_COLUMN_MAJOR },
6557 { "unnamed_block", "Unnamed uniform block", false, false, glu::MATRIXORDER_LAST },
6558 { "unnamed_block_row_major", "Unnamed uniform block", false, false, glu::MATRIXORDER_ROW_MAJOR },
6559 { "unnamed_block_col_major", "Unnamed uniform block", false, false, glu::MATRIXORDER_COLUMN_MAJOR },
6562 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6563 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
6564 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6565 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6567 for (int childNdx = 0; childNdx < (int)DE_LENGTH_OF_ARRAY(children); ++childNdx)
6569 ResourceDefinition::Node::SharedPtr parentStructure = buffer;
6570 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, children[childNdx].name, children[childNdx].description);
6572 targetGroup->addChild(blockGroup);
6574 if (children[childNdx].order != glu::MATRIXORDER_LAST)
6577 layout.matrixOrder = children[childNdx].order;
6578 parentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(parentStructure, layout));
6581 parentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(parentStructure, children[childNdx].namedBlock));
6583 blockContentGenerator(context, parentStructure, blockGroup, children[childNdx].extendedBasicTypeCases);
6587 static void generateBufferVariableMatrixVariableBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramResourcePropFlags targetProp)
6589 // all matrix types and some non-matrix
6591 static const glu::DataType variableTypes[] =
6595 glu::TYPE_FLOAT_MAT2,
6596 glu::TYPE_FLOAT_MAT2X3,
6597 glu::TYPE_FLOAT_MAT2X4,
6598 glu::TYPE_FLOAT_MAT3X2,
6599 glu::TYPE_FLOAT_MAT3,
6600 glu::TYPE_FLOAT_MAT3X4,
6601 glu::TYPE_FLOAT_MAT4X2,
6602 glu::TYPE_FLOAT_MAT4X3,
6603 glu::TYPE_FLOAT_MAT4,
6606 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6608 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx]));
6609 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp)));
6613 static void generateBufferVariableMatrixVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramResourcePropFlags targetProp)
6616 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp, glu::TYPE_FLOAT_MAT3X2, "", 2);
6620 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6621 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(unsized, glu::TYPE_FLOAT_MAT3X2));
6623 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp), "var_unsized_array"));
6627 template <ProgramResourcePropFlags TargetProp>
6628 static void generateBufferVariableMatrixCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool extendedTypeCases)
6631 if (extendedTypeCases)
6633 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "types", "Types");
6634 targetGroup->addChild(blockGroup);
6635 generateBufferVariableMatrixVariableBasicTypeCases(context, parentStructure, blockGroup, TargetProp);
6640 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "no_qualifier", "No qualifier");
6641 targetGroup->addChild(blockGroup);
6642 generateBufferVariableMatrixVariableCases(context, parentStructure, blockGroup, TargetProp);
6647 const ResourceDefinition::Node::SharedPtr matrixOrder(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, -1, glu::FORMATLAYOUT_LAST, glu::MATRIXORDER_COLUMN_MAJOR)));
6649 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "column_major", "Column major qualifier");
6650 targetGroup->addChild(blockGroup);
6651 generateBufferVariableMatrixVariableCases(context, matrixOrder, blockGroup, TargetProp);
6656 const ResourceDefinition::Node::SharedPtr matrixOrder(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, -1, glu::FORMATLAYOUT_LAST, glu::MATRIXORDER_ROW_MAJOR)));
6658 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "row_major", "Row major qualifier");
6659 targetGroup->addChild(blockGroup);
6660 generateBufferVariableMatrixVariableCases(context, matrixOrder, blockGroup, TargetProp);
6664 static void generateBufferVariableNameLengthCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
6668 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
6669 targetGroup->addChild(blockGroup);
6671 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 3);
6676 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6677 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unsized", "Unsized target");
6678 targetGroup->addChild(blockGroup);
6680 generateBufferBackedVariableAggregateTypeCases(context, unsized, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 2);
6684 static void generateBufferVariableOffsetCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
6688 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
6689 targetGroup->addChild(blockGroup);
6691 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_OFFSET, glu::TYPE_FLOAT, "", 3);
6696 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6697 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unsized", "Unsized target");
6698 targetGroup->addChild(blockGroup);
6700 generateBufferBackedVariableAggregateTypeCases(context, unsized, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_OFFSET, glu::TYPE_FLOAT, "", 2);
6704 static void generateBufferVariableReferencedByBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
6706 DE_UNREF(expandLevel);
6708 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER);
6709 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6710 const ResourceDefinition::Node::SharedPtr storage (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6711 const bool singleShaderCase = parentStructure->getType() == ResourceDefinition::Node::TYPE_SHADER;
6715 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(storage, true));
6716 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block", "Named block");
6718 targetGroup->addChild(blockGroup);
6720 generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, singleShaderCase);
6725 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(storage, false));
6726 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "Unnamed block");
6728 targetGroup->addChild(blockGroup);
6730 generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, false);
6735 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(storage));
6736 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
6737 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "Block array");
6739 targetGroup->addChild(blockGroup);
6741 generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, false);
6745 template <ProgramResourcePropFlags TargetProp>
6746 static void generateBufferVariableTopLevelCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
6748 // basic and aggregate types
6749 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp, glu::TYPE_FLOAT_VEC4, "", 3);
6751 // basic and aggregate types in an unsized array
6753 const ResourceDefinition::Node::SharedPtr unsized(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6755 generateBufferBackedVariableAggregateTypeCases(context, unsized, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp, glu::TYPE_FLOAT_VEC4, "_unsized_array", 2);
6759 static void generateBufferVariableTypeBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
6764 glu::DataType dataType;
6767 { 0, glu::TYPE_FLOAT },
6768 { 1, glu::TYPE_INT },
6769 { 1, glu::TYPE_UINT },
6770 { 1, glu::TYPE_BOOL },
6772 { 3, glu::TYPE_FLOAT_VEC2 },
6773 { 1, glu::TYPE_FLOAT_VEC3 },
6774 { 1, glu::TYPE_FLOAT_VEC4 },
6776 { 3, glu::TYPE_INT_VEC2 },
6777 { 2, glu::TYPE_INT_VEC3 },
6778 { 3, glu::TYPE_INT_VEC4 },
6780 { 3, glu::TYPE_UINT_VEC2 },
6781 { 2, glu::TYPE_UINT_VEC3 },
6782 { 3, glu::TYPE_UINT_VEC4 },
6784 { 3, glu::TYPE_BOOL_VEC2 },
6785 { 2, glu::TYPE_BOOL_VEC3 },
6786 { 3, glu::TYPE_BOOL_VEC4 },
6788 { 2, glu::TYPE_FLOAT_MAT2 },
6789 { 3, glu::TYPE_FLOAT_MAT2X3 },
6790 { 3, glu::TYPE_FLOAT_MAT2X4 },
6791 { 2, glu::TYPE_FLOAT_MAT3X2 },
6792 { 2, glu::TYPE_FLOAT_MAT3 },
6793 { 3, glu::TYPE_FLOAT_MAT3X4 },
6794 { 2, glu::TYPE_FLOAT_MAT4X2 },
6795 { 3, glu::TYPE_FLOAT_MAT4X3 },
6796 { 2, glu::TYPE_FLOAT_MAT4 },
6799 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6801 if (variableTypes[ndx].level <= expandLevel)
6803 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
6804 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_TYPE)));
6809 static void generateBufferVariableTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int depth = 3)
6814 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic type");
6815 targetGroup->addChild(blockGroup);
6816 generateBufferVariableTypeBasicTypeCases(context, parentStructure, blockGroup, depth);
6820 // flatten bottom-level
6821 generateBufferVariableTypeBasicTypeCases(context, parentStructure, targetGroup, depth);
6827 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
6828 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Arrays");
6830 targetGroup->addChild(blockGroup);
6831 generateBufferVariableTypeCases(context, arrayElement, blockGroup, depth-1);
6837 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
6838 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Structs");
6840 targetGroup->addChild(blockGroup);
6841 generateBufferVariableTypeCases(context, structMember, blockGroup, depth-1);
6845 static void generateBufferVariableTypeBlock (Context& context, tcu::TestCaseGroup* targetGroup)
6847 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6848 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
6849 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6850 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6851 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(buffer, true));
6853 generateBufferVariableTypeCases(context, block, targetGroup);
6856 static void generateBufferVariableRandomCase (Context& context, tcu::TestCaseGroup* const targetGroup, int index, bool onlyExtensionStages)
6858 de::Random rnd (index * 0x12345);
6859 const ResourceDefinition::Node::SharedPtr shader = generateRandomShaderSet(rnd, onlyExtensionStages);
6860 const glu::DataType type = generateRandomDataType(rnd, true);
6861 const glu::Layout layout = generateRandomVariableLayout(rnd, type, true);
6862 const bool namedBlock = rnd.getBool();
6863 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6864 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6865 ResourceDefinition::Node::SharedPtr currentStructure (new ResourceDefinition::LayoutQualifier(buffer, generateRandomBufferBlockLayout(rnd)));
6867 if (namedBlock && rnd.getBool())
6868 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
6869 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(currentStructure, namedBlock));
6871 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, layout));
6872 currentStructure = generateRandomVariableDefinition(rnd, currentStructure, type, layout, true);
6874 targetGroup->addChild(new ResourceTestCase(context, currentStructure, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BUFFER_VARIABLE_MASK), de::toString(index).c_str()));
6877 static void generateBufferVariableRandomCases (Context& context, tcu::TestCaseGroup* const targetGroup)
6879 const int numBasicCases = 40;
6880 const int numTessGeoCases = 40;
6882 for (int ndx = 0; ndx < numBasicCases; ++ndx)
6883 generateBufferVariableRandomCase(context, targetGroup, ndx, false);
6884 for (int ndx = 0; ndx < numTessGeoCases; ++ndx)
6885 generateBufferVariableRandomCase(context, targetGroup, numBasicCases + ndx, true);
6888 class BufferVariableTestGroup : public TestCaseGroup
6891 BufferVariableTestGroup (Context& context);
6895 BufferVariableTestGroup::BufferVariableTestGroup (Context& context)
6896 : TestCaseGroup(context, "buffer_variable", "Buffer variable")
6900 void BufferVariableTestGroup::init (void)
6904 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "resource_list", "Resource list");
6905 addChild(blockGroup);
6906 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableResourceListBlockContentsProxy);
6911 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_size", "Array size");
6912 addChild(blockGroup);
6913 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableArrayCases<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6918 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_stride", "Array stride");
6919 addChild(blockGroup);
6920 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableArrayCases<PROGRAMRESOURCEPROP_ARRAY_STRIDE>);
6925 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "block_index", "Block index");
6926 addChild(blockGroup);
6927 generateBufferVariableBlockIndexCases(m_context, blockGroup);
6932 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "is_row_major", "Is row major");
6933 addChild(blockGroup);
6934 generateBufferVariableMatrixCaseBlocks(m_context, blockGroup, generateBufferVariableMatrixCases<PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR>);
6939 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "matrix_stride", "Matrix stride");
6940 addChild(blockGroup);
6941 generateBufferVariableMatrixCaseBlocks(m_context, blockGroup, generateBufferVariableMatrixCases<PROGRAMRESOURCEPROP_MATRIX_STRIDE>);
6946 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "name_length", "Name length");
6947 addChild(blockGroup);
6948 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableNameLengthCases);
6953 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "offset", "Offset");
6954 addChild(blockGroup);
6955 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableOffsetCases);
6960 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "referenced_by", "Referenced by");
6961 addChild(blockGroup);
6962 generateReferencedByShaderCaseBlocks(m_context, blockGroup, generateBufferVariableReferencedByBlockContents);
6965 // .top_level_array_size
6967 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "top_level_array_size", "Top-level array size");
6968 addChild(blockGroup);
6969 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableTopLevelCases<PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_SIZE>);
6972 // .top_level_array_stride
6974 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "top_level_array_stride", "Top-level array stride");
6975 addChild(blockGroup);
6976 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableTopLevelCases<PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_STRIDE>);
6981 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "type", "Type");
6982 addChild(blockGroup);
6983 generateBufferVariableTypeBlock(m_context, blockGroup);
6988 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "random", "Random");
6989 addChild(blockGroup);
6990 generateBufferVariableRandomCases(m_context, blockGroup);
6996 ProgramInterfaceQueryTests::ProgramInterfaceQueryTests (Context& context)
6997 : TestCaseGroup(context, "program_interface_query", "Program interface query tests")
7001 ProgramInterfaceQueryTests::~ProgramInterfaceQueryTests (void)
7005 void ProgramInterfaceQueryTests::init (void)
7009 // .buffer_limited_query
7011 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "buffer_limited_query", "Queries limited by the buffer size");
7015 group->addChild(new ResourceNameBufferLimitCase(m_context, "resource_name_query", "Test GetProgramResourceName with too small a buffer"));
7016 group->addChild(new ResourceQueryBufferLimitCase(m_context, "resource_query", "Test GetProgramResourceiv with too small a buffer"));
7022 addChild(new UniformInterfaceTestGroup(m_context));
7025 addChild(new BufferBackedBlockInterfaceTestGroup(m_context, glu::STORAGE_UNIFORM));
7027 // .atomic_counter_buffer
7028 addChild(new AtomicCounterTestGroup(m_context));
7031 addChild(new ProgramInputTestGroup(m_context));
7034 addChild(new ProgramOutputTestGroup(m_context));
7036 // .transform_feedback_varying
7037 addChild(new TransformFeedbackVaryingTestGroup(m_context));
7040 addChild(new BufferVariableTestGroup(m_context));
7042 // .shader_storage_block
7043 addChild(new BufferBackedBlockInterfaceTestGroup(m_context, glu::STORAGE_BUFFER));