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 getReferencingMask (void) const;
430 const glu::GLSLVersion m_version;
432 bool m_stagePresent[glu::SHADERTYPE_LAST];
433 bool m_stageReferencing[glu::SHADERTYPE_LAST];
436 ShaderSet::ShaderSet (const SharedPtr& enclosing, glu::GLSLVersion version)
437 : Node (TYPE_SHADER_SET, enclosing)
438 , m_version (version)
440 DE_ASSERT(enclosing->getType() == TYPE_PROGRAM);
442 deMemset(m_stagePresent, 0, sizeof(m_stagePresent));
443 deMemset(m_stageReferencing, 0, sizeof(m_stageReferencing));
446 ShaderSet::ShaderSet (const SharedPtr& enclosing,
447 glu::GLSLVersion version,
448 deUint32 stagesPresentBits,
449 deUint32 stagesReferencingBits)
450 : Node (TYPE_SHADER_SET, enclosing)
451 , m_version (version)
453 for (deUint32 stageNdx = 0; stageNdx < glu::SHADERTYPE_LAST; ++stageNdx)
455 const deUint32 stageMask = (1u << stageNdx);
456 const bool stagePresent = (stagesPresentBits & stageMask) != 0;
457 const bool stageReferencing = (stagesReferencingBits & stageMask) != 0;
459 DE_ASSERT(stagePresent || !stageReferencing);
461 m_stagePresent[stageNdx] = stagePresent;
462 m_stageReferencing[stageNdx] = stageReferencing;
466 void ShaderSet::setStage (glu::ShaderType type, bool referencing)
468 DE_ASSERT(type < glu::SHADERTYPE_LAST);
469 m_stagePresent[type] = true;
470 m_stageReferencing[type] = referencing;
473 bool ShaderSet::isStagePresent (glu::ShaderType stage) const
475 DE_ASSERT(stage < glu::SHADERTYPE_LAST);
476 return m_stagePresent[stage];
479 bool ShaderSet::isStageReferencing (glu::ShaderType stage) const
481 DE_ASSERT(stage < glu::SHADERTYPE_LAST);
482 return m_stageReferencing[stage];
485 deUint32 ShaderSet::getReferencingMask (void) const
488 for (deUint32 stage = 0; stage < glu::SHADERTYPE_LAST; ++stage)
490 if (m_stageReferencing[stage])
491 mask |= (1u << stage);
496 class TransformFeedbackTarget : public Node
499 TransformFeedbackTarget (const SharedPtr& enclosing, const char* builtinVarName = DE_NULL)
500 : Node (TYPE_TRANSFORM_FEEDBACK_TARGET, enclosing)
501 , m_builtinVarName (builtinVarName)
505 const char* const m_builtinVarName;
508 } // ResourceDefinition
510 static glu::Precision getDataTypeDefaultPrecision (const glu::DataType& type)
512 if (glu::isDataTypeBoolOrBVec(type))
513 return glu::PRECISION_LAST;
514 else if (glu::isDataTypeScalarOrVector(type) || glu::isDataTypeMatrix(type))
515 return glu::PRECISION_HIGHP;
516 else if (glu::isDataTypeSampler(type))
517 return glu::PRECISION_HIGHP;
518 else if (glu::isDataTypeImage(type))
519 return glu::PRECISION_HIGHP;
520 else if (type == glu::TYPE_UINT_ATOMIC_COUNTER)
521 return glu::PRECISION_HIGHP;
524 return glu::PRECISION_LAST;
527 static de::MovePtr<ProgramInterfaceDefinition::Program> generateProgramDefinitionFromResource (const ResourceDefinition::Node* resource)
529 de::MovePtr<ProgramInterfaceDefinition::Program> program (new ProgramInterfaceDefinition::Program());
530 const ResourceDefinition::Node* head = resource;
532 if (head->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
534 DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));
539 BINDING_INTERFACE_BLOCK,
540 BINDING_DEFAULT_BLOCK
544 int autoAssignArraySize = 0;
545 const glu::DataType basicType = static_cast<const ResourceDefinition::Variable*>(resource)->m_dataType;
546 BindingType boundObject = BINDING_VARIABLE;
547 glu::VariableDeclaration variable (glu::VarType(basicType, getDataTypeDefaultPrecision(basicType)), "target");
548 glu::InterfaceBlock interfaceBlock;
549 ProgramInterfaceDefinition::DefaultBlock defaultBlock;
550 std::vector<std::string> feedbackTargetVaryingPath;
551 bool feedbackTargetSet = false;
554 if (glu::isDataTypeImage(basicType))
556 variable.memoryAccessQualifierBits |= glu::MEMORYACCESSQUALIFIER_READONLY_BIT;
557 variable.layout.binding = 1;
559 if (basicType >= glu::TYPE_IMAGE_2D && basicType <= glu::TYPE_IMAGE_3D)
560 variable.layout.format = glu::FORMATLAYOUT_RGBA8;
561 else if (basicType >= glu::TYPE_INT_IMAGE_2D && basicType <= glu::TYPE_INT_IMAGE_3D)
562 variable.layout.format = glu::FORMATLAYOUT_RGBA8I;
563 else if (basicType >= glu::TYPE_UINT_IMAGE_2D && basicType <= glu::TYPE_UINT_IMAGE_3D)
564 variable.layout.format = glu::FORMATLAYOUT_RGBA8UI;
569 // atomic counter specific
570 if (basicType == glu::TYPE_UINT_ATOMIC_COUNTER)
571 variable.layout.binding = 1;
573 for (head = head->getEnclosingNode(); head; head = head->getEnclosingNode())
575 if (head->getType() == ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER)
577 const ResourceDefinition::StorageQualifier* qualifier = static_cast<const ResourceDefinition::StorageQualifier*>(head);
579 DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(head));
581 if (boundObject == BINDING_VARIABLE)
583 DE_ASSERT(variable.storage == glu::STORAGE_LAST);
584 variable.storage = qualifier->m_storage;
586 else if (boundObject == BINDING_INTERFACE_BLOCK)
588 DE_ASSERT(interfaceBlock.storage == glu::STORAGE_LAST);
589 interfaceBlock.storage = qualifier->m_storage;
594 else if (head->getType() == ResourceDefinition::Node::TYPE_LAYOUT_QUALIFIER)
596 const ResourceDefinition::LayoutQualifier* qualifier = static_cast<const ResourceDefinition::LayoutQualifier*>(head);
597 glu::Layout* targetLayout = DE_NULL;
599 DE_ASSERT(dynamic_cast<const ResourceDefinition::LayoutQualifier*>(head));
601 if (boundObject == BINDING_VARIABLE)
602 targetLayout = &variable.layout;
603 else if (boundObject == BINDING_INTERFACE_BLOCK)
604 targetLayout = &interfaceBlock.layout;
608 if (qualifier->m_layout.location != -1)
609 targetLayout->location = qualifier->m_layout.location;
611 if (qualifier->m_layout.binding != -1)
612 targetLayout->binding = qualifier->m_layout.binding;
614 if (qualifier->m_layout.offset != -1)
615 targetLayout->offset = qualifier->m_layout.offset;
617 if (qualifier->m_layout.format != glu::FORMATLAYOUT_LAST)
618 targetLayout->format = qualifier->m_layout.format;
620 if (qualifier->m_layout.matrixOrder != glu::MATRIXORDER_LAST)
621 targetLayout->matrixOrder = qualifier->m_layout.matrixOrder;
623 else if (head->getType() == ResourceDefinition::Node::TYPE_INTERPOLATION_QUALIFIER)
625 const ResourceDefinition::InterpolationQualifier* qualifier = static_cast<const ResourceDefinition::InterpolationQualifier*>(head);
627 DE_ASSERT(dynamic_cast<const ResourceDefinition::InterpolationQualifier*>(head));
629 if (boundObject == BINDING_VARIABLE)
630 variable.interpolation = qualifier->m_interpolation;
634 else if (head->getType() == ResourceDefinition::Node::TYPE_ARRAY_ELEMENT)
636 DE_ASSERT(dynamic_cast<const ResourceDefinition::ArrayElement*>(head));
638 const ResourceDefinition::ArrayElement* arrayElement = static_cast<const ResourceDefinition::ArrayElement*>(head);
641 // Vary array size per level
642 if (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::DEFAULT_SIZE)
644 if (--autoAssignArraySize <= 1)
645 autoAssignArraySize = 3;
647 arraySize = autoAssignArraySize;
649 else if (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::UNSIZED_ARRAY)
650 arraySize = glu::VarType::UNSIZED_ARRAY;
652 arraySize = arrayElement->m_arraySize;
654 if (boundObject == BINDING_VARIABLE)
655 variable.varType = glu::VarType(variable.varType, arraySize);
656 else if (boundObject == BINDING_INTERFACE_BLOCK)
657 interfaceBlock.dimensions.push_back(arraySize);
661 if (feedbackTargetSet)
662 feedbackTargetVaryingPath.back().append("[0]");
664 else if (head->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER)
666 DE_ASSERT(dynamic_cast<const ResourceDefinition::StructMember*>(head));
667 DE_ASSERT(boundObject == BINDING_VARIABLE);
669 // Struct members cannot contain any qualifiers except precision
670 DE_ASSERT(variable.interpolation == glu::INTERPOLATION_LAST);
671 DE_ASSERT(variable.layout == glu::Layout());
672 DE_ASSERT(variable.memoryAccessQualifierBits == 0);
673 DE_ASSERT(variable.storage == glu::STORAGE_LAST);
676 glu::StructType* structPtr = new glu::StructType(("StructType" + de::toString(structNdx++)).c_str());
677 structPtr->addMember(variable.name.c_str(), variable.varType);
679 variable = glu::VariableDeclaration(glu::VarType(structPtr), "target");
682 if (feedbackTargetSet)
683 feedbackTargetVaryingPath.push_back("target");
685 else if (head->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
687 DE_ASSERT(dynamic_cast<const ResourceDefinition::InterfaceBlock*>(head));
688 DE_ASSERT(boundObject == BINDING_VARIABLE);
690 const bool named = static_cast<const ResourceDefinition::InterfaceBlock*>(head)->m_named;
692 boundObject = BINDING_INTERFACE_BLOCK;
694 interfaceBlock.interfaceName = "TargetInterface";
695 interfaceBlock.instanceName = (named) ? ("targetInstance") : ("");
696 interfaceBlock.variables.push_back(variable);
698 if (feedbackTargetSet && !interfaceBlock.instanceName.empty())
699 feedbackTargetVaryingPath.push_back(interfaceBlock.interfaceName);
701 else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
703 DE_ASSERT(dynamic_cast<const ResourceDefinition::DefaultBlock*>(head));
704 DE_ASSERT(boundObject == BINDING_VARIABLE || boundObject == BINDING_INTERFACE_BLOCK);
706 if (boundObject == BINDING_VARIABLE)
707 defaultBlock.variables.push_back(variable);
708 else if (boundObject == BINDING_INTERFACE_BLOCK)
709 defaultBlock.interfaceBlocks.push_back(interfaceBlock);
713 boundObject = BINDING_DEFAULT_BLOCK;
715 else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER)
717 DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(head));
719 const ResourceDefinition::Shader* shaderDef = static_cast<const ResourceDefinition::Shader*>(head);
720 ProgramInterfaceDefinition::Shader* shader = program->addShader(shaderDef->m_type, shaderDef->m_version);
722 shader->getDefaultBlock() = defaultBlock;
724 else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER_SET)
726 DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(head));
728 const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(head);
730 for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
732 if (shaderDef->isStagePresent((glu::ShaderType)shaderType))
734 ProgramInterfaceDefinition::Shader* shader = program->addShader((glu::ShaderType)shaderType, shaderDef->m_version);
736 if (shaderDef->isStageReferencing((glu::ShaderType)shaderType))
737 shader->getDefaultBlock() = defaultBlock;
741 else if (head->getType() == ResourceDefinition::Node::TYPE_PROGRAM)
743 DE_ASSERT(dynamic_cast<const ResourceDefinition::Program*>(head));
745 const ResourceDefinition::Program* programDef = static_cast<const ResourceDefinition::Program*>(head);
747 program->setSeparable(programDef->m_separable);
749 DE_ASSERT(feedbackTargetSet == !feedbackTargetVaryingPath.empty());
750 if (!feedbackTargetVaryingPath.empty())
752 std::ostringstream buf;
754 for (std::vector<std::string>::reverse_iterator it = feedbackTargetVaryingPath.rbegin(); it != feedbackTargetVaryingPath.rend(); ++it)
756 if (it != feedbackTargetVaryingPath.rbegin())
761 program->addTransformFeedbackVarying(buf.str());
762 program->setTransformFeedbackMode(GL_INTERLEAVED_ATTRIBS);
766 else if (head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
768 DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(head));
770 const ResourceDefinition::TransformFeedbackTarget* feedbackTarget = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(head);
772 DE_ASSERT(feedbackTarget->m_builtinVarName == DE_NULL);
773 DE_UNREF(feedbackTarget);
775 feedbackTargetSet = true;
776 feedbackTargetVaryingPath.push_back(variable.name);
785 else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK ||
786 head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
788 const char* feedbackTargetVaryingName = DE_NULL;
790 // empty default block
792 for (; head; head = head->getEnclosingNode())
794 if (head->getType() == ResourceDefinition::Node::TYPE_SHADER)
796 DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(head));
798 const ResourceDefinition::Shader* shaderDef = static_cast<const ResourceDefinition::Shader*>(head);
800 program->addShader(shaderDef->m_type, shaderDef->m_version);
802 else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER_SET)
804 DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(head));
806 const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(head);
808 for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
809 if (shaderDef->isStagePresent((glu::ShaderType)shaderType))
810 program->addShader((glu::ShaderType)shaderType, shaderDef->m_version);
812 else if (head->getType() == ResourceDefinition::Node::TYPE_PROGRAM)
814 DE_ASSERT(dynamic_cast<const ResourceDefinition::Program*>(head));
816 const ResourceDefinition::Program* programDef = static_cast<const ResourceDefinition::Program*>(head);
818 program->setSeparable(programDef->m_separable);
819 if (feedbackTargetVaryingName)
821 program->addTransformFeedbackVarying(std::string(feedbackTargetVaryingName));
822 program->setTransformFeedbackMode(GL_INTERLEAVED_ATTRIBS);
826 else if (head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
828 DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(head));
830 const ResourceDefinition::TransformFeedbackTarget* feedbackTarget = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(head);
832 DE_ASSERT(feedbackTarget->m_builtinVarName != DE_NULL);
834 feedbackTargetVaryingName = feedbackTarget->m_builtinVarName;
836 else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
847 if (program->hasStage(glu::SHADERTYPE_GEOMETRY))
848 program->setGeometryNumOutputVertices(1);
849 if (program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
850 program->setTessellationNumOutputPatchVertices(1);
855 static void checkAndLogProgram (const glu::ShaderProgram& program, const ProgramInterfaceDefinition::Program* programDefinition, const glw::Functions& gl, tcu::TestLog& log)
857 const tcu::ScopedLogSection section(log, "Program", "Program");
862 log << tcu::TestLog::Message << "Program build failed, checking if program exceeded implementation limits" << tcu::TestLog::EndMessage;
863 checkProgramResourceUsage(programDefinition, gl, log);
866 throw tcu::TestError("could not build program");
870 // Resource list query case
872 class ResourceListTestCase : public TestCase
875 ResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, ProgramInterface interface, const char* name = DE_NULL);
876 ~ResourceListTestCase (void);
881 IterateResult iterate (void);
883 void queryResourceList (std::vector<std::string>& dst, glw::GLuint program);
884 bool verifyResourceList (const std::vector<std::string>& resourceList, const std::vector<std::string>& expectedResources);
885 bool verifyResourceIndexQuery (const std::vector<std::string>& resourceList, const std::vector<std::string>& referenceResources, glw::GLuint program);
886 bool verifyMaxNameLength (const std::vector<std::string>& referenceResourceList, glw::GLuint program);
888 static std::string genTestCaseName (ProgramInterface interface, const ResourceDefinition::Node*);
889 static bool isArrayedInterface (ProgramInterface interface, deUint32 stageBits);
891 const ProgramInterface m_programInterface;
892 ResourceDefinition::Node::SharedPtr m_targetResource;
893 ProgramInterfaceDefinition::Program* m_programDefinition;
896 ResourceListTestCase::ResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, ProgramInterface interface, const char* name)
897 : TestCase (context, (name == DE_NULL) ? (genTestCaseName(interface, targetResource.get()).c_str()) : (name), "")
898 , m_programInterface (interface)
899 , m_targetResource (targetResource)
900 , m_programDefinition (DE_NULL)
902 // GL_ATOMIC_COUNTER_BUFFER: no resource names
903 DE_ASSERT(m_programInterface != PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER);
906 ResourceListTestCase::~ResourceListTestCase (void)
911 void ResourceListTestCase::init (void)
913 m_programDefinition = generateProgramDefinitionFromResource(m_targetResource.get()).release();
915 if ((m_programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION)) &&
916 !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
918 throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
920 if (m_programDefinition->hasStage(glu::SHADERTYPE_GEOMETRY) &&
921 !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
923 throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
925 if (programContainsIOBlocks(m_programDefinition) &&
926 !m_context.getContextInfo().isExtensionSupported("GL_EXT_shader_io_blocks"))
928 throw tcu::NotSupportedError("Test requires GL_EXT_shader_io_blocks extension");
932 void ResourceListTestCase::deinit (void)
934 m_targetResource.clear();
936 delete m_programDefinition;
937 m_programDefinition = DE_NULL;
940 ResourceListTestCase::IterateResult ResourceListTestCase::iterate (void)
942 const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_programDefinition));
944 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
945 checkAndLogProgram(program, m_programDefinition, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
947 // Check resource list
949 const tcu::ScopedLogSection section (m_testCtx.getLog(), "ResourceList", "Resource list");
950 std::vector<std::string> resourceList;
951 std::vector<std::string> expectedResources;
953 queryResourceList(resourceList, program.getProgram());
954 expectedResources = getProgramInterfaceResourceList(m_programDefinition, m_programInterface);
956 // verify the list and the expected list match
958 if (!verifyResourceList(resourceList, expectedResources))
959 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid resource list");
961 // verify GetProgramResourceIndex() matches the indices of the list
963 if (!verifyResourceIndexQuery(resourceList, expectedResources, program.getProgram()))
964 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GetProgramResourceIndex returned unexpected values");
966 // Verify MAX_NAME_LENGTH
967 if (!verifyMaxNameLength(resourceList, program.getProgram()))
968 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "MAX_NAME_LENGTH invalid");
974 void ResourceListTestCase::queryResourceList (std::vector<std::string>& dst, glw::GLuint program)
976 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
977 const glw::GLenum programInterface = getProgramInterfaceGLEnum(m_programInterface);
978 glw::GLint numActiveResources = 0;
979 glw::GLint maxNameLength = 0;
980 std::vector<char> buffer;
982 m_testCtx.getLog() << tcu::TestLog::Message << "Querying " << glu::getProgramInterfaceName(programInterface) << " interface:" << tcu::TestLog::EndMessage;
984 gl.getProgramInterfaceiv(program, programInterface, GL_ACTIVE_RESOURCES, &numActiveResources);
985 gl.getProgramInterfaceiv(program, programInterface, GL_MAX_NAME_LENGTH, &maxNameLength);
986 GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
988 m_testCtx.getLog() << tcu::TestLog::Message
989 << "\tGL_ACTIVE_RESOURCES = " << numActiveResources << "\n"
990 << "\tGL_MAX_NAME_LENGTH = " << maxNameLength
991 << tcu::TestLog::EndMessage;
993 m_testCtx.getLog() << tcu::TestLog::Message << "Querying all active resources" << tcu::TestLog::EndMessage;
995 buffer.resize(maxNameLength+1, '\0');
997 for (int resourceNdx = 0; resourceNdx < numActiveResources; ++resourceNdx)
999 glw::GLint written = 0;
1001 gl.getProgramResourceName(program, programInterface, resourceNdx, maxNameLength, &written, &buffer[0]);
1002 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource name");
1004 dst.push_back(std::string(&buffer[0], written));
1008 bool ResourceListTestCase::verifyResourceList (const std::vector<std::string>& resourceList, const std::vector<std::string>& expectedResources)
1012 // Log and compare resource lists
1014 m_testCtx.getLog() << tcu::TestLog::Message << "GL returned resources:" << tcu::TestLog::EndMessage;
1016 for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1018 // dummyZero is a uniform that may be added by
1019 // generateProgramInterfaceProgramSources. Omit it here to avoid
1020 // confusion about the output.
1021 if (resourceList[ndx] != getDummyZeroUniformName())
1022 m_testCtx.getLog() << tcu::TestLog::Message << "\t" << ndx << ": " << resourceList[ndx] << tcu::TestLog::EndMessage;
1025 m_testCtx.getLog() << tcu::TestLog::Message << "Expected list of resources:" << tcu::TestLog::EndMessage;
1027 for (int ndx = 0; ndx < (int)expectedResources.size(); ++ndx)
1028 m_testCtx.getLog() << tcu::TestLog::Message << "\t" << ndx << ": " << expectedResources[ndx] << tcu::TestLog::EndMessage;
1030 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying resource list contents." << tcu::TestLog::EndMessage;
1032 for (int ndx = 0; ndx < (int)expectedResources.size(); ++ndx)
1034 if (!de::contains(resourceList.begin(), resourceList.end(), expectedResources[ndx]))
1036 m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource list did not contain active resource " << expectedResources[ndx] << tcu::TestLog::EndMessage;
1041 for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1043 if (!de::contains(expectedResources.begin(), expectedResources.end(), resourceList[ndx]))
1045 // Ignore all builtin variables or the variable dummyZero,
1046 // mismatch causes errors otherwise. dummyZero is a uniform that
1047 // may be added by generateProgramInterfaceProgramSources.
1048 if (deStringBeginsWith(resourceList[ndx].c_str(), "gl_") == DE_FALSE &&
1049 resourceList[ndx] != getDummyZeroUniformName())
1051 m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource list contains unexpected resource name " << resourceList[ndx] << tcu::TestLog::EndMessage;
1055 m_testCtx.getLog() << tcu::TestLog::Message << "Note, resource list contains unknown built-in " << resourceList[ndx] << ". This variable is ignored." << tcu::TestLog::EndMessage;
1062 bool ResourceListTestCase::verifyResourceIndexQuery (const std::vector<std::string>& resourceList, const std::vector<std::string>& referenceResources, glw::GLuint program)
1064 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1065 const glw::GLenum programInterface = getProgramInterfaceGLEnum(m_programInterface);
1068 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying GetProgramResourceIndex returns correct indices for resource names." << tcu::TestLog::EndMessage;
1070 for (int ndx = 0; ndx < (int)referenceResources.size(); ++ndx)
1072 const glw::GLuint index = gl.getProgramResourceIndex(program, programInterface, referenceResources[ndx].c_str());
1073 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1075 if (index == GL_INVALID_INDEX)
1077 m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx] << "\" got index GL_INVALID_INDEX." << tcu::TestLog::EndMessage;
1080 else if ((int)index >= (int)resourceList.size())
1082 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;
1085 else if (resourceList[index] != referenceResources[ndx])
1087 m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx] << "\" got index (index = " << index << ") of another resource (" << resourceList[index] << ")." << tcu::TestLog::EndMessage;
1092 // Query for "name" should match "name[0]" except for XFB
1094 if (m_programInterface != PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING)
1096 for (int ndx = 0; ndx < (int)referenceResources.size(); ++ndx)
1098 if (de::endsWith(referenceResources[ndx], "[0]"))
1100 const std::string queryString = referenceResources[ndx].substr(0, referenceResources[ndx].length()-3);
1101 const glw::GLuint index = gl.getProgramResourceIndex(program, programInterface, queryString.c_str());
1102 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1104 if (index == GL_INVALID_INDEX)
1106 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" resulted in index GL_INVALID_INDEX." << tcu::TestLog::EndMessage;
1109 else if ((int)index >= (int)resourceList.size())
1111 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" resulted in index " << index << " (larger or equal to GL_ACTIVE_RESOURCES)." << tcu::TestLog::EndMessage;
1114 else if (resourceList[index] != queryString + "[0]")
1116 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" got index (index = " << index << ") of another resource (\"" << resourceList[index] << "\")." << tcu::TestLog::EndMessage;
1126 bool ResourceListTestCase::verifyMaxNameLength (const std::vector<std::string>& resourceList, glw::GLuint program)
1128 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1129 const glw::GLenum programInterface = getProgramInterfaceGLEnum(m_programInterface);
1130 glw::GLint maxNameLength = 0;
1131 glw::GLint expectedMaxNameLength = 0;
1133 gl.getProgramInterfaceiv(program, programInterface, GL_MAX_NAME_LENGTH, &maxNameLength);
1134 GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
1136 for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1137 expectedMaxNameLength = de::max(expectedMaxNameLength, (int)resourceList[ndx].size() + 1);
1139 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying MAX_NAME_LENGTH, expecting " << expectedMaxNameLength << " (i.e. consistent with the queried resource list)" << tcu::TestLog::EndMessage;
1141 if (expectedMaxNameLength != maxNameLength)
1143 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got " << maxNameLength << tcu::TestLog::EndMessage;
1150 std::string ResourceListTestCase::genTestCaseName (ProgramInterface interface, const ResourceDefinition::Node* root)
1152 bool isImplicitlySizedArray = false;
1153 bool hasVariable = false;
1154 bool accumulateName = true;
1155 std::string buf = "var";
1158 for (const ResourceDefinition::Node* node = root; node; node = node->getEnclosingNode())
1160 switch (node->getType())
1162 case ResourceDefinition::Node::TYPE_VARIABLE:
1168 case ResourceDefinition::Node::TYPE_STRUCT_MEMBER:
1175 case ResourceDefinition::Node::TYPE_ARRAY_ELEMENT:
1177 DE_ASSERT(dynamic_cast<const ResourceDefinition::ArrayElement*>(node));
1178 const ResourceDefinition::ArrayElement* arrayElement = static_cast<const ResourceDefinition::ArrayElement*>(node);
1180 isImplicitlySizedArray = (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::UNSIZED_ARRAY);
1187 case ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER:
1189 DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(node));
1190 const ResourceDefinition::StorageQualifier* storageDef = static_cast<const ResourceDefinition::StorageQualifier*>(node);
1192 if (storageDef->m_storage == glu::STORAGE_PATCH_IN ||
1193 storageDef->m_storage == glu::STORAGE_PATCH_OUT)
1201 case ResourceDefinition::Node::TYPE_SHADER:
1202 case ResourceDefinition::Node::TYPE_SHADER_SET:
1204 bool arrayedInterface;
1206 if (node->getType() == ResourceDefinition::Node::TYPE_SHADER)
1208 DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(node));
1209 const ResourceDefinition::Shader* shaderDef = static_cast<const ResourceDefinition::Shader*>(node);
1211 arrayedInterface = isArrayedInterface(interface, (1u << shaderDef->m_type));
1215 DE_ASSERT(node->getType() == ResourceDefinition::Node::TYPE_SHADER_SET);
1216 DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(node));
1217 const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(node);
1219 arrayedInterface = isArrayedInterface(interface, shaderDef->getReferencingMask());
1222 if (arrayedInterface && isImplicitlySizedArray)
1224 // omit implicit arrayness from name, i.e. remove trailing "_array"
1225 DE_ASSERT(de::endsWith(buf, "_array"));
1226 buf = buf.substr(0, buf.length() - 6);
1232 case ResourceDefinition::Node::TYPE_INTERFACE_BLOCK:
1234 accumulateName = false;
1244 return prefix + "empty";
1246 return prefix + buf;
1249 bool ResourceListTestCase::isArrayedInterface (ProgramInterface interface, deUint32 stageBits)
1251 if (interface == PROGRAMINTERFACE_PROGRAM_INPUT)
1253 const glu::ShaderType firstStage = getShaderMaskFirstStage(stageBits);
1254 return firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
1255 firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
1256 firstStage == glu::SHADERTYPE_GEOMETRY;
1258 else if (interface == PROGRAMINTERFACE_PROGRAM_OUTPUT)
1260 const glu::ShaderType lastStage = getShaderMaskLastStage(stageBits);
1261 return lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL;
1266 // Resouce property query case
1268 class ResourceTestCase : public ProgramInterfaceQueryTestCase
1271 ResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, const ProgramResourceQueryTestTarget& queryTarget, const char* name = DE_NULL);
1272 ~ResourceTestCase (void);
1277 const ProgramInterfaceDefinition::Program* getProgramDefinition (void) const;
1278 std::vector<std::string> getQueryTargetResources (void) const;
1280 static std::string genTestCaseName (const ResourceDefinition::Node*);
1281 static std::string genMultilineDescription (const ResourceDefinition::Node*);
1283 ResourceDefinition::Node::SharedPtr m_targetResource;
1284 ProgramInterfaceDefinition::Program* m_program;
1285 std::vector<std::string> m_targetResources;
1288 ResourceTestCase::ResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, const ProgramResourceQueryTestTarget& queryTarget, const char* name)
1289 : ProgramInterfaceQueryTestCase (context, (name == DE_NULL) ? (genTestCaseName(targetResource.get()).c_str()) : (name), "", queryTarget)
1290 , m_targetResource (targetResource)
1291 , m_program (DE_NULL)
1295 ResourceTestCase::~ResourceTestCase (void)
1300 void ResourceTestCase::init (void)
1303 << tcu::TestLog::Message
1304 << genMultilineDescription(m_targetResource.get())
1305 << tcu::TestLog::EndMessage;
1309 // Generate interface with target resource
1310 m_program = generateProgramDefinitionFromResource(m_targetResource.get()).release();
1311 m_targetResources = getProgramInterfaceResourceList(m_program, getTargetInterface());
1315 void ResourceTestCase::deinit (void)
1317 m_targetResource.clear();
1320 m_program = DE_NULL;
1322 m_targetResources = std::vector<std::string>();
1325 const ProgramInterfaceDefinition::Program* ResourceTestCase::getProgramDefinition (void) const
1330 std::vector<std::string> ResourceTestCase::getQueryTargetResources (void) const
1332 return m_targetResources;
1335 std::string ResourceTestCase::genTestCaseName (const ResourceDefinition::Node* resource)
1337 if (resource->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
1339 DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));
1341 const ResourceDefinition::Variable* variable = static_cast<const ResourceDefinition::Variable*>(resource);
1343 return convertGLTypeNameToTestName(glu::getDataTypeName(variable->m_dataType));
1350 std::string ResourceTestCase::genMultilineDescription (const ResourceDefinition::Node* resource)
1352 if (resource->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
1354 DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));
1356 const ResourceDefinition::Variable* varDef = static_cast<const ResourceDefinition::Variable*>(resource);
1357 std::ostringstream buf;
1358 std::ostringstream structureDescriptor;
1359 std::string uniformType;
1361 for (const ResourceDefinition::Node* node = resource; node; node = node->getEnclosingNode())
1363 if (node->getType() == ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER)
1365 DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(node));
1367 const ResourceDefinition::StorageQualifier* storageDef = static_cast<const ResourceDefinition::StorageQualifier*>(node);
1369 uniformType = std::string(" ") + glu::getStorageName(storageDef->m_storage);
1370 structureDescriptor << "\n\tdeclared as \"" << glu::getStorageName(storageDef->m_storage) << "\"";
1373 if (node->getType() == ResourceDefinition::Node::TYPE_ARRAY_ELEMENT)
1374 structureDescriptor << "\n\tarray";
1376 if (node->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER)
1377 structureDescriptor << "\n\tin a struct";
1379 if (node->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
1380 structureDescriptor << "\n\tin the default block";
1382 if (node->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
1383 structureDescriptor << "\n\tin an interface block";
1386 buf << "Querying properties of " << glu::getDataTypeName(varDef->m_dataType) << uniformType << " variable.\n"
1388 << "\t" << glu::getDataTypeName(varDef->m_dataType)
1389 << structureDescriptor.str();
1393 else if (resource->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
1395 DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(resource));
1397 const ResourceDefinition::TransformFeedbackTarget* xfbDef = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(resource);
1399 DE_ASSERT(xfbDef->m_builtinVarName);
1401 return std::string("Querying properties of a builtin variable ") + xfbDef->m_builtinVarName;
1408 class ResourceNameBufferLimitCase : public TestCase
1411 ResourceNameBufferLimitCase (Context& context, const char* name, const char* description);
1412 ~ResourceNameBufferLimitCase (void);
1415 IterateResult iterate (void);
1418 ResourceNameBufferLimitCase::ResourceNameBufferLimitCase (Context& context, const char* name, const char* description)
1419 : TestCase(context, name, description)
1423 ResourceNameBufferLimitCase::~ResourceNameBufferLimitCase (void)
1427 ResourceNameBufferLimitCase::IterateResult ResourceNameBufferLimitCase::iterate (void)
1429 static const char* const computeSource = "#version 310 es\n"
1430 "layout(local_size_x = 1) in;\n"
1431 "uniform highp int u_uniformWithALongName;\n"
1432 "writeonly buffer OutputBufferBlock { highp int b_output_int; };\n"
1435 " b_output_int = u_uniformWithALongName;\n"
1438 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1439 const glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(computeSource));
1440 glw::GLuint uniformIndex;
1442 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1446 const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program", "Program");
1448 m_testCtx.getLog() << program;
1449 if (!program.isOk())
1450 throw tcu::TestError("could not build program");
1453 uniformIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_uniformWithALongName");
1454 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1456 if (uniformIndex == GL_INVALID_INDEX)
1457 throw tcu::TestError("Uniform u_uniformWithALongName resource index was GL_INVALID_INDEX");
1459 // Query with different sized buffers, len("u_uniformWithALongName") == 22
1464 const char* description;
1469 { "Query to larger buffer", 24, true },
1470 { "Query to buffer the same size", 23, true },
1471 { "Query to one byte too small buffer", 22, true },
1472 { "Query to one byte buffer", 1, true },
1473 { "Query to zero sized buffer", 0, true },
1474 { "Query to one byte too small buffer, null length argument", 22, false },
1475 { "Query to one byte buffer, null length argument", 1, false },
1476 { "Query to zero sized buffer, null length argument", 0, false },
1479 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(querySizes); ++ndx)
1481 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Query", querySizes[ndx].description);
1482 const int uniformNameLen = 22;
1483 const int expectedWriteLen = (querySizes[ndx].querySize != 0) ? (de::min(uniformNameLen, (querySizes[ndx].querySize - 1))) : (0);
1485 glw::GLsizei written = -1;
1487 // One byte for guard
1488 DE_ASSERT((int)sizeof(buffer) > querySizes[ndx].querySize);
1490 deMemset(buffer, 'x', sizeof(buffer));
1492 if (querySizes[ndx].querySize)
1494 << tcu::TestLog::Message
1495 << "Querying uniform name to a buffer of size " << querySizes[ndx].querySize
1496 << ", expecting query to write " << expectedWriteLen << " bytes followed by a null terminator"
1497 << tcu::TestLog::EndMessage;
1500 << tcu::TestLog::Message
1501 << "Querying uniform name to a buffer of size " << querySizes[ndx].querySize
1502 << ", expecting query to write 0 bytes"
1503 << tcu::TestLog::EndMessage;
1505 gl.getProgramResourceName(program.getProgram(), GL_UNIFORM, uniformIndex, querySizes[ndx].querySize, (querySizes[ndx].returnLength) ? (&written) : (DE_NULL), buffer);
1506 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource name");
1508 if (querySizes[ndx].returnLength && written != expectedWriteLen)
1510 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected write length of " << expectedWriteLen << ", got " << written << tcu::TestLog::EndMessage;
1511 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected write lenght");
1513 else if (querySizes[ndx].querySize != 0 && buffer[expectedWriteLen] != 0)
1515 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected null terminator at " << expectedWriteLen << ", got dec=" << (int)buffer[expectedWriteLen] << tcu::TestLog::EndMessage;
1516 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Missing null terminator");
1518 else if (querySizes[ndx].querySize != 0 && buffer[expectedWriteLen+1] != 'x')
1520 m_testCtx.getLog() << tcu::TestLog::Message << "Error, guard at index " << (expectedWriteLen+1) << " was modified, got dec=" << (int)buffer[expectedWriteLen+1] << tcu::TestLog::EndMessage;
1521 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrote over buffer size");
1523 else if (querySizes[ndx].querySize == 0 && buffer[0] != 'x')
1525 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;
1526 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents were modified");
1534 class ResourceQueryBufferLimitCase : public TestCase
1537 ResourceQueryBufferLimitCase (Context& context, const char* name, const char* description);
1538 ~ResourceQueryBufferLimitCase (void);
1541 IterateResult iterate (void);
1544 ResourceQueryBufferLimitCase::ResourceQueryBufferLimitCase (Context& context, const char* name, const char* description)
1545 : TestCase(context, name, description)
1549 ResourceQueryBufferLimitCase::~ResourceQueryBufferLimitCase (void)
1553 ResourceQueryBufferLimitCase::IterateResult ResourceQueryBufferLimitCase::iterate (void)
1555 static const char* const computeSource = "#version 310 es\n"
1556 "layout(local_size_x = 1) in;\n"
1557 "uniform highp int u_uniform;\n"
1558 "writeonly buffer OutputBufferBlock { highp int b_output_int; };\n"
1561 " b_output_int = u_uniform;\n"
1564 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1565 const glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(computeSource));
1566 glw::GLuint uniformIndex;
1568 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1572 const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program", "Program");
1574 m_testCtx.getLog() << program;
1575 if (!program.isOk())
1576 throw tcu::TestError("could not build program");
1579 uniformIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_uniform");
1580 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1582 if (uniformIndex == GL_INVALID_INDEX)
1583 throw tcu::TestError("Uniform u_uniform resource index was GL_INVALID_INDEX");
1585 // Query uniform properties
1590 const char* description;
1596 { "Query to a larger buffer", 2, 3, true },
1597 { "Query to too small a buffer", 3, 2, true },
1598 { "Query to zero sized buffer", 3, 0, true },
1599 { "Query to a larger buffer, null length argument", 2, 3, false },
1600 { "Query to too small a buffer, null length argument", 3, 2, false },
1601 { "Query to zero sized buffer, null length argument", 3, 0, false },
1604 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(querySizes); ++ndx)
1606 const tcu::ScopedLogSection section (m_testCtx.getLog(), "QueryToLarger", querySizes[ndx].description);
1607 const glw::GLenum props[] = { GL_LOCATION, GL_LOCATION, GL_LOCATION };
1608 const int expectedWriteLen = de::min(querySizes[ndx].bufferSize, querySizes[ndx].numProps);
1609 int params[] = { 255, 255, 255, 255 };
1610 glw::GLsizei written = -1;
1612 DE_ASSERT(querySizes[ndx].numProps <= DE_LENGTH_OF_ARRAY(props));
1613 DE_ASSERT(querySizes[ndx].bufferSize < DE_LENGTH_OF_ARRAY(params)); // leave at least one element for overflow detection
1616 << tcu::TestLog::Message
1617 << "Querying " << querySizes[ndx].numProps << " uniform prop(s) to a buffer with size " << querySizes[ndx].bufferSize << ". Expecting query to return " << expectedWriteLen << " prop(s)"
1618 << tcu::TestLog::EndMessage;
1620 gl.getProgramResourceiv(program.getProgram(), GL_UNIFORM, uniformIndex, querySizes[ndx].numProps, props, querySizes[ndx].bufferSize, (querySizes[ndx].returnLength) ? (&written) : (DE_NULL), params);
1621 GLU_EXPECT_NO_ERROR(gl.getError(), "query program resources");
1623 if (querySizes[ndx].returnLength && written != expectedWriteLen)
1625 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected write length of " << expectedWriteLen << ", got " << written << tcu::TestLog::EndMessage;
1626 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected write lenght");
1628 else if (params[expectedWriteLen] != 255)
1630 m_testCtx.getLog() << tcu::TestLog::Message << "Error, guard at index " << (expectedWriteLen) << " was modified. Was 255 before call, got dec=" << params[expectedWriteLen] << tcu::TestLog::EndMessage;
1631 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrote over buffer size");
1639 class InterfaceBlockBaseCase : public TestCase
1644 CASE_NAMED_BLOCK = 0,
1651 InterfaceBlockBaseCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
1652 ~InterfaceBlockBaseCase (void);
1659 const glu::Storage m_storage;
1660 const CaseType m_caseType;
1661 ProgramInterfaceDefinition::Program* m_program;
1664 InterfaceBlockBaseCase::InterfaceBlockBaseCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
1665 : TestCase (context, name, description)
1666 , m_storage (storage)
1667 , m_caseType (caseType)
1668 , m_program (DE_NULL)
1670 DE_ASSERT(storage == glu::STORAGE_UNIFORM || storage == glu::STORAGE_BUFFER);
1673 InterfaceBlockBaseCase::~InterfaceBlockBaseCase (void)
1678 void InterfaceBlockBaseCase::init (void)
1680 ProgramInterfaceDefinition::Shader* shader;
1682 m_program = new ProgramInterfaceDefinition::Program();
1683 shader = m_program->addShader(glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES);
1685 // PrecedingInterface
1687 glu::InterfaceBlock precedingInterfaceBlock;
1689 precedingInterfaceBlock.interfaceName = "PrecedingInterface";
1690 precedingInterfaceBlock.layout.binding = 0;
1691 precedingInterfaceBlock.storage = m_storage;
1692 precedingInterfaceBlock.instanceName = "precedingInstance";
1694 precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "precedingMember"));
1696 // Unsized array type
1697 if (m_storage == glu::STORAGE_BUFFER)
1698 precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY), "precedingMemberUnsizedArray"));
1700 precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 2), "precedingMemberArray"));
1702 shader->getDefaultBlock().interfaceBlocks.push_back(precedingInterfaceBlock);
1707 glu::InterfaceBlock targetInterfaceBlock;
1709 targetInterfaceBlock.interfaceName = "TargetInterface";
1710 targetInterfaceBlock.layout.binding = 1;
1711 targetInterfaceBlock.storage = m_storage;
1713 if (m_caseType == CASE_UNNAMED_BLOCK)
1714 targetInterfaceBlock.instanceName = "";
1716 targetInterfaceBlock.instanceName = "targetInstance";
1718 if (m_caseType == CASE_BLOCK_ARRAY)
1719 targetInterfaceBlock.dimensions.push_back(2);
1723 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "blockMemberBasic"));
1728 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 3), "blockMemberArray"));
1733 glu::StructType* structPtr = new glu::StructType("StructType");
1734 structPtr->addMember("structMemberBasic", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP));
1735 structPtr->addMember("structMemberArray", glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 2));
1737 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(structPtr), 2), "blockMemberStruct"));
1740 // Unsized array type
1741 if (m_storage == glu::STORAGE_BUFFER)
1742 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY), "blockMemberUnsizedArray"));
1744 shader->getDefaultBlock().interfaceBlocks.push_back(targetInterfaceBlock);
1747 // TrailingInterface
1749 glu::InterfaceBlock trailingInterfaceBlock;
1751 trailingInterfaceBlock.interfaceName = "TrailingInterface";
1752 trailingInterfaceBlock.layout.binding = 3;
1753 trailingInterfaceBlock.storage = m_storage;
1754 trailingInterfaceBlock.instanceName = "trailingInstance";
1755 trailingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "trailingMember"));
1757 shader->getDefaultBlock().interfaceBlocks.push_back(trailingInterfaceBlock);
1760 DE_ASSERT(m_program->isValid());
1763 void InterfaceBlockBaseCase::deinit (void)
1766 m_program = DE_NULL;
1769 class InterfaceBlockActiveVariablesTestCase : public InterfaceBlockBaseCase
1772 InterfaceBlockActiveVariablesTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
1775 IterateResult iterate (void);
1778 InterfaceBlockActiveVariablesTestCase::InterfaceBlockActiveVariablesTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
1779 : InterfaceBlockBaseCase(context, name, description, storage, caseType)
1783 InterfaceBlockActiveVariablesTestCase::IterateResult InterfaceBlockActiveVariablesTestCase::iterate (void)
1785 const ProgramInterface programInterface = (m_storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
1786 (m_storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
1787 (PROGRAMINTERFACE_LAST);
1788 const glw::GLenum programGLInterfaceValue = getProgramInterfaceGLEnum(programInterface);
1789 const glw::GLenum programMemberInterfaceValue = (m_storage == glu::STORAGE_UNIFORM) ? (GL_UNIFORM) :
1790 (m_storage == glu::STORAGE_BUFFER) ? (GL_BUFFER_VARIABLE) :
1792 const std::vector<std::string> blockNames = getProgramInterfaceResourceList(m_program, programInterface);
1793 glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
1794 int expectedMaxNumActiveVariables = 0;
1796 DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
1798 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1799 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1801 // Verify all blocks
1803 for (int blockNdx = 0; blockNdx < (int)blockNames.size(); ++blockNdx)
1805 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Block", "Block \"" + blockNames[blockNdx] + "\"");
1806 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1807 const glw::GLuint resourceNdx = gl.getProgramResourceIndex(program.getProgram(), programGLInterfaceValue, blockNames[blockNdx].c_str());
1808 glw::GLint numActiveResources;
1809 std::vector<std::string> activeResourceNames;
1811 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1813 if (resourceNdx == GL_INVALID_INDEX)
1815 m_testCtx.getLog() << tcu::TestLog::Message << "Error, getProgramResourceIndex returned GL_INVALID_INDEX for \"" << blockNames[blockNdx] << "\"" << tcu::TestLog::EndMessage;
1816 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Resource not found");
1820 // query block information
1823 const glw::GLenum props[] = { GL_NUM_ACTIVE_VARIABLES };
1824 glw::GLint retBuffer[2] = { -1, -1 };
1825 glw::GLint written = -1;
1827 gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, DE_LENGTH_OF_ARRAY(props), props, 1, &written, retBuffer);
1828 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_NUM_ACTIVE_VARIABLES");
1830 numActiveResources = retBuffer[0];
1831 expectedMaxNumActiveVariables = de::max(expectedMaxNumActiveVariables, numActiveResources);
1832 m_testCtx.getLog() << tcu::TestLog::Message << "NUM_ACTIVE_VARIABLES = " << numActiveResources << tcu::TestLog::EndMessage;
1834 if (written == -1 || retBuffer[0] == -1)
1836 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for NUM_ACTIVE_VARIABLES did not return a value" << tcu::TestLog::EndMessage;
1837 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for NUM_ACTIVE_VARIABLES failed");
1840 else if (retBuffer[1] != -1)
1842 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for NUM_ACTIVE_VARIABLES returned too many values" << tcu::TestLog::EndMessage;
1843 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for NUM_ACTIVE_VARIABLES returned too many values");
1846 else if (retBuffer[0] < 0)
1848 m_testCtx.getLog() << tcu::TestLog::Message << "Error, NUM_ACTIVE_VARIABLES < 0" << tcu::TestLog::EndMessage;
1849 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "NUM_ACTIVE_VARIABLES < 0");
1854 // query block variable information
1857 const glw::GLenum props[] = { GL_ACTIVE_VARIABLES };
1858 std::vector<glw::GLint> activeVariableIndices (numActiveResources + 1, -1); // Allocate one extra trailing to detect wrong write lengths
1859 glw::GLint written = -1;
1861 gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, DE_LENGTH_OF_ARRAY(props), props, (glw::GLsizei)activeVariableIndices.size(), &written, &activeVariableIndices[0]);
1862 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_ACTIVE_VARIABLES");
1866 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for GL_ACTIVE_VARIABLES did not return any values" << tcu::TestLog::EndMessage;
1867 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES failed");
1870 else if (written != numActiveResources)
1872 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for GL_ACTIVE_VARIABLES did not return NUM_ACTIVE_VARIABLES values" << tcu::TestLog::EndMessage;
1873 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES returned invalid number of values");
1876 else if (activeVariableIndices.back() != -1)
1878 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;
1879 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES returned too many values");
1885 tcu::MessageBuilder builder(&m_testCtx.getLog());
1887 builder << "Active variable indices: {";
1888 for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1892 builder << activeVariableIndices[varNdx];
1894 builder << "}" << tcu::TestLog::EndMessage;
1899 activeResourceNames.resize(numActiveResources);
1901 for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1903 const glw::GLenum nameProp = GL_NAME_LENGTH;
1904 glw::GLint nameLength = -1;
1905 std::vector<char> nameBuffer;
1908 gl.getProgramResourceiv(program.getProgram(), programMemberInterfaceValue, activeVariableIndices[varNdx], 1, &nameProp, 1, &written, &nameLength);
1909 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_NAME_LENGTH");
1911 if (nameLength <= 0 || written <= 0)
1913 m_testCtx.getLog() << tcu::TestLog::Message << "Error, GL_NAME_LENGTH query failed" << tcu::TestLog::EndMessage;
1914 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GL_NAME_LENGTH query failed");
1918 nameBuffer.resize(nameLength + 2, 'X'); // allocate more than required
1920 gl.getProgramResourceName(program.getProgram(), programMemberInterfaceValue, activeVariableIndices[varNdx], nameLength+1, &written, &nameBuffer[0]);
1921 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramResourceName");
1925 m_testCtx.getLog() << tcu::TestLog::Message << "Error, name query failed, no data written" << tcu::TestLog::EndMessage;
1926 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "name query failed");
1929 else if (written > nameLength)
1931 m_testCtx.getLog() << tcu::TestLog::Message << "Error, name query failed, query returned too much data" << tcu::TestLog::EndMessage;
1932 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "name query failed");
1936 activeResourceNames[varNdx] = std::string(&nameBuffer[0], written);
1939 // log collected names
1941 tcu::MessageBuilder builder(&m_testCtx.getLog());
1943 builder << "Active variables:\n";
1944 for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1945 builder << "\t" << activeResourceNames[varNdx] << "\n";
1946 builder << tcu::TestLog::EndMessage;
1952 glu::InterfaceBlock* block = DE_NULL;
1953 const std::string blockName = glu::parseVariableName(blockNames[blockNdx].c_str());
1954 std::vector<std::string> referenceList;
1956 for (int interfaceNdx = 0; interfaceNdx < (int)m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx)
1958 if (m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].interfaceName == blockName)
1960 block = &m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx];
1966 throw tcu::InternalError("could not find block referenced in the reference resource list");
1968 // generate reference list
1970 referenceList = getProgramInterfaceBlockMemberResourceList(*block);
1972 tcu::MessageBuilder builder(&m_testCtx.getLog());
1974 builder << "Expected variable names:\n";
1975 for (int varNdx = 0; varNdx < (int)referenceList.size(); ++varNdx)
1976 builder << "\t" << referenceList[varNdx] << "\n";
1977 builder << tcu::TestLog::EndMessage;
1982 bool listsIdentical = true;
1984 for (int ndx = 0; ndx < (int)referenceList.size(); ++ndx)
1986 if (!de::contains(activeResourceNames.begin(), activeResourceNames.end(), referenceList[ndx]))
1988 m_testCtx.getLog() << tcu::TestLog::Message << "Error, variable name list did not contain active variable " << referenceList[ndx] << tcu::TestLog::EndMessage;
1989 listsIdentical = false;
1993 for (int ndx = 0; ndx < (int)activeResourceNames.size(); ++ndx)
1995 if (!de::contains(referenceList.begin(), referenceList.end(), activeResourceNames[ndx]))
1997 m_testCtx.getLog() << tcu::TestLog::Message << "Error, variable name list contains unexpected resource \"" << activeResourceNames[ndx] << "\"" << tcu::TestLog::EndMessage;
1998 listsIdentical = false;
2003 m_testCtx.getLog() << tcu::TestLog::Message << "Lists identical" << tcu::TestLog::EndMessage;
2006 m_testCtx.getLog() << tcu::TestLog::Message << "Error, invalid active variable list" << tcu::TestLog::EndMessage;
2007 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid active variable list");
2014 // Max num active variables
2016 const tcu::ScopedLogSection section (m_testCtx.getLog(), "MaxNumActiveVariables", "MAX_NUM_ACTIVE_VARIABLES");
2017 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2018 glw::GLint maxNumActiveVariables = -1;
2020 gl.getProgramInterfaceiv(program.getProgram(), programGLInterfaceValue, GL_MAX_NUM_ACTIVE_VARIABLES, &maxNumActiveVariables);
2021 GLU_EXPECT_NO_ERROR(gl.getError(), "query MAX_NUM_ACTIVE_VARIABLES");
2023 m_testCtx.getLog() << tcu::TestLog::Message << "MAX_NUM_ACTIVE_VARIABLES = " << maxNumActiveVariables << tcu::TestLog::EndMessage;
2025 if (expectedMaxNumActiveVariables != maxNumActiveVariables)
2027 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected MAX_NUM_ACTIVE_VARIABLES" << tcu::TestLog::EndMessage;
2028 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected MAX_NUM_ACTIVE_VARIABLES");
2031 m_testCtx.getLog() << tcu::TestLog::Message << "MAX_NUM_ACTIVE_VARIABLES valid" << tcu::TestLog::EndMessage;
2037 class InterfaceBlockDataSizeTestCase : public InterfaceBlockBaseCase
2040 InterfaceBlockDataSizeTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
2043 IterateResult iterate (void);
2044 int getBlockMinDataSize (const std::string& blockName) const;
2045 int getBlockMinDataSize (const glu::InterfaceBlock& block) const;
2048 InterfaceBlockDataSizeTestCase::InterfaceBlockDataSizeTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
2049 : InterfaceBlockBaseCase(context, name, description, storage, caseType)
2053 InterfaceBlockDataSizeTestCase::IterateResult InterfaceBlockDataSizeTestCase::iterate (void)
2055 const ProgramInterface programInterface = (m_storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
2056 (m_storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
2057 (PROGRAMINTERFACE_LAST);
2058 const glw::GLenum programGLInterfaceValue = getProgramInterfaceGLEnum(programInterface);
2059 const std::vector<std::string> blockNames = getProgramInterfaceResourceList(m_program, programInterface);
2060 glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2062 DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
2064 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2065 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2067 // Verify all blocks
2068 for (int blockNdx = 0; blockNdx < (int)blockNames.size(); ++blockNdx)
2070 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Block", "Block \"" + blockNames[blockNdx] + "\"");
2071 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2072 const glw::GLuint resourceNdx = gl.getProgramResourceIndex(program.getProgram(), programGLInterfaceValue, blockNames[blockNdx].c_str());
2073 const int expectedMinDataSize = getBlockMinDataSize(blockNames[blockNdx]);
2074 glw::GLint queryDataSize = -1;
2076 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
2078 if (resourceNdx == GL_INVALID_INDEX)
2080 m_testCtx.getLog() << tcu::TestLog::Message << "Error, getProgramResourceIndex returned GL_INVALID_INDEX for \"" << blockNames[blockNdx] << "\"" << tcu::TestLog::EndMessage;
2081 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Resource not found");
2087 const glw::GLenum prop = GL_BUFFER_DATA_SIZE;
2089 gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, 1, &prop, 1, DE_NULL, &queryDataSize);
2090 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource BUFFER_DATA_SIZE");
2094 << tcu::TestLog::Message
2095 << "BUFFER_DATA_SIZE = " << queryDataSize << "\n"
2096 << "Buffer data size with tight packing: " << expectedMinDataSize
2097 << tcu::TestLog::EndMessage;
2099 if (queryDataSize < expectedMinDataSize)
2101 m_testCtx.getLog() << tcu::TestLog::Message << "Error, buffer size was less than minimum buffer data size" << tcu::TestLog::EndMessage;
2102 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer data size invalid");
2106 m_testCtx.getLog() << tcu::TestLog::Message << "Buffer size valid" << tcu::TestLog::EndMessage;
2112 int InterfaceBlockDataSizeTestCase::getBlockMinDataSize (const std::string& blockFullName) const
2114 const std::string blockName = glu::parseVariableName(blockFullName.c_str());
2116 for (int interfaceNdx = 0; interfaceNdx < (int)m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx)
2118 if (m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].interfaceName == blockName &&
2119 m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].storage == m_storage)
2120 return getBlockMinDataSize(m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx]);
2127 class AtomicCounterCase : public TestCase
2130 AtomicCounterCase (Context& context, const char* name, const char* description);
2131 ~AtomicCounterCase (void);
2138 int getNumAtomicCounterBuffers (void) const;
2139 int getMaxNumActiveVariables (void) const;
2140 int getBufferVariableCount (int binding) const;
2141 int getBufferMinimumDataSize (int binding) const;
2143 ProgramInterfaceDefinition::Program* m_program;
2146 AtomicCounterCase::AtomicCounterCase (Context& context, const char* name, const char* description)
2147 : TestCase (context, name, description)
2148 , m_program (DE_NULL)
2152 AtomicCounterCase::~AtomicCounterCase (void)
2157 void AtomicCounterCase::init (void)
2159 ProgramInterfaceDefinition::Shader* shader;
2161 m_program = new ProgramInterfaceDefinition::Program();
2162 shader = m_program->addShader(glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES);
2165 glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding1_counter1", glu::STORAGE_UNIFORM);
2166 decl.layout.binding = 1;
2167 shader->getDefaultBlock().variables.push_back(decl);
2170 glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding1_counter2", glu::STORAGE_UNIFORM);
2171 decl.layout.binding = 1;
2172 decl.layout.offset = 8;
2174 shader->getDefaultBlock().variables.push_back(decl);
2177 glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding2_counter1", glu::STORAGE_UNIFORM);
2178 decl.layout.binding = 2;
2179 shader->getDefaultBlock().variables.push_back(decl);
2182 DE_ASSERT(m_program->isValid());
2185 void AtomicCounterCase::deinit (void)
2188 m_program = DE_NULL;
2191 int AtomicCounterCase::getNumAtomicCounterBuffers (void) const
2193 std::set<int> buffers;
2195 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2197 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2198 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()))
2200 buffers.insert(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding);
2204 return (int)buffers.size();
2207 int AtomicCounterCase::getMaxNumActiveVariables (void) const
2210 std::map<int,int> numBufferVars;
2212 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2214 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2215 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()))
2217 const int binding = m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding;
2219 if (numBufferVars.find(binding) == numBufferVars.end())
2220 numBufferVars[binding] = 1;
2222 ++numBufferVars[binding];
2226 for (std::map<int,int>::const_iterator it = numBufferVars.begin(); it != numBufferVars.end(); ++it)
2227 maxVars = de::max(maxVars, it->second);
2232 int AtomicCounterCase::getBufferVariableCount (int binding) const
2236 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2238 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2239 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()) &&
2240 m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding == binding)
2247 int AtomicCounterCase::getBufferMinimumDataSize (int binding) const
2250 int currentOffset = 0;
2252 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2254 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2255 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()) &&
2256 m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding == binding)
2258 const int thisOffset = (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.offset != -1) ? (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.offset) : (currentOffset);
2259 currentOffset = thisOffset + 4;
2261 minSize = de::max(minSize, thisOffset + 4);
2268 class AtomicCounterResourceListCase : public AtomicCounterCase
2271 AtomicCounterResourceListCase (Context& context, const char* name, const char* description);
2274 IterateResult iterate (void);
2277 AtomicCounterResourceListCase::AtomicCounterResourceListCase (Context& context, const char* name, const char* description)
2278 : AtomicCounterCase(context, name, description)
2282 AtomicCounterResourceListCase::IterateResult AtomicCounterResourceListCase::iterate (void)
2284 const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2286 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2287 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2290 const tcu::ScopedLogSection section (m_testCtx.getLog(), "ActiveResources", "ACTIVE_RESOURCES");
2291 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2292 glw::GLint numActiveResources = -1;
2293 const int numExpectedActiveResources = 2; // 2 buffer bindings
2295 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying ACTIVE_RESOURCES, expecting " << numExpectedActiveResources << tcu::TestLog::EndMessage;
2297 gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &numActiveResources);
2298 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_ACTIVE_RESOURCES");
2300 m_testCtx.getLog() << tcu::TestLog::Message << "ACTIVE_RESOURCES = " << numActiveResources << tcu::TestLog::EndMessage;
2302 if (numActiveResources != numExpectedActiveResources)
2304 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected ACTIVE_RESOURCES" << tcu::TestLog::EndMessage;
2305 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected ACTIVE_RESOURCES");
2308 m_testCtx.getLog() << tcu::TestLog::Message << "ACTIVE_RESOURCES valid" << tcu::TestLog::EndMessage;
2314 class AtomicCounterActiveVariablesCase : public AtomicCounterCase
2317 AtomicCounterActiveVariablesCase (Context& context, const char* name, const char* description);
2320 IterateResult iterate (void);
2323 AtomicCounterActiveVariablesCase::AtomicCounterActiveVariablesCase (Context& context, const char* name, const char* description)
2324 : AtomicCounterCase(context, name, description)
2328 AtomicCounterActiveVariablesCase::IterateResult AtomicCounterActiveVariablesCase::iterate (void)
2330 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2331 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2332 const int numAtomicBuffers = getNumAtomicCounterBuffers();
2333 const int expectedMaxNumActiveVariables = getMaxNumActiveVariables();
2335 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2336 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2338 // check active variables
2340 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Interface", "ATOMIC_COUNTER_BUFFER interface");
2341 glw::GLint queryActiveResources = -1;
2342 glw::GLint queryMaxNumActiveVariables = -1;
2344 gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &queryActiveResources);
2345 gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, &queryMaxNumActiveVariables);
2346 GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
2349 << tcu::TestLog::Message
2350 << "GL_ACTIVE_RESOURCES = " << queryActiveResources << "\n"
2351 << "GL_MAX_NUM_ACTIVE_VARIABLES = " << queryMaxNumActiveVariables << "\n"
2352 << tcu::TestLog::EndMessage;
2354 if (queryActiveResources != numAtomicBuffers)
2356 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected GL_ACTIVE_RESOURCES, expected " << numAtomicBuffers << tcu::TestLog::EndMessage;
2357 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected GL_ACTIVE_RESOURCES");
2360 if (queryMaxNumActiveVariables != expectedMaxNumActiveVariables)
2362 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected GL_MAX_NUM_ACTIVE_VARIABLES, expected " << expectedMaxNumActiveVariables << tcu::TestLog::EndMessage;
2363 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected GL_MAX_NUM_ACTIVE_VARIABLES");
2367 // Check each buffer
2368 for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2370 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
2371 std::vector<glw::GLint> activeVariables;
2372 std::vector<std::string> memberNames;
2374 // Find active variables
2376 const glw::GLenum numActiveVariablesProp = GL_NUM_ACTIVE_VARIABLES;
2377 const glw::GLenum activeVariablesProp = GL_ACTIVE_VARIABLES;
2378 glw::GLint numActiveVariables = -2;
2379 glw::GLint written = -1;
2381 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &numActiveVariablesProp, 1, &written, &numActiveVariables);
2382 GLU_EXPECT_NO_ERROR(gl.getError(), "query num active variables");
2384 if (numActiveVariables <= 0)
2386 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected NUM_ACTIVE_VARIABLES: " << numActiveVariables << tcu::TestLog::EndMessage;
2387 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected NUM_ACTIVE_VARIABLES");
2393 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for NUM_ACTIVE_VARIABLES returned no values" << tcu::TestLog::EndMessage;
2394 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "NUM_ACTIVE_VARIABLES query failed");
2398 m_testCtx.getLog() << tcu::TestLog::Message << "GL_NUM_ACTIVE_VARIABLES = " << numActiveVariables << tcu::TestLog::EndMessage;
2401 activeVariables.resize(numActiveVariables + 1, -2);
2403 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &activeVariablesProp, numActiveVariables, &written, &activeVariables[0]);
2404 GLU_EXPECT_NO_ERROR(gl.getError(), "query active variables");
2406 if (written != numActiveVariables)
2408 m_testCtx.getLog() << tcu::TestLog::Message << "Error, unexpected number of ACTIVE_VARIABLES, NUM_ACTIVE_VARIABLES = " << numActiveVariables << ", query returned " << written << " values" << tcu::TestLog::EndMessage;
2409 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected ACTIVE_VARIABLES");
2413 if (activeVariables.back() != -2)
2415 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for ACTIVE_VARIABLES wrote over target buffer bounds" << tcu::TestLog::EndMessage;
2416 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "ACTIVE_VARIABLES query failed");
2420 activeVariables.pop_back();
2425 tcu::MessageBuilder builder(&m_testCtx.getLog());
2427 builder << "Active variable indices: {";
2428 for (int varNdx = 0; varNdx < (int)activeVariables.size(); ++varNdx)
2432 builder << activeVariables[varNdx];
2434 builder << "}" << tcu::TestLog::EndMessage;
2437 // collect member names
2438 for (int ndx = 0; ndx < (int)activeVariables.size(); ++ndx)
2440 const glw::GLenum nameLengthProp = GL_NAME_LENGTH;
2441 glw::GLint nameLength = -1;
2442 glw::GLint written = -1;
2443 std::vector<char> nameBuf;
2445 gl.getProgramResourceiv(program.getProgram(), GL_UNIFORM, activeVariables[ndx], 1, &nameLengthProp, 1, &written, &nameLength);
2446 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer variable name length");
2448 if (written <= 0 || nameLength == -1)
2450 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for GL_NAME_LENGTH returned no values" << tcu::TestLog::EndMessage;
2451 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GL_NAME_LENGTH query failed");
2455 nameBuf.resize(nameLength + 2, 'X'); // +2 to tolerate potential off-by-ones in some implementations, name queries will check these cases better
2458 gl.getProgramResourceName(program.getProgram(), GL_UNIFORM, activeVariables[ndx], (int)nameBuf.size(), &written, &nameBuf[0]);
2459 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer variable name");
2463 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for resource name returned no name" << tcu::TestLog::EndMessage;
2464 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Name query failed");
2468 memberNames.push_back(std::string(&nameBuf[0], written));
2473 tcu::MessageBuilder builder(&m_testCtx.getLog());
2475 builder << "Active variables:\n";
2476 for (int varNdx = 0; varNdx < (int)memberNames.size(); ++varNdx)
2478 builder << "\t" << memberNames[varNdx] << "\n";
2480 builder << tcu::TestLog::EndMessage;
2483 // check names are all in the same buffer
2485 bool bindingsValid = true;
2487 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying names" << tcu::TestLog::EndMessage;
2489 for (int nameNdx = 0; nameNdx < (int)memberNames.size(); ++nameNdx)
2491 int prevBinding = -1;
2493 for (int varNdx = 0; varNdx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++varNdx)
2495 if (m_program->getShaders()[0]->getDefaultBlock().variables[varNdx].name == memberNames[nameNdx])
2497 const int varBinding = m_program->getShaders()[0]->getDefaultBlock().variables[varNdx].layout.binding;
2499 if (prevBinding == -1 || prevBinding == varBinding)
2500 prevBinding = varBinding;
2502 bindingsValid = false;
2506 if (prevBinding == -1)
2508 m_testCtx.getLog() << tcu::TestLog::Message << "Error, could not find variable with name \"" << memberNames[nameNdx] << "\"" << tcu::TestLog::EndMessage;
2509 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Variable name invalid");
2511 else if (getBufferVariableCount(prevBinding) != (int)memberNames.size())
2514 << tcu::TestLog::Message
2515 << "Error, unexpected variable count for binding " << prevBinding
2516 << ". Expected " << getBufferVariableCount(prevBinding) << ", got " << (int)memberNames.size()
2517 << tcu::TestLog::EndMessage;
2518 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Variable names invalid");
2524 m_testCtx.getLog() << tcu::TestLog::Message << "Error, all resource do not share the same buffer" << tcu::TestLog::EndMessage;
2525 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Active variables invalid");
2534 class AtomicCounterBufferBindingCase : public AtomicCounterCase
2537 AtomicCounterBufferBindingCase (Context& context, const char* name, const char* description);
2540 IterateResult iterate (void);
2543 AtomicCounterBufferBindingCase::AtomicCounterBufferBindingCase (Context& context, const char* name, const char* description)
2544 : AtomicCounterCase(context, name, description)
2548 AtomicCounterBufferBindingCase::IterateResult AtomicCounterBufferBindingCase::iterate (void)
2550 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2551 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2552 const int numAtomicBuffers = getNumAtomicCounterBuffers();
2554 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2555 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2557 // check every buffer
2558 for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2560 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
2561 const glw::GLenum bufferBindingProp = GL_BUFFER_BINDING;
2562 glw::GLint bufferBinding = -1;
2563 glw::GLint written = -1;
2565 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &bufferBindingProp, 1, &written, &bufferBinding);
2566 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2570 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for BUFFER_BINDING returned no values." << tcu::TestLog::EndMessage;
2571 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "BUFFER_BINDING query failed");
2574 m_testCtx.getLog() << tcu::TestLog::Message << "GL_BUFFER_BINDING = " << bufferBinding << tcu::TestLog::EndMessage;
2576 // no such buffer binding?
2577 if (getBufferVariableCount(bufferBinding) == 0)
2579 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_BINDING = " << bufferBinding << ", but such buffer does not exist." << tcu::TestLog::EndMessage;
2580 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2587 class AtomicCounterBufferDataSizeCase : public AtomicCounterCase
2590 AtomicCounterBufferDataSizeCase (Context& context, const char* name, const char* description);
2593 IterateResult iterate (void);
2596 AtomicCounterBufferDataSizeCase::AtomicCounterBufferDataSizeCase (Context& context, const char* name, const char* description)
2597 : AtomicCounterCase(context, name, description)
2601 AtomicCounterBufferDataSizeCase::IterateResult AtomicCounterBufferDataSizeCase::iterate (void)
2603 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2604 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2605 const int numAtomicBuffers = getNumAtomicCounterBuffers();
2607 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2608 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2610 // check every buffer
2611 for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2613 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
2614 const glw::GLenum props[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE };
2615 glw::GLint values[] = { -1, -1 };
2616 glw::GLint written = -1;
2617 int bufferMinDataSize;
2619 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, DE_LENGTH_OF_ARRAY(props), props, DE_LENGTH_OF_ARRAY(values), &written, values);
2620 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2624 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for (BUFFER_BINDING, BUFFER_DATA_SIZE) returned " << written << " value(s)." << tcu::TestLog::EndMessage;
2625 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
2630 << tcu::TestLog::Message
2631 << "GL_BUFFER_BINDING = " << values[0] << "\n"
2632 << "GL_BUFFER_DATA_SIZE = " << values[1]
2633 << tcu::TestLog::EndMessage;
2635 bufferMinDataSize = getBufferMinimumDataSize(values[0]);
2636 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying data size, expected greater than or equal to " << bufferMinDataSize << tcu::TestLog::EndMessage;
2638 // no such buffer binding?
2639 if (bufferMinDataSize == -1)
2641 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_BINDING = " << values[0] << ", but such buffer does not exist." << tcu::TestLog::EndMessage;
2642 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2644 else if (values[1] < bufferMinDataSize)
2646 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;
2647 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2650 m_testCtx.getLog() << tcu::TestLog::Message << "Data size valid" << tcu::TestLog::EndMessage;
2656 class AtomicCounterReferencedByCase : public TestCase
2659 AtomicCounterReferencedByCase (Context& context,
2661 const char* description,
2663 deUint32 presentStagesMask,
2664 deUint32 activeStagesMask);
2665 ~AtomicCounterReferencedByCase (void);
2670 IterateResult iterate (void);
2672 const bool m_separable;
2673 const deUint32 m_presentStagesMask;
2674 const deUint32 m_activeStagesMask;
2675 ProgramInterfaceDefinition::Program* m_program;
2678 AtomicCounterReferencedByCase::AtomicCounterReferencedByCase (Context& context,
2680 const char* description,
2682 deUint32 presentStagesMask,
2683 deUint32 activeStagesMask)
2684 : TestCase (context, name, description)
2685 , m_separable (separable)
2686 , m_presentStagesMask (presentStagesMask)
2687 , m_activeStagesMask (activeStagesMask)
2688 , m_program (DE_NULL)
2690 DE_ASSERT((activeStagesMask & presentStagesMask) == activeStagesMask);
2693 AtomicCounterReferencedByCase::~AtomicCounterReferencedByCase (void)
2698 void AtomicCounterReferencedByCase::init (void)
2700 const deUint32 geometryMask = (1 << glu::SHADERTYPE_GEOMETRY);
2701 const deUint32 tessellationMask = (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION);
2702 glu::VariableDeclaration atomicVar (glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "targetCounter", glu::STORAGE_UNIFORM);
2704 if ((m_presentStagesMask & tessellationMask) != 0 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
2705 throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
2706 if ((m_presentStagesMask & geometryMask) != 0 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
2707 throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
2709 atomicVar.layout.binding = 1;
2711 m_program = new ProgramInterfaceDefinition::Program();
2712 m_program->setSeparable(m_separable);
2714 for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
2716 if (m_activeStagesMask & (1 << shaderType))
2717 m_program->addShader((glu::ShaderType)shaderType, glu::GLSL_VERSION_310_ES)->getDefaultBlock().variables.push_back(atomicVar);
2718 else if (m_presentStagesMask & (1 << shaderType))
2719 m_program->addShader((glu::ShaderType)shaderType, glu::GLSL_VERSION_310_ES);
2722 if (m_program->hasStage(glu::SHADERTYPE_GEOMETRY))
2723 m_program->setGeometryNumOutputVertices(1);
2724 if (m_program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
2725 m_program->setTessellationNumOutputPatchVertices(1);
2727 DE_ASSERT(m_program->isValid());
2730 void AtomicCounterReferencedByCase::deinit (void)
2733 m_program = DE_NULL;
2736 AtomicCounterReferencedByCase::IterateResult AtomicCounterReferencedByCase::iterate (void)
2740 glw::GLenum propName;
2741 glu::ShaderType shaderType;
2742 const char* extension;
2745 { GL_REFERENCED_BY_VERTEX_SHADER, glu::SHADERTYPE_VERTEX, DE_NULL },
2746 { GL_REFERENCED_BY_FRAGMENT_SHADER, glu::SHADERTYPE_FRAGMENT, DE_NULL },
2747 { GL_REFERENCED_BY_COMPUTE_SHADER, glu::SHADERTYPE_COMPUTE, DE_NULL },
2748 { GL_REFERENCED_BY_TESS_CONTROL_SHADER, glu::SHADERTYPE_TESSELLATION_CONTROL, "GL_EXT_tessellation_shader" },
2749 { GL_REFERENCED_BY_TESS_EVALUATION_SHADER, glu::SHADERTYPE_TESSELLATION_EVALUATION, "GL_EXT_tessellation_shader" },
2750 { GL_REFERENCED_BY_GEOMETRY_SHADER, glu::SHADERTYPE_GEOMETRY, "GL_EXT_geometry_shader" },
2753 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2754 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2756 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2757 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2760 for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(targetProps); ++propNdx)
2762 if (targetProps[propNdx].extension == DE_NULL || m_context.getContextInfo().isExtensionSupported(targetProps[propNdx].extension))
2764 const glw::GLenum prop = targetProps[propNdx].propName;
2765 const glw::GLint expected = ((m_activeStagesMask & (1 << targetProps[propNdx].shaderType)) != 0) ? (GL_TRUE) : (GL_FALSE);
2766 glw::GLint value = -1;
2767 glw::GLint written = -1;
2769 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying " << glu::getProgramResourcePropertyName(prop) << ", expecting " << glu::getBooleanName(expected) << tcu::TestLog::EndMessage;
2771 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, 0, 1, &prop, 1, &written, &value);
2772 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2776 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for referenced_by_* returned invalid number of values." << tcu::TestLog::EndMessage;
2777 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
2781 m_testCtx.getLog() << tcu::TestLog::Message << glu::getProgramResourcePropertyName(prop) << " = " << glu::getBooleanStr(value) << tcu::TestLog::EndMessage;
2783 if (value != expected)
2785 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected value" << tcu::TestLog::EndMessage;
2786 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected property value");
2795 class ProgramInputOutputReferencedByCase : public TestCase
2800 CASE_VERTEX_FRAGMENT = 0,
2801 CASE_VERTEX_GEO_FRAGMENT,
2802 CASE_VERTEX_TESS_FRAGMENT,
2803 CASE_VERTEX_TESS_GEO_FRAGMENT,
2805 CASE_SEPARABLE_VERTEX,
2806 CASE_SEPARABLE_FRAGMENT,
2807 CASE_SEPARABLE_GEOMETRY,
2808 CASE_SEPARABLE_TESS_CTRL,
2809 CASE_SEPARABLE_TESS_EVAL,
2813 ProgramInputOutputReferencedByCase (Context& context, const char* name, const char* description, glu::Storage targetStorage, CaseType caseType);
2814 ~ProgramInputOutputReferencedByCase (void);
2819 IterateResult iterate (void);
2821 const CaseType m_caseType;
2822 const glu::Storage m_targetStorage;
2823 ProgramInterfaceDefinition::Program* m_program;
2826 ProgramInputOutputReferencedByCase::ProgramInputOutputReferencedByCase (Context& context, const char* name, const char* description, glu::Storage targetStorage, CaseType caseType)
2827 : TestCase (context, name, description)
2828 , m_caseType (caseType)
2829 , m_targetStorage (targetStorage)
2830 , m_program (DE_NULL)
2832 DE_ASSERT(caseType < CASE_LAST);
2835 ProgramInputOutputReferencedByCase::~ProgramInputOutputReferencedByCase (void)
2840 void ProgramInputOutputReferencedByCase::init (void)
2842 const bool hasTessellationShader = (m_caseType == CASE_VERTEX_TESS_FRAGMENT) ||
2843 (m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT) ||
2844 (m_caseType == CASE_SEPARABLE_TESS_CTRL) ||
2845 (m_caseType == CASE_SEPARABLE_TESS_EVAL);
2846 const bool hasGeometryShader = (m_caseType == CASE_VERTEX_GEO_FRAGMENT) ||
2847 (m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT) ||
2848 (m_caseType == CASE_SEPARABLE_GEOMETRY);
2850 if (hasTessellationShader && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
2851 throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
2852 if (hasGeometryShader && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
2853 throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
2855 m_program = new ProgramInterfaceDefinition::Program();
2857 if (m_caseType == CASE_SEPARABLE_VERTEX ||
2858 m_caseType == CASE_SEPARABLE_FRAGMENT ||
2859 m_caseType == CASE_SEPARABLE_GEOMETRY ||
2860 m_caseType == CASE_SEPARABLE_TESS_CTRL ||
2861 m_caseType == CASE_SEPARABLE_TESS_EVAL)
2863 const bool isInputCase = (m_targetStorage == glu::STORAGE_IN || m_targetStorage == glu::STORAGE_PATCH_IN);
2864 const bool perPatchStorage = (m_targetStorage == glu::STORAGE_PATCH_IN || m_targetStorage == glu::STORAGE_PATCH_OUT);
2865 const char* varName = (isInputCase) ? ("shaderInput") : ("shaderOutput");
2866 const glu::VariableDeclaration targetDecl (glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), varName, m_targetStorage);
2867 const glu::ShaderType shaderType = (m_caseType == CASE_SEPARABLE_VERTEX) ? (glu::SHADERTYPE_VERTEX)
2868 : (m_caseType == CASE_SEPARABLE_FRAGMENT) ? (glu::SHADERTYPE_FRAGMENT)
2869 : (m_caseType == CASE_SEPARABLE_GEOMETRY) ? (glu::SHADERTYPE_GEOMETRY)
2870 : (m_caseType == CASE_SEPARABLE_TESS_CTRL) ? (glu::SHADERTYPE_TESSELLATION_CONTROL)
2871 : (m_caseType == CASE_SEPARABLE_TESS_EVAL) ? (glu::SHADERTYPE_TESSELLATION_EVALUATION)
2872 : (glu::SHADERTYPE_LAST);
2873 const bool arrayedInterface = (isInputCase) ? ((shaderType == glu::SHADERTYPE_GEOMETRY) ||
2874 (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL) ||
2875 (shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION))
2876 : (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL);
2878 m_program->setSeparable(true);
2880 if (arrayedInterface && !perPatchStorage)
2882 const glu::VariableDeclaration targetDeclArr(glu::VarType(targetDecl.varType, glu::VarType::UNSIZED_ARRAY), varName, m_targetStorage);
2883 m_program->addShader(shaderType, glu::GLSL_VERSION_310_ES)->getDefaultBlock().variables.push_back(targetDeclArr);
2887 m_program->addShader(shaderType, glu::GLSL_VERSION_310_ES)->getDefaultBlock().variables.push_back(targetDecl);
2890 else if (m_caseType == CASE_VERTEX_FRAGMENT ||
2891 m_caseType == CASE_VERTEX_GEO_FRAGMENT ||
2892 m_caseType == CASE_VERTEX_TESS_FRAGMENT ||
2893 m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
2895 ProgramInterfaceDefinition::Shader* vertex = m_program->addShader(glu::SHADERTYPE_VERTEX, glu::GLSL_VERSION_310_ES);
2896 ProgramInterfaceDefinition::Shader* fragment = m_program->addShader(glu::SHADERTYPE_FRAGMENT, glu::GLSL_VERSION_310_ES);
2898 m_program->setSeparable(false);
2900 vertex->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2903 vertex->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2906 glu::INTERPOLATION_LAST,
2909 fragment->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2912 glu::INTERPOLATION_LAST,
2914 fragment->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2917 glu::INTERPOLATION_LAST,
2920 if (m_caseType == CASE_VERTEX_TESS_FRAGMENT || m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
2922 ProgramInterfaceDefinition::Shader* tessCtrl = m_program->addShader(glu::SHADERTYPE_TESSELLATION_CONTROL, glu::GLSL_VERSION_310_ES);
2923 ProgramInterfaceDefinition::Shader* tessEval = m_program->addShader(glu::SHADERTYPE_TESSELLATION_EVALUATION, glu::GLSL_VERSION_310_ES);
2925 tessCtrl->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2928 glu::INTERPOLATION_LAST,
2930 tessCtrl->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2933 glu::INTERPOLATION_LAST,
2936 tessEval->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2939 glu::INTERPOLATION_LAST,
2941 tessEval->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2944 glu::INTERPOLATION_LAST,
2948 if (m_caseType == CASE_VERTEX_GEO_FRAGMENT || m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
2950 ProgramInterfaceDefinition::Shader* geometry = m_program->addShader(glu::SHADERTYPE_GEOMETRY, glu::GLSL_VERSION_310_ES);
2952 geometry->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2955 glu::INTERPOLATION_LAST,
2957 geometry->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2960 glu::INTERPOLATION_LAST,
2967 if (m_program->hasStage(glu::SHADERTYPE_GEOMETRY))
2968 m_program->setGeometryNumOutputVertices(1);
2969 if (m_program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
2970 m_program->setTessellationNumOutputPatchVertices(1);
2972 DE_ASSERT(m_program->isValid());
2975 void ProgramInputOutputReferencedByCase::deinit (void)
2978 m_program = DE_NULL;
2981 ProgramInputOutputReferencedByCase::IterateResult ProgramInputOutputReferencedByCase::iterate (void)
2985 glw::GLenum propName;
2986 glu::ShaderType shaderType;
2987 const char* extension;
2990 { GL_REFERENCED_BY_VERTEX_SHADER, glu::SHADERTYPE_VERTEX, DE_NULL },
2991 { GL_REFERENCED_BY_FRAGMENT_SHADER, glu::SHADERTYPE_FRAGMENT, DE_NULL },
2992 { GL_REFERENCED_BY_COMPUTE_SHADER, glu::SHADERTYPE_COMPUTE, DE_NULL },
2993 { GL_REFERENCED_BY_TESS_CONTROL_SHADER, glu::SHADERTYPE_TESSELLATION_CONTROL, "GL_EXT_tessellation_shader" },
2994 { GL_REFERENCED_BY_TESS_EVALUATION_SHADER, glu::SHADERTYPE_TESSELLATION_EVALUATION, "GL_EXT_tessellation_shader" },
2995 { GL_REFERENCED_BY_GEOMETRY_SHADER, glu::SHADERTYPE_GEOMETRY, "GL_EXT_geometry_shader" },
2998 const bool isInputCase = (m_targetStorage == glu::STORAGE_IN || m_targetStorage == glu::STORAGE_PATCH_IN);
2999 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3000 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
3001 const std::string targetResourceName = (isInputCase) ? ("shaderInput") : ("shaderOutput");
3002 const glw::GLenum programGLInterface = (isInputCase) ? (GL_PROGRAM_INPUT) : (GL_PROGRAM_OUTPUT);
3003 glw::GLuint resourceIndex;
3005 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3006 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
3008 // find target resource index
3010 resourceIndex = gl.getProgramResourceIndex(program.getProgram(), programGLInterface, targetResourceName.c_str());
3011 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
3013 if (resourceIndex == GL_INVALID_INDEX)
3015 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for resource \"" << targetResourceName << "\" index returned invalid index." << tcu::TestLog::EndMessage;
3016 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "could not find target resource");
3021 for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(targetProps); ++propNdx)
3023 if (targetProps[propNdx].extension == DE_NULL || m_context.getContextInfo().isExtensionSupported(targetProps[propNdx].extension))
3025 const glw::GLenum prop = targetProps[propNdx].propName;
3026 const bool expected = (isInputCase) ? (targetProps[propNdx].shaderType == m_program->getFirstStage()) : (targetProps[propNdx].shaderType == m_program->getLastStage());
3027 glw::GLint value = -1;
3028 glw::GLint written = -1;
3030 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying " << glu::getProgramResourcePropertyName(prop) << ", expecting " << ((expected) ? ("TRUE") : ("FALSE")) << tcu::TestLog::EndMessage;
3032 gl.getProgramResourceiv(program.getProgram(), programGLInterface, resourceIndex, 1, &prop, 1, &written, &value);
3033 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
3037 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for referenced_by_* returned invalid number of values." << tcu::TestLog::EndMessage;
3038 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
3042 m_testCtx.getLog() << tcu::TestLog::Message << glu::getProgramResourcePropertyName(prop) << " = " << glu::getBooleanStr(value) << tcu::TestLog::EndMessage;
3044 if (value != ((expected) ? (GL_TRUE) : (GL_FALSE)))
3046 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected value" << tcu::TestLog::EndMessage;
3047 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected property value");
3056 class FeedbackResourceListTestCase : public ResourceListTestCase
3059 FeedbackResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& resource, const char* name);
3060 ~FeedbackResourceListTestCase (void);
3063 IterateResult iterate (void);
3066 FeedbackResourceListTestCase::FeedbackResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& resource, const char* name)
3067 : ResourceListTestCase(context, resource, PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, name)
3071 FeedbackResourceListTestCase::~FeedbackResourceListTestCase (void)
3076 FeedbackResourceListTestCase::IterateResult FeedbackResourceListTestCase::iterate (void)
3078 const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_programDefinition));
3080 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3082 // Feedback varyings
3084 tcu::MessageBuilder builder(&m_testCtx.getLog());
3085 builder << "Transform feedback varyings: {";
3086 for (int ndx = 0; ndx < (int)m_programDefinition->getTransformFeedbackVaryings().size(); ++ndx)
3090 builder << "\"" << m_programDefinition->getTransformFeedbackVaryings()[ndx] << "\"";
3092 builder << "}" << tcu::TestLog::EndMessage;
3095 checkAndLogProgram(program, m_programDefinition, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
3097 // Check resource list
3099 const tcu::ScopedLogSection section (m_testCtx.getLog(), "ResourceList", "Resource list");
3100 std::vector<std::string> resourceList;
3101 std::vector<std::string> expectedResources;
3103 queryResourceList(resourceList, program.getProgram());
3104 expectedResources = getProgramInterfaceResourceList(m_programDefinition, m_programInterface);
3106 // verify the list and the expected list match
3108 if (!verifyResourceList(resourceList, expectedResources))
3109 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid resource list");
3111 // verify GetProgramResourceIndex() matches the indices of the list
3113 if (!verifyResourceIndexQuery(resourceList, expectedResources, program.getProgram()))
3114 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GetProgramResourceIndex returned unexpected values");
3116 // Verify MAX_NAME_LENGTH
3117 if (!verifyMaxNameLength(resourceList, program.getProgram()))
3118 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "MAX_NAME_LENGTH invalid");
3124 int InterfaceBlockDataSizeTestCase::getBlockMinDataSize (const glu::InterfaceBlock& block) const
3128 for (int ndx = 0; ndx < (int)block.variables.size(); ++ndx)
3129 dataSize += getVarTypeSize(block.variables[ndx].varType);
3134 static bool isDataTypeLayoutQualified (glu::DataType type)
3136 return glu::isDataTypeImage(type) || glu::isDataTypeAtomicCounter(type);
3139 static void generateVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3, bool createTestGroup = true)
3144 glu::DataType dataType;
3147 { 0, glu::TYPE_FLOAT },
3148 { 1, glu::TYPE_INT },
3149 { 1, glu::TYPE_UINT },
3150 { 1, glu::TYPE_BOOL },
3152 { 3, glu::TYPE_FLOAT_VEC2 },
3153 { 1, glu::TYPE_FLOAT_VEC3 },
3154 { 1, glu::TYPE_FLOAT_VEC4 },
3156 { 3, glu::TYPE_INT_VEC2 },
3157 { 2, glu::TYPE_INT_VEC3 },
3158 { 3, glu::TYPE_INT_VEC4 },
3160 { 3, glu::TYPE_UINT_VEC2 },
3161 { 2, glu::TYPE_UINT_VEC3 },
3162 { 3, glu::TYPE_UINT_VEC4 },
3164 { 3, glu::TYPE_BOOL_VEC2 },
3165 { 2, glu::TYPE_BOOL_VEC3 },
3166 { 3, glu::TYPE_BOOL_VEC4 },
3168 { 2, glu::TYPE_FLOAT_MAT2 },
3169 { 3, glu::TYPE_FLOAT_MAT2X3 },
3170 { 3, glu::TYPE_FLOAT_MAT2X4 },
3171 { 2, glu::TYPE_FLOAT_MAT3X2 },
3172 { 2, glu::TYPE_FLOAT_MAT3 },
3173 { 3, glu::TYPE_FLOAT_MAT3X4 },
3174 { 2, glu::TYPE_FLOAT_MAT4X2 },
3175 { 3, glu::TYPE_FLOAT_MAT4X3 },
3176 { 2, glu::TYPE_FLOAT_MAT4 },
3179 tcu::TestCaseGroup* group;
3181 if (createTestGroup)
3183 group = new tcu::TestCaseGroup(context.getTestContext(), "basic_type", "Basic variable");
3184 targetGroup->addChild(group);
3187 group = targetGroup;
3189 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3191 if (variableTypes[ndx].level <= expandLevel)
3193 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
3194 group->addChild(new ResourceTestCase(context, variable, queryTarget));
3199 static void generateOpaqueTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3, bool createTestGroup = true)
3204 glu::DataType dataType;
3207 { 0, glu::TYPE_SAMPLER_2D },
3208 { 2, glu::TYPE_SAMPLER_CUBE },
3209 { 1, glu::TYPE_SAMPLER_2D_ARRAY },
3210 { 1, glu::TYPE_SAMPLER_3D },
3211 { 2, glu::TYPE_SAMPLER_2D_SHADOW },
3212 { 3, glu::TYPE_SAMPLER_CUBE_SHADOW },
3213 { 3, glu::TYPE_SAMPLER_2D_ARRAY_SHADOW },
3214 { 1, glu::TYPE_INT_SAMPLER_2D },
3215 { 3, glu::TYPE_INT_SAMPLER_CUBE },
3216 { 3, glu::TYPE_INT_SAMPLER_2D_ARRAY },
3217 { 3, glu::TYPE_INT_SAMPLER_3D },
3218 { 2, glu::TYPE_UINT_SAMPLER_2D },
3219 { 3, glu::TYPE_UINT_SAMPLER_CUBE },
3220 { 3, glu::TYPE_UINT_SAMPLER_2D_ARRAY },
3221 { 3, glu::TYPE_UINT_SAMPLER_3D },
3222 { 2, glu::TYPE_SAMPLER_2D_MULTISAMPLE },
3223 { 2, glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE },
3224 { 3, glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE },
3225 { 1, glu::TYPE_IMAGE_2D },
3226 { 3, glu::TYPE_IMAGE_CUBE },
3227 { 3, glu::TYPE_IMAGE_2D_ARRAY },
3228 { 3, glu::TYPE_IMAGE_3D },
3229 { 3, glu::TYPE_INT_IMAGE_2D },
3230 { 3, glu::TYPE_INT_IMAGE_CUBE },
3231 { 1, glu::TYPE_INT_IMAGE_2D_ARRAY },
3232 { 3, glu::TYPE_INT_IMAGE_3D },
3233 { 2, glu::TYPE_UINT_IMAGE_2D },
3234 { 3, glu::TYPE_UINT_IMAGE_CUBE },
3235 { 3, glu::TYPE_UINT_IMAGE_2D_ARRAY },
3236 { 3, glu::TYPE_UINT_IMAGE_3D },
3237 { 1, glu::TYPE_UINT_ATOMIC_COUNTER },
3240 bool isStructMember = false;
3243 for (const ResourceDefinition::Node* node = parentStructure.get(); node; node = node->getEnclosingNode())
3245 // Don't insert inside a interface block
3246 if (node->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3249 isStructMember |= (node->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER);
3254 tcu::TestCaseGroup* group;
3256 if (createTestGroup)
3258 group = new tcu::TestCaseGroup(context.getTestContext(), "opaque_type", "Opaque types");
3259 targetGroup->addChild(group);
3262 group = targetGroup;
3264 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3266 if (variableTypes[ndx].level > expandLevel)
3269 // Layout qualifiers are not allowed on struct members
3270 if (isDataTypeLayoutQualified(variableTypes[ndx].dataType) && isStructMember)
3274 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
3275 group->addChild(new ResourceTestCase(context, variable, queryTarget));
3281 static void generateCompoundVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3);
3283 static void generateVariableArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3)
3285 if (expandLevel > 0)
3287 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3288 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3290 targetGroup->addChild(blockGroup);
3292 // Arrays of basic variables
3293 generateVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3295 // Arrays of opaque types
3296 generateOpaqueTypeCases(context, arrayElement, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3299 generateVariableArrayCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3301 // Arrays of structs
3302 generateCompoundVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3306 static void generateCompoundVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
3308 if (expandLevel > 0)
3310 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3311 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "struct", "Structs");
3313 targetGroup->addChild(blockGroup);
3315 // Struct containing basic variable
3316 generateVariableCases(context, structMember, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3318 // Struct containing opaque types
3319 generateOpaqueTypeCases(context, structMember, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3321 // Struct containing arrays
3322 generateVariableArrayCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3324 // Struct containing struct
3325 generateCompoundVariableCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3329 // Resource list cases
3333 BLOCKFLAG_DEFAULT = 0x01,
3334 BLOCKFLAG_NAMED = 0x02,
3335 BLOCKFLAG_UNNAMED = 0x04,
3336 BLOCKFLAG_ARRAY = 0x08,
3338 BLOCKFLAG_ALL = 0x0F
3341 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))
3343 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
3344 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
3347 if (blockFlags & BLOCKFLAG_DEFAULT)
3349 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "default_block", "Default block");
3350 targetGroup->addChild(blockGroup);
3352 blockContentGenerator(context, uniform, blockGroup);
3356 if (blockFlags & BLOCKFLAG_NAMED)
3358 const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(uniform, true));
3360 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "named_block", "Named uniform block");
3361 targetGroup->addChild(blockGroup);
3363 blockContentGenerator(context, block, blockGroup);
3367 if (blockFlags & BLOCKFLAG_UNNAMED)
3369 const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(uniform, false));
3371 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "unnamed_block", "Unnamed uniform block");
3372 targetGroup->addChild(blockGroup);
3374 blockContentGenerator(context, block, blockGroup);
3378 if (blockFlags & BLOCKFLAG_ARRAY)
3380 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(uniform));
3381 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
3383 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "block_array", "Uniform block array");
3384 targetGroup->addChild(blockGroup);
3386 blockContentGenerator(context, block, blockGroup);
3390 static void generateBufferBackedResourceListBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, int depth)
3394 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, glu::TYPE_FLOAT_VEC4));
3395 targetGroup->addChild(new ResourceListTestCase(context, variable, interface));
3401 const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
3402 generateBufferBackedResourceListBlockContentCases(context, structMember, targetGroup, interface, depth - 1);
3408 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
3409 generateBufferBackedResourceListBlockContentCases(context, arrayElement, targetGroup, interface, depth - 1);
3413 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)
3417 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, dataType));
3418 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, targetProp), ("var" + nameSuffix).c_str()));
3424 const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
3425 generateBufferBackedVariableAggregateTypeCases(context, structMember, targetGroup, interface, targetProp, dataType, "_struct" + nameSuffix, depth - 1);
3431 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
3432 generateBufferBackedVariableAggregateTypeCases(context, arrayElement, targetGroup, interface, targetProp, dataType, "_array" + nameSuffix, depth - 1);
3436 static void generateUniformResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3438 generateBufferBackedResourceListBlockContentCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, 4);
3441 static void generateUniformBlockArraySizeContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3443 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ARRAY_SIZE);
3444 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3445 const bool namedNonArrayBlock = isInterfaceBlock &&
3446 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3447 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3449 if (!isInterfaceBlock || namedNonArrayBlock)
3453 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3454 targetGroup->addChild(blockGroup);
3456 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3457 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3462 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3463 targetGroup->addChild(blockGroup);
3465 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_ARRAY_SIZE, glu::TYPE_FLOAT, "", 3);
3471 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, queryTarget.interface, PROGRAMRESOURCEPROP_ARRAY_SIZE, glu::TYPE_FLOAT, "", 2);
3475 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)
3479 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, type));
3480 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_ARRAY_STRIDE), namePrefix.c_str()));
3483 if (expandLevel > 0)
3485 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3486 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3489 generateBufferBackedArrayStrideTypeAggregateSubCases(context, structMember, targetGroup, namePrefix + "_struct", interface, type, expandLevel - 1);
3492 generateBufferBackedArrayStrideTypeAggregateSubCases(context, arrayElement, targetGroup, namePrefix + "_array", interface, type, expandLevel - 1);
3496 static void generateBufferBackedArrayStrideTypeAggregateCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, glu::DataType type, int expandLevel, bool includeBaseCase)
3498 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3499 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3500 const std::string namePrefix = glu::getDataTypeName(type);
3502 if (expandLevel == 0 || includeBaseCase)
3504 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, type));
3505 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_ARRAY_STRIDE), namePrefix.c_str()));
3507 if (expandLevel >= 1)
3510 if (!glu::isDataTypeAtomicCounter(type))
3511 generateBufferBackedArrayStrideTypeAggregateSubCases(context, structMember, targetGroup, namePrefix + "_struct", interface, type, expandLevel - 1);
3514 generateBufferBackedArrayStrideTypeAggregateSubCases(context, arrayElement, targetGroup, namePrefix + "_array", interface, type, expandLevel - 1);
3518 static void generateUniformBlockArrayStrideContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3520 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ARRAY_STRIDE);
3521 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3522 const bool namedNonArrayBlock = isInterfaceBlock &&
3523 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3524 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3526 if (!isInterfaceBlock || namedNonArrayBlock)
3530 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3531 targetGroup->addChild(blockGroup);
3533 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3534 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3539 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3540 targetGroup->addChild(blockGroup);
3543 if (!isInterfaceBlock)
3544 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_SAMPLER_2D, 1, false);
3546 // .atomic_counter_*
3547 if (!isInterfaceBlock)
3549 const ResourceDefinition::Node::SharedPtr layout(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
3550 generateBufferBackedArrayStrideTypeAggregateCases(context, layout, blockGroup, queryTarget.interface, glu::TYPE_UINT_ATOMIC_COUNTER, 1, false);
3554 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_FLOAT, 2, false);
3557 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_BOOL, 1, false);
3560 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_BOOL_VEC3, 2, false);
3563 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_FLOAT_VEC3, 2, false);
3566 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_INT_VEC3, 2, false);
3571 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3572 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3573 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3577 static void generateUniformBlockLocationContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3579 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_LOCATION);
3580 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3582 if (!isInterfaceBlock)
3584 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 3);
3585 generateOpaqueTypeCases(context, parentStructure, targetGroup, queryTarget, 3);
3586 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 2);
3587 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 2);
3590 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1, false);
3593 static void generateUniformBlockBlockIndexContents (Context& context, tcu::TestCaseGroup* const targetGroup)
3595 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
3596 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
3597 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
3598 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
3599 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(uniform, glu::Layout(-1, 0)));
3603 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(uniform, glu::TYPE_FLOAT_VEC4));
3605 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "default_block"));
3610 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, true));
3611 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3613 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "named_block"));
3618 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, false));
3619 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3621 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "unnamed_block"));
3626 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding));
3627 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
3628 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3630 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "block_array"));
3634 static void generateUniformBlockAtomicCounterBufferIndexContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3636 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ATOMIC_COUNTER_BUFFER_INDEX);
3637 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3639 if (!isInterfaceBlock)
3641 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 3);
3642 generateOpaqueTypeCases(context, parentStructure, targetGroup, queryTarget, 3);
3646 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3647 const ResourceDefinition::Node::SharedPtr arrayArrayElement (new ResourceDefinition::ArrayElement(arrayElement));
3648 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3649 const ResourceDefinition::Node::SharedPtr elementvariable (new ResourceDefinition::Variable(arrayArrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3650 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3652 targetGroup->addChild(blockGroup);
3654 blockGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "var_array"));
3655 blockGroup->addChild(new ResourceTestCase(context, elementvariable, queryTarget, "var_array_array"));
3659 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1, false);
3662 static void generateUniformBlockNameLengthContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3664 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3665 const bool namedNonArrayBlock = isInterfaceBlock &&
3666 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3667 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3669 if (!isInterfaceBlock || namedNonArrayBlock)
3670 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 2);
3672 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 1);
3675 static void generateUniformBlockTypeContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3677 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_TYPE);
3678 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3679 const bool namedNonArrayBlock = isInterfaceBlock &&
3680 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3681 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3683 if (!isInterfaceBlock || namedNonArrayBlock)
3687 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3688 targetGroup->addChild(blockGroup);
3690 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3691 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3694 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3695 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3700 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3701 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3702 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3706 static void generateUniformBlockOffsetContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3708 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_OFFSET);
3709 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3710 const bool namedNonArrayBlock = isInterfaceBlock &&
3711 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3712 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3714 if (!isInterfaceBlock)
3718 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3719 targetGroup->addChild(blockGroup);
3721 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3722 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3727 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3728 targetGroup->addChild(blockGroup);
3730 // .atomic_uint_struct
3731 // .atomic_uint_array
3733 const ResourceDefinition::Node::SharedPtr offset (new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, 4)));
3734 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(offset));
3735 const ResourceDefinition::Node::SharedPtr elementVariable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3737 blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "atomic_uint_array"));
3743 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3744 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3745 const ResourceDefinition::Node::SharedPtr memberVariable (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
3746 const ResourceDefinition::Node::SharedPtr elementVariable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
3748 blockGroup->addChild(new ResourceTestCase(context, memberVariable, queryTarget, "float_struct"));
3749 blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "float_array"));
3753 else if (namedNonArrayBlock)
3757 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3758 targetGroup->addChild(blockGroup);
3760 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3761 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3766 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3767 targetGroup->addChild(blockGroup);
3772 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3773 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::StructMember(parentStructure));
3774 const ResourceDefinition::Node::SharedPtr memberVariable (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
3775 const ResourceDefinition::Node::SharedPtr elementVariable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
3777 blockGroup->addChild(new ResourceTestCase(context, memberVariable, queryTarget, "float_struct"));
3778 blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "float_array"));
3784 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3785 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3786 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3790 static void generateMatrixVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, bool createTestGroup = true, int expandLevel = 2)
3798 { 0, glu::TYPE_FLOAT_MAT2 },
3799 { 1, glu::TYPE_FLOAT_MAT2X3 },
3800 { 2, glu::TYPE_FLOAT_MAT2X4 },
3801 { 2, glu::TYPE_FLOAT_MAT3X2 },
3802 { 1, glu::TYPE_FLOAT_MAT3 },
3803 { 0, glu::TYPE_FLOAT_MAT3X4 },
3804 { 2, glu::TYPE_FLOAT_MAT4X2 },
3805 { 1, glu::TYPE_FLOAT_MAT4X3 },
3806 { 0, glu::TYPE_FLOAT_MAT4 },
3809 tcu::TestCaseGroup* group;
3811 if (createTestGroup)
3813 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "matrix", "Basic matrix type");
3814 targetGroup->addChild(blockGroup);
3818 group = targetGroup;
3820 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3822 if (variableTypes[ndx].priority < expandLevel)
3824 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
3825 group->addChild(new ResourceTestCase(context, variable, queryTarget));
3830 static void generateMatrixStructCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel);
3832 static void generateMatrixArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
3834 if (expandLevel > 0)
3836 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3837 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3839 targetGroup->addChild(blockGroup);
3841 // Arrays of basic variables
3842 generateMatrixVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel != 1, expandLevel);
3845 generateMatrixArrayCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3847 // Arrays of structs
3848 generateMatrixStructCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3852 static void generateMatrixStructCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
3854 if (expandLevel > 0)
3856 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3857 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "struct", "Structs");
3859 targetGroup->addChild(blockGroup);
3861 // Struct containing basic variable
3862 generateMatrixVariableCases(context, structMember, blockGroup, queryTarget, expandLevel != 1, expandLevel);
3864 // Struct containing arrays
3865 generateMatrixArrayCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3867 // Struct containing struct
3868 generateMatrixStructCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3872 static void generateUniformMatrixOrderCaseBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, bool extendedBasicTypeCases, bool opaqueCases)
3877 glu::MatrixOrder order;
3880 { "no_qualifier", glu::MATRIXORDER_LAST },
3881 { "row_major", glu::MATRIXORDER_ROW_MAJOR },
3882 { "column_major", glu::MATRIXORDER_COLUMN_MAJOR },
3885 const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR);
3887 for (int qualifierNdx = 0; qualifierNdx < DE_LENGTH_OF_ARRAY(qualifiers); ++qualifierNdx)
3889 // Add layout qualifiers only for block members
3890 if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST || parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3892 ResourceDefinition::Node::SharedPtr subStructure = parentStructure;
3893 tcu::TestCaseGroup* const qualifierGroup = new tcu::TestCaseGroup(context.getTestContext(), qualifiers[qualifierNdx].name, "");
3895 targetGroup->addChild(qualifierGroup);
3897 if (qualifiers[qualifierNdx].order != glu::MATRIXORDER_LAST)
3900 layout.matrixOrder = qualifiers[qualifierNdx].order;
3901 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
3904 if (extendedBasicTypeCases && qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST)
3908 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "");
3909 qualifierGroup->addChild(blockGroup);
3911 generateVariableCases(context, subStructure, blockGroup, queryTarget, 1, false);
3912 generateMatrixVariableCases(context, subStructure, blockGroup, queryTarget, false);
3914 generateOpaqueTypeCases(context, subStructure, blockGroup, queryTarget, 2, false);
3919 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "");
3920 qualifierGroup->addChild(blockGroup);
3922 generateBufferBackedVariableAggregateTypeCases(context, subStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
3927 generateBufferBackedVariableAggregateTypeCases(context, subStructure, qualifierGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
3933 static void generateUniformMatrixStrideCaseBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, bool extendedBasicTypeCases, bool opaqueCases)
3938 glu::MatrixOrder order;
3941 { "no_qualifier", glu::MATRIXORDER_LAST },
3942 { "row_major", glu::MATRIXORDER_ROW_MAJOR },
3943 { "column_major", glu::MATRIXORDER_COLUMN_MAJOR },
3946 const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_MATRIX_STRIDE);
3948 for (int qualifierNdx = 0; qualifierNdx < DE_LENGTH_OF_ARRAY(qualifiers); ++qualifierNdx)
3950 // Add layout qualifiers only for block members
3951 if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST || parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3953 ResourceDefinition::Node::SharedPtr subStructure = parentStructure;
3954 tcu::TestCaseGroup* const qualifierGroup = new tcu::TestCaseGroup(context.getTestContext(), qualifiers[qualifierNdx].name, "");
3956 targetGroup->addChild(qualifierGroup);
3958 if (qualifiers[qualifierNdx].order != glu::MATRIXORDER_LAST)
3961 layout.matrixOrder = qualifiers[qualifierNdx].order;
3962 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
3965 if (extendedBasicTypeCases)
3969 if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST)
3971 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "");
3972 qualifierGroup->addChild(blockGroup);
3974 generateVariableCases(context, subStructure, blockGroup, queryTarget, 1, false);
3975 generateMatrixVariableCases(context, subStructure, blockGroup, queryTarget, false);
3977 generateOpaqueTypeCases(context, subStructure, blockGroup, queryTarget, 2, false);
3980 generateMatrixVariableCases(context, subStructure, qualifierGroup, queryTarget);
3984 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "");
3985 qualifierGroup->addChild(blockGroup);
3987 generateBufferBackedVariableAggregateTypeCases(context, subStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
3991 generateBufferBackedVariableAggregateTypeCases(context, subStructure, qualifierGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
3996 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))
4001 const char* description;
4004 bool extendedBasicTypeCases;
4005 glu::MatrixOrder order;
4008 { "default_block", "Default block", false, true, true, glu::MATRIXORDER_LAST },
4009 { "named_block", "Named uniform block", true, true, true, glu::MATRIXORDER_LAST },
4010 { "named_block_row_major", "Named uniform block", true, true, false, glu::MATRIXORDER_ROW_MAJOR },
4011 { "named_block_col_major", "Named uniform block", true, true, false, glu::MATRIXORDER_COLUMN_MAJOR },
4012 { "unnamed_block", "Unnamed uniform block", true, false, false, glu::MATRIXORDER_LAST },
4013 { "unnamed_block_row_major", "Unnamed uniform block", true, false, false, glu::MATRIXORDER_ROW_MAJOR },
4014 { "unnamed_block_col_major", "Unnamed uniform block", true, false, false, glu::MATRIXORDER_COLUMN_MAJOR },
4017 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
4018 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4020 for (int childNdx = 0; childNdx < (int)DE_LENGTH_OF_ARRAY(children); ++childNdx)
4022 ResourceDefinition::Node::SharedPtr subStructure = uniform;
4023 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), children[childNdx].name, children[childNdx].description);
4024 const bool addOpaqueCases = children[childNdx].extendedBasicTypeCases && !children[childNdx].block;
4026 targetGroup->addChild(blockGroup);
4028 if (children[childNdx].order != glu::MATRIXORDER_LAST)
4031 layout.matrixOrder = children[childNdx].order;
4032 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
4035 if (children[childNdx].block)
4036 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(subStructure, children[childNdx].namedBlock));
4038 blockContentGenerator(context, subStructure, blockGroup, children[childNdx].extendedBasicTypeCases, addOpaqueCases);
4042 static void generateBufferReferencedByShaderInterfaceBlockCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, bool extendedCases)
4044 const bool isDefaultBlock = (parentStructure->getType() != ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
4050 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(parentStructure, glu::TYPE_FLOAT));
4051 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
4052 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4053 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4054 const ResourceDefinition::Node::SharedPtr variableStruct (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
4056 targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "float"));
4057 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_array"));
4058 targetGroup->addChild(new ResourceTestCase(context, variableStruct, queryTarget, "float_struct"));
4066 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
4067 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_SAMPLER_2D));
4068 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(layout));
4069 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4070 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_SAMPLER_2D));
4071 const ResourceDefinition::Node::SharedPtr variableStruct (new ResourceDefinition::Variable(structMember, glu::TYPE_SAMPLER_2D));
4073 targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "sampler"));
4074 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "sampler_array"));
4075 targetGroup->addChild(new ResourceTestCase(context, variableStruct, queryTarget, "sampler_struct"));
4079 // .atomic_uint_array
4082 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
4083 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_UINT_ATOMIC_COUNTER));
4084 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(layout));
4085 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
4087 targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "atomic_uint"));
4088 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "atomic_uint_array"));
4093 // .float_array_struct
4095 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4096 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(structMember));
4097 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4099 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_array_struct"));
4102 // .float_struct_array
4104 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
4105 const ResourceDefinition::Node::SharedPtr arrayStructMember (new ResourceDefinition::StructMember(arrayElement));
4106 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(arrayStructMember, glu::TYPE_FLOAT));
4108 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_struct_array"));
4111 // .float_array_array
4113 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
4114 const ResourceDefinition::Node::SharedPtr subArrayElement (new ResourceDefinition::ArrayElement(arrayElement));
4115 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(subArrayElement, glu::TYPE_FLOAT));
4117 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_array_array"));
4120 // .float_struct_struct
4122 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4123 const ResourceDefinition::Node::SharedPtr subStructMember (new ResourceDefinition::StructMember(structMember));
4124 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(subStructMember, glu::TYPE_FLOAT));
4126 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_struct_struct"));
4129 if (queryTarget.interface == PROGRAMINTERFACE_BUFFER_VARIABLE)
4131 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
4133 // .float_unsized_array
4135 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4137 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_unsized_array"));
4140 // .float_unsized_struct_array
4142 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(arrayElement));
4143 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
4145 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_unsized_struct_array"));
4151 static void generateUniformReferencedByShaderSingleBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, int expandLevel)
4153 DE_UNREF(expandLevel);
4155 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
4156 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4157 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER);
4158 const bool singleShaderCase = parentStructure->getType() == ResourceDefinition::Node::TYPE_SHADER;
4162 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "default_block", "");
4163 targetGroup->addChild(blockGroup);
4165 generateBufferReferencedByShaderInterfaceBlockCases(context, uniform, blockGroup, queryTarget, singleShaderCase);
4170 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(uniform, true));
4171 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "uniform_block", "");
4173 targetGroup->addChild(blockGroup);
4175 generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, singleShaderCase);
4180 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(uniform, false));
4181 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "");
4183 targetGroup->addChild(blockGroup);
4185 generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, false);
4190 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(uniform));
4191 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4192 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "");
4194 targetGroup->addChild(blockGroup);
4196 generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, false);
4200 static void generateReferencedByShaderCaseBlocks (Context& context, tcu::TestCaseGroup* const targetGroup, void (*generateBlockContent)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, int expandLevel))
4205 glu::ShaderType stage;
4207 } singleStageCases[] =
4209 { "compute", glu::SHADERTYPE_COMPUTE, 3 },
4210 { "separable_vertex", glu::SHADERTYPE_VERTEX, 2 },
4211 { "separable_fragment", glu::SHADERTYPE_FRAGMENT, 2 },
4212 { "separable_tess_ctrl", glu::SHADERTYPE_TESSELLATION_CONTROL, 2 },
4213 { "separable_tess_eval", glu::SHADERTYPE_TESSELLATION_EVALUATION, 2 },
4214 { "separable_geometry", glu::SHADERTYPE_GEOMETRY, 2 },
4226 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT),
4231 "vertex_tess_fragment",
4232 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
4237 "vertex_geo_fragment",
4238 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY),
4243 "vertex_tess_geo_fragment",
4244 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
4250 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
4252 TestCaseGroup* const blockGroup = new TestCaseGroup(context, singleStageCases[ndx].name, "");
4253 const bool programSeparable = (singleStageCases[ndx].stage != glu::SHADERTYPE_COMPUTE);
4254 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(programSeparable));
4255 const ResourceDefinition::Node::SharedPtr stage (new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glu::GLSL_VERSION_310_ES));
4257 targetGroup->addChild(blockGroup);
4259 generateBlockContent(context, stage, blockGroup, singleStageCases[ndx].expandLevel);
4262 for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
4266 TestCaseGroup* const blockGroup = new TestCaseGroup(context, pipelines[pipelineNdx].name, "");
4267 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4268 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program,
4269 glu::GLSL_VERSION_310_ES,
4270 pipelines[pipelineNdx].flags,
4271 pipelines[pipelineNdx].flags);
4272 targetGroup->addChild(blockGroup);
4275 const ResourceDefinition::Node::SharedPtr shaders(shaderSet);
4276 generateBlockContent(context, shaders, blockGroup, pipelines[pipelineNdx].expandLevel);
4281 for (int selectedStageBit = 0; selectedStageBit < glu::SHADERTYPE_LAST; ++selectedStageBit)
4283 if (pipelines[pipelineNdx].flags & (1 << selectedStageBit))
4285 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4286 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program,
4287 glu::GLSL_VERSION_310_ES,
4288 pipelines[pipelineNdx].flags,
4289 (1u << selectedStageBit));
4290 const char* stageName = (selectedStageBit == glu::SHADERTYPE_VERTEX) ? ("vertex")
4291 : (selectedStageBit == glu::SHADERTYPE_FRAGMENT) ? ("fragment")
4292 : (selectedStageBit == glu::SHADERTYPE_GEOMETRY) ? ("geo")
4293 : (selectedStageBit == glu::SHADERTYPE_TESSELLATION_CONTROL) ? ("tess_ctrl")
4294 : (selectedStageBit == glu::SHADERTYPE_TESSELLATION_EVALUATION) ? ("tess_eval")
4296 const std::string setName = std::string() + pipelines[pipelineNdx].name + "_only_" + stageName;
4297 TestCaseGroup* const blockGroup = new TestCaseGroup(context, setName.c_str(), "");
4298 const ResourceDefinition::Node::SharedPtr shaders (shaderSet);
4300 generateBlockContent(context, shaders, blockGroup, pipelines[pipelineNdx].subExpandLevel);
4301 targetGroup->addChild(blockGroup);
4307 static glu::DataType generateRandomDataType (de::Random& rnd, bool excludeOpaqueTypes)
4309 static const glu::DataType s_types[] =
4315 glu::TYPE_FLOAT_VEC2,
4316 glu::TYPE_FLOAT_VEC3,
4317 glu::TYPE_FLOAT_VEC4,
4321 glu::TYPE_UINT_VEC2,
4322 glu::TYPE_UINT_VEC3,
4323 glu::TYPE_UINT_VEC4,
4324 glu::TYPE_BOOL_VEC2,
4325 glu::TYPE_BOOL_VEC3,
4326 glu::TYPE_BOOL_VEC4,
4327 glu::TYPE_FLOAT_MAT2,
4328 glu::TYPE_FLOAT_MAT2X3,
4329 glu::TYPE_FLOAT_MAT2X4,
4330 glu::TYPE_FLOAT_MAT3X2,
4331 glu::TYPE_FLOAT_MAT3,
4332 glu::TYPE_FLOAT_MAT3X4,
4333 glu::TYPE_FLOAT_MAT4X2,
4334 glu::TYPE_FLOAT_MAT4X3,
4335 glu::TYPE_FLOAT_MAT4,
4337 glu::TYPE_SAMPLER_2D,
4338 glu::TYPE_SAMPLER_CUBE,
4339 glu::TYPE_SAMPLER_2D_ARRAY,
4340 glu::TYPE_SAMPLER_3D,
4341 glu::TYPE_SAMPLER_2D_SHADOW,
4342 glu::TYPE_SAMPLER_CUBE_SHADOW,
4343 glu::TYPE_SAMPLER_2D_ARRAY_SHADOW,
4344 glu::TYPE_INT_SAMPLER_2D,
4345 glu::TYPE_INT_SAMPLER_CUBE,
4346 glu::TYPE_INT_SAMPLER_2D_ARRAY,
4347 glu::TYPE_INT_SAMPLER_3D,
4348 glu::TYPE_UINT_SAMPLER_2D,
4349 glu::TYPE_UINT_SAMPLER_CUBE,
4350 glu::TYPE_UINT_SAMPLER_2D_ARRAY,
4351 glu::TYPE_UINT_SAMPLER_3D,
4352 glu::TYPE_SAMPLER_2D_MULTISAMPLE,
4353 glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE,
4354 glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE,
4356 glu::TYPE_IMAGE_CUBE,
4357 glu::TYPE_IMAGE_2D_ARRAY,
4359 glu::TYPE_INT_IMAGE_2D,
4360 glu::TYPE_INT_IMAGE_CUBE,
4361 glu::TYPE_INT_IMAGE_2D_ARRAY,
4362 glu::TYPE_INT_IMAGE_3D,
4363 glu::TYPE_UINT_IMAGE_2D,
4364 glu::TYPE_UINT_IMAGE_CUBE,
4365 glu::TYPE_UINT_IMAGE_2D_ARRAY,
4366 glu::TYPE_UINT_IMAGE_3D,
4367 glu::TYPE_UINT_ATOMIC_COUNTER
4372 const glu::DataType type = s_types[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_types)-1)];
4374 if (!excludeOpaqueTypes ||
4375 glu::isDataTypeScalarOrVector(type) ||
4376 glu::isDataTypeMatrix(type))
4381 static ResourceDefinition::Node::SharedPtr generateRandomVariableDefinition (de::Random& rnd,
4382 const ResourceDefinition::Node::SharedPtr& parentStructure,
4383 glu::DataType baseType,
4384 const glu::Layout& layout,
4387 const int maxNesting = 4;
4388 ResourceDefinition::Node::SharedPtr currentStructure = parentStructure;
4389 const bool canBeInsideAStruct = layout.binding == -1 && !isDataTypeLayoutQualified(baseType);
4391 for (int nestNdx = 0; nestNdx < maxNesting; ++nestNdx)
4393 if (allowUnsized && nestNdx == 0 && rnd.getFloat() < 0.2)
4394 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
4395 else if (rnd.getFloat() < 0.3 && canBeInsideAStruct)
4396 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StructMember(currentStructure));
4397 else if (rnd.getFloat() < 0.3)
4398 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
4403 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Variable(currentStructure, baseType));
4406 static ResourceDefinition::Node::SharedPtr generateRandomCoreShaderSet (de::Random& rnd)
4408 if (rnd.getFloat() < 0.5f)
4411 const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
4412 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
4414 else if (rnd.getFloat() < 0.5f)
4416 // vertex and fragment
4417 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4418 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program, glu::GLSL_VERSION_310_ES);
4422 shaderSet->setStage(glu::SHADERTYPE_VERTEX, true);
4423 shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, rnd.getBool());
4427 shaderSet->setStage(glu::SHADERTYPE_VERTEX, rnd.getBool());
4428 shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, true);
4431 return ResourceDefinition::Node::SharedPtr(shaderSet);
4435 // separate vertex or fragment
4436 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
4437 const glu::ShaderType shaderType = (rnd.getBool()) ? (glu::SHADERTYPE_VERTEX) : (glu::SHADERTYPE_FRAGMENT);
4439 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, shaderType, glu::GLSL_VERSION_310_ES));
4443 static ResourceDefinition::Node::SharedPtr generateRandomExtShaderSet (de::Random& rnd)
4445 if (rnd.getFloat() < 0.5f)
4448 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4449 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program, glu::GLSL_VERSION_310_ES);
4451 shaderSet->setStage(glu::SHADERTYPE_VERTEX, rnd.getBool());
4452 shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, rnd.getBool());
4454 // tess shader are either both or neither present. Make cases interesting
4455 // by forcing one extended shader to always have reference
4458 shaderSet->setStage(glu::SHADERTYPE_GEOMETRY, true);
4462 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, rnd.getBool());
4463 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, rnd.getBool());
4468 shaderSet->setStage(glu::SHADERTYPE_GEOMETRY, rnd.getBool());
4472 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, true);
4473 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, rnd.getBool());
4477 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, rnd.getBool());
4478 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, true);
4482 return ResourceDefinition::Node::SharedPtr(shaderSet);
4487 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
4488 const int selector = rnd.getInt(0, 2);
4489 const glu::ShaderType shaderType = (selector == 0) ? (glu::SHADERTYPE_GEOMETRY)
4490 : (selector == 1) ? (glu::SHADERTYPE_TESSELLATION_CONTROL)
4491 : (selector == 2) ? (glu::SHADERTYPE_TESSELLATION_EVALUATION)
4492 : (glu::SHADERTYPE_LAST);
4494 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, shaderType, glu::GLSL_VERSION_310_ES));
4498 static ResourceDefinition::Node::SharedPtr generateRandomShaderSet (de::Random& rnd, bool onlyExtensionStages)
4500 if (!onlyExtensionStages)
4501 return generateRandomCoreShaderSet(rnd);
4503 return generateRandomExtShaderSet(rnd);
4506 static glu::Layout generateRandomUniformBlockLayout (de::Random& rnd)
4511 layout.binding = rnd.getInt(0, 5);
4514 layout.matrixOrder = (rnd.getBool()) ? (glu::MATRIXORDER_COLUMN_MAJOR) : (glu::MATRIXORDER_ROW_MAJOR);
4519 static glu::Layout generateRandomBufferBlockLayout (de::Random& rnd)
4521 return generateRandomUniformBlockLayout(rnd);
4524 static glu::Layout generateRandomVariableLayout (de::Random& rnd, glu::DataType type, bool interfaceBlockMember)
4528 if ((glu::isDataTypeAtomicCounter(type) || glu::isDataTypeImage(type) || glu::isDataTypeSampler(type)) && rnd.getBool())
4529 layout.binding = rnd.getInt(0, 5);
4531 if (glu::isDataTypeAtomicCounter(type) && rnd.getBool())
4532 layout.offset = rnd.getInt(0, 3) * 4;
4534 if (glu::isDataTypeMatrix(type) && interfaceBlockMember && rnd.getBool())
4535 layout.matrixOrder = (rnd.getBool()) ? (glu::MATRIXORDER_COLUMN_MAJOR) : (glu::MATRIXORDER_ROW_MAJOR);
4540 static void generateUniformRandomCase (Context& context, tcu::TestCaseGroup* const targetGroup, int index, bool onlyExtensionStages)
4542 de::Random rnd (index * 0x12345);
4543 const ResourceDefinition::Node::SharedPtr shader = generateRandomShaderSet(rnd, onlyExtensionStages);
4544 const bool interfaceBlock = rnd.getBool();
4545 const glu::DataType type = generateRandomDataType(rnd, interfaceBlock);
4546 const glu::Layout layout = generateRandomVariableLayout(rnd, type, interfaceBlock);
4547 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
4548 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4549 ResourceDefinition::Node::SharedPtr currentStructure = uniform;
4553 const bool namedBlock = rnd.getBool();
4555 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, generateRandomUniformBlockLayout(rnd)));
4557 if (namedBlock && rnd.getBool())
4558 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
4560 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(currentStructure, namedBlock));
4563 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, layout));
4564 currentStructure = generateRandomVariableDefinition(rnd, currentStructure, type, layout, false);
4566 targetGroup->addChild(new ResourceTestCase(context, currentStructure, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_UNIFORM_INTERFACE_MASK), de::toString(index).c_str()));
4569 static void generateUniformCaseRandomCases (Context& context, tcu::TestCaseGroup* const targetGroup)
4571 const int numBasicCases = 40;
4572 const int numTessGeoCases = 40;
4574 for (int ndx = 0; ndx < numBasicCases; ++ndx)
4575 generateUniformRandomCase(context, targetGroup, ndx, false);
4576 for (int ndx = 0; ndx < numTessGeoCases; ++ndx)
4577 generateUniformRandomCase(context, targetGroup, numBasicCases + ndx, true);
4580 class UniformInterfaceTestGroup : public TestCaseGroup
4583 UniformInterfaceTestGroup (Context& context);
4587 UniformInterfaceTestGroup::UniformInterfaceTestGroup (Context& context)
4588 : TestCaseGroup(context, "uniform", "Uniform interace")
4592 void UniformInterfaceTestGroup::init (void)
4594 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4595 const ResourceDefinition::Node::SharedPtr computeShader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
4599 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
4600 addChild(blockGroup);
4601 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformResourceListBlockContents);
4606 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Query array size");
4607 addChild(blockGroup);
4608 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockArraySizeContents);
4613 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_stride", "Query array stride");
4614 addChild(blockGroup);
4615 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockArrayStrideContents);
4618 // .atomic_counter_buffer_index
4620 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "atomic_counter_buffer_index", "Query atomic counter buffer index");
4621 addChild(blockGroup);
4622 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_DEFAULT | BLOCKFLAG_NAMED, generateUniformBlockAtomicCounterBufferIndexContents);
4627 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "block_index", "Query block index");
4628 addChild(blockGroup);
4629 generateUniformBlockBlockIndexContents(m_context, blockGroup);
4634 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Query location");
4635 addChild(blockGroup);
4636 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_DEFAULT | BLOCKFLAG_NAMED | BLOCKFLAG_UNNAMED, generateUniformBlockLocationContents);
4639 // .matrix_row_major
4641 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "matrix_row_major", "Query matrix row_major");
4642 addChild(blockGroup);
4643 generateUniformMatrixCaseBlocks(m_context, computeShader, blockGroup, generateUniformMatrixOrderCaseBlockContentCases);
4648 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "matrix_stride", "Query matrix stride");
4649 addChild(blockGroup);
4650 generateUniformMatrixCaseBlocks(m_context, computeShader, blockGroup, generateUniformMatrixStrideCaseBlockContentCases);
4655 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Query name length");
4656 addChild(blockGroup);
4657 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockNameLengthContents);
4662 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "offset", "Query offset");
4663 addChild(blockGroup);
4664 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockOffsetContents);
4667 // .referenced_by_shader
4669 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by_shader", "Query referenced by shader");
4670 addChild(blockGroup);
4671 generateReferencedByShaderCaseBlocks(m_context, blockGroup, generateUniformReferencedByShaderSingleBlockContentCases);
4676 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Query type");
4677 addChild(blockGroup);
4678 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockTypeContents);
4683 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random");
4684 addChild(blockGroup);
4685 generateUniformCaseRandomCases(m_context, blockGroup);
4689 static void generateBufferBackedInterfaceResourceListCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, const char* blockName)
4691 targetGroup->addChild(new ResourceListTestCase(context, targetResource, interface, blockName));
4694 static void generateBufferBackedInterfaceNameLengthCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, const char* blockName)
4696 targetGroup->addChild(new ResourceTestCase(context, targetResource, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_NAME_LENGTH), blockName));
4699 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))
4701 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4702 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
4703 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
4704 const ResourceDefinition::Node::SharedPtr storageQualifier (new ResourceDefinition::StorageQualifier(defaultBlock, storage));
4705 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(storageQualifier, glu::Layout(-1, 1)));
4706 const ProgramInterface programInterface = (storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) : (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK);
4710 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, true));
4711 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4713 blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "named_block");
4718 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, false));
4719 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4721 blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "unnamed_block");
4726 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding, 3));
4727 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4728 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4730 blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "block_array");
4733 // .block_array_single_element
4735 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding, 1));
4736 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4737 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4739 blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "block_array_single_element");
4743 static void generateBufferBackedInterfaceResourceBufferBindingCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
4745 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4746 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
4747 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
4748 const ResourceDefinition::Node::SharedPtr storageQualifier (new ResourceDefinition::StorageQualifier(defaultBlock, storage));
4750 for (int ndx = 0; ndx < 2; ++ndx)
4752 const bool explicitBinding = (ndx == 1);
4753 const int bindingNdx = (explicitBinding) ? (1) : (-1);
4754 const std::string nameSuffix = (explicitBinding) ? ("_explicit_binding") : ("");
4755 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(storageQualifier, glu::Layout(-1, bindingNdx)));
4756 const ProgramInterface programInterface = (storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) : (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK);
4760 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, true));
4761 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4763 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("named_block" + nameSuffix).c_str()));
4768 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, false));
4769 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4771 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("unnamed_block" + nameSuffix).c_str()));
4776 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding, 3));
4777 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4778 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4780 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("block_array" + nameSuffix).c_str()));
4785 template <glu::Storage Storage>
4786 static void generateBufferBlockReferencedByShaderSingleBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
4788 const ProgramInterface programInterface = (Storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
4789 (Storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
4790 (PROGRAMINTERFACE_LAST);
4791 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
4792 const ResourceDefinition::Node::SharedPtr storage (new ResourceDefinition::StorageQualifier(defaultBlock, Storage));
4794 DE_UNREF(expandLevel);
4796 DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
4800 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, true));
4801 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4803 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "named_block"));
4808 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, false));
4809 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4811 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "unnamed_block"));
4816 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(storage, 3));
4817 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4818 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4820 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "block_array"));
4824 static void generateBufferBackedInterfaceResourceActiveVariablesCase (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
4826 targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "named_block", "Named block", storage, InterfaceBlockActiveVariablesTestCase::CASE_NAMED_BLOCK));
4827 targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "unnamed_block", "Unnamed block", storage, InterfaceBlockActiveVariablesTestCase::CASE_UNNAMED_BLOCK));
4828 targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "block_array", "Block array", storage, InterfaceBlockActiveVariablesTestCase::CASE_BLOCK_ARRAY));
4831 static void generateBufferBackedInterfaceResourceBufferDataSizeCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
4833 targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "named_block", "Named block", storage, InterfaceBlockDataSizeTestCase::CASE_NAMED_BLOCK));
4834 targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "unnamed_block", "Unnamed block", storage, InterfaceBlockDataSizeTestCase::CASE_UNNAMED_BLOCK));
4835 targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "block_array", "Block array", storage, InterfaceBlockDataSizeTestCase::CASE_BLOCK_ARRAY));
4838 class BufferBackedBlockInterfaceTestGroup : public TestCaseGroup
4841 BufferBackedBlockInterfaceTestGroup (Context& context, glu::Storage interfaceBlockStorage);
4845 static const char* getGroupName (glu::Storage storage);
4846 static const char* getGroupDescription (glu::Storage storage);
4848 const glu::Storage m_storage;
4851 BufferBackedBlockInterfaceTestGroup::BufferBackedBlockInterfaceTestGroup(Context& context, glu::Storage storage)
4852 : TestCaseGroup (context, getGroupName(storage), getGroupDescription(storage))
4853 , m_storage (storage)
4855 DE_ASSERT(storage == glu::STORAGE_BUFFER || storage == glu::STORAGE_UNIFORM);
4858 void BufferBackedBlockInterfaceTestGroup::init (void)
4862 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
4863 addChild(blockGroup);
4864 generateBufferBackedInterfaceResourceBasicBlockTypes(m_context, blockGroup, m_storage, generateBufferBackedInterfaceResourceListCase);
4867 // .active_variables
4869 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "active_variables", "Active variables");
4870 addChild(blockGroup);
4871 generateBufferBackedInterfaceResourceActiveVariablesCase(m_context, blockGroup, m_storage);
4876 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "buffer_binding", "Buffer binding");
4877 addChild(blockGroup);
4878 generateBufferBackedInterfaceResourceBufferBindingCases(m_context, blockGroup, m_storage);
4881 // .buffer_data_size
4883 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "buffer_data_size", "Buffer data size");
4884 addChild(blockGroup);
4885 generateBufferBackedInterfaceResourceBufferDataSizeCases(m_context, blockGroup, m_storage);
4890 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
4891 addChild(blockGroup);
4892 generateBufferBackedInterfaceResourceBasicBlockTypes(m_context, blockGroup, m_storage, generateBufferBackedInterfaceNameLengthCase);
4897 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Referenced by shader");
4898 addChild(blockGroup);
4900 if (m_storage == glu::STORAGE_UNIFORM)
4901 generateReferencedByShaderCaseBlocks(m_context, blockGroup, generateBufferBlockReferencedByShaderSingleBlockContentCases<glu::STORAGE_UNIFORM>);
4902 else if (m_storage == glu::STORAGE_BUFFER)
4903 generateReferencedByShaderCaseBlocks(m_context, blockGroup, generateBufferBlockReferencedByShaderSingleBlockContentCases<glu::STORAGE_BUFFER>);
4909 const char* BufferBackedBlockInterfaceTestGroup::getGroupName (glu::Storage storage)
4913 case glu::STORAGE_UNIFORM: return "uniform_block";
4914 case glu::STORAGE_BUFFER: return "shader_storage_block";
4921 const char* BufferBackedBlockInterfaceTestGroup::getGroupDescription (glu::Storage storage)
4925 case glu::STORAGE_UNIFORM: return "Uniform block interface";
4926 case glu::STORAGE_BUFFER: return "Shader storage block interface";
4933 class AtomicCounterTestGroup : public TestCaseGroup
4936 AtomicCounterTestGroup (Context& context);
4940 AtomicCounterTestGroup::AtomicCounterTestGroup (Context& context)
4941 : TestCaseGroup(context, "atomic_counter_buffer", "Atomic counter buffer")
4945 void AtomicCounterTestGroup::init (void)
4955 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT)
4958 "vertex_tess_fragment",
4959 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION)
4962 "vertex_geo_fragment",
4963 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY)
4966 "vertex_tess_geo_fragment",
4967 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
4972 addChild(new AtomicCounterResourceListCase(m_context, "resource_list", "Resource list"));
4974 // .active_variables
4975 addChild(new AtomicCounterActiveVariablesCase(m_context, "active_variables", "Active variables"));
4978 addChild(new AtomicCounterBufferBindingCase(m_context, "buffer_binding", "Buffer binding"));
4980 // .buffer_data_size
4981 addChild(new AtomicCounterBufferDataSizeCase(m_context, "buffer_data_size", "Buffer binding"));
4984 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_compute", "", false, (1 << glu::SHADERTYPE_COMPUTE), (1 << glu::SHADERTYPE_COMPUTE)));
4985 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_vertex", "", true, (1 << glu::SHADERTYPE_VERTEX), (1 << glu::SHADERTYPE_VERTEX)));
4986 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_fragment", "", true, (1 << glu::SHADERTYPE_FRAGMENT), (1 << glu::SHADERTYPE_FRAGMENT)));
4987 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_geometry", "", true, (1 << glu::SHADERTYPE_GEOMETRY), (1 << glu::SHADERTYPE_GEOMETRY)));
4988 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_tess_ctrl", "", true, (1 << glu::SHADERTYPE_TESSELLATION_CONTROL), (1 << glu::SHADERTYPE_TESSELLATION_CONTROL)));
4989 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_tess_eval", "", true, (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION), (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION)));
4991 for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
4993 addChild(new AtomicCounterReferencedByCase(m_context, (std::string() + "referenced_by_" + pipelines[pipelineNdx].name).c_str(), "", false, pipelines[pipelineNdx].flags, pipelines[pipelineNdx].flags));
4995 for (deUint32 stageNdx = 0; stageNdx < glu::SHADERTYPE_LAST; ++stageNdx)
4997 const deUint32 currentBit = (1u << stageNdx);
4998 if (currentBit > pipelines[pipelineNdx].flags)
5000 if (currentBit & pipelines[pipelineNdx].flags)
5002 const char* stageName = (stageNdx == glu::SHADERTYPE_VERTEX) ? ("vertex")
5003 : (stageNdx == glu::SHADERTYPE_FRAGMENT) ? ("fragment")
5004 : (stageNdx == glu::SHADERTYPE_GEOMETRY) ? ("geo")
5005 : (stageNdx == glu::SHADERTYPE_TESSELLATION_CONTROL) ? ("tess_ctrl")
5006 : (stageNdx == glu::SHADERTYPE_TESSELLATION_EVALUATION) ? ("tess_eval")
5008 const std::string name = std::string() + "referenced_by_" + pipelines[pipelineNdx].name + "_only_" + stageName;
5010 addChild(new AtomicCounterReferencedByCase(m_context, name.c_str(), "", false, pipelines[pipelineNdx].flags, currentBit));
5016 static void generateProgramInputOutputShaderCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, bool withCompute, bool inputCase, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, deUint32))
5021 glu::ShaderType stage;
5022 } singleStageCases[] =
5024 { "separable_vertex", glu::SHADERTYPE_VERTEX },
5025 { "separable_fragment", glu::SHADERTYPE_FRAGMENT },
5026 { "separable_tess_ctrl", glu::SHADERTYPE_TESSELLATION_CONTROL },
5027 { "separable_tess_eval", glu::SHADERTYPE_TESSELLATION_EVALUATION },
5028 { "separable_geometry", glu::SHADERTYPE_GEOMETRY },
5033 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "vertex_fragment", "Vertex and fragment");
5034 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(false));
5035 ResourceDefinition::ShaderSet* shaderSetPtr = new ResourceDefinition::ShaderSet(program, glu::GLSL_VERSION_310_ES);
5036 const ResourceDefinition::Node::SharedPtr shaderSet (shaderSetPtr);
5037 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shaderSet));
5039 shaderSetPtr->setStage(glu::SHADERTYPE_VERTEX, inputCase);
5040 shaderSetPtr->setStage(glu::SHADERTYPE_FRAGMENT, !inputCase);
5042 targetGroup->addChild(blockGroup);
5044 blockContentGenerator(context, defaultBlock, blockGroup, (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT));
5048 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
5050 TestCaseGroup* const blockGroup = new TestCaseGroup(context, singleStageCases[ndx].name, "");
5051 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
5052 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glu::GLSL_VERSION_310_ES));
5053 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
5055 targetGroup->addChild(blockGroup);
5056 blockContentGenerator(context, defaultBlock, blockGroup, (1 << singleStageCases[ndx].stage));
5062 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "compute", "Compute");
5063 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
5064 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
5065 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
5067 targetGroup->addChild(blockGroup);
5069 blockContentGenerator(context, defaultBlock, blockGroup, (1 << glu::SHADERTYPE_COMPUTE));
5072 // .interface_blocks
5076 const char* inputName;
5077 glu::ShaderType inputStage;
5078 glu::Storage inputStorage;
5079 const char* outputName;
5080 glu::ShaderType outputStage;
5081 glu::Storage outputStorage;
5086 glu::SHADERTYPE_FRAGMENT,
5089 glu::SHADERTYPE_VERTEX,
5094 glu::SHADERTYPE_TESSELLATION_EVALUATION,
5095 glu::STORAGE_PATCH_IN,
5097 glu::SHADERTYPE_TESSELLATION_CONTROL,
5098 glu::STORAGE_PATCH_OUT,
5102 tcu::TestCaseGroup* const ioBlocksGroup = new TestCaseGroup(context, "interface_blocks", "Interface blocks");
5103 targetGroup->addChild(ioBlocksGroup);
5108 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(ioBlockTypes); ++ndx)
5110 const char* const name = (inputCase) ? (ioBlockTypes[ndx].inputName) : (ioBlockTypes[ndx].outputName);
5111 const glu::ShaderType shaderType = (inputCase) ? (ioBlockTypes[ndx].inputStage) : (ioBlockTypes[ndx].outputStage);
5112 const glu::Storage storageType = (inputCase) ? (ioBlockTypes[ndx].inputStorage) : (ioBlockTypes[ndx].outputStorage);
5113 tcu::TestCaseGroup* const ioBlockGroup = new TestCaseGroup(context, name, "");
5114 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
5115 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, shaderType, glu::GLSL_VERSION_310_ES));
5116 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
5117 const ResourceDefinition::Node::SharedPtr storage (new ResourceDefinition::StorageQualifier(defaultBlock, storageType));
5119 ioBlocksGroup->addChild(ioBlockGroup);
5123 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, true));
5124 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block", "Named block");
5126 ioBlockGroup->addChild(blockGroup);
5128 blockContentGenerator(context, block, blockGroup, (1 << shaderType));
5131 // .named_block_explicit_location
5133 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(storage, glu::Layout(3)));
5134 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(layout, true));
5135 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block_explicit_location", "Named block with explicit location");
5137 ioBlockGroup->addChild(blockGroup);
5139 blockContentGenerator(context, block, blockGroup, (1 << shaderType));
5144 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, false));
5145 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "Unnamed block");
5147 ioBlockGroup->addChild(blockGroup);
5149 blockContentGenerator(context, block, blockGroup, (1 << shaderType));
5154 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(storage));
5155 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
5156 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "Block array");
5158 ioBlockGroup->addChild(blockGroup);
5160 blockContentGenerator(context, block, blockGroup, (1 << shaderType));
5166 static void generateProgramInputBlockContents (Context& context,
5167 const ResourceDefinition::Node::SharedPtr& parentStructure,
5168 tcu::TestCaseGroup* targetGroup,
5169 deUint32 presentShadersMask,
5171 void (*genCase)(Context& context,
5172 const ResourceDefinition::Node::SharedPtr& parentStructure,
5173 tcu::TestCaseGroup* targetGroup,
5174 ProgramInterface interface,
5177 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5178 const ResourceDefinition::Node::SharedPtr input = (inDefaultBlock)
5179 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
5180 : (parentStructure);
5181 const glu::ShaderType firstStage = getShaderMaskFirstStage(presentShadersMask);
5184 if (includeEmpty && inDefaultBlock)
5185 genCase(context, parentStructure, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "empty");
5187 if (firstStage == glu::SHADERTYPE_VERTEX)
5190 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5191 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5193 else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5197 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5198 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5202 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(input));
5203 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5204 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var_struct");
5208 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input));
5209 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5210 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var_array");
5213 else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
5214 firstStage == glu::SHADERTYPE_GEOMETRY)
5216 // arrayed interface
5220 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5221 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5222 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5224 // extension forbids use arrays of structs
5225 // extension forbids use arrays of arrays
5227 else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5229 // arrayed interface
5230 const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5234 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5235 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5236 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5238 // extension forbids use arrays of structs
5239 // extension forbids use arrays of arrays
5243 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchInput, glu::TYPE_FLOAT_VEC4));
5244 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var");
5246 // .patch_var_struct
5248 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchInput));
5249 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5250 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var_struct");
5254 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchInput));
5255 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5256 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var_array");
5259 else if (firstStage == glu::SHADERTYPE_COMPUTE)
5267 static void generateProgramOutputBlockContents (Context& context,
5268 const ResourceDefinition::Node::SharedPtr& parentStructure,
5269 tcu::TestCaseGroup* targetGroup,
5270 deUint32 presentShadersMask,
5272 void (*genCase)(Context& context,
5273 const ResourceDefinition::Node::SharedPtr& parentStructure,
5274 tcu::TestCaseGroup* targetGroup,
5275 ProgramInterface interface,
5278 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5279 const ResourceDefinition::Node::SharedPtr output = (inDefaultBlock)
5280 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
5281 : (parentStructure);
5282 const glu::ShaderType lastStage = getShaderMaskLastStage(presentShadersMask);
5285 if (includeEmpty && inDefaultBlock)
5286 genCase(context, parentStructure, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "empty");
5288 if (lastStage == glu::SHADERTYPE_VERTEX ||
5289 lastStage == glu::SHADERTYPE_GEOMETRY ||
5290 lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
5295 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5296 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5300 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
5301 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5302 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_struct");
5306 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5307 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5308 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_array");
5311 else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5315 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5316 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5320 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5321 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5322 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_array");
5325 else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5327 // arrayed interface
5328 const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5332 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5333 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5334 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5336 // extension forbids use arrays of structs
5337 // extension forbids use array of arrays
5341 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchOutput, glu::TYPE_FLOAT_VEC4));
5342 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var");
5344 // .patch_var_struct
5346 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchOutput));
5347 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5348 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var_struct");
5352 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchOutput));
5353 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5354 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var_array");
5357 else if (lastStage == glu::SHADERTYPE_COMPUTE)
5365 static void addProgramInputOutputResourceListCase (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramInterface programInterface, const char* name)
5367 ResourceListTestCase* const resourceListCase = new ResourceListTestCase(context, parentStructure, programInterface);
5369 DE_ASSERT(deStringEqual(name, resourceListCase->getName()));
5371 targetGroup->addChild(resourceListCase);
5374 static void generateProgramInputResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5376 generateProgramInputBlockContents(context, parentStructure, targetGroup, presentShadersMask, true, addProgramInputOutputResourceListCase);
5379 static void generateProgramOutputResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5381 generateProgramOutputBlockContents(context, parentStructure, targetGroup, presentShadersMask, true, addProgramInputOutputResourceListCase);
5384 template <ProgramResourcePropFlags TargetProp>
5385 static void addProgramInputOutputResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramInterface programInterface, const char* name)
5387 ResourceTestCase* const resourceTestCase = new ResourceTestCase(context, parentStructure, ProgramResourceQueryTestTarget(programInterface, TargetProp), name);
5388 targetGroup->addChild(resourceTestCase);
5391 template <ProgramResourcePropFlags TargetProp>
5392 static void generateProgramInputBasicBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5394 generateProgramInputBlockContents(context, parentStructure, targetGroup, presentShadersMask, false, addProgramInputOutputResourceTestCase<TargetProp>);
5397 template <ProgramResourcePropFlags TargetProp>
5398 static void generateProgramOutputBasicBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5400 generateProgramOutputBlockContents(context, parentStructure, targetGroup, presentShadersMask, false, addProgramInputOutputResourceTestCase<TargetProp>);
5403 static void generateProgramInputLocationBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5405 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5406 const ResourceDefinition::Node::SharedPtr input = (inDefaultBlock)
5407 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
5408 : (parentStructure);
5409 const glu::ShaderType firstStage = getShaderMaskFirstStage(presentShadersMask);
5411 if (firstStage == glu::SHADERTYPE_VERTEX)
5415 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5416 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5418 // .var_explicit_location
5420 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5421 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5422 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5425 else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5429 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5430 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5432 // .var_explicit_location
5434 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5435 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5436 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5440 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(input));
5441 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5442 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct"));
5444 // .var_struct_explicit_location
5446 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5447 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5448 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5449 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct_explicit_location"));
5453 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input));
5454 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5455 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
5457 // .var_array_explicit_location
5459 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5460 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5461 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5462 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
5465 else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
5466 firstStage == glu::SHADERTYPE_GEOMETRY)
5468 // arrayed interface
5472 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5473 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5474 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5476 // .var_explicit_location
5478 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5479 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5480 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5481 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5483 // extension forbids use arrays of structs
5484 // extension forbids use arrays of arrays
5486 else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5488 // arrayed interface
5489 const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5493 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5494 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5495 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5497 // .var_explicit_location
5499 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5500 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5501 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5502 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5504 // extension forbids use arrays of structs
5505 // extension forbids use arrays of arrays
5509 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchInput, glu::TYPE_FLOAT_VEC4));
5510 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var"));
5512 // .patch_var_explicit_location
5514 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
5515 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5516 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_explicit_location"));
5518 // .patch_var_struct
5520 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchInput));
5521 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5522 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct"));
5524 // .patch_var_struct_explicit_location
5526 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
5527 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5528 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5529 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct_explicit_location"));
5533 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchInput));
5534 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5535 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array"));
5537 // .patch_var_array_explicit_location
5539 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
5540 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5541 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5542 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array_explicit_location"));
5545 else if (firstStage == glu::SHADERTYPE_COMPUTE)
5553 static void generateProgramOutputLocationBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5555 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5556 const ResourceDefinition::Node::SharedPtr output = (inDefaultBlock)
5557 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
5558 : (parentStructure);
5559 const glu::ShaderType lastStage = getShaderMaskLastStage(presentShadersMask);
5561 if (lastStage == glu::SHADERTYPE_VERTEX ||
5562 lastStage == glu::SHADERTYPE_GEOMETRY ||
5563 lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
5568 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5569 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5571 // .var_explicit_location
5573 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5574 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5575 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5579 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
5580 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5581 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct"));
5583 // .var_struct_explicit_location
5585 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5586 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5587 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5588 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct_explicit_location"));
5592 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5593 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5594 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
5596 // .var_array_explicit_location
5598 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5599 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5600 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5601 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
5604 else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5608 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5609 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5611 // .var_explicit_location
5613 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5614 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5615 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5619 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5620 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5621 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
5623 // .var_array_explicit_location
5625 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(1)));
5626 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5627 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5628 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
5631 else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5633 // arrayed interface
5634 const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5638 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5639 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5640 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5642 // .var_explicit_location
5644 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5645 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5646 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5647 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5649 // extension forbids use arrays of structs
5650 // extension forbids use array of arrays
5654 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchOutput, glu::TYPE_FLOAT_VEC4));
5655 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var"));
5657 // .patch_var_explicit_location
5659 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
5660 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5661 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_explicit_location"));
5663 // .patch_var_struct
5665 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchOutput));
5666 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5667 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct"));
5669 // .patch_var_struct_explicit_location
5671 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
5672 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5673 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5674 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct_explicit_location"));
5678 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchOutput));
5679 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5680 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array"));
5682 // .patch_var_array_explicit_location
5684 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
5685 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5686 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5687 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array_explicit_location"));
5690 else if (lastStage == glu::SHADERTYPE_COMPUTE)
5698 static void generateProgramInputOutputReferencedByCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
5700 // all whole pipelines
5701 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_FRAGMENT));
5702 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_tess_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_TESS_FRAGMENT));
5703 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_geo_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_GEO_FRAGMENT));
5704 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_tess_geo_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_TESS_GEO_FRAGMENT));
5706 // all partial pipelines
5707 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_vertex", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_VERTEX));
5708 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_FRAGMENT));
5709 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_geometry", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_GEOMETRY));
5710 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_eval", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_EVAL));
5711 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_ctrl", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_CTRL));
5714 if (storage == glu::STORAGE_IN)
5715 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_eval_patch_in", "", glu::STORAGE_PATCH_IN, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_EVAL));
5716 else if (storage == glu::STORAGE_OUT)
5717 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_ctrl_patch_out", "", glu::STORAGE_PATCH_OUT, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_CTRL));
5722 template <ProgramInterface interface>
5723 static void generateProgramInputOutputTypeBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool allowMatrixCases, int expandLevel)
5732 { glu::TYPE_FLOAT, false, 0 },
5733 { glu::TYPE_INT, false, 1 },
5734 { glu::TYPE_UINT, false, 1 },
5735 { glu::TYPE_FLOAT_VEC2, false, 2 },
5736 { glu::TYPE_FLOAT_VEC3, false, 1 },
5737 { glu::TYPE_FLOAT_VEC4, false, 2 },
5738 { glu::TYPE_INT_VEC2, false, 0 },
5739 { glu::TYPE_INT_VEC3, false, 2 },
5740 { glu::TYPE_INT_VEC4, false, 2 },
5741 { glu::TYPE_UINT_VEC2, false, 2 },
5742 { glu::TYPE_UINT_VEC3, false, 2 },
5743 { glu::TYPE_UINT_VEC4, false, 0 },
5744 { glu::TYPE_FLOAT_MAT2, true, 2 },
5745 { glu::TYPE_FLOAT_MAT2X3, true, 2 },
5746 { glu::TYPE_FLOAT_MAT2X4, true, 2 },
5747 { glu::TYPE_FLOAT_MAT3X2, true, 0 },
5748 { glu::TYPE_FLOAT_MAT3, true, 2 },
5749 { glu::TYPE_FLOAT_MAT3X4, true, 2 },
5750 { glu::TYPE_FLOAT_MAT4X2, true, 2 },
5751 { glu::TYPE_FLOAT_MAT4X3, true, 2 },
5752 { glu::TYPE_FLOAT_MAT4, true, 2 },
5755 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
5757 if (!allowMatrixCases && variableTypes[ndx].isMatrix)
5760 if (variableTypes[ndx].level <= expandLevel)
5762 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
5763 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_TYPE)));
5768 static void generateProgramInputTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5770 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5771 const ResourceDefinition::Node::SharedPtr input = (inDefaultBlock)
5772 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
5773 : (parentStructure);
5774 const glu::ShaderType firstStage = getShaderMaskFirstStage(presentShadersMask);
5775 const int interfaceBlockExpansionReducement = (!inDefaultBlock) ? (1) : (0); // lesser expansions on block members to keep test counts reasonable
5777 if (firstStage == glu::SHADERTYPE_VERTEX)
5779 // Only basic types (and no booleans)
5780 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, input, targetGroup, true, 2 - interfaceBlockExpansionReducement);
5782 else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5784 const ResourceDefinition::Node::SharedPtr flatShading(new ResourceDefinition::InterpolationQualifier(input, glu::INTERPOLATION_FLAT));
5786 // Only basic types, arrays of basic types, struct of basic types (and no booleans)
5788 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5789 targetGroup->addChild(blockGroup);
5790 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, flatShading, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5793 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(flatShading));
5794 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
5796 targetGroup->addChild(blockGroup);
5797 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElement, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5800 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(flatShading));
5801 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Struct types");
5803 targetGroup->addChild(blockGroup);
5804 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, structMember, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5807 else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
5808 firstStage == glu::SHADERTYPE_GEOMETRY)
5810 // arrayed interface
5812 // Only basic types (and no booleans)
5813 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5814 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElement, targetGroup, true, 2);
5816 else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5818 // arrayed interface
5819 const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5823 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5824 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5826 targetGroup->addChild(blockGroup);
5827 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElem, blockGroup, true, 2);
5829 // extension forbids use arrays of structs
5830 // extension forbids use arrays of arrays
5834 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var", "Basic types, per-patch");
5836 targetGroup->addChild(blockGroup);
5837 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, patchInput, blockGroup, true, 1);
5839 // .patch_var_struct
5841 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchInput));
5842 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_struct", "Struct types, per-patch");
5844 targetGroup->addChild(blockGroup);
5845 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, structMbr, blockGroup, true, 1);
5849 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchInput));
5850 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_array", "Array types, per-patch");
5852 targetGroup->addChild(blockGroup);
5853 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElem, blockGroup, true, 1);
5856 else if (firstStage == glu::SHADERTYPE_COMPUTE)
5864 static void generateProgramOutputTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5866 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5867 const ResourceDefinition::Node::SharedPtr output = (inDefaultBlock)
5868 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
5869 : (parentStructure);
5870 const glu::ShaderType lastStage = getShaderMaskLastStage(presentShadersMask);
5871 const int interfaceBlockExpansionReducement = (!inDefaultBlock) ? (1) : (0); // lesser expansions on block members to keep test counts reasonable
5873 if (lastStage == glu::SHADERTYPE_VERTEX ||
5874 lastStage == glu::SHADERTYPE_GEOMETRY ||
5875 lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
5878 const ResourceDefinition::Node::SharedPtr flatShading(new ResourceDefinition::InterpolationQualifier(output, glu::INTERPOLATION_FLAT));
5880 // Only basic types, arrays of basic types, struct of basic types (and no booleans)
5882 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5883 targetGroup->addChild(blockGroup);
5884 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, flatShading, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5887 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(flatShading));
5888 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
5889 const int typeExpansionReducement = (lastStage != glu::SHADERTYPE_VERTEX) ? (1) : (0); // lesser expansions on other stages
5890 const int expansionLevel = 2 - interfaceBlockExpansionReducement - typeExpansionReducement;
5892 targetGroup->addChild(blockGroup);
5893 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElement, blockGroup, true, expansionLevel);
5896 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(flatShading));
5897 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Struct types");
5898 const int typeExpansionReducement = (lastStage != glu::SHADERTYPE_VERTEX) ? (1) : (0); // lesser expansions on other stages
5899 const int expansionLevel = 2 - interfaceBlockExpansionReducement - typeExpansionReducement;
5901 targetGroup->addChild(blockGroup);
5902 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, structMember, blockGroup, true, expansionLevel);
5905 else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5907 // only basic type and basic type array (and no booleans or matrices)
5909 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5910 targetGroup->addChild(blockGroup);
5911 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, output, blockGroup, false, 2);
5914 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(output));
5915 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
5917 targetGroup->addChild(blockGroup);
5918 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElement, blockGroup, false, 2);
5921 else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5923 // arrayed interface
5924 const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5928 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5929 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5931 targetGroup->addChild(blockGroup);
5932 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElem, blockGroup, true, 2);
5934 // extension forbids use arrays of structs
5935 // extension forbids use arrays of arrays
5939 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var", "Basic types, per-patch");
5941 targetGroup->addChild(blockGroup);
5942 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, patchOutput, blockGroup, true, 1);
5944 // .patch_var_struct
5946 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchOutput));
5947 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_struct", "Struct types, per-patch");
5949 targetGroup->addChild(blockGroup);
5950 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, structMbr, blockGroup, true, 1);
5954 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchOutput));
5955 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_array", "Array types, per-patch");
5957 targetGroup->addChild(blockGroup);
5958 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElem, blockGroup, true, 1);
5961 else if (lastStage == glu::SHADERTYPE_COMPUTE)
5969 class ProgramInputTestGroup : public TestCaseGroup
5972 ProgramInputTestGroup (Context& context);
5976 ProgramInputTestGroup::ProgramInputTestGroup (Context& context)
5977 : TestCaseGroup(context, "program_input", "Program input")
5981 void ProgramInputTestGroup::init (void)
5985 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
5986 addChild(blockGroup);
5987 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, true, true, generateProgramInputResourceListBlockContents);
5992 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Array size");
5993 addChild(blockGroup);
5994 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
5999 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Location");
6000 addChild(blockGroup);
6001 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputLocationBlockContents);
6006 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
6007 addChild(blockGroup);
6008 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6013 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Reference by shader");
6014 addChild(blockGroup);
6015 generateProgramInputOutputReferencedByCases(m_context, blockGroup, glu::STORAGE_IN);
6020 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Type");
6021 addChild(blockGroup);
6022 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputTypeBlockContents);
6027 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "is_per_patch", "Is per patch");
6028 addChild(blockGroup);
6029 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
6033 class ProgramOutputTestGroup : public TestCaseGroup
6036 ProgramOutputTestGroup (Context& context);
6040 ProgramOutputTestGroup::ProgramOutputTestGroup (Context& context)
6041 : TestCaseGroup(context, "program_output", "Program output")
6045 void ProgramOutputTestGroup::init (void)
6049 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
6050 addChild(blockGroup);
6051 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, true, false, generateProgramOutputResourceListBlockContents);
6056 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Array size");
6057 addChild(blockGroup);
6058 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6063 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Location");
6064 addChild(blockGroup);
6065 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputLocationBlockContents);
6070 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
6071 addChild(blockGroup);
6072 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6077 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Reference by shader");
6078 addChild(blockGroup);
6079 generateProgramInputOutputReferencedByCases(m_context, blockGroup, glu::STORAGE_OUT);
6084 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Type");
6085 addChild(blockGroup);
6086 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputTypeBlockContents);
6091 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "is_per_patch", "Is per patch");
6092 addChild(blockGroup);
6093 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
6097 static void generateTransformFeedbackShaderCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, bool))
6103 deUint32 lastStageBit;
6109 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT),
6110 (1 << glu::SHADERTYPE_VERTEX),
6114 "vertex_tess_fragment",
6115 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
6116 (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
6120 "vertex_geo_fragment",
6121 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY),
6122 (1 << glu::SHADERTYPE_GEOMETRY),
6126 "vertex_tess_geo_fragment",
6127 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
6128 (1 << glu::SHADERTYPE_GEOMETRY),
6135 glu::ShaderType stage;
6137 } singleStageCases[] =
6139 { "separable_vertex", glu::SHADERTYPE_VERTEX, false },
6140 { "separable_tess_eval", glu::SHADERTYPE_TESSELLATION_EVALUATION, true },
6141 { "separable_geometry", glu::SHADERTYPE_GEOMETRY, true },
6144 // monolithic pipeline
6145 for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
6147 TestCaseGroup* const blockGroup = new TestCaseGroup(context, pipelines[pipelineNdx].name, "");
6148 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6149 const ResourceDefinition::Node::SharedPtr shaderSet (new ResourceDefinition::ShaderSet(program,
6150 glu::GLSL_VERSION_310_ES,
6151 pipelines[pipelineNdx].stageBits,
6152 pipelines[pipelineNdx].lastStageBit));
6154 targetGroup->addChild(blockGroup);
6155 blockContentGenerator(context, shaderSet, blockGroup, pipelines[pipelineNdx].reducedSet);
6158 // separable pipeline
6159 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
6161 TestCaseGroup* const blockGroup = new TestCaseGroup(context, singleStageCases[ndx].name, "");
6162 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
6163 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glu::GLSL_VERSION_310_ES));
6165 targetGroup->addChild(blockGroup);
6166 blockContentGenerator(context, shader, blockGroup, singleStageCases[ndx].reducedSet);
6170 static void generateTransformFeedbackResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6172 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6173 const ResourceDefinition::Node::SharedPtr output (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6175 DE_UNREF(reducedSet);
6177 // .builtin_gl_position
6179 const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6180 targetGroup->addChild(new FeedbackResourceListTestCase(context, xfbTarget, "builtin_gl_position"));
6182 // .default_block_basic_type
6184 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6185 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6186 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_basic_type"));
6188 // .default_block_struct_member
6190 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
6191 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(structMbr));
6192 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6193 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_struct_member"));
6195 // .default_block_array
6197 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6198 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(xfbTarget));
6199 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6200 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_array"));
6202 // .default_block_array_element
6204 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
6205 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(arrayElem));
6206 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6207 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_array_element"));
6211 template <ProgramResourcePropFlags TargetProp>
6212 static void generateTransformFeedbackVariableBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6214 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6215 const ResourceDefinition::Node::SharedPtr output (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6217 DE_UNREF(reducedSet);
6219 // .builtin_gl_position
6221 const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6222 targetGroup->addChild(new ResourceTestCase(context, xfbTarget, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "builtin_gl_position"));
6224 // .default_block_basic_type
6226 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6227 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6228 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_basic_type"));
6230 // .default_block_struct_member
6232 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
6233 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(structMbr));
6234 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6235 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_struct_member"));
6237 // .default_block_array
6239 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6240 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(xfbTarget));
6241 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6242 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_array"));
6244 // .default_block_array_element
6246 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
6247 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(arrayElem));
6248 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6249 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_array_element"));
6253 static void generateTransformFeedbackVariableBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6261 { glu::TYPE_FLOAT, true },
6262 { glu::TYPE_INT, true },
6263 { glu::TYPE_UINT, true },
6265 { glu::TYPE_FLOAT_VEC2, false },
6266 { glu::TYPE_FLOAT_VEC3, true },
6267 { glu::TYPE_FLOAT_VEC4, false },
6269 { glu::TYPE_INT_VEC2, false },
6270 { glu::TYPE_INT_VEC3, true },
6271 { glu::TYPE_INT_VEC4, false },
6273 { glu::TYPE_UINT_VEC2, true },
6274 { glu::TYPE_UINT_VEC3, false },
6275 { glu::TYPE_UINT_VEC4, false },
6277 { glu::TYPE_FLOAT_MAT2, false },
6278 { glu::TYPE_FLOAT_MAT2X3, false },
6279 { glu::TYPE_FLOAT_MAT2X4, false },
6280 { glu::TYPE_FLOAT_MAT3X2, false },
6281 { glu::TYPE_FLOAT_MAT3, false },
6282 { glu::TYPE_FLOAT_MAT3X4, true },
6283 { glu::TYPE_FLOAT_MAT4X2, false },
6284 { glu::TYPE_FLOAT_MAT4X3, false },
6285 { glu::TYPE_FLOAT_MAT4, false },
6288 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6290 if (variableTypes[ndx].important || !reducedSet)
6292 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
6293 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, PROGRAMRESOURCEPROP_TYPE)));
6298 static void generateTransformFeedbackVariableTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6300 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6301 const ResourceDefinition::Node::SharedPtr output (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6302 const ResourceDefinition::Node::SharedPtr flatShading (new ResourceDefinition::InterpolationQualifier(output, glu::INTERPOLATION_FLAT));
6304 // Only builtins, basic types, arrays of basic types, struct of basic types (and no booleans)
6306 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6307 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "builtin", "Built-in outputs");
6309 targetGroup->addChild(blockGroup);
6310 blockGroup->addChild(new ResourceTestCase(context, xfbTarget, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, PROGRAMRESOURCEPROP_TYPE), "gl_position"));
6313 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(flatShading));
6314 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
6316 targetGroup->addChild(blockGroup);
6317 generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
6320 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(flatShading));
6321 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(arrayElement));
6322 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
6324 targetGroup->addChild(blockGroup);
6325 generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
6328 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(flatShading));
6329 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(xfbTarget));
6330 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "whole_array", "Whole array");
6332 targetGroup->addChild(blockGroup);
6333 generateTransformFeedbackVariableBasicTypeCases(context, arrayElement, blockGroup, reducedSet);
6336 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(flatShading));
6337 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(structMember));
6338 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Struct types");
6340 targetGroup->addChild(blockGroup);
6341 generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
6345 class TransformFeedbackVaryingTestGroup : public TestCaseGroup
6348 TransformFeedbackVaryingTestGroup (Context& context);
6352 TransformFeedbackVaryingTestGroup::TransformFeedbackVaryingTestGroup (Context& context)
6353 : TestCaseGroup(context, "transform_feedback_varying", "Transform feedback varyings")
6357 void TransformFeedbackVaryingTestGroup::init (void)
6361 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "resource_list", "Resource list");
6362 addChild(blockGroup);
6363 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, generateTransformFeedbackResourceListBlockContents);
6368 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_size", "Array size");
6369 addChild(blockGroup);
6370 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, generateTransformFeedbackVariableBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6375 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "name_length", "Name length");
6376 addChild(blockGroup);
6377 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, generateTransformFeedbackVariableBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6382 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "type", "Type");
6383 addChild(blockGroup);
6384 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, generateTransformFeedbackVariableTypeBlockContents);
6388 static void generateBufferVariableBufferCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*))
6390 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6391 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
6392 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6393 const ResourceDefinition::Node::SharedPtr bufferStorage (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6394 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(bufferStorage, glu::Layout(-1, 0)));
6398 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, true));
6399 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block", "Named block");
6401 targetGroup->addChild(blockGroup);
6403 blockContentGenerator(context, buffer, blockGroup);
6408 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, false));
6409 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "Unnamed block");
6411 targetGroup->addChild(blockGroup);
6413 blockContentGenerator(context, buffer, blockGroup);
6418 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding));
6419 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
6420 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "Block array");
6422 targetGroup->addChild(blockGroup);
6424 blockContentGenerator(context, buffer, blockGroup);
6428 static void generateBufferVariableResourceListBlockContentsProxy (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
6430 generateBufferBackedResourceListBlockContentCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, 4);
6433 static void generateBufferVariableArraySizeSubCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramResourcePropFlags targetProp, bool sizedArray, bool extendedCases)
6435 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp);
6436 tcu::TestCaseGroup* aggregateGroup;
6441 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
6442 targetGroup->addChild(blockGroup);
6444 generateVariableCases(context, parentStructure, blockGroup, queryTarget, (sizedArray) ? (2) : (1), false);
6450 aggregateGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
6451 targetGroup->addChild(aggregateGroup);
6454 aggregateGroup = targetGroup;
6457 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_FLOAT, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6460 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_BOOL, (extendedCases && sizedArray) ? (1) : (0), !extendedCases);
6463 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_BOOL_VEC3, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6466 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_FLOAT_VEC4, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6469 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_INT_VEC2, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6472 template <ProgramResourcePropFlags TargetProp>
6473 static void generateBufferVariableArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
6475 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp);
6476 const bool namedNonArrayBlock = static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named && parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
6479 if (namedNonArrayBlock)
6481 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "non_array", "Non-array target");
6482 targetGroup->addChild(blockGroup);
6484 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 1, false);
6489 const ResourceDefinition::Node::SharedPtr sized (new ResourceDefinition::ArrayElement(parentStructure));
6490 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
6491 targetGroup->addChild(blockGroup);
6493 generateBufferVariableArraySizeSubCases(context, sized, blockGroup, TargetProp, true, namedNonArrayBlock);
6498 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6499 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unsized", "Unsized target");
6500 targetGroup->addChild(blockGroup);
6502 generateBufferVariableArraySizeSubCases(context, unsized, blockGroup, TargetProp, false, namedNonArrayBlock);
6506 static void generateBufferVariableBlockIndexCases (Context& context, tcu::TestCaseGroup* const targetGroup)
6508 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6509 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
6510 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6511 const ResourceDefinition::Node::SharedPtr bufferStorage (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6512 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(bufferStorage, glu::Layout(-1, 0)));
6516 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, true));
6517 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
6519 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "named_block"));
6524 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, false));
6525 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
6527 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "unnamed_block"));
6532 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding));
6533 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
6534 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
6536 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "block_array"));
6540 static void generateBufferVariableMatrixCaseBlocks (Context& context, tcu::TestCaseGroup* const targetGroup, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, bool))
6545 const char* description;
6547 bool extendedBasicTypeCases;
6548 glu::MatrixOrder order;
6551 { "named_block", "Named uniform block", true, true, glu::MATRIXORDER_LAST },
6552 { "named_block_row_major", "Named uniform block", true, false, glu::MATRIXORDER_ROW_MAJOR },
6553 { "named_block_col_major", "Named uniform block", true, false, glu::MATRIXORDER_COLUMN_MAJOR },
6554 { "unnamed_block", "Unnamed uniform block", false, false, glu::MATRIXORDER_LAST },
6555 { "unnamed_block_row_major", "Unnamed uniform block", false, false, glu::MATRIXORDER_ROW_MAJOR },
6556 { "unnamed_block_col_major", "Unnamed uniform block", false, false, glu::MATRIXORDER_COLUMN_MAJOR },
6559 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6560 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
6561 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6562 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6564 for (int childNdx = 0; childNdx < (int)DE_LENGTH_OF_ARRAY(children); ++childNdx)
6566 ResourceDefinition::Node::SharedPtr parentStructure = buffer;
6567 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, children[childNdx].name, children[childNdx].description);
6569 targetGroup->addChild(blockGroup);
6571 if (children[childNdx].order != glu::MATRIXORDER_LAST)
6574 layout.matrixOrder = children[childNdx].order;
6575 parentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(parentStructure, layout));
6578 parentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(parentStructure, children[childNdx].namedBlock));
6580 blockContentGenerator(context, parentStructure, blockGroup, children[childNdx].extendedBasicTypeCases);
6584 static void generateBufferVariableMatrixVariableBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramResourcePropFlags targetProp)
6586 // all matrix types and some non-matrix
6588 static const glu::DataType variableTypes[] =
6592 glu::TYPE_FLOAT_MAT2,
6593 glu::TYPE_FLOAT_MAT2X3,
6594 glu::TYPE_FLOAT_MAT2X4,
6595 glu::TYPE_FLOAT_MAT3X2,
6596 glu::TYPE_FLOAT_MAT3,
6597 glu::TYPE_FLOAT_MAT3X4,
6598 glu::TYPE_FLOAT_MAT4X2,
6599 glu::TYPE_FLOAT_MAT4X3,
6600 glu::TYPE_FLOAT_MAT4,
6603 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6605 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx]));
6606 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp)));
6610 static void generateBufferVariableMatrixVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramResourcePropFlags targetProp)
6613 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp, glu::TYPE_FLOAT_MAT3X2, "", 2);
6617 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6618 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(unsized, glu::TYPE_FLOAT_MAT3X2));
6620 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp), "var_unsized_array"));
6624 template <ProgramResourcePropFlags TargetProp>
6625 static void generateBufferVariableMatrixCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool extendedTypeCases)
6628 if (extendedTypeCases)
6630 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "types", "Types");
6631 targetGroup->addChild(blockGroup);
6632 generateBufferVariableMatrixVariableBasicTypeCases(context, parentStructure, blockGroup, TargetProp);
6637 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "no_qualifier", "No qualifier");
6638 targetGroup->addChild(blockGroup);
6639 generateBufferVariableMatrixVariableCases(context, parentStructure, blockGroup, TargetProp);
6644 const ResourceDefinition::Node::SharedPtr matrixOrder(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, -1, glu::FORMATLAYOUT_LAST, glu::MATRIXORDER_COLUMN_MAJOR)));
6646 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "column_major", "Column major qualifier");
6647 targetGroup->addChild(blockGroup);
6648 generateBufferVariableMatrixVariableCases(context, matrixOrder, blockGroup, TargetProp);
6653 const ResourceDefinition::Node::SharedPtr matrixOrder(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, -1, glu::FORMATLAYOUT_LAST, glu::MATRIXORDER_ROW_MAJOR)));
6655 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "row_major", "Row major qualifier");
6656 targetGroup->addChild(blockGroup);
6657 generateBufferVariableMatrixVariableCases(context, matrixOrder, blockGroup, TargetProp);
6661 static void generateBufferVariableNameLengthCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
6665 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
6666 targetGroup->addChild(blockGroup);
6668 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 3);
6673 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6674 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unsized", "Unsized target");
6675 targetGroup->addChild(blockGroup);
6677 generateBufferBackedVariableAggregateTypeCases(context, unsized, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 2);
6681 static void generateBufferVariableOffsetCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
6685 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
6686 targetGroup->addChild(blockGroup);
6688 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_OFFSET, glu::TYPE_FLOAT, "", 3);
6693 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6694 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unsized", "Unsized target");
6695 targetGroup->addChild(blockGroup);
6697 generateBufferBackedVariableAggregateTypeCases(context, unsized, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_OFFSET, glu::TYPE_FLOAT, "", 2);
6701 static void generateBufferVariableReferencedByBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
6703 DE_UNREF(expandLevel);
6705 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER);
6706 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6707 const ResourceDefinition::Node::SharedPtr storage (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6708 const bool singleShaderCase = parentStructure->getType() == ResourceDefinition::Node::TYPE_SHADER;
6712 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(storage, true));
6713 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block", "Named block");
6715 targetGroup->addChild(blockGroup);
6717 generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, singleShaderCase);
6722 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(storage, false));
6723 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "Unnamed block");
6725 targetGroup->addChild(blockGroup);
6727 generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, false);
6732 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(storage));
6733 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
6734 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "Block array");
6736 targetGroup->addChild(blockGroup);
6738 generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, false);
6742 template <ProgramResourcePropFlags TargetProp>
6743 static void generateBufferVariableTopLevelCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
6745 // basic and aggregate types
6746 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp, glu::TYPE_FLOAT_VEC4, "", 3);
6748 // basic and aggregate types in an unsized array
6750 const ResourceDefinition::Node::SharedPtr unsized(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6752 generateBufferBackedVariableAggregateTypeCases(context, unsized, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp, glu::TYPE_FLOAT_VEC4, "_unsized_array", 2);
6756 static void generateBufferVariableTypeBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
6761 glu::DataType dataType;
6764 { 0, glu::TYPE_FLOAT },
6765 { 1, glu::TYPE_INT },
6766 { 1, glu::TYPE_UINT },
6767 { 1, glu::TYPE_BOOL },
6769 { 3, glu::TYPE_FLOAT_VEC2 },
6770 { 1, glu::TYPE_FLOAT_VEC3 },
6771 { 1, glu::TYPE_FLOAT_VEC4 },
6773 { 3, glu::TYPE_INT_VEC2 },
6774 { 2, glu::TYPE_INT_VEC3 },
6775 { 3, glu::TYPE_INT_VEC4 },
6777 { 3, glu::TYPE_UINT_VEC2 },
6778 { 2, glu::TYPE_UINT_VEC3 },
6779 { 3, glu::TYPE_UINT_VEC4 },
6781 { 3, glu::TYPE_BOOL_VEC2 },
6782 { 2, glu::TYPE_BOOL_VEC3 },
6783 { 3, glu::TYPE_BOOL_VEC4 },
6785 { 2, glu::TYPE_FLOAT_MAT2 },
6786 { 3, glu::TYPE_FLOAT_MAT2X3 },
6787 { 3, glu::TYPE_FLOAT_MAT2X4 },
6788 { 2, glu::TYPE_FLOAT_MAT3X2 },
6789 { 2, glu::TYPE_FLOAT_MAT3 },
6790 { 3, glu::TYPE_FLOAT_MAT3X4 },
6791 { 2, glu::TYPE_FLOAT_MAT4X2 },
6792 { 3, glu::TYPE_FLOAT_MAT4X3 },
6793 { 2, glu::TYPE_FLOAT_MAT4 },
6796 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6798 if (variableTypes[ndx].level <= expandLevel)
6800 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
6801 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_TYPE)));
6806 static void generateBufferVariableTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int depth = 3)
6811 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic type");
6812 targetGroup->addChild(blockGroup);
6813 generateBufferVariableTypeBasicTypeCases(context, parentStructure, blockGroup, depth);
6817 // flatten bottom-level
6818 generateBufferVariableTypeBasicTypeCases(context, parentStructure, targetGroup, depth);
6824 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
6825 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Arrays");
6827 targetGroup->addChild(blockGroup);
6828 generateBufferVariableTypeCases(context, arrayElement, blockGroup, depth-1);
6834 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
6835 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Structs");
6837 targetGroup->addChild(blockGroup);
6838 generateBufferVariableTypeCases(context, structMember, blockGroup, depth-1);
6842 static void generateBufferVariableTypeBlock (Context& context, tcu::TestCaseGroup* targetGroup)
6844 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6845 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
6846 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6847 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6848 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(buffer, true));
6850 generateBufferVariableTypeCases(context, block, targetGroup);
6853 static void generateBufferVariableRandomCase (Context& context, tcu::TestCaseGroup* const targetGroup, int index, bool onlyExtensionStages)
6855 de::Random rnd (index * 0x12345);
6856 const ResourceDefinition::Node::SharedPtr shader = generateRandomShaderSet(rnd, onlyExtensionStages);
6857 const glu::DataType type = generateRandomDataType(rnd, true);
6858 const glu::Layout layout = generateRandomVariableLayout(rnd, type, true);
6859 const bool namedBlock = rnd.getBool();
6860 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6861 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6862 ResourceDefinition::Node::SharedPtr currentStructure (new ResourceDefinition::LayoutQualifier(buffer, generateRandomBufferBlockLayout(rnd)));
6864 if (namedBlock && rnd.getBool())
6865 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
6866 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(currentStructure, namedBlock));
6868 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, layout));
6869 currentStructure = generateRandomVariableDefinition(rnd, currentStructure, type, layout, true);
6871 targetGroup->addChild(new ResourceTestCase(context, currentStructure, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BUFFER_VARIABLE_MASK), de::toString(index).c_str()));
6874 static void generateBufferVariableRandomCases (Context& context, tcu::TestCaseGroup* const targetGroup)
6876 const int numBasicCases = 40;
6877 const int numTessGeoCases = 40;
6879 for (int ndx = 0; ndx < numBasicCases; ++ndx)
6880 generateBufferVariableRandomCase(context, targetGroup, ndx, false);
6881 for (int ndx = 0; ndx < numTessGeoCases; ++ndx)
6882 generateBufferVariableRandomCase(context, targetGroup, numBasicCases + ndx, true);
6885 class BufferVariableTestGroup : public TestCaseGroup
6888 BufferVariableTestGroup (Context& context);
6892 BufferVariableTestGroup::BufferVariableTestGroup (Context& context)
6893 : TestCaseGroup(context, "buffer_variable", "Buffer variable")
6897 void BufferVariableTestGroup::init (void)
6901 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "resource_list", "Resource list");
6902 addChild(blockGroup);
6903 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableResourceListBlockContentsProxy);
6908 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_size", "Array size");
6909 addChild(blockGroup);
6910 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableArrayCases<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6915 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_stride", "Array stride");
6916 addChild(blockGroup);
6917 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableArrayCases<PROGRAMRESOURCEPROP_ARRAY_STRIDE>);
6922 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "block_index", "Block index");
6923 addChild(blockGroup);
6924 generateBufferVariableBlockIndexCases(m_context, blockGroup);
6929 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "is_row_major", "Is row major");
6930 addChild(blockGroup);
6931 generateBufferVariableMatrixCaseBlocks(m_context, blockGroup, generateBufferVariableMatrixCases<PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR>);
6936 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "matrix_stride", "Matrix stride");
6937 addChild(blockGroup);
6938 generateBufferVariableMatrixCaseBlocks(m_context, blockGroup, generateBufferVariableMatrixCases<PROGRAMRESOURCEPROP_MATRIX_STRIDE>);
6943 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "name_length", "Name length");
6944 addChild(blockGroup);
6945 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableNameLengthCases);
6950 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "offset", "Offset");
6951 addChild(blockGroup);
6952 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableOffsetCases);
6957 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "referenced_by", "Referenced by");
6958 addChild(blockGroup);
6959 generateReferencedByShaderCaseBlocks(m_context, blockGroup, generateBufferVariableReferencedByBlockContents);
6962 // .top_level_array_size
6964 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "top_level_array_size", "Top-level array size");
6965 addChild(blockGroup);
6966 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableTopLevelCases<PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_SIZE>);
6969 // .top_level_array_stride
6971 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "top_level_array_stride", "Top-level array stride");
6972 addChild(blockGroup);
6973 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableTopLevelCases<PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_STRIDE>);
6978 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "type", "Type");
6979 addChild(blockGroup);
6980 generateBufferVariableTypeBlock(m_context, blockGroup);
6985 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "random", "Random");
6986 addChild(blockGroup);
6987 generateBufferVariableRandomCases(m_context, blockGroup);
6993 ProgramInterfaceQueryTests::ProgramInterfaceQueryTests (Context& context)
6994 : TestCaseGroup(context, "program_interface_query", "Program interface query tests")
6998 ProgramInterfaceQueryTests::~ProgramInterfaceQueryTests (void)
7002 void ProgramInterfaceQueryTests::init (void)
7006 // .buffer_limited_query
7008 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "buffer_limited_query", "Queries limited by the buffer size");
7012 group->addChild(new ResourceNameBufferLimitCase(m_context, "resource_name_query", "Test GetProgramResourceName with too small a buffer"));
7013 group->addChild(new ResourceQueryBufferLimitCase(m_context, "resource_query", "Test GetProgramResourceiv with too small a buffer"));
7019 addChild(new UniformInterfaceTestGroup(m_context));
7022 addChild(new BufferBackedBlockInterfaceTestGroup(m_context, glu::STORAGE_UNIFORM));
7024 // .atomic_counter_buffer
7025 addChild(new AtomicCounterTestGroup(m_context));
7028 addChild(new ProgramInputTestGroup(m_context));
7031 addChild(new ProgramOutputTestGroup(m_context));
7033 // .transform_feedback_varying
7034 addChild(new TransformFeedbackVaryingTestGroup(m_context));
7037 addChild(new BufferVariableTestGroup(m_context));
7039 // .shader_storage_block
7040 addChild(new BufferBackedBlockInterfaceTestGroup(m_context, glu::STORAGE_BUFFER));