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 "tcuStringTemplate.hpp"
30 #include "gluShaderProgram.hpp"
31 #include "gluVarTypeUtil.hpp"
32 #include "gluStrUtil.hpp"
33 #include "gluContextInfo.hpp"
34 #include "glwFunctions.hpp"
35 #include "glwEnums.hpp"
36 #include "deRandom.hpp"
38 #include "deStringUtil.hpp"
39 #include "deSharedPtr.hpp"
40 #include "deUniquePtr.hpp"
41 #include "deSTLUtil.hpp"
42 #include "deArrayUtil.hpp"
56 static int getTypeSize (glu::DataType type)
58 if (type == glu::TYPE_FLOAT)
60 else if (type == glu::TYPE_INT || type == glu::TYPE_UINT)
62 else if (type == glu::TYPE_BOOL)
69 static int getVarTypeSize (const glu::VarType& type)
71 if (type.isBasicType())
72 return glu::getDataTypeScalarSize(type.getBasicType()) * getTypeSize(glu::getDataTypeScalarType(type.getBasicType()));
73 else if (type.isStructType())
76 for (int ndx = 0; ndx < type.getStructPtr()->getNumMembers(); ++ndx)
77 size += getVarTypeSize(type.getStructPtr()->getMember(ndx).getType());
80 else if (type.isArrayType())
82 if (type.getArraySize() == glu::VarType::UNSIZED_ARRAY)
83 return getVarTypeSize(type.getElementType());
85 return type.getArraySize() * getVarTypeSize(type.getElementType());
94 static std::string convertGLTypeNameToTestName (const char* glName)
96 // vectors and matrices are fine as is
98 if (deStringBeginsWith(glName, "vec") == DE_TRUE ||
99 deStringBeginsWith(glName, "ivec") == DE_TRUE ||
100 deStringBeginsWith(glName, "uvec") == DE_TRUE ||
101 deStringBeginsWith(glName, "bvec") == DE_TRUE ||
102 deStringBeginsWith(glName, "mat") == DE_TRUE)
103 return std::string(glName);
106 // convert camel case to use underscore
108 std::ostringstream buf;
109 std::istringstream name (glName);
110 bool mergeNextToken = false;
111 bool previousTokenWasDigit = false;
115 std::ostringstream token;
117 while (name.peek() != EOF)
119 if ((de::isDigit((char)name.peek()) || de::isUpper((char)name.peek())) && token.tellp())
122 token << de::toLower((char)name.get());
125 if (buf.str().empty() || mergeNextToken)
128 buf << '_' << token.str();
130 // 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
131 mergeNextToken = false;
132 if (token.tellp() == (std::streamoff)1)
134 if (!previousTokenWasDigit || token.str()[0] != 'd')
135 mergeNextToken = true;
137 previousTokenWasDigit = de::isDigit(token.str()[0]);
140 previousTokenWasDigit = false;
147 static glw::GLenum getProgramInterfaceGLEnum (ProgramInterface interface)
149 static const glw::GLenum s_enums[] =
151 GL_UNIFORM, // PROGRAMINTERFACE_UNIFORM
152 GL_UNIFORM_BLOCK, // PROGRAMINTERFACE_UNIFORM_BLOCK
153 GL_ATOMIC_COUNTER_BUFFER, // PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER
154 GL_PROGRAM_INPUT, // PROGRAMINTERFACE_PROGRAM_INPUT
155 GL_PROGRAM_OUTPUT, // PROGRAMINTERFACE_PROGRAM_OUTPUT
156 GL_TRANSFORM_FEEDBACK_VARYING, // PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING
157 GL_BUFFER_VARIABLE, // PROGRAMINTERFACE_BUFFER_VARIABLE
158 GL_SHADER_STORAGE_BLOCK, // PROGRAMINTERFACE_SHADER_STORAGE_BLOCK
161 return de::getSizedArrayElement<PROGRAMINTERFACE_LAST>(s_enums, interface);
164 static glu::ShaderType getShaderMaskFirstStage (deUint32 mask)
166 if (mask & (1u << glu::SHADERTYPE_COMPUTE))
167 return glu::SHADERTYPE_COMPUTE;
169 if (mask & (1u << glu::SHADERTYPE_VERTEX))
170 return glu::SHADERTYPE_VERTEX;
172 if (mask & (1u << glu::SHADERTYPE_TESSELLATION_CONTROL))
173 return glu::SHADERTYPE_TESSELLATION_CONTROL;
175 if (mask & (1u << glu::SHADERTYPE_TESSELLATION_EVALUATION))
176 return glu::SHADERTYPE_TESSELLATION_EVALUATION;
178 if (mask & (1u << glu::SHADERTYPE_GEOMETRY))
179 return glu::SHADERTYPE_GEOMETRY;
181 if (mask & (1u << glu::SHADERTYPE_FRAGMENT))
182 return glu::SHADERTYPE_FRAGMENT;
185 return glu::SHADERTYPE_LAST;
188 static glu::ShaderType getShaderMaskLastStage (deUint32 mask)
190 if (mask & (1u << glu::SHADERTYPE_FRAGMENT))
191 return glu::SHADERTYPE_FRAGMENT;
193 if (mask & (1u << glu::SHADERTYPE_GEOMETRY))
194 return glu::SHADERTYPE_GEOMETRY;
196 if (mask & (1u << glu::SHADERTYPE_TESSELLATION_EVALUATION))
197 return glu::SHADERTYPE_TESSELLATION_EVALUATION;
199 if (mask & (1u << glu::SHADERTYPE_TESSELLATION_CONTROL))
200 return glu::SHADERTYPE_TESSELLATION_CONTROL;
202 if (mask & (1u << glu::SHADERTYPE_VERTEX))
203 return glu::SHADERTYPE_VERTEX;
205 if (mask & (1u << glu::SHADERTYPE_COMPUTE))
206 return glu::SHADERTYPE_COMPUTE;
209 return glu::SHADERTYPE_LAST;
212 static std::string specializeShader(Context& context, const char* code)
214 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(context.getRenderContext().getType());
215 std::map<std::string, std::string> specializationMap;
217 specializationMap["GLSL_VERSION_DECL"] = glu::getGLSLVersionDeclaration(glslVersion);
219 return tcu::StringTemplate(code).specialize(specializationMap);
222 namespace ResourceDefinition
234 TYPE_INTERFACE_BLOCK,
237 TYPE_STORAGE_QUALIFIER,
238 TYPE_LAYOUT_QUALIFIER,
240 TYPE_INTERPOLATION_QUALIFIER,
241 TYPE_TRANSFORM_FEEDBACK_TARGET,
246 typedef de::SharedPtr<const Node> SharedPtr;
248 Node (NodeType type, const SharedPtr& enclosingNode) : m_type(type), m_enclosingNode(enclosingNode) { DE_ASSERT(type < TYPE_LAST); }
249 virtual ~Node (void) { }
251 inline const Node* getEnclosingNode (void) const { return m_enclosingNode.get(); }
252 inline NodeType getType (void) const { return m_type; }
255 const NodeType m_type;
256 const SharedPtr m_enclosingNode;
259 class Program : public Node
262 Program (bool separable = false)
263 : Node (TYPE_PROGRAM, SharedPtr())
264 , m_separable (separable)
268 const bool m_separable;
271 class Shader : public Node
274 Shader (const SharedPtr& enclosingNode, glu::ShaderType type, glu::GLSLVersion version)
275 : Node (TYPE_SHADER, enclosingNode)
277 , m_version (version)
279 DE_ASSERT(enclosingNode->getType() == TYPE_PROGRAM);
280 DE_ASSERT(type < glu::SHADERTYPE_LAST);
283 const glu::ShaderType m_type;
284 const glu::GLSLVersion m_version;
287 class DefaultBlock : public Node
290 DefaultBlock (const SharedPtr& enclosing)
291 : Node(TYPE_DEFAULT_BLOCK, enclosing)
293 // enclosed by the shader
294 DE_ASSERT(enclosing->getType() == TYPE_SHADER ||
295 enclosing->getType() == TYPE_SHADER_SET);
299 class StorageQualifier : public Node
302 StorageQualifier (const SharedPtr& enclosing, glu::Storage storage)
303 : Node (TYPE_STORAGE_QUALIFIER, enclosing)
304 , m_storage (storage)
306 // not a part of any block
307 DE_ASSERT(enclosing->getType() == TYPE_DEFAULT_BLOCK);
310 const glu::Storage m_storage;
313 class Variable : public Node
316 Variable (const SharedPtr& enclosing, glu::DataType dataType)
317 : Node (TYPE_VARIABLE, enclosing)
318 , m_dataType (dataType)
320 DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER ||
321 enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
322 enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER ||
323 enclosing->getType() == TYPE_INTERFACE_BLOCK ||
324 enclosing->getType() == TYPE_ARRAY_ELEMENT ||
325 enclosing->getType() == TYPE_STRUCT_MEMBER ||
326 enclosing->getType() == TYPE_TRANSFORM_FEEDBACK_TARGET);
329 const glu::DataType m_dataType;
332 class InterfaceBlock : public Node
335 InterfaceBlock (const SharedPtr& enclosing, bool named)
336 : Node (TYPE_INTERFACE_BLOCK, enclosing)
339 // Must be storage qualified
340 const Node* storageNode = enclosing.get();
341 while (storageNode->getType() == TYPE_ARRAY_ELEMENT ||
342 storageNode->getType() == TYPE_LAYOUT_QUALIFIER)
344 storageNode = storageNode->getEnclosingNode();
347 DE_ASSERT(storageNode->getType() == TYPE_STORAGE_QUALIFIER);
348 DE_UNREF(storageNode);
354 class ArrayElement : public Node
357 ArrayElement (const SharedPtr& enclosing, int arraySize = DEFAULT_SIZE)
358 : Node (TYPE_ARRAY_ELEMENT, enclosing)
359 , m_arraySize (arraySize)
361 DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER ||
362 enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
363 enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER ||
364 enclosing->getType() == TYPE_INTERFACE_BLOCK ||
365 enclosing->getType() == TYPE_ARRAY_ELEMENT ||
366 enclosing->getType() == TYPE_STRUCT_MEMBER ||
367 enclosing->getType() == TYPE_TRANSFORM_FEEDBACK_TARGET);
370 const int m_arraySize;
379 class StructMember : public Node
382 StructMember (const SharedPtr& enclosing)
383 : Node(TYPE_STRUCT_MEMBER, enclosing)
385 DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER ||
386 enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
387 enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER ||
388 enclosing->getType() == TYPE_INTERFACE_BLOCK ||
389 enclosing->getType() == TYPE_ARRAY_ELEMENT ||
390 enclosing->getType() == TYPE_STRUCT_MEMBER ||
391 enclosing->getType() == TYPE_TRANSFORM_FEEDBACK_TARGET);
395 class LayoutQualifier : public Node
398 LayoutQualifier (const SharedPtr& enclosing, const glu::Layout& layout)
399 : Node (TYPE_LAYOUT_QUALIFIER, enclosing)
402 DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER ||
403 enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
404 enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER ||
405 enclosing->getType() == TYPE_DEFAULT_BLOCK ||
406 enclosing->getType() == TYPE_INTERFACE_BLOCK);
409 const glu::Layout m_layout;
412 class InterpolationQualifier : public Node
415 InterpolationQualifier (const SharedPtr& enclosing, const glu::Interpolation& interpolation)
416 : Node (TYPE_INTERPOLATION_QUALIFIER, enclosing)
417 , m_interpolation (interpolation)
419 DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER ||
420 enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
421 enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER ||
422 enclosing->getType() == TYPE_DEFAULT_BLOCK ||
423 enclosing->getType() == TYPE_INTERFACE_BLOCK);
426 const glu::Interpolation m_interpolation;
429 class ShaderSet : public Node
432 ShaderSet (const SharedPtr& enclosing, glu::GLSLVersion version);
433 ShaderSet (const SharedPtr& enclosing, glu::GLSLVersion version, deUint32 stagesPresentBits, deUint32 stagesReferencingBits);
435 void setStage (glu::ShaderType type, bool referencing);
436 bool isStagePresent (glu::ShaderType stage) const;
437 bool isStageReferencing (glu::ShaderType stage) const;
439 deUint32 getReferencingMask (void) const;
441 const glu::GLSLVersion m_version;
443 bool m_stagePresent[glu::SHADERTYPE_LAST];
444 bool m_stageReferencing[glu::SHADERTYPE_LAST];
447 ShaderSet::ShaderSet (const SharedPtr& enclosing, glu::GLSLVersion version)
448 : Node (TYPE_SHADER_SET, enclosing)
449 , m_version (version)
451 DE_ASSERT(enclosing->getType() == TYPE_PROGRAM);
453 deMemset(m_stagePresent, 0, sizeof(m_stagePresent));
454 deMemset(m_stageReferencing, 0, sizeof(m_stageReferencing));
457 ShaderSet::ShaderSet (const SharedPtr& enclosing,
458 glu::GLSLVersion version,
459 deUint32 stagesPresentBits,
460 deUint32 stagesReferencingBits)
461 : Node (TYPE_SHADER_SET, enclosing)
462 , m_version (version)
464 for (deUint32 stageNdx = 0; stageNdx < glu::SHADERTYPE_LAST; ++stageNdx)
466 const deUint32 stageMask = (1u << stageNdx);
467 const bool stagePresent = (stagesPresentBits & stageMask) != 0;
468 const bool stageReferencing = (stagesReferencingBits & stageMask) != 0;
470 DE_ASSERT(stagePresent || !stageReferencing);
472 m_stagePresent[stageNdx] = stagePresent;
473 m_stageReferencing[stageNdx] = stageReferencing;
477 void ShaderSet::setStage (glu::ShaderType type, bool referencing)
479 DE_ASSERT(type < glu::SHADERTYPE_LAST);
480 m_stagePresent[type] = true;
481 m_stageReferencing[type] = referencing;
484 bool ShaderSet::isStagePresent (glu::ShaderType stage) const
486 DE_ASSERT(stage < glu::SHADERTYPE_LAST);
487 return m_stagePresent[stage];
490 bool ShaderSet::isStageReferencing (glu::ShaderType stage) const
492 DE_ASSERT(stage < glu::SHADERTYPE_LAST);
493 return m_stageReferencing[stage];
496 deUint32 ShaderSet::getReferencingMask (void) const
499 for (deUint32 stage = 0; stage < glu::SHADERTYPE_LAST; ++stage)
501 if (m_stageReferencing[stage])
502 mask |= (1u << stage);
507 class TransformFeedbackTarget : public Node
510 TransformFeedbackTarget (const SharedPtr& enclosing, const char* builtinVarName = DE_NULL)
511 : Node (TYPE_TRANSFORM_FEEDBACK_TARGET, enclosing)
512 , m_builtinVarName (builtinVarName)
516 const char* const m_builtinVarName;
519 } // ResourceDefinition
521 static glu::Precision getDataTypeDefaultPrecision (const glu::DataType& type)
523 if (glu::isDataTypeBoolOrBVec(type))
524 return glu::PRECISION_LAST;
525 else if (glu::isDataTypeScalarOrVector(type) || glu::isDataTypeMatrix(type))
526 return glu::PRECISION_HIGHP;
527 else if (glu::isDataTypeSampler(type))
528 return glu::PRECISION_HIGHP;
529 else if (glu::isDataTypeImage(type))
530 return glu::PRECISION_HIGHP;
531 else if (type == glu::TYPE_UINT_ATOMIC_COUNTER)
532 return glu::PRECISION_HIGHP;
535 return glu::PRECISION_LAST;
538 static de::MovePtr<ProgramInterfaceDefinition::Program> generateProgramDefinitionFromResource (const ResourceDefinition::Node* resource)
540 de::MovePtr<ProgramInterfaceDefinition::Program> program (new ProgramInterfaceDefinition::Program());
541 const ResourceDefinition::Node* head = resource;
543 if (head->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
545 DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));
550 BINDING_INTERFACE_BLOCK,
551 BINDING_DEFAULT_BLOCK
555 int autoAssignArraySize = 0;
556 const glu::DataType basicType = static_cast<const ResourceDefinition::Variable*>(resource)->m_dataType;
557 BindingType boundObject = BINDING_VARIABLE;
558 glu::VariableDeclaration variable (glu::VarType(basicType, getDataTypeDefaultPrecision(basicType)), "target");
559 glu::InterfaceBlock interfaceBlock;
560 ProgramInterfaceDefinition::DefaultBlock defaultBlock;
561 std::vector<std::string> feedbackTargetVaryingPath;
562 bool feedbackTargetSet = false;
565 if (glu::isDataTypeImage(basicType))
567 variable.memoryAccessQualifierBits |= glu::MEMORYACCESSQUALIFIER_READONLY_BIT;
568 variable.layout.binding = 1;
570 if (basicType >= glu::TYPE_IMAGE_2D && basicType <= glu::TYPE_IMAGE_3D)
571 variable.layout.format = glu::FORMATLAYOUT_RGBA8;
572 else if (basicType >= glu::TYPE_INT_IMAGE_2D && basicType <= glu::TYPE_INT_IMAGE_3D)
573 variable.layout.format = glu::FORMATLAYOUT_RGBA8I;
574 else if (basicType >= glu::TYPE_UINT_IMAGE_2D && basicType <= glu::TYPE_UINT_IMAGE_3D)
575 variable.layout.format = glu::FORMATLAYOUT_RGBA8UI;
580 // atomic counter specific
581 if (basicType == glu::TYPE_UINT_ATOMIC_COUNTER)
582 variable.layout.binding = 1;
584 for (head = head->getEnclosingNode(); head; head = head->getEnclosingNode())
586 if (head->getType() == ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER)
588 const ResourceDefinition::StorageQualifier* qualifier = static_cast<const ResourceDefinition::StorageQualifier*>(head);
590 DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(head));
592 if (boundObject == BINDING_VARIABLE)
594 DE_ASSERT(variable.storage == glu::STORAGE_LAST);
595 variable.storage = qualifier->m_storage;
597 else if (boundObject == BINDING_INTERFACE_BLOCK)
599 DE_ASSERT(interfaceBlock.storage == glu::STORAGE_LAST);
600 interfaceBlock.storage = qualifier->m_storage;
605 else if (head->getType() == ResourceDefinition::Node::TYPE_LAYOUT_QUALIFIER)
607 const ResourceDefinition::LayoutQualifier* qualifier = static_cast<const ResourceDefinition::LayoutQualifier*>(head);
608 glu::Layout* targetLayout = DE_NULL;
610 DE_ASSERT(dynamic_cast<const ResourceDefinition::LayoutQualifier*>(head));
612 if (boundObject == BINDING_VARIABLE)
613 targetLayout = &variable.layout;
614 else if (boundObject == BINDING_INTERFACE_BLOCK)
615 targetLayout = &interfaceBlock.layout;
619 if (qualifier->m_layout.location != -1)
620 targetLayout->location = qualifier->m_layout.location;
622 if (qualifier->m_layout.binding != -1)
623 targetLayout->binding = qualifier->m_layout.binding;
625 if (qualifier->m_layout.offset != -1)
626 targetLayout->offset = qualifier->m_layout.offset;
628 if (qualifier->m_layout.format != glu::FORMATLAYOUT_LAST)
629 targetLayout->format = qualifier->m_layout.format;
631 if (qualifier->m_layout.matrixOrder != glu::MATRIXORDER_LAST)
632 targetLayout->matrixOrder = qualifier->m_layout.matrixOrder;
634 else if (head->getType() == ResourceDefinition::Node::TYPE_INTERPOLATION_QUALIFIER)
636 const ResourceDefinition::InterpolationQualifier* qualifier = static_cast<const ResourceDefinition::InterpolationQualifier*>(head);
638 DE_ASSERT(dynamic_cast<const ResourceDefinition::InterpolationQualifier*>(head));
640 if (boundObject == BINDING_VARIABLE)
641 variable.interpolation = qualifier->m_interpolation;
645 else if (head->getType() == ResourceDefinition::Node::TYPE_ARRAY_ELEMENT)
647 DE_ASSERT(dynamic_cast<const ResourceDefinition::ArrayElement*>(head));
649 const ResourceDefinition::ArrayElement* arrayElement = static_cast<const ResourceDefinition::ArrayElement*>(head);
652 // Vary array size per level
653 if (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::DEFAULT_SIZE)
655 if (--autoAssignArraySize <= 1)
656 autoAssignArraySize = 3;
658 arraySize = autoAssignArraySize;
660 else if (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::UNSIZED_ARRAY)
661 arraySize = glu::VarType::UNSIZED_ARRAY;
663 arraySize = arrayElement->m_arraySize;
665 if (boundObject == BINDING_VARIABLE)
666 variable.varType = glu::VarType(variable.varType, arraySize);
667 else if (boundObject == BINDING_INTERFACE_BLOCK)
668 interfaceBlock.dimensions.push_back(arraySize);
672 if (feedbackTargetSet)
673 feedbackTargetVaryingPath.back().append("[0]");
675 else if (head->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER)
677 DE_ASSERT(dynamic_cast<const ResourceDefinition::StructMember*>(head));
678 DE_ASSERT(boundObject == BINDING_VARIABLE);
680 // Struct members cannot contain any qualifiers except precision
681 DE_ASSERT(variable.interpolation == glu::INTERPOLATION_LAST);
682 DE_ASSERT(variable.layout == glu::Layout());
683 DE_ASSERT(variable.memoryAccessQualifierBits == 0);
684 DE_ASSERT(variable.storage == glu::STORAGE_LAST);
687 glu::StructType* structPtr = new glu::StructType(("StructType" + de::toString(structNdx++)).c_str());
688 structPtr->addMember(variable.name.c_str(), variable.varType);
690 variable = glu::VariableDeclaration(glu::VarType(structPtr), "target");
693 if (feedbackTargetSet)
694 feedbackTargetVaryingPath.push_back("target");
696 else if (head->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
698 DE_ASSERT(dynamic_cast<const ResourceDefinition::InterfaceBlock*>(head));
699 DE_ASSERT(boundObject == BINDING_VARIABLE);
701 const bool named = static_cast<const ResourceDefinition::InterfaceBlock*>(head)->m_named;
703 boundObject = BINDING_INTERFACE_BLOCK;
705 interfaceBlock.interfaceName = "TargetInterface";
706 interfaceBlock.instanceName = (named) ? ("targetInstance") : ("");
707 interfaceBlock.variables.push_back(variable);
709 if (feedbackTargetSet && !interfaceBlock.instanceName.empty())
710 feedbackTargetVaryingPath.push_back(interfaceBlock.interfaceName);
712 else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
714 DE_ASSERT(dynamic_cast<const ResourceDefinition::DefaultBlock*>(head));
715 DE_ASSERT(boundObject == BINDING_VARIABLE || boundObject == BINDING_INTERFACE_BLOCK);
717 if (boundObject == BINDING_VARIABLE)
718 defaultBlock.variables.push_back(variable);
719 else if (boundObject == BINDING_INTERFACE_BLOCK)
720 defaultBlock.interfaceBlocks.push_back(interfaceBlock);
724 boundObject = BINDING_DEFAULT_BLOCK;
726 else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER)
728 DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(head));
730 const ResourceDefinition::Shader* shaderDef = static_cast<const ResourceDefinition::Shader*>(head);
731 ProgramInterfaceDefinition::Shader* shader = program->addShader(shaderDef->m_type, shaderDef->m_version);
733 shader->getDefaultBlock() = defaultBlock;
735 else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER_SET)
737 DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(head));
739 const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(head);
741 for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
743 if (shaderDef->isStagePresent((glu::ShaderType)shaderType))
745 ProgramInterfaceDefinition::Shader* shader = program->addShader((glu::ShaderType)shaderType, shaderDef->m_version);
747 if (shaderDef->isStageReferencing((glu::ShaderType)shaderType))
748 shader->getDefaultBlock() = defaultBlock;
752 else if (head->getType() == ResourceDefinition::Node::TYPE_PROGRAM)
754 DE_ASSERT(dynamic_cast<const ResourceDefinition::Program*>(head));
756 const ResourceDefinition::Program* programDef = static_cast<const ResourceDefinition::Program*>(head);
758 program->setSeparable(programDef->m_separable);
760 DE_ASSERT(feedbackTargetSet == !feedbackTargetVaryingPath.empty());
761 if (!feedbackTargetVaryingPath.empty())
763 std::ostringstream buf;
765 for (std::vector<std::string>::reverse_iterator it = feedbackTargetVaryingPath.rbegin(); it != feedbackTargetVaryingPath.rend(); ++it)
767 if (it != feedbackTargetVaryingPath.rbegin())
772 program->addTransformFeedbackVarying(buf.str());
773 program->setTransformFeedbackMode(GL_INTERLEAVED_ATTRIBS);
777 else if (head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
779 DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(head));
781 const ResourceDefinition::TransformFeedbackTarget* feedbackTarget = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(head);
783 DE_ASSERT(feedbackTarget->m_builtinVarName == DE_NULL);
784 DE_UNREF(feedbackTarget);
786 feedbackTargetSet = true;
787 feedbackTargetVaryingPath.push_back(variable.name);
796 else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK ||
797 head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
799 const char* feedbackTargetVaryingName = DE_NULL;
801 // empty default block
803 for (; head; head = head->getEnclosingNode())
805 if (head->getType() == ResourceDefinition::Node::TYPE_SHADER)
807 DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(head));
809 const ResourceDefinition::Shader* shaderDef = static_cast<const ResourceDefinition::Shader*>(head);
811 program->addShader(shaderDef->m_type, shaderDef->m_version);
813 else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER_SET)
815 DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(head));
817 const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(head);
819 for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
820 if (shaderDef->isStagePresent((glu::ShaderType)shaderType))
821 program->addShader((glu::ShaderType)shaderType, shaderDef->m_version);
823 else if (head->getType() == ResourceDefinition::Node::TYPE_PROGRAM)
825 DE_ASSERT(dynamic_cast<const ResourceDefinition::Program*>(head));
827 const ResourceDefinition::Program* programDef = static_cast<const ResourceDefinition::Program*>(head);
829 program->setSeparable(programDef->m_separable);
830 if (feedbackTargetVaryingName)
832 program->addTransformFeedbackVarying(std::string(feedbackTargetVaryingName));
833 program->setTransformFeedbackMode(GL_INTERLEAVED_ATTRIBS);
837 else if (head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
839 DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(head));
841 const ResourceDefinition::TransformFeedbackTarget* feedbackTarget = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(head);
843 DE_ASSERT(feedbackTarget->m_builtinVarName != DE_NULL);
845 feedbackTargetVaryingName = feedbackTarget->m_builtinVarName;
847 else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
858 if (program->hasStage(glu::SHADERTYPE_GEOMETRY))
859 program->setGeometryNumOutputVertices(1);
860 if (program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
861 program->setTessellationNumOutputPatchVertices(1);
866 static void checkAndLogProgram (const glu::ShaderProgram& program, const ProgramInterfaceDefinition::Program* programDefinition, const glw::Functions& gl, tcu::TestLog& log)
868 const tcu::ScopedLogSection section(log, "Program", "Program");
873 log << tcu::TestLog::Message << "Program build failed, checking if program exceeded implementation limits" << tcu::TestLog::EndMessage;
874 checkProgramResourceUsage(programDefinition, gl, log);
877 throw tcu::TestError("could not build program");
881 // Resource list query case
883 class ResourceListTestCase : public TestCase
886 ResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, ProgramInterface interface, const char* name = DE_NULL);
887 ~ResourceListTestCase (void);
892 IterateResult iterate (void);
894 void queryResourceList (std::vector<std::string>& dst, glw::GLuint program);
895 bool verifyResourceList (const std::vector<std::string>& resourceList, const std::vector<std::string>& expectedResources);
896 bool verifyResourceIndexQuery (const std::vector<std::string>& resourceList, const std::vector<std::string>& referenceResources, glw::GLuint program);
897 bool verifyMaxNameLength (const std::vector<std::string>& referenceResourceList, glw::GLuint program);
899 static std::string genTestCaseName (ProgramInterface interface, const ResourceDefinition::Node*);
900 static bool isArrayedInterface (ProgramInterface interface, deUint32 stageBits);
902 const ProgramInterface m_programInterface;
903 ResourceDefinition::Node::SharedPtr m_targetResource;
904 ProgramInterfaceDefinition::Program* m_programDefinition;
907 ResourceListTestCase::ResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, ProgramInterface interface, const char* name)
908 : TestCase (context, (name == DE_NULL) ? (genTestCaseName(interface, targetResource.get()).c_str()) : (name), "")
909 , m_programInterface (interface)
910 , m_targetResource (targetResource)
911 , m_programDefinition (DE_NULL)
913 // GL_ATOMIC_COUNTER_BUFFER: no resource names
914 DE_ASSERT(m_programInterface != PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER);
917 ResourceListTestCase::~ResourceListTestCase (void)
922 void ResourceListTestCase::init (void)
924 m_programDefinition = generateProgramDefinitionFromResource(m_targetResource.get()).release();
925 const bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
927 if ((m_programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION)) &&
928 !supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
930 throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
932 if (m_programDefinition->hasStage(glu::SHADERTYPE_GEOMETRY) &&
933 !supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
935 throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
937 if (programContainsIOBlocks(m_programDefinition) &&
938 !supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_shader_io_blocks"))
940 throw tcu::NotSupportedError("Test requires GL_EXT_shader_io_blocks extension");
944 void ResourceListTestCase::deinit (void)
946 m_targetResource.clear();
948 delete m_programDefinition;
949 m_programDefinition = DE_NULL;
952 ResourceListTestCase::IterateResult ResourceListTestCase::iterate (void)
954 const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_programDefinition));
956 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
957 checkAndLogProgram(program, m_programDefinition, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
959 // Check resource list
961 const tcu::ScopedLogSection section (m_testCtx.getLog(), "ResourceList", "Resource list");
962 std::vector<std::string> resourceList;
963 std::vector<std::string> expectedResources;
965 queryResourceList(resourceList, program.getProgram());
966 expectedResources = getProgramInterfaceResourceList(m_programDefinition, m_programInterface);
968 // verify the list and the expected list match
970 if (!verifyResourceList(resourceList, expectedResources))
971 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid resource list");
973 // verify GetProgramResourceIndex() matches the indices of the list
975 if (!verifyResourceIndexQuery(resourceList, expectedResources, program.getProgram()))
976 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GetProgramResourceIndex returned unexpected values");
978 // Verify MAX_NAME_LENGTH
979 if (!verifyMaxNameLength(resourceList, program.getProgram()))
980 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "MAX_NAME_LENGTH invalid");
986 void ResourceListTestCase::queryResourceList (std::vector<std::string>& dst, glw::GLuint program)
988 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
989 const glw::GLenum programInterface = getProgramInterfaceGLEnum(m_programInterface);
990 glw::GLint numActiveResources = 0;
991 glw::GLint maxNameLength = 0;
992 std::vector<char> buffer;
994 m_testCtx.getLog() << tcu::TestLog::Message << "Querying " << glu::getProgramInterfaceName(programInterface) << " interface:" << tcu::TestLog::EndMessage;
996 gl.getProgramInterfaceiv(program, programInterface, GL_ACTIVE_RESOURCES, &numActiveResources);
997 gl.getProgramInterfaceiv(program, programInterface, GL_MAX_NAME_LENGTH, &maxNameLength);
998 GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
1000 m_testCtx.getLog() << tcu::TestLog::Message
1001 << "\tGL_ACTIVE_RESOURCES = " << numActiveResources << "\n"
1002 << "\tGL_MAX_NAME_LENGTH = " << maxNameLength
1003 << tcu::TestLog::EndMessage;
1005 m_testCtx.getLog() << tcu::TestLog::Message << "Querying all active resources" << tcu::TestLog::EndMessage;
1007 buffer.resize(maxNameLength+1, '\0');
1009 for (int resourceNdx = 0; resourceNdx < numActiveResources; ++resourceNdx)
1011 glw::GLint written = 0;
1013 gl.getProgramResourceName(program, programInterface, resourceNdx, maxNameLength, &written, &buffer[0]);
1014 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource name");
1016 dst.push_back(std::string(&buffer[0], written));
1020 bool ResourceListTestCase::verifyResourceList (const std::vector<std::string>& resourceList, const std::vector<std::string>& expectedResources)
1024 // Log and compare resource lists
1026 m_testCtx.getLog() << tcu::TestLog::Message << "GL returned resources:" << tcu::TestLog::EndMessage;
1028 for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1030 // dummyZero is a uniform that may be added by
1031 // generateProgramInterfaceProgramSources. Omit it here to avoid
1032 // confusion about the output.
1033 if (resourceList[ndx] != getDummyZeroUniformName())
1034 m_testCtx.getLog() << tcu::TestLog::Message << "\t" << ndx << ": " << resourceList[ndx] << tcu::TestLog::EndMessage;
1037 m_testCtx.getLog() << tcu::TestLog::Message << "Expected list of resources:" << tcu::TestLog::EndMessage;
1039 for (int ndx = 0; ndx < (int)expectedResources.size(); ++ndx)
1040 m_testCtx.getLog() << tcu::TestLog::Message << "\t" << ndx << ": " << expectedResources[ndx] << tcu::TestLog::EndMessage;
1042 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying resource list contents." << tcu::TestLog::EndMessage;
1044 for (int ndx = 0; ndx < (int)expectedResources.size(); ++ndx)
1046 if (!de::contains(resourceList.begin(), resourceList.end(), expectedResources[ndx]))
1048 m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource list did not contain active resource " << expectedResources[ndx] << tcu::TestLog::EndMessage;
1053 for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1055 if (!de::contains(expectedResources.begin(), expectedResources.end(), resourceList[ndx]))
1057 // Ignore all builtin variables or the variable dummyZero,
1058 // mismatch causes errors otherwise. dummyZero is a uniform that
1059 // may be added by generateProgramInterfaceProgramSources.
1060 if (deStringBeginsWith(resourceList[ndx].c_str(), "gl_") == DE_FALSE &&
1061 resourceList[ndx] != getDummyZeroUniformName())
1063 m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource list contains unexpected resource name " << resourceList[ndx] << tcu::TestLog::EndMessage;
1067 m_testCtx.getLog() << tcu::TestLog::Message << "Note, resource list contains unknown built-in " << resourceList[ndx] << ". This variable is ignored." << tcu::TestLog::EndMessage;
1074 bool ResourceListTestCase::verifyResourceIndexQuery (const std::vector<std::string>& resourceList, const std::vector<std::string>& referenceResources, glw::GLuint program)
1076 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1077 const glw::GLenum programInterface = getProgramInterfaceGLEnum(m_programInterface);
1080 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying GetProgramResourceIndex returns correct indices for resource names." << tcu::TestLog::EndMessage;
1082 for (int ndx = 0; ndx < (int)referenceResources.size(); ++ndx)
1084 const glw::GLuint index = gl.getProgramResourceIndex(program, programInterface, referenceResources[ndx].c_str());
1085 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1087 if (index == GL_INVALID_INDEX)
1089 m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx] << "\" got index GL_INVALID_INDEX." << tcu::TestLog::EndMessage;
1092 else if ((int)index >= (int)resourceList.size())
1094 m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx] << "\" got index " << index << " (larger or equal to GL_ACTIVE_RESOURCES)." << tcu::TestLog::EndMessage;
1097 else if (resourceList[index] != referenceResources[ndx])
1099 m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx] << "\" got index (index = " << index << ") of another resource (" << resourceList[index] << ")." << tcu::TestLog::EndMessage;
1104 // Query for "name" should match "name[0]" except for XFB
1106 if (m_programInterface != PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING)
1108 for (int ndx = 0; ndx < (int)referenceResources.size(); ++ndx)
1110 if (de::endsWith(referenceResources[ndx], "[0]"))
1112 const std::string queryString = referenceResources[ndx].substr(0, referenceResources[ndx].length()-3);
1113 const glw::GLuint index = gl.getProgramResourceIndex(program, programInterface, queryString.c_str());
1114 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1116 if (index == GL_INVALID_INDEX)
1118 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" resulted in index GL_INVALID_INDEX." << tcu::TestLog::EndMessage;
1121 else if ((int)index >= (int)resourceList.size())
1123 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" resulted in index " << index << " (larger or equal to GL_ACTIVE_RESOURCES)." << tcu::TestLog::EndMessage;
1126 else if (resourceList[index] != queryString + "[0]")
1128 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" got index (index = " << index << ") of another resource (\"" << resourceList[index] << "\")." << tcu::TestLog::EndMessage;
1138 bool ResourceListTestCase::verifyMaxNameLength (const std::vector<std::string>& resourceList, glw::GLuint program)
1140 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1141 const glw::GLenum programInterface = getProgramInterfaceGLEnum(m_programInterface);
1142 glw::GLint maxNameLength = 0;
1143 glw::GLint expectedMaxNameLength = 0;
1145 gl.getProgramInterfaceiv(program, programInterface, GL_MAX_NAME_LENGTH, &maxNameLength);
1146 GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
1148 for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1149 expectedMaxNameLength = de::max(expectedMaxNameLength, (int)resourceList[ndx].size() + 1);
1151 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying MAX_NAME_LENGTH, expecting " << expectedMaxNameLength << " (i.e. consistent with the queried resource list)" << tcu::TestLog::EndMessage;
1153 if (expectedMaxNameLength != maxNameLength)
1155 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got " << maxNameLength << tcu::TestLog::EndMessage;
1162 std::string ResourceListTestCase::genTestCaseName (ProgramInterface interface, const ResourceDefinition::Node* root)
1164 bool isImplicitlySizedArray = false;
1165 bool hasVariable = false;
1166 bool accumulateName = true;
1167 std::string buf = "var";
1170 for (const ResourceDefinition::Node* node = root; node; node = node->getEnclosingNode())
1172 switch (node->getType())
1174 case ResourceDefinition::Node::TYPE_VARIABLE:
1180 case ResourceDefinition::Node::TYPE_STRUCT_MEMBER:
1187 case ResourceDefinition::Node::TYPE_ARRAY_ELEMENT:
1189 DE_ASSERT(dynamic_cast<const ResourceDefinition::ArrayElement*>(node));
1190 const ResourceDefinition::ArrayElement* arrayElement = static_cast<const ResourceDefinition::ArrayElement*>(node);
1192 isImplicitlySizedArray = (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::UNSIZED_ARRAY);
1199 case ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER:
1201 DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(node));
1202 const ResourceDefinition::StorageQualifier* storageDef = static_cast<const ResourceDefinition::StorageQualifier*>(node);
1204 if (storageDef->m_storage == glu::STORAGE_PATCH_IN ||
1205 storageDef->m_storage == glu::STORAGE_PATCH_OUT)
1213 case ResourceDefinition::Node::TYPE_SHADER:
1214 case ResourceDefinition::Node::TYPE_SHADER_SET:
1216 bool arrayedInterface;
1218 if (node->getType() == ResourceDefinition::Node::TYPE_SHADER)
1220 DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(node));
1221 const ResourceDefinition::Shader* shaderDef = static_cast<const ResourceDefinition::Shader*>(node);
1223 arrayedInterface = isArrayedInterface(interface, (1u << shaderDef->m_type));
1227 DE_ASSERT(node->getType() == ResourceDefinition::Node::TYPE_SHADER_SET);
1228 DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(node));
1229 const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(node);
1231 arrayedInterface = isArrayedInterface(interface, shaderDef->getReferencingMask());
1234 if (arrayedInterface && isImplicitlySizedArray)
1236 // omit implicit arrayness from name, i.e. remove trailing "_array"
1237 DE_ASSERT(de::endsWith(buf, "_array"));
1238 buf = buf.substr(0, buf.length() - 6);
1244 case ResourceDefinition::Node::TYPE_INTERFACE_BLOCK:
1246 accumulateName = false;
1256 return prefix + "empty";
1258 return prefix + buf;
1261 bool ResourceListTestCase::isArrayedInterface (ProgramInterface interface, deUint32 stageBits)
1263 if (interface == PROGRAMINTERFACE_PROGRAM_INPUT)
1265 const glu::ShaderType firstStage = getShaderMaskFirstStage(stageBits);
1266 return firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
1267 firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
1268 firstStage == glu::SHADERTYPE_GEOMETRY;
1270 else if (interface == PROGRAMINTERFACE_PROGRAM_OUTPUT)
1272 const glu::ShaderType lastStage = getShaderMaskLastStage(stageBits);
1273 return lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL;
1278 // Resouce property query case
1280 class ResourceTestCase : public ProgramInterfaceQueryTestCase
1283 ResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, const ProgramResourceQueryTestTarget& queryTarget, const char* name = DE_NULL);
1284 ~ResourceTestCase (void);
1289 const ProgramInterfaceDefinition::Program* getProgramDefinition (void) const;
1290 std::vector<std::string> getQueryTargetResources (void) const;
1292 static std::string genTestCaseName (const ResourceDefinition::Node*);
1293 static std::string genMultilineDescription (const ResourceDefinition::Node*);
1295 ResourceDefinition::Node::SharedPtr m_targetResource;
1296 ProgramInterfaceDefinition::Program* m_program;
1297 std::vector<std::string> m_targetResources;
1300 ResourceTestCase::ResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, const ProgramResourceQueryTestTarget& queryTarget, const char* name)
1301 : ProgramInterfaceQueryTestCase (context, (name == DE_NULL) ? (genTestCaseName(targetResource.get()).c_str()) : (name), "", queryTarget)
1302 , m_targetResource (targetResource)
1303 , m_program (DE_NULL)
1307 ResourceTestCase::~ResourceTestCase (void)
1312 void ResourceTestCase::init (void)
1315 << tcu::TestLog::Message
1316 << genMultilineDescription(m_targetResource.get())
1317 << tcu::TestLog::EndMessage;
1321 // Generate interface with target resource
1322 m_program = generateProgramDefinitionFromResource(m_targetResource.get()).release();
1323 m_targetResources = getProgramInterfaceResourceList(m_program, getTargetInterface());
1327 void ResourceTestCase::deinit (void)
1329 m_targetResource.clear();
1332 m_program = DE_NULL;
1334 m_targetResources = std::vector<std::string>();
1337 const ProgramInterfaceDefinition::Program* ResourceTestCase::getProgramDefinition (void) const
1342 std::vector<std::string> ResourceTestCase::getQueryTargetResources (void) const
1344 return m_targetResources;
1347 std::string ResourceTestCase::genTestCaseName (const ResourceDefinition::Node* resource)
1349 if (resource->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
1351 DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));
1353 const ResourceDefinition::Variable* variable = static_cast<const ResourceDefinition::Variable*>(resource);
1355 return convertGLTypeNameToTestName(glu::getDataTypeName(variable->m_dataType));
1362 std::string ResourceTestCase::genMultilineDescription (const ResourceDefinition::Node* resource)
1364 if (resource->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
1366 DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));
1368 const ResourceDefinition::Variable* varDef = static_cast<const ResourceDefinition::Variable*>(resource);
1369 std::ostringstream buf;
1370 std::ostringstream structureDescriptor;
1371 std::string uniformType;
1373 for (const ResourceDefinition::Node* node = resource; node; node = node->getEnclosingNode())
1375 if (node->getType() == ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER)
1377 DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(node));
1379 const ResourceDefinition::StorageQualifier* storageDef = static_cast<const ResourceDefinition::StorageQualifier*>(node);
1381 uniformType = std::string(" ") + glu::getStorageName(storageDef->m_storage);
1382 structureDescriptor << "\n\tdeclared as \"" << glu::getStorageName(storageDef->m_storage) << "\"";
1385 if (node->getType() == ResourceDefinition::Node::TYPE_ARRAY_ELEMENT)
1386 structureDescriptor << "\n\tarray";
1388 if (node->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER)
1389 structureDescriptor << "\n\tin a struct";
1391 if (node->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
1392 structureDescriptor << "\n\tin the default block";
1394 if (node->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
1395 structureDescriptor << "\n\tin an interface block";
1398 buf << "Querying properties of " << glu::getDataTypeName(varDef->m_dataType) << uniformType << " variable.\n"
1400 << "\t" << glu::getDataTypeName(varDef->m_dataType)
1401 << structureDescriptor.str();
1405 else if (resource->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
1407 DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(resource));
1409 const ResourceDefinition::TransformFeedbackTarget* xfbDef = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(resource);
1411 DE_ASSERT(xfbDef->m_builtinVarName);
1413 return std::string("Querying properties of a builtin variable ") + xfbDef->m_builtinVarName;
1420 class ResourceNameBufferLimitCase : public TestCase
1423 ResourceNameBufferLimitCase (Context& context, const char* name, const char* description);
1424 ~ResourceNameBufferLimitCase (void);
1427 IterateResult iterate (void);
1430 ResourceNameBufferLimitCase::ResourceNameBufferLimitCase (Context& context, const char* name, const char* description)
1431 : TestCase(context, name, description)
1435 ResourceNameBufferLimitCase::~ResourceNameBufferLimitCase (void)
1439 ResourceNameBufferLimitCase::IterateResult ResourceNameBufferLimitCase::iterate (void)
1441 static const char* const computeSource = "${GLSL_VERSION_DECL}\n"
1442 "layout(local_size_x = 1) in;\n"
1443 "uniform highp int u_uniformWithALongName;\n"
1444 "writeonly buffer OutputBufferBlock { highp int b_output_int; };\n"
1447 " b_output_int = u_uniformWithALongName;\n"
1450 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1451 const glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(specializeShader(m_context, computeSource)));
1452 glw::GLuint uniformIndex;
1454 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1458 const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program", "Program");
1460 m_testCtx.getLog() << program;
1461 if (!program.isOk())
1462 throw tcu::TestError("could not build program");
1465 uniformIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_uniformWithALongName");
1466 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1468 if (uniformIndex == GL_INVALID_INDEX)
1469 throw tcu::TestError("Uniform u_uniformWithALongName resource index was GL_INVALID_INDEX");
1471 // Query with different sized buffers, len("u_uniformWithALongName") == 22
1476 const char* description;
1481 { "Query to larger buffer", 24, true },
1482 { "Query to buffer the same size", 23, true },
1483 { "Query to one byte too small buffer", 22, true },
1484 { "Query to one byte buffer", 1, true },
1485 { "Query to zero sized buffer", 0, true },
1486 { "Query to one byte too small buffer, null length argument", 22, false },
1487 { "Query to one byte buffer, null length argument", 1, false },
1488 { "Query to zero sized buffer, null length argument", 0, false },
1491 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(querySizes); ++ndx)
1493 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Query", querySizes[ndx].description);
1494 const int uniformNameLen = 22;
1495 const int expectedWriteLen = (querySizes[ndx].querySize != 0) ? (de::min(uniformNameLen, (querySizes[ndx].querySize - 1))) : (0);
1497 glw::GLsizei written = -1;
1499 // One byte for guard
1500 DE_ASSERT((int)sizeof(buffer) > querySizes[ndx].querySize);
1502 deMemset(buffer, 'x', sizeof(buffer));
1504 if (querySizes[ndx].querySize)
1506 << tcu::TestLog::Message
1507 << "Querying uniform name to a buffer of size " << querySizes[ndx].querySize
1508 << ", expecting query to write " << expectedWriteLen << " bytes followed by a null terminator"
1509 << tcu::TestLog::EndMessage;
1512 << tcu::TestLog::Message
1513 << "Querying uniform name to a buffer of size " << querySizes[ndx].querySize
1514 << ", expecting query to write 0 bytes"
1515 << tcu::TestLog::EndMessage;
1517 gl.getProgramResourceName(program.getProgram(), GL_UNIFORM, uniformIndex, querySizes[ndx].querySize, (querySizes[ndx].returnLength) ? (&written) : (DE_NULL), buffer);
1518 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource name");
1520 if (querySizes[ndx].returnLength && written != expectedWriteLen)
1522 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected write length of " << expectedWriteLen << ", got " << written << tcu::TestLog::EndMessage;
1523 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected write lenght");
1525 else if (querySizes[ndx].querySize != 0 && buffer[expectedWriteLen] != 0)
1527 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected null terminator at " << expectedWriteLen << ", got dec=" << (int)buffer[expectedWriteLen] << tcu::TestLog::EndMessage;
1528 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Missing null terminator");
1530 else if (querySizes[ndx].querySize != 0 && buffer[expectedWriteLen+1] != 'x')
1532 m_testCtx.getLog() << tcu::TestLog::Message << "Error, guard at index " << (expectedWriteLen+1) << " was modified, got dec=" << (int)buffer[expectedWriteLen+1] << tcu::TestLog::EndMessage;
1533 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrote over buffer size");
1535 else if (querySizes[ndx].querySize == 0 && buffer[0] != 'x')
1537 m_testCtx.getLog() << tcu::TestLog::Message << "Error, buffer size was 0 but buffer contents were modified. At index 0 got dec=" << (int)buffer[0] << tcu::TestLog::EndMessage;
1538 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents were modified");
1546 class ResourceQueryBufferLimitCase : public TestCase
1549 ResourceQueryBufferLimitCase (Context& context, const char* name, const char* description);
1550 ~ResourceQueryBufferLimitCase (void);
1553 IterateResult iterate (void);
1556 ResourceQueryBufferLimitCase::ResourceQueryBufferLimitCase (Context& context, const char* name, const char* description)
1557 : TestCase(context, name, description)
1561 ResourceQueryBufferLimitCase::~ResourceQueryBufferLimitCase (void)
1565 ResourceQueryBufferLimitCase::IterateResult ResourceQueryBufferLimitCase::iterate (void)
1567 static const char* const computeSource = "${GLSL_VERSION_DECL}\n"
1568 "layout(local_size_x = 1) in;\n"
1569 "uniform highp int u_uniform;\n"
1570 "writeonly buffer OutputBufferBlock { highp int b_output_int; };\n"
1573 " b_output_int = u_uniform;\n"
1576 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1577 const glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(specializeShader(m_context, computeSource)));
1578 glw::GLuint uniformIndex;
1580 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1584 const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program", "Program");
1586 m_testCtx.getLog() << program;
1587 if (!program.isOk())
1588 throw tcu::TestError("could not build program");
1591 uniformIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_uniform");
1592 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1594 if (uniformIndex == GL_INVALID_INDEX)
1595 throw tcu::TestError("Uniform u_uniform resource index was GL_INVALID_INDEX");
1597 // Query uniform properties
1602 const char* description;
1608 { "Query to a larger buffer", 2, 3, true },
1609 { "Query to too small a buffer", 3, 2, true },
1610 { "Query to zero sized buffer", 3, 0, true },
1611 { "Query to a larger buffer, null length argument", 2, 3, false },
1612 { "Query to too small a buffer, null length argument", 3, 2, false },
1613 { "Query to zero sized buffer, null length argument", 3, 0, false },
1616 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(querySizes); ++ndx)
1618 const tcu::ScopedLogSection section (m_testCtx.getLog(), "QueryToLarger", querySizes[ndx].description);
1619 const glw::GLenum props[] = { GL_LOCATION, GL_LOCATION, GL_LOCATION };
1620 const int expectedWriteLen = de::min(querySizes[ndx].bufferSize, querySizes[ndx].numProps);
1621 int params[] = { 255, 255, 255, 255 };
1622 glw::GLsizei written = -1;
1624 DE_ASSERT(querySizes[ndx].numProps <= DE_LENGTH_OF_ARRAY(props));
1625 DE_ASSERT(querySizes[ndx].bufferSize < DE_LENGTH_OF_ARRAY(params)); // leave at least one element for overflow detection
1628 << tcu::TestLog::Message
1629 << "Querying " << querySizes[ndx].numProps << " uniform prop(s) to a buffer with size " << querySizes[ndx].bufferSize << ". Expecting query to return " << expectedWriteLen << " prop(s)"
1630 << tcu::TestLog::EndMessage;
1632 gl.getProgramResourceiv(program.getProgram(), GL_UNIFORM, uniformIndex, querySizes[ndx].numProps, props, querySizes[ndx].bufferSize, (querySizes[ndx].returnLength) ? (&written) : (DE_NULL), params);
1633 GLU_EXPECT_NO_ERROR(gl.getError(), "query program resources");
1635 if (querySizes[ndx].returnLength && written != expectedWriteLen)
1637 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected write length of " << expectedWriteLen << ", got " << written << tcu::TestLog::EndMessage;
1638 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected write lenght");
1640 else if (params[expectedWriteLen] != 255)
1642 m_testCtx.getLog() << tcu::TestLog::Message << "Error, guard at index " << (expectedWriteLen) << " was modified. Was 255 before call, got dec=" << params[expectedWriteLen] << tcu::TestLog::EndMessage;
1643 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrote over buffer size");
1651 class InterfaceBlockBaseCase : public TestCase
1656 CASE_NAMED_BLOCK = 0,
1663 InterfaceBlockBaseCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
1664 ~InterfaceBlockBaseCase (void);
1671 const glu::Storage m_storage;
1672 const CaseType m_caseType;
1673 ProgramInterfaceDefinition::Program* m_program;
1676 InterfaceBlockBaseCase::InterfaceBlockBaseCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
1677 : TestCase (context, name, description)
1678 , m_storage (storage)
1679 , m_caseType (caseType)
1680 , m_program (DE_NULL)
1682 DE_ASSERT(storage == glu::STORAGE_UNIFORM || storage == glu::STORAGE_BUFFER);
1685 InterfaceBlockBaseCase::~InterfaceBlockBaseCase (void)
1690 void InterfaceBlockBaseCase::init (void)
1692 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
1693 ProgramInterfaceDefinition::Shader* shader;
1695 m_program = new ProgramInterfaceDefinition::Program();
1696 shader = m_program->addShader(glu::SHADERTYPE_COMPUTE, glslVersion);
1698 // PrecedingInterface
1700 glu::InterfaceBlock precedingInterfaceBlock;
1702 precedingInterfaceBlock.interfaceName = "PrecedingInterface";
1703 precedingInterfaceBlock.layout.binding = 0;
1704 precedingInterfaceBlock.storage = m_storage;
1705 precedingInterfaceBlock.instanceName = "precedingInstance";
1707 precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "precedingMember"));
1709 // Unsized array type
1710 if (m_storage == glu::STORAGE_BUFFER)
1711 precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY), "precedingMemberUnsizedArray"));
1713 precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 2), "precedingMemberArray"));
1715 shader->getDefaultBlock().interfaceBlocks.push_back(precedingInterfaceBlock);
1720 glu::InterfaceBlock targetInterfaceBlock;
1722 targetInterfaceBlock.interfaceName = "TargetInterface";
1723 targetInterfaceBlock.layout.binding = 1;
1724 targetInterfaceBlock.storage = m_storage;
1726 if (m_caseType == CASE_UNNAMED_BLOCK)
1727 targetInterfaceBlock.instanceName = "";
1729 targetInterfaceBlock.instanceName = "targetInstance";
1731 if (m_caseType == CASE_BLOCK_ARRAY)
1732 targetInterfaceBlock.dimensions.push_back(2);
1736 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "blockMemberBasic"));
1741 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 3), "blockMemberArray"));
1746 glu::StructType* structPtr = new glu::StructType("StructType");
1747 structPtr->addMember("structMemberBasic", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP));
1748 structPtr->addMember("structMemberArray", glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 2));
1750 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(structPtr), 2), "blockMemberStruct"));
1753 // Unsized array type
1754 if (m_storage == glu::STORAGE_BUFFER)
1755 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY), "blockMemberUnsizedArray"));
1757 shader->getDefaultBlock().interfaceBlocks.push_back(targetInterfaceBlock);
1760 // TrailingInterface
1762 glu::InterfaceBlock trailingInterfaceBlock;
1764 trailingInterfaceBlock.interfaceName = "TrailingInterface";
1765 trailingInterfaceBlock.layout.binding = 3;
1766 trailingInterfaceBlock.storage = m_storage;
1767 trailingInterfaceBlock.instanceName = "trailingInstance";
1768 trailingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "trailingMember"));
1770 shader->getDefaultBlock().interfaceBlocks.push_back(trailingInterfaceBlock);
1773 DE_ASSERT(m_program->isValid());
1776 void InterfaceBlockBaseCase::deinit (void)
1779 m_program = DE_NULL;
1782 class InterfaceBlockActiveVariablesTestCase : public InterfaceBlockBaseCase
1785 InterfaceBlockActiveVariablesTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
1788 IterateResult iterate (void);
1791 InterfaceBlockActiveVariablesTestCase::InterfaceBlockActiveVariablesTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
1792 : InterfaceBlockBaseCase(context, name, description, storage, caseType)
1796 InterfaceBlockActiveVariablesTestCase::IterateResult InterfaceBlockActiveVariablesTestCase::iterate (void)
1798 const ProgramInterface programInterface = (m_storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
1799 (m_storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
1800 (PROGRAMINTERFACE_LAST);
1801 const glw::GLenum programGLInterfaceValue = getProgramInterfaceGLEnum(programInterface);
1802 const glw::GLenum programMemberInterfaceValue = (m_storage == glu::STORAGE_UNIFORM) ? (GL_UNIFORM) :
1803 (m_storage == glu::STORAGE_BUFFER) ? (GL_BUFFER_VARIABLE) :
1805 const std::vector<std::string> blockNames = getProgramInterfaceResourceList(m_program, programInterface);
1806 glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
1807 int expectedMaxNumActiveVariables = 0;
1809 DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
1811 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1812 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1814 // Verify all blocks
1816 for (int blockNdx = 0; blockNdx < (int)blockNames.size(); ++blockNdx)
1818 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Block", "Block \"" + blockNames[blockNdx] + "\"");
1819 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1820 const glw::GLuint resourceNdx = gl.getProgramResourceIndex(program.getProgram(), programGLInterfaceValue, blockNames[blockNdx].c_str());
1821 glw::GLint numActiveResources;
1822 std::vector<std::string> activeResourceNames;
1824 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1826 if (resourceNdx == GL_INVALID_INDEX)
1828 m_testCtx.getLog() << tcu::TestLog::Message << "Error, getProgramResourceIndex returned GL_INVALID_INDEX for \"" << blockNames[blockNdx] << "\"" << tcu::TestLog::EndMessage;
1829 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Resource not found");
1833 // query block information
1836 const glw::GLenum props[] = { GL_NUM_ACTIVE_VARIABLES };
1837 glw::GLint retBuffer[2] = { -1, -1 };
1838 glw::GLint written = -1;
1840 gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, DE_LENGTH_OF_ARRAY(props), props, 1, &written, retBuffer);
1841 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_NUM_ACTIVE_VARIABLES");
1843 numActiveResources = retBuffer[0];
1844 expectedMaxNumActiveVariables = de::max(expectedMaxNumActiveVariables, numActiveResources);
1845 m_testCtx.getLog() << tcu::TestLog::Message << "NUM_ACTIVE_VARIABLES = " << numActiveResources << tcu::TestLog::EndMessage;
1847 if (written == -1 || retBuffer[0] == -1)
1849 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for NUM_ACTIVE_VARIABLES did not return a value" << tcu::TestLog::EndMessage;
1850 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for NUM_ACTIVE_VARIABLES failed");
1853 else if (retBuffer[1] != -1)
1855 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for NUM_ACTIVE_VARIABLES returned too many values" << tcu::TestLog::EndMessage;
1856 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for NUM_ACTIVE_VARIABLES returned too many values");
1859 else if (retBuffer[0] < 0)
1861 m_testCtx.getLog() << tcu::TestLog::Message << "Error, NUM_ACTIVE_VARIABLES < 0" << tcu::TestLog::EndMessage;
1862 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "NUM_ACTIVE_VARIABLES < 0");
1867 // query block variable information
1870 const glw::GLenum props[] = { GL_ACTIVE_VARIABLES };
1871 std::vector<glw::GLint> activeVariableIndices (numActiveResources + 1, -1); // Allocate one extra trailing to detect wrong write lengths
1872 glw::GLint written = -1;
1874 gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, DE_LENGTH_OF_ARRAY(props), props, (glw::GLsizei)activeVariableIndices.size(), &written, &activeVariableIndices[0]);
1875 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_ACTIVE_VARIABLES");
1879 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for GL_ACTIVE_VARIABLES did not return any values" << tcu::TestLog::EndMessage;
1880 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES failed");
1883 else if (written != numActiveResources)
1885 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for GL_ACTIVE_VARIABLES did not return NUM_ACTIVE_VARIABLES values" << tcu::TestLog::EndMessage;
1886 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES returned invalid number of values");
1889 else if (activeVariableIndices.back() != -1)
1891 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;
1892 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES returned too many values");
1898 tcu::MessageBuilder builder(&m_testCtx.getLog());
1900 builder << "Active variable indices: {";
1901 for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1905 builder << activeVariableIndices[varNdx];
1907 builder << "}" << tcu::TestLog::EndMessage;
1912 activeResourceNames.resize(numActiveResources);
1914 for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1916 const glw::GLenum nameProp = GL_NAME_LENGTH;
1917 glw::GLint nameLength = -1;
1918 std::vector<char> nameBuffer;
1921 gl.getProgramResourceiv(program.getProgram(), programMemberInterfaceValue, activeVariableIndices[varNdx], 1, &nameProp, 1, &written, &nameLength);
1922 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_NAME_LENGTH");
1924 if (nameLength <= 0 || written <= 0)
1926 m_testCtx.getLog() << tcu::TestLog::Message << "Error, GL_NAME_LENGTH query failed" << tcu::TestLog::EndMessage;
1927 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GL_NAME_LENGTH query failed");
1931 nameBuffer.resize(nameLength + 2, 'X'); // allocate more than required
1933 gl.getProgramResourceName(program.getProgram(), programMemberInterfaceValue, activeVariableIndices[varNdx], nameLength+1, &written, &nameBuffer[0]);
1934 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramResourceName");
1938 m_testCtx.getLog() << tcu::TestLog::Message << "Error, name query failed, no data written" << tcu::TestLog::EndMessage;
1939 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "name query failed");
1942 else if (written > nameLength)
1944 m_testCtx.getLog() << tcu::TestLog::Message << "Error, name query failed, query returned too much data" << tcu::TestLog::EndMessage;
1945 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "name query failed");
1949 activeResourceNames[varNdx] = std::string(&nameBuffer[0], written);
1952 // log collected names
1954 tcu::MessageBuilder builder(&m_testCtx.getLog());
1956 builder << "Active variables:\n";
1957 for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1958 builder << "\t" << activeResourceNames[varNdx] << "\n";
1959 builder << tcu::TestLog::EndMessage;
1965 glu::InterfaceBlock* block = DE_NULL;
1966 const std::string blockName = glu::parseVariableName(blockNames[blockNdx].c_str());
1967 std::vector<std::string> referenceList;
1969 for (int interfaceNdx = 0; interfaceNdx < (int)m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx)
1971 if (m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].interfaceName == blockName)
1973 block = &m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx];
1979 throw tcu::InternalError("could not find block referenced in the reference resource list");
1981 // generate reference list
1983 referenceList = getProgramInterfaceBlockMemberResourceList(*block);
1985 tcu::MessageBuilder builder(&m_testCtx.getLog());
1987 builder << "Expected variable names:\n";
1988 for (int varNdx = 0; varNdx < (int)referenceList.size(); ++varNdx)
1989 builder << "\t" << referenceList[varNdx] << "\n";
1990 builder << tcu::TestLog::EndMessage;
1995 bool listsIdentical = true;
1997 for (int ndx = 0; ndx < (int)referenceList.size(); ++ndx)
1999 if (!de::contains(activeResourceNames.begin(), activeResourceNames.end(), referenceList[ndx]))
2001 m_testCtx.getLog() << tcu::TestLog::Message << "Error, variable name list did not contain active variable " << referenceList[ndx] << tcu::TestLog::EndMessage;
2002 listsIdentical = false;
2006 for (int ndx = 0; ndx < (int)activeResourceNames.size(); ++ndx)
2008 if (!de::contains(referenceList.begin(), referenceList.end(), activeResourceNames[ndx]))
2010 m_testCtx.getLog() << tcu::TestLog::Message << "Error, variable name list contains unexpected resource \"" << activeResourceNames[ndx] << "\"" << tcu::TestLog::EndMessage;
2011 listsIdentical = false;
2016 m_testCtx.getLog() << tcu::TestLog::Message << "Lists identical" << tcu::TestLog::EndMessage;
2019 m_testCtx.getLog() << tcu::TestLog::Message << "Error, invalid active variable list" << tcu::TestLog::EndMessage;
2020 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid active variable list");
2027 // Max num active variables
2029 const tcu::ScopedLogSection section (m_testCtx.getLog(), "MaxNumActiveVariables", "MAX_NUM_ACTIVE_VARIABLES");
2030 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2031 glw::GLint maxNumActiveVariables = -1;
2033 gl.getProgramInterfaceiv(program.getProgram(), programGLInterfaceValue, GL_MAX_NUM_ACTIVE_VARIABLES, &maxNumActiveVariables);
2034 GLU_EXPECT_NO_ERROR(gl.getError(), "query MAX_NUM_ACTIVE_VARIABLES");
2036 m_testCtx.getLog() << tcu::TestLog::Message << "MAX_NUM_ACTIVE_VARIABLES = " << maxNumActiveVariables << tcu::TestLog::EndMessage;
2038 if (expectedMaxNumActiveVariables != maxNumActiveVariables)
2040 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected MAX_NUM_ACTIVE_VARIABLES" << tcu::TestLog::EndMessage;
2041 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected MAX_NUM_ACTIVE_VARIABLES");
2044 m_testCtx.getLog() << tcu::TestLog::Message << "MAX_NUM_ACTIVE_VARIABLES valid" << tcu::TestLog::EndMessage;
2050 class InterfaceBlockDataSizeTestCase : public InterfaceBlockBaseCase
2053 InterfaceBlockDataSizeTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
2056 IterateResult iterate (void);
2057 int getBlockMinDataSize (const std::string& blockName) const;
2058 int getBlockMinDataSize (const glu::InterfaceBlock& block) const;
2061 InterfaceBlockDataSizeTestCase::InterfaceBlockDataSizeTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
2062 : InterfaceBlockBaseCase(context, name, description, storage, caseType)
2066 InterfaceBlockDataSizeTestCase::IterateResult InterfaceBlockDataSizeTestCase::iterate (void)
2068 const ProgramInterface programInterface = (m_storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
2069 (m_storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
2070 (PROGRAMINTERFACE_LAST);
2071 const glw::GLenum programGLInterfaceValue = getProgramInterfaceGLEnum(programInterface);
2072 const std::vector<std::string> blockNames = getProgramInterfaceResourceList(m_program, programInterface);
2073 glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2075 DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
2077 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2078 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2080 // Verify all blocks
2081 for (int blockNdx = 0; blockNdx < (int)blockNames.size(); ++blockNdx)
2083 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Block", "Block \"" + blockNames[blockNdx] + "\"");
2084 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2085 const glw::GLuint resourceNdx = gl.getProgramResourceIndex(program.getProgram(), programGLInterfaceValue, blockNames[blockNdx].c_str());
2086 const int expectedMinDataSize = getBlockMinDataSize(blockNames[blockNdx]);
2087 glw::GLint queryDataSize = -1;
2089 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
2091 if (resourceNdx == GL_INVALID_INDEX)
2093 m_testCtx.getLog() << tcu::TestLog::Message << "Error, getProgramResourceIndex returned GL_INVALID_INDEX for \"" << blockNames[blockNdx] << "\"" << tcu::TestLog::EndMessage;
2094 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Resource not found");
2100 const glw::GLenum prop = GL_BUFFER_DATA_SIZE;
2102 gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, 1, &prop, 1, DE_NULL, &queryDataSize);
2103 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource BUFFER_DATA_SIZE");
2107 << tcu::TestLog::Message
2108 << "BUFFER_DATA_SIZE = " << queryDataSize << "\n"
2109 << "Buffer data size with tight packing: " << expectedMinDataSize
2110 << tcu::TestLog::EndMessage;
2112 if (queryDataSize < expectedMinDataSize)
2114 m_testCtx.getLog() << tcu::TestLog::Message << "Error, buffer size was less than minimum buffer data size" << tcu::TestLog::EndMessage;
2115 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer data size invalid");
2119 m_testCtx.getLog() << tcu::TestLog::Message << "Buffer size valid" << tcu::TestLog::EndMessage;
2125 int InterfaceBlockDataSizeTestCase::getBlockMinDataSize (const std::string& blockFullName) const
2127 const std::string blockName = glu::parseVariableName(blockFullName.c_str());
2129 for (int interfaceNdx = 0; interfaceNdx < (int)m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx)
2131 if (m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].interfaceName == blockName &&
2132 m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].storage == m_storage)
2133 return getBlockMinDataSize(m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx]);
2140 class AtomicCounterCase : public TestCase
2143 AtomicCounterCase (Context& context, const char* name, const char* description);
2144 ~AtomicCounterCase (void);
2151 int getNumAtomicCounterBuffers (void) const;
2152 int getMaxNumActiveVariables (void) const;
2153 int getBufferVariableCount (int binding) const;
2154 int getBufferMinimumDataSize (int binding) const;
2156 ProgramInterfaceDefinition::Program* m_program;
2159 AtomicCounterCase::AtomicCounterCase (Context& context, const char* name, const char* description)
2160 : TestCase (context, name, description)
2161 , m_program (DE_NULL)
2165 AtomicCounterCase::~AtomicCounterCase (void)
2170 void AtomicCounterCase::init (void)
2172 ProgramInterfaceDefinition::Shader* shader;
2173 glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
2175 m_program = new ProgramInterfaceDefinition::Program();
2176 shader = m_program->addShader(glu::SHADERTYPE_COMPUTE, glslVersion);
2179 glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding1_counter1", glu::STORAGE_UNIFORM);
2180 decl.layout.binding = 1;
2181 shader->getDefaultBlock().variables.push_back(decl);
2184 glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding1_counter2", glu::STORAGE_UNIFORM);
2185 decl.layout.binding = 1;
2186 decl.layout.offset = 8;
2188 shader->getDefaultBlock().variables.push_back(decl);
2191 glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding2_counter1", glu::STORAGE_UNIFORM);
2192 decl.layout.binding = 2;
2193 shader->getDefaultBlock().variables.push_back(decl);
2196 DE_ASSERT(m_program->isValid());
2199 void AtomicCounterCase::deinit (void)
2202 m_program = DE_NULL;
2205 int AtomicCounterCase::getNumAtomicCounterBuffers (void) const
2207 std::set<int> buffers;
2209 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2211 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2212 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()))
2214 buffers.insert(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding);
2218 return (int)buffers.size();
2221 int AtomicCounterCase::getMaxNumActiveVariables (void) const
2224 std::map<int,int> numBufferVars;
2226 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2228 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2229 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()))
2231 const int binding = m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding;
2233 if (numBufferVars.find(binding) == numBufferVars.end())
2234 numBufferVars[binding] = 1;
2236 ++numBufferVars[binding];
2240 for (std::map<int,int>::const_iterator it = numBufferVars.begin(); it != numBufferVars.end(); ++it)
2241 maxVars = de::max(maxVars, it->second);
2246 int AtomicCounterCase::getBufferVariableCount (int binding) const
2250 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2252 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2253 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()) &&
2254 m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding == binding)
2261 int AtomicCounterCase::getBufferMinimumDataSize (int binding) const
2264 int currentOffset = 0;
2266 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2268 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2269 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()) &&
2270 m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding == binding)
2272 const int thisOffset = (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.offset != -1) ? (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.offset) : (currentOffset);
2273 currentOffset = thisOffset + 4;
2275 minSize = de::max(minSize, thisOffset + 4);
2282 class AtomicCounterResourceListCase : public AtomicCounterCase
2285 AtomicCounterResourceListCase (Context& context, const char* name, const char* description);
2288 IterateResult iterate (void);
2291 AtomicCounterResourceListCase::AtomicCounterResourceListCase (Context& context, const char* name, const char* description)
2292 : AtomicCounterCase(context, name, description)
2296 AtomicCounterResourceListCase::IterateResult AtomicCounterResourceListCase::iterate (void)
2298 const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2300 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2301 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2304 const tcu::ScopedLogSection section (m_testCtx.getLog(), "ActiveResources", "ACTIVE_RESOURCES");
2305 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2306 glw::GLint numActiveResources = -1;
2307 const int numExpectedActiveResources = 2; // 2 buffer bindings
2309 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying ACTIVE_RESOURCES, expecting " << numExpectedActiveResources << tcu::TestLog::EndMessage;
2311 gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &numActiveResources);
2312 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_ACTIVE_RESOURCES");
2314 m_testCtx.getLog() << tcu::TestLog::Message << "ACTIVE_RESOURCES = " << numActiveResources << tcu::TestLog::EndMessage;
2316 if (numActiveResources != numExpectedActiveResources)
2318 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected ACTIVE_RESOURCES" << tcu::TestLog::EndMessage;
2319 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected ACTIVE_RESOURCES");
2322 m_testCtx.getLog() << tcu::TestLog::Message << "ACTIVE_RESOURCES valid" << tcu::TestLog::EndMessage;
2328 class AtomicCounterActiveVariablesCase : public AtomicCounterCase
2331 AtomicCounterActiveVariablesCase (Context& context, const char* name, const char* description);
2334 IterateResult iterate (void);
2337 AtomicCounterActiveVariablesCase::AtomicCounterActiveVariablesCase (Context& context, const char* name, const char* description)
2338 : AtomicCounterCase(context, name, description)
2342 AtomicCounterActiveVariablesCase::IterateResult AtomicCounterActiveVariablesCase::iterate (void)
2344 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2345 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2346 const int numAtomicBuffers = getNumAtomicCounterBuffers();
2347 const int expectedMaxNumActiveVariables = getMaxNumActiveVariables();
2349 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2350 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2352 // check active variables
2354 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Interface", "ATOMIC_COUNTER_BUFFER interface");
2355 glw::GLint queryActiveResources = -1;
2356 glw::GLint queryMaxNumActiveVariables = -1;
2358 gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &queryActiveResources);
2359 gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, &queryMaxNumActiveVariables);
2360 GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
2363 << tcu::TestLog::Message
2364 << "GL_ACTIVE_RESOURCES = " << queryActiveResources << "\n"
2365 << "GL_MAX_NUM_ACTIVE_VARIABLES = " << queryMaxNumActiveVariables << "\n"
2366 << tcu::TestLog::EndMessage;
2368 if (queryActiveResources != numAtomicBuffers)
2370 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected GL_ACTIVE_RESOURCES, expected " << numAtomicBuffers << tcu::TestLog::EndMessage;
2371 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected GL_ACTIVE_RESOURCES");
2374 if (queryMaxNumActiveVariables != expectedMaxNumActiveVariables)
2376 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected GL_MAX_NUM_ACTIVE_VARIABLES, expected " << expectedMaxNumActiveVariables << tcu::TestLog::EndMessage;
2377 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected GL_MAX_NUM_ACTIVE_VARIABLES");
2381 // Check each buffer
2382 for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2384 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
2385 std::vector<glw::GLint> activeVariables;
2386 std::vector<std::string> memberNames;
2388 // Find active variables
2390 const glw::GLenum numActiveVariablesProp = GL_NUM_ACTIVE_VARIABLES;
2391 const glw::GLenum activeVariablesProp = GL_ACTIVE_VARIABLES;
2392 glw::GLint numActiveVariables = -2;
2393 glw::GLint written = -1;
2395 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &numActiveVariablesProp, 1, &written, &numActiveVariables);
2396 GLU_EXPECT_NO_ERROR(gl.getError(), "query num active variables");
2398 if (numActiveVariables <= 0)
2400 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected NUM_ACTIVE_VARIABLES: " << numActiveVariables << tcu::TestLog::EndMessage;
2401 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected NUM_ACTIVE_VARIABLES");
2407 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for NUM_ACTIVE_VARIABLES returned no values" << tcu::TestLog::EndMessage;
2408 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "NUM_ACTIVE_VARIABLES query failed");
2412 m_testCtx.getLog() << tcu::TestLog::Message << "GL_NUM_ACTIVE_VARIABLES = " << numActiveVariables << tcu::TestLog::EndMessage;
2415 activeVariables.resize(numActiveVariables + 1, -2);
2417 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &activeVariablesProp, numActiveVariables, &written, &activeVariables[0]);
2418 GLU_EXPECT_NO_ERROR(gl.getError(), "query active variables");
2420 if (written != numActiveVariables)
2422 m_testCtx.getLog() << tcu::TestLog::Message << "Error, unexpected number of ACTIVE_VARIABLES, NUM_ACTIVE_VARIABLES = " << numActiveVariables << ", query returned " << written << " values" << tcu::TestLog::EndMessage;
2423 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected ACTIVE_VARIABLES");
2427 if (activeVariables.back() != -2)
2429 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for ACTIVE_VARIABLES wrote over target buffer bounds" << tcu::TestLog::EndMessage;
2430 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "ACTIVE_VARIABLES query failed");
2434 activeVariables.pop_back();
2439 tcu::MessageBuilder builder(&m_testCtx.getLog());
2441 builder << "Active variable indices: {";
2442 for (int varNdx = 0; varNdx < (int)activeVariables.size(); ++varNdx)
2446 builder << activeVariables[varNdx];
2448 builder << "}" << tcu::TestLog::EndMessage;
2451 // collect member names
2452 for (int ndx = 0; ndx < (int)activeVariables.size(); ++ndx)
2454 const glw::GLenum nameLengthProp = GL_NAME_LENGTH;
2455 glw::GLint nameLength = -1;
2456 glw::GLint written = -1;
2457 std::vector<char> nameBuf;
2459 gl.getProgramResourceiv(program.getProgram(), GL_UNIFORM, activeVariables[ndx], 1, &nameLengthProp, 1, &written, &nameLength);
2460 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer variable name length");
2462 if (written <= 0 || nameLength == -1)
2464 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for GL_NAME_LENGTH returned no values" << tcu::TestLog::EndMessage;
2465 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GL_NAME_LENGTH query failed");
2469 nameBuf.resize(nameLength + 2, 'X'); // +2 to tolerate potential off-by-ones in some implementations, name queries will check these cases better
2472 gl.getProgramResourceName(program.getProgram(), GL_UNIFORM, activeVariables[ndx], (int)nameBuf.size(), &written, &nameBuf[0]);
2473 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer variable name");
2477 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for resource name returned no name" << tcu::TestLog::EndMessage;
2478 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Name query failed");
2482 memberNames.push_back(std::string(&nameBuf[0], written));
2487 tcu::MessageBuilder builder(&m_testCtx.getLog());
2489 builder << "Active variables:\n";
2490 for (int varNdx = 0; varNdx < (int)memberNames.size(); ++varNdx)
2492 builder << "\t" << memberNames[varNdx] << "\n";
2494 builder << tcu::TestLog::EndMessage;
2497 // check names are all in the same buffer
2499 bool bindingsValid = true;
2501 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying names" << tcu::TestLog::EndMessage;
2503 for (int nameNdx = 0; nameNdx < (int)memberNames.size(); ++nameNdx)
2505 int prevBinding = -1;
2507 for (int varNdx = 0; varNdx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++varNdx)
2509 if (m_program->getShaders()[0]->getDefaultBlock().variables[varNdx].name == memberNames[nameNdx])
2511 const int varBinding = m_program->getShaders()[0]->getDefaultBlock().variables[varNdx].layout.binding;
2513 if (prevBinding == -1 || prevBinding == varBinding)
2514 prevBinding = varBinding;
2516 bindingsValid = false;
2520 if (prevBinding == -1)
2522 m_testCtx.getLog() << tcu::TestLog::Message << "Error, could not find variable with name \"" << memberNames[nameNdx] << "\"" << tcu::TestLog::EndMessage;
2523 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Variable name invalid");
2525 else if (getBufferVariableCount(prevBinding) != (int)memberNames.size())
2528 << tcu::TestLog::Message
2529 << "Error, unexpected variable count for binding " << prevBinding
2530 << ". Expected " << getBufferVariableCount(prevBinding) << ", got " << (int)memberNames.size()
2531 << tcu::TestLog::EndMessage;
2532 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Variable names invalid");
2538 m_testCtx.getLog() << tcu::TestLog::Message << "Error, all resource do not share the same buffer" << tcu::TestLog::EndMessage;
2539 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Active variables invalid");
2548 class AtomicCounterBufferBindingCase : public AtomicCounterCase
2551 AtomicCounterBufferBindingCase (Context& context, const char* name, const char* description);
2554 IterateResult iterate (void);
2557 AtomicCounterBufferBindingCase::AtomicCounterBufferBindingCase (Context& context, const char* name, const char* description)
2558 : AtomicCounterCase(context, name, description)
2562 AtomicCounterBufferBindingCase::IterateResult AtomicCounterBufferBindingCase::iterate (void)
2564 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2565 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2566 const int numAtomicBuffers = getNumAtomicCounterBuffers();
2568 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2569 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2571 // check every buffer
2572 for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2574 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
2575 const glw::GLenum bufferBindingProp = GL_BUFFER_BINDING;
2576 glw::GLint bufferBinding = -1;
2577 glw::GLint written = -1;
2579 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &bufferBindingProp, 1, &written, &bufferBinding);
2580 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2584 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for BUFFER_BINDING returned no values." << tcu::TestLog::EndMessage;
2585 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "BUFFER_BINDING query failed");
2588 m_testCtx.getLog() << tcu::TestLog::Message << "GL_BUFFER_BINDING = " << bufferBinding << tcu::TestLog::EndMessage;
2590 // no such buffer binding?
2591 if (getBufferVariableCount(bufferBinding) == 0)
2593 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_BINDING = " << bufferBinding << ", but such buffer does not exist." << tcu::TestLog::EndMessage;
2594 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2601 class AtomicCounterBufferDataSizeCase : public AtomicCounterCase
2604 AtomicCounterBufferDataSizeCase (Context& context, const char* name, const char* description);
2607 IterateResult iterate (void);
2610 AtomicCounterBufferDataSizeCase::AtomicCounterBufferDataSizeCase (Context& context, const char* name, const char* description)
2611 : AtomicCounterCase(context, name, description)
2615 AtomicCounterBufferDataSizeCase::IterateResult AtomicCounterBufferDataSizeCase::iterate (void)
2617 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2618 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2619 const int numAtomicBuffers = getNumAtomicCounterBuffers();
2621 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2622 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2624 // check every buffer
2625 for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2627 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
2628 const glw::GLenum props[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE };
2629 glw::GLint values[] = { -1, -1 };
2630 glw::GLint written = -1;
2631 int bufferMinDataSize;
2633 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, DE_LENGTH_OF_ARRAY(props), props, DE_LENGTH_OF_ARRAY(values), &written, values);
2634 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2638 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for (BUFFER_BINDING, BUFFER_DATA_SIZE) returned " << written << " value(s)." << tcu::TestLog::EndMessage;
2639 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
2644 << tcu::TestLog::Message
2645 << "GL_BUFFER_BINDING = " << values[0] << "\n"
2646 << "GL_BUFFER_DATA_SIZE = " << values[1]
2647 << tcu::TestLog::EndMessage;
2649 bufferMinDataSize = getBufferMinimumDataSize(values[0]);
2650 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying data size, expected greater than or equal to " << bufferMinDataSize << tcu::TestLog::EndMessage;
2652 // no such buffer binding?
2653 if (bufferMinDataSize == -1)
2655 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_BINDING = " << values[0] << ", but such buffer does not exist." << tcu::TestLog::EndMessage;
2656 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2658 else if (values[1] < bufferMinDataSize)
2660 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;
2661 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2664 m_testCtx.getLog() << tcu::TestLog::Message << "Data size valid" << tcu::TestLog::EndMessage;
2670 class AtomicCounterReferencedByCase : public TestCase
2673 AtomicCounterReferencedByCase (Context& context,
2675 const char* description,
2677 deUint32 presentStagesMask,
2678 deUint32 activeStagesMask);
2679 ~AtomicCounterReferencedByCase (void);
2684 IterateResult iterate (void);
2686 const bool m_separable;
2687 const deUint32 m_presentStagesMask;
2688 const deUint32 m_activeStagesMask;
2689 ProgramInterfaceDefinition::Program* m_program;
2692 AtomicCounterReferencedByCase::AtomicCounterReferencedByCase (Context& context,
2694 const char* description,
2696 deUint32 presentStagesMask,
2697 deUint32 activeStagesMask)
2698 : TestCase (context, name, description)
2699 , m_separable (separable)
2700 , m_presentStagesMask (presentStagesMask)
2701 , m_activeStagesMask (activeStagesMask)
2702 , m_program (DE_NULL)
2704 DE_ASSERT((activeStagesMask & presentStagesMask) == activeStagesMask);
2707 AtomicCounterReferencedByCase::~AtomicCounterReferencedByCase (void)
2712 void AtomicCounterReferencedByCase::init (void)
2714 const deUint32 geometryMask = (1 << glu::SHADERTYPE_GEOMETRY);
2715 const deUint32 tessellationMask = (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION);
2716 glu::VariableDeclaration atomicVar (glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "targetCounter", glu::STORAGE_UNIFORM);
2717 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
2718 const bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
2720 if ((m_presentStagesMask & tessellationMask) != 0 && !supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
2721 throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
2722 if ((m_presentStagesMask & geometryMask) != 0 && !supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
2723 throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
2725 atomicVar.layout.binding = 1;
2727 m_program = new ProgramInterfaceDefinition::Program();
2728 m_program->setSeparable(m_separable);
2730 for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
2732 if (m_activeStagesMask & (1 << shaderType))
2733 m_program->addShader((glu::ShaderType)shaderType, glslVersion)->getDefaultBlock().variables.push_back(atomicVar);
2734 else if (m_presentStagesMask & (1 << shaderType))
2735 m_program->addShader((glu::ShaderType)shaderType, glslVersion);
2738 if (m_program->hasStage(glu::SHADERTYPE_GEOMETRY))
2739 m_program->setGeometryNumOutputVertices(1);
2740 if (m_program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
2741 m_program->setTessellationNumOutputPatchVertices(1);
2743 DE_ASSERT(m_program->isValid());
2746 void AtomicCounterReferencedByCase::deinit (void)
2749 m_program = DE_NULL;
2752 AtomicCounterReferencedByCase::IterateResult AtomicCounterReferencedByCase::iterate (void)
2754 const bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
2758 glw::GLenum propName;
2759 glu::ShaderType shaderType;
2760 const char* extension;
2763 { GL_REFERENCED_BY_VERTEX_SHADER, glu::SHADERTYPE_VERTEX, DE_NULL },
2764 { GL_REFERENCED_BY_FRAGMENT_SHADER, glu::SHADERTYPE_FRAGMENT, DE_NULL },
2765 { GL_REFERENCED_BY_COMPUTE_SHADER, glu::SHADERTYPE_COMPUTE, DE_NULL },
2766 { GL_REFERENCED_BY_TESS_CONTROL_SHADER, glu::SHADERTYPE_TESSELLATION_CONTROL, (supportsES32 ? DE_NULL : "GL_EXT_tessellation_shader") },
2767 { GL_REFERENCED_BY_TESS_EVALUATION_SHADER, glu::SHADERTYPE_TESSELLATION_EVALUATION, (supportsES32 ? DE_NULL : "GL_EXT_tessellation_shader") },
2768 { GL_REFERENCED_BY_GEOMETRY_SHADER, glu::SHADERTYPE_GEOMETRY, (supportsES32 ? DE_NULL : "GL_EXT_geometry_shader") },
2771 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2772 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2774 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2775 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2778 for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(targetProps); ++propNdx)
2780 if (targetProps[propNdx].extension == DE_NULL || m_context.getContextInfo().isExtensionSupported(targetProps[propNdx].extension))
2782 const glw::GLenum prop = targetProps[propNdx].propName;
2783 const glw::GLint expected = ((m_activeStagesMask & (1 << targetProps[propNdx].shaderType)) != 0) ? (GL_TRUE) : (GL_FALSE);
2784 glw::GLint value = -1;
2785 glw::GLint written = -1;
2787 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying " << glu::getProgramResourcePropertyName(prop) << ", expecting " << glu::getBooleanName(expected) << tcu::TestLog::EndMessage;
2789 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, 0, 1, &prop, 1, &written, &value);
2790 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2794 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for referenced_by_* returned invalid number of values." << tcu::TestLog::EndMessage;
2795 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
2799 m_testCtx.getLog() << tcu::TestLog::Message << glu::getProgramResourcePropertyName(prop) << " = " << glu::getBooleanStr(value) << tcu::TestLog::EndMessage;
2801 if (value != expected)
2803 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected value" << tcu::TestLog::EndMessage;
2804 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected property value");
2813 class ProgramInputOutputReferencedByCase : public TestCase
2818 CASE_VERTEX_FRAGMENT = 0,
2819 CASE_VERTEX_GEO_FRAGMENT,
2820 CASE_VERTEX_TESS_FRAGMENT,
2821 CASE_VERTEX_TESS_GEO_FRAGMENT,
2823 CASE_SEPARABLE_VERTEX,
2824 CASE_SEPARABLE_FRAGMENT,
2825 CASE_SEPARABLE_GEOMETRY,
2826 CASE_SEPARABLE_TESS_CTRL,
2827 CASE_SEPARABLE_TESS_EVAL,
2831 ProgramInputOutputReferencedByCase (Context& context, const char* name, const char* description, glu::Storage targetStorage, CaseType caseType);
2832 ~ProgramInputOutputReferencedByCase (void);
2837 IterateResult iterate (void);
2839 const CaseType m_caseType;
2840 const glu::Storage m_targetStorage;
2841 ProgramInterfaceDefinition::Program* m_program;
2844 ProgramInputOutputReferencedByCase::ProgramInputOutputReferencedByCase (Context& context, const char* name, const char* description, glu::Storage targetStorage, CaseType caseType)
2845 : TestCase (context, name, description)
2846 , m_caseType (caseType)
2847 , m_targetStorage (targetStorage)
2848 , m_program (DE_NULL)
2850 DE_ASSERT(caseType < CASE_LAST);
2853 ProgramInputOutputReferencedByCase::~ProgramInputOutputReferencedByCase (void)
2858 void ProgramInputOutputReferencedByCase::init (void)
2860 const bool hasTessellationShader = (m_caseType == CASE_VERTEX_TESS_FRAGMENT) ||
2861 (m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT) ||
2862 (m_caseType == CASE_SEPARABLE_TESS_CTRL) ||
2863 (m_caseType == CASE_SEPARABLE_TESS_EVAL);
2864 const bool hasGeometryShader = (m_caseType == CASE_VERTEX_GEO_FRAGMENT) ||
2865 (m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT) ||
2866 (m_caseType == CASE_SEPARABLE_GEOMETRY);
2867 const bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
2869 if (hasTessellationShader && !supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
2870 throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
2871 if (hasGeometryShader && !supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
2872 throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
2874 glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
2875 m_program = new ProgramInterfaceDefinition::Program();
2877 if (m_caseType == CASE_SEPARABLE_VERTEX ||
2878 m_caseType == CASE_SEPARABLE_FRAGMENT ||
2879 m_caseType == CASE_SEPARABLE_GEOMETRY ||
2880 m_caseType == CASE_SEPARABLE_TESS_CTRL ||
2881 m_caseType == CASE_SEPARABLE_TESS_EVAL)
2883 const bool isInputCase = (m_targetStorage == glu::STORAGE_IN || m_targetStorage == glu::STORAGE_PATCH_IN);
2884 const bool perPatchStorage = (m_targetStorage == glu::STORAGE_PATCH_IN || m_targetStorage == glu::STORAGE_PATCH_OUT);
2885 const char* varName = (isInputCase) ? ("shaderInput") : ("shaderOutput");
2886 const glu::VariableDeclaration targetDecl (glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), varName, m_targetStorage);
2887 const glu::ShaderType shaderType = (m_caseType == CASE_SEPARABLE_VERTEX) ? (glu::SHADERTYPE_VERTEX)
2888 : (m_caseType == CASE_SEPARABLE_FRAGMENT) ? (glu::SHADERTYPE_FRAGMENT)
2889 : (m_caseType == CASE_SEPARABLE_GEOMETRY) ? (glu::SHADERTYPE_GEOMETRY)
2890 : (m_caseType == CASE_SEPARABLE_TESS_CTRL) ? (glu::SHADERTYPE_TESSELLATION_CONTROL)
2891 : (m_caseType == CASE_SEPARABLE_TESS_EVAL) ? (glu::SHADERTYPE_TESSELLATION_EVALUATION)
2892 : (glu::SHADERTYPE_LAST);
2893 const bool arrayedInterface = (isInputCase) ? ((shaderType == glu::SHADERTYPE_GEOMETRY) ||
2894 (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL) ||
2895 (shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION))
2896 : (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL);
2898 m_program->setSeparable(true);
2900 if (arrayedInterface && !perPatchStorage)
2902 const glu::VariableDeclaration targetDeclArr(glu::VarType(targetDecl.varType, glu::VarType::UNSIZED_ARRAY), varName, m_targetStorage);
2903 m_program->addShader(shaderType, glslVersion)->getDefaultBlock().variables.push_back(targetDeclArr);
2907 m_program->addShader(shaderType, glslVersion)->getDefaultBlock().variables.push_back(targetDecl);
2910 else if (m_caseType == CASE_VERTEX_FRAGMENT ||
2911 m_caseType == CASE_VERTEX_GEO_FRAGMENT ||
2912 m_caseType == CASE_VERTEX_TESS_FRAGMENT ||
2913 m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
2915 ProgramInterfaceDefinition::Shader* vertex = m_program->addShader(glu::SHADERTYPE_VERTEX, glslVersion);
2916 ProgramInterfaceDefinition::Shader* fragment = m_program->addShader(glu::SHADERTYPE_FRAGMENT, glslVersion);
2918 m_program->setSeparable(false);
2920 vertex->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2923 vertex->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2926 glu::INTERPOLATION_LAST,
2929 fragment->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2932 glu::INTERPOLATION_LAST,
2934 fragment->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2937 glu::INTERPOLATION_LAST,
2940 if (m_caseType == CASE_VERTEX_TESS_FRAGMENT || m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
2942 ProgramInterfaceDefinition::Shader* tessCtrl = m_program->addShader(glu::SHADERTYPE_TESSELLATION_CONTROL, glslVersion);
2943 ProgramInterfaceDefinition::Shader* tessEval = m_program->addShader(glu::SHADERTYPE_TESSELLATION_EVALUATION, glslVersion);
2945 tessCtrl->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2948 glu::INTERPOLATION_LAST,
2950 tessCtrl->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2953 glu::INTERPOLATION_LAST,
2956 tessEval->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2959 glu::INTERPOLATION_LAST,
2961 tessEval->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2964 glu::INTERPOLATION_LAST,
2968 if (m_caseType == CASE_VERTEX_GEO_FRAGMENT || m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
2970 ProgramInterfaceDefinition::Shader* geometry = m_program->addShader(glu::SHADERTYPE_GEOMETRY, glslVersion);
2972 geometry->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2975 glu::INTERPOLATION_LAST,
2977 geometry->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2980 glu::INTERPOLATION_LAST,
2987 if (m_program->hasStage(glu::SHADERTYPE_GEOMETRY))
2988 m_program->setGeometryNumOutputVertices(1);
2989 if (m_program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
2990 m_program->setTessellationNumOutputPatchVertices(1);
2992 DE_ASSERT(m_program->isValid());
2995 void ProgramInputOutputReferencedByCase::deinit (void)
2998 m_program = DE_NULL;
3001 ProgramInputOutputReferencedByCase::IterateResult ProgramInputOutputReferencedByCase::iterate (void)
3005 glw::GLenum propName;
3006 glu::ShaderType shaderType;
3007 const char* extension;
3010 { GL_REFERENCED_BY_VERTEX_SHADER, glu::SHADERTYPE_VERTEX, DE_NULL },
3011 { GL_REFERENCED_BY_FRAGMENT_SHADER, glu::SHADERTYPE_FRAGMENT, DE_NULL },
3012 { GL_REFERENCED_BY_COMPUTE_SHADER, glu::SHADERTYPE_COMPUTE, DE_NULL },
3013 { GL_REFERENCED_BY_TESS_CONTROL_SHADER, glu::SHADERTYPE_TESSELLATION_CONTROL, "GL_EXT_tessellation_shader" },
3014 { GL_REFERENCED_BY_TESS_EVALUATION_SHADER, glu::SHADERTYPE_TESSELLATION_EVALUATION, "GL_EXT_tessellation_shader" },
3015 { GL_REFERENCED_BY_GEOMETRY_SHADER, glu::SHADERTYPE_GEOMETRY, "GL_EXT_geometry_shader" },
3018 const bool isInputCase = (m_targetStorage == glu::STORAGE_IN || m_targetStorage == glu::STORAGE_PATCH_IN);
3019 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3020 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
3021 const std::string targetResourceName = (isInputCase) ? ("shaderInput") : ("shaderOutput");
3022 const glw::GLenum programGLInterface = (isInputCase) ? (GL_PROGRAM_INPUT) : (GL_PROGRAM_OUTPUT);
3023 glw::GLuint resourceIndex;
3025 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3026 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
3028 // find target resource index
3030 resourceIndex = gl.getProgramResourceIndex(program.getProgram(), programGLInterface, targetResourceName.c_str());
3031 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
3033 if (resourceIndex == GL_INVALID_INDEX)
3035 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for resource \"" << targetResourceName << "\" index returned invalid index." << tcu::TestLog::EndMessage;
3036 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "could not find target resource");
3041 for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(targetProps); ++propNdx)
3043 if (targetProps[propNdx].extension == DE_NULL || m_context.getContextInfo().isExtensionSupported(targetProps[propNdx].extension))
3045 const glw::GLenum prop = targetProps[propNdx].propName;
3046 const bool expected = (isInputCase) ? (targetProps[propNdx].shaderType == m_program->getFirstStage()) : (targetProps[propNdx].shaderType == m_program->getLastStage());
3047 glw::GLint value = -1;
3048 glw::GLint written = -1;
3050 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying " << glu::getProgramResourcePropertyName(prop) << ", expecting " << ((expected) ? ("TRUE") : ("FALSE")) << tcu::TestLog::EndMessage;
3052 gl.getProgramResourceiv(program.getProgram(), programGLInterface, resourceIndex, 1, &prop, 1, &written, &value);
3053 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
3057 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for referenced_by_* returned invalid number of values." << tcu::TestLog::EndMessage;
3058 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
3062 m_testCtx.getLog() << tcu::TestLog::Message << glu::getProgramResourcePropertyName(prop) << " = " << glu::getBooleanStr(value) << tcu::TestLog::EndMessage;
3064 if (value != ((expected) ? (GL_TRUE) : (GL_FALSE)))
3066 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected value" << tcu::TestLog::EndMessage;
3067 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected property value");
3076 class FeedbackResourceListTestCase : public ResourceListTestCase
3079 FeedbackResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& resource, const char* name);
3080 ~FeedbackResourceListTestCase (void);
3083 IterateResult iterate (void);
3086 FeedbackResourceListTestCase::FeedbackResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& resource, const char* name)
3087 : ResourceListTestCase(context, resource, PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, name)
3091 FeedbackResourceListTestCase::~FeedbackResourceListTestCase (void)
3096 FeedbackResourceListTestCase::IterateResult FeedbackResourceListTestCase::iterate (void)
3098 const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_programDefinition));
3100 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3102 // Feedback varyings
3104 tcu::MessageBuilder builder(&m_testCtx.getLog());
3105 builder << "Transform feedback varyings: {";
3106 for (int ndx = 0; ndx < (int)m_programDefinition->getTransformFeedbackVaryings().size(); ++ndx)
3110 builder << "\"" << m_programDefinition->getTransformFeedbackVaryings()[ndx] << "\"";
3112 builder << "}" << tcu::TestLog::EndMessage;
3115 checkAndLogProgram(program, m_programDefinition, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
3117 // Check resource list
3119 const tcu::ScopedLogSection section (m_testCtx.getLog(), "ResourceList", "Resource list");
3120 std::vector<std::string> resourceList;
3121 std::vector<std::string> expectedResources;
3123 queryResourceList(resourceList, program.getProgram());
3124 expectedResources = getProgramInterfaceResourceList(m_programDefinition, m_programInterface);
3126 // verify the list and the expected list match
3128 if (!verifyResourceList(resourceList, expectedResources))
3129 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid resource list");
3131 // verify GetProgramResourceIndex() matches the indices of the list
3133 if (!verifyResourceIndexQuery(resourceList, expectedResources, program.getProgram()))
3134 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GetProgramResourceIndex returned unexpected values");
3136 // Verify MAX_NAME_LENGTH
3137 if (!verifyMaxNameLength(resourceList, program.getProgram()))
3138 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "MAX_NAME_LENGTH invalid");
3144 int InterfaceBlockDataSizeTestCase::getBlockMinDataSize (const glu::InterfaceBlock& block) const
3148 for (int ndx = 0; ndx < (int)block.variables.size(); ++ndx)
3149 dataSize += getVarTypeSize(block.variables[ndx].varType);
3154 static bool isDataTypeLayoutQualified (glu::DataType type)
3156 return glu::isDataTypeImage(type) || glu::isDataTypeAtomicCounter(type);
3159 static void generateVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3, bool createTestGroup = true)
3164 glu::DataType dataType;
3167 { 0, glu::TYPE_FLOAT },
3168 { 1, glu::TYPE_INT },
3169 { 1, glu::TYPE_UINT },
3170 { 1, glu::TYPE_BOOL },
3172 { 3, glu::TYPE_FLOAT_VEC2 },
3173 { 1, glu::TYPE_FLOAT_VEC3 },
3174 { 1, glu::TYPE_FLOAT_VEC4 },
3176 { 3, glu::TYPE_INT_VEC2 },
3177 { 2, glu::TYPE_INT_VEC3 },
3178 { 3, glu::TYPE_INT_VEC4 },
3180 { 3, glu::TYPE_UINT_VEC2 },
3181 { 2, glu::TYPE_UINT_VEC3 },
3182 { 3, glu::TYPE_UINT_VEC4 },
3184 { 3, glu::TYPE_BOOL_VEC2 },
3185 { 2, glu::TYPE_BOOL_VEC3 },
3186 { 3, glu::TYPE_BOOL_VEC4 },
3188 { 2, glu::TYPE_FLOAT_MAT2 },
3189 { 3, glu::TYPE_FLOAT_MAT2X3 },
3190 { 3, glu::TYPE_FLOAT_MAT2X4 },
3191 { 2, glu::TYPE_FLOAT_MAT3X2 },
3192 { 2, glu::TYPE_FLOAT_MAT3 },
3193 { 3, glu::TYPE_FLOAT_MAT3X4 },
3194 { 2, glu::TYPE_FLOAT_MAT4X2 },
3195 { 3, glu::TYPE_FLOAT_MAT4X3 },
3196 { 2, glu::TYPE_FLOAT_MAT4 },
3199 tcu::TestCaseGroup* group;
3201 if (createTestGroup)
3203 group = new tcu::TestCaseGroup(context.getTestContext(), "basic_type", "Basic variable");
3204 targetGroup->addChild(group);
3207 group = targetGroup;
3209 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3211 if (variableTypes[ndx].level <= expandLevel)
3213 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
3214 group->addChild(new ResourceTestCase(context, variable, queryTarget));
3219 static void generateOpaqueTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3, bool createTestGroup = true)
3224 glu::DataType dataType;
3227 { 0, glu::TYPE_SAMPLER_2D },
3228 { 2, glu::TYPE_SAMPLER_CUBE },
3229 { 1, glu::TYPE_SAMPLER_2D_ARRAY },
3230 { 1, glu::TYPE_SAMPLER_3D },
3231 { 2, glu::TYPE_SAMPLER_2D_SHADOW },
3232 { 3, glu::TYPE_SAMPLER_CUBE_SHADOW },
3233 { 3, glu::TYPE_SAMPLER_2D_ARRAY_SHADOW },
3234 { 1, glu::TYPE_INT_SAMPLER_2D },
3235 { 3, glu::TYPE_INT_SAMPLER_CUBE },
3236 { 3, glu::TYPE_INT_SAMPLER_2D_ARRAY },
3237 { 3, glu::TYPE_INT_SAMPLER_3D },
3238 { 2, glu::TYPE_UINT_SAMPLER_2D },
3239 { 3, glu::TYPE_UINT_SAMPLER_CUBE },
3240 { 3, glu::TYPE_UINT_SAMPLER_2D_ARRAY },
3241 { 3, glu::TYPE_UINT_SAMPLER_3D },
3242 { 2, glu::TYPE_SAMPLER_2D_MULTISAMPLE },
3243 { 2, glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE },
3244 { 3, glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE },
3245 { 1, glu::TYPE_IMAGE_2D },
3246 { 3, glu::TYPE_IMAGE_CUBE },
3247 { 3, glu::TYPE_IMAGE_2D_ARRAY },
3248 { 3, glu::TYPE_IMAGE_3D },
3249 { 3, glu::TYPE_INT_IMAGE_2D },
3250 { 3, glu::TYPE_INT_IMAGE_CUBE },
3251 { 1, glu::TYPE_INT_IMAGE_2D_ARRAY },
3252 { 3, glu::TYPE_INT_IMAGE_3D },
3253 { 2, glu::TYPE_UINT_IMAGE_2D },
3254 { 3, glu::TYPE_UINT_IMAGE_CUBE },
3255 { 3, glu::TYPE_UINT_IMAGE_2D_ARRAY },
3256 { 3, glu::TYPE_UINT_IMAGE_3D },
3257 { 1, glu::TYPE_UINT_ATOMIC_COUNTER },
3260 bool isStructMember = false;
3263 for (const ResourceDefinition::Node* node = parentStructure.get(); node; node = node->getEnclosingNode())
3265 // Don't insert inside a interface block
3266 if (node->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3269 isStructMember |= (node->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER);
3274 tcu::TestCaseGroup* group;
3276 if (createTestGroup)
3278 group = new tcu::TestCaseGroup(context.getTestContext(), "opaque_type", "Opaque types");
3279 targetGroup->addChild(group);
3282 group = targetGroup;
3284 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3286 if (variableTypes[ndx].level > expandLevel)
3289 // Layout qualifiers are not allowed on struct members
3290 if (isDataTypeLayoutQualified(variableTypes[ndx].dataType) && isStructMember)
3294 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
3295 group->addChild(new ResourceTestCase(context, variable, queryTarget));
3301 static void generateCompoundVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3);
3303 static void generateVariableArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3)
3305 if (expandLevel > 0)
3307 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3308 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3310 targetGroup->addChild(blockGroup);
3312 // Arrays of basic variables
3313 generateVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3315 // Arrays of opaque types
3316 generateOpaqueTypeCases(context, arrayElement, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3319 generateVariableArrayCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3321 // Arrays of structs
3322 generateCompoundVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3326 static void generateCompoundVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
3328 if (expandLevel > 0)
3330 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3331 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "struct", "Structs");
3333 targetGroup->addChild(blockGroup);
3335 // Struct containing basic variable
3336 generateVariableCases(context, structMember, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3338 // Struct containing opaque types
3339 generateOpaqueTypeCases(context, structMember, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3341 // Struct containing arrays
3342 generateVariableArrayCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3344 // Struct containing struct
3345 generateCompoundVariableCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3349 // Resource list cases
3353 BLOCKFLAG_DEFAULT = 0x01,
3354 BLOCKFLAG_NAMED = 0x02,
3355 BLOCKFLAG_UNNAMED = 0x04,
3356 BLOCKFLAG_ARRAY = 0x08,
3358 BLOCKFLAG_ALL = 0x0F
3361 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))
3363 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
3364 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
3367 if (blockFlags & BLOCKFLAG_DEFAULT)
3369 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "default_block", "Default block");
3370 targetGroup->addChild(blockGroup);
3372 blockContentGenerator(context, uniform, blockGroup);
3376 if (blockFlags & BLOCKFLAG_NAMED)
3378 const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(uniform, true));
3380 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "named_block", "Named uniform block");
3381 targetGroup->addChild(blockGroup);
3383 blockContentGenerator(context, block, blockGroup);
3387 if (blockFlags & BLOCKFLAG_UNNAMED)
3389 const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(uniform, false));
3391 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "unnamed_block", "Unnamed uniform block");
3392 targetGroup->addChild(blockGroup);
3394 blockContentGenerator(context, block, blockGroup);
3398 if (blockFlags & BLOCKFLAG_ARRAY)
3400 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(uniform));
3401 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
3403 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "block_array", "Uniform block array");
3404 targetGroup->addChild(blockGroup);
3406 blockContentGenerator(context, block, blockGroup);
3410 static void generateBufferBackedResourceListBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, int depth)
3414 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, glu::TYPE_FLOAT_VEC4));
3415 targetGroup->addChild(new ResourceListTestCase(context, variable, interface));
3421 const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
3422 generateBufferBackedResourceListBlockContentCases(context, structMember, targetGroup, interface, depth - 1);
3428 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
3429 generateBufferBackedResourceListBlockContentCases(context, arrayElement, targetGroup, interface, depth - 1);
3433 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)
3437 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, dataType));
3438 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, targetProp), ("var" + nameSuffix).c_str()));
3444 const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
3445 generateBufferBackedVariableAggregateTypeCases(context, structMember, targetGroup, interface, targetProp, dataType, "_struct" + nameSuffix, depth - 1);
3451 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
3452 generateBufferBackedVariableAggregateTypeCases(context, arrayElement, targetGroup, interface, targetProp, dataType, "_array" + nameSuffix, depth - 1);
3456 static void generateUniformResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3458 generateBufferBackedResourceListBlockContentCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, 4);
3461 static void generateUniformBlockArraySizeContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3463 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ARRAY_SIZE);
3464 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3465 const bool namedNonArrayBlock = isInterfaceBlock &&
3466 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3467 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3469 if (!isInterfaceBlock || namedNonArrayBlock)
3473 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3474 targetGroup->addChild(blockGroup);
3476 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3477 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3482 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3483 targetGroup->addChild(blockGroup);
3485 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_ARRAY_SIZE, glu::TYPE_FLOAT, "", 3);
3491 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, queryTarget.interface, PROGRAMRESOURCEPROP_ARRAY_SIZE, glu::TYPE_FLOAT, "", 2);
3495 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)
3499 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, type));
3500 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_ARRAY_STRIDE), namePrefix.c_str()));
3503 if (expandLevel > 0)
3505 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3506 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3509 generateBufferBackedArrayStrideTypeAggregateSubCases(context, structMember, targetGroup, namePrefix + "_struct", interface, type, expandLevel - 1);
3512 generateBufferBackedArrayStrideTypeAggregateSubCases(context, arrayElement, targetGroup, namePrefix + "_array", interface, type, expandLevel - 1);
3516 static void generateBufferBackedArrayStrideTypeAggregateCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, glu::DataType type, int expandLevel, bool includeBaseCase)
3518 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3519 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3520 const std::string namePrefix = glu::getDataTypeName(type);
3522 if (expandLevel == 0 || includeBaseCase)
3524 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, type));
3525 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_ARRAY_STRIDE), namePrefix.c_str()));
3527 if (expandLevel >= 1)
3530 if (!glu::isDataTypeAtomicCounter(type))
3531 generateBufferBackedArrayStrideTypeAggregateSubCases(context, structMember, targetGroup, namePrefix + "_struct", interface, type, expandLevel - 1);
3534 generateBufferBackedArrayStrideTypeAggregateSubCases(context, arrayElement, targetGroup, namePrefix + "_array", interface, type, expandLevel - 1);
3538 static void generateUniformBlockArrayStrideContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3540 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ARRAY_STRIDE);
3541 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3542 const bool namedNonArrayBlock = isInterfaceBlock &&
3543 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3544 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3546 if (!isInterfaceBlock || namedNonArrayBlock)
3550 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3551 targetGroup->addChild(blockGroup);
3553 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3554 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3559 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3560 targetGroup->addChild(blockGroup);
3563 if (!isInterfaceBlock)
3564 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_SAMPLER_2D, 1, false);
3566 // .atomic_counter_*
3567 if (!isInterfaceBlock)
3569 const ResourceDefinition::Node::SharedPtr layout(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
3570 generateBufferBackedArrayStrideTypeAggregateCases(context, layout, blockGroup, queryTarget.interface, glu::TYPE_UINT_ATOMIC_COUNTER, 1, false);
3574 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_FLOAT, 2, false);
3577 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_BOOL, 1, false);
3580 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_BOOL_VEC3, 2, false);
3583 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_FLOAT_VEC3, 2, false);
3586 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_INT_VEC3, 2, false);
3591 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3592 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3593 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3597 static void generateUniformBlockLocationContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3599 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_LOCATION);
3600 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3602 if (!isInterfaceBlock)
3604 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 3);
3605 generateOpaqueTypeCases(context, parentStructure, targetGroup, queryTarget, 3);
3606 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 2);
3607 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 2);
3610 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1, false);
3613 static void generateUniformBlockBlockIndexContents (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion)
3615 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
3616 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
3617 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
3618 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
3619 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(uniform, glu::Layout(-1, 0)));
3623 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(uniform, glu::TYPE_FLOAT_VEC4));
3625 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "default_block"));
3630 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, true));
3631 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3633 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "named_block"));
3638 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, false));
3639 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3641 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "unnamed_block"));
3646 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding));
3647 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
3648 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3650 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "block_array"));
3654 static void generateUniformBlockAtomicCounterBufferIndexContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3656 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ATOMIC_COUNTER_BUFFER_INDEX);
3657 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3659 if (!isInterfaceBlock)
3661 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 3);
3662 generateOpaqueTypeCases(context, parentStructure, targetGroup, queryTarget, 3);
3666 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3667 const ResourceDefinition::Node::SharedPtr arrayArrayElement (new ResourceDefinition::ArrayElement(arrayElement));
3668 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3669 const ResourceDefinition::Node::SharedPtr elementvariable (new ResourceDefinition::Variable(arrayArrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3670 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3672 targetGroup->addChild(blockGroup);
3674 blockGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "var_array"));
3675 blockGroup->addChild(new ResourceTestCase(context, elementvariable, queryTarget, "var_array_array"));
3679 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1, false);
3682 static void generateUniformBlockNameLengthContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3684 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3685 const bool namedNonArrayBlock = isInterfaceBlock &&
3686 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3687 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3689 if (!isInterfaceBlock || namedNonArrayBlock)
3690 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 2);
3692 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 1);
3695 static void generateUniformBlockTypeContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3697 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_TYPE);
3698 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3699 const bool namedNonArrayBlock = isInterfaceBlock &&
3700 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3701 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3703 if (!isInterfaceBlock || namedNonArrayBlock)
3707 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3708 targetGroup->addChild(blockGroup);
3710 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3711 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3714 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3715 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3720 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3721 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3722 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3726 static void generateUniformBlockOffsetContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3728 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_OFFSET);
3729 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3730 const bool namedNonArrayBlock = isInterfaceBlock &&
3731 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3732 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3734 if (!isInterfaceBlock)
3738 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3739 targetGroup->addChild(blockGroup);
3741 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3742 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3747 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3748 targetGroup->addChild(blockGroup);
3750 // .atomic_uint_struct
3751 // .atomic_uint_array
3753 const ResourceDefinition::Node::SharedPtr offset (new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, 4)));
3754 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(offset));
3755 const ResourceDefinition::Node::SharedPtr elementVariable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3757 blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "atomic_uint_array"));
3763 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3764 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3765 const ResourceDefinition::Node::SharedPtr memberVariable (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
3766 const ResourceDefinition::Node::SharedPtr elementVariable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
3768 blockGroup->addChild(new ResourceTestCase(context, memberVariable, queryTarget, "float_struct"));
3769 blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "float_array"));
3773 else if (namedNonArrayBlock)
3777 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3778 targetGroup->addChild(blockGroup);
3780 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3781 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3786 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3787 targetGroup->addChild(blockGroup);
3792 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3793 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::StructMember(parentStructure));
3794 const ResourceDefinition::Node::SharedPtr memberVariable (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
3795 const ResourceDefinition::Node::SharedPtr elementVariable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
3797 blockGroup->addChild(new ResourceTestCase(context, memberVariable, queryTarget, "float_struct"));
3798 blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "float_array"));
3804 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3805 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3806 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3810 static void generateMatrixVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, bool createTestGroup = true, int expandLevel = 2)
3818 { 0, glu::TYPE_FLOAT_MAT2 },
3819 { 1, glu::TYPE_FLOAT_MAT2X3 },
3820 { 2, glu::TYPE_FLOAT_MAT2X4 },
3821 { 2, glu::TYPE_FLOAT_MAT3X2 },
3822 { 1, glu::TYPE_FLOAT_MAT3 },
3823 { 0, glu::TYPE_FLOAT_MAT3X4 },
3824 { 2, glu::TYPE_FLOAT_MAT4X2 },
3825 { 1, glu::TYPE_FLOAT_MAT4X3 },
3826 { 0, glu::TYPE_FLOAT_MAT4 },
3829 tcu::TestCaseGroup* group;
3831 if (createTestGroup)
3833 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "matrix", "Basic matrix type");
3834 targetGroup->addChild(blockGroup);
3838 group = targetGroup;
3840 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3842 if (variableTypes[ndx].priority < expandLevel)
3844 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
3845 group->addChild(new ResourceTestCase(context, variable, queryTarget));
3850 static void generateMatrixStructCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel);
3852 static void generateMatrixArrayCases (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 arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3857 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3859 targetGroup->addChild(blockGroup);
3861 // Arrays of basic variables
3862 generateMatrixVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel != 1, expandLevel);
3865 generateMatrixArrayCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3867 // Arrays of structs
3868 generateMatrixStructCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3872 static void generateMatrixStructCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
3874 if (expandLevel > 0)
3876 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3877 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "struct", "Structs");
3879 targetGroup->addChild(blockGroup);
3881 // Struct containing basic variable
3882 generateMatrixVariableCases(context, structMember, blockGroup, queryTarget, expandLevel != 1, expandLevel);
3884 // Struct containing arrays
3885 generateMatrixArrayCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3887 // Struct containing struct
3888 generateMatrixStructCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3892 static void generateUniformMatrixOrderCaseBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, bool extendedBasicTypeCases, bool opaqueCases)
3897 glu::MatrixOrder order;
3900 { "no_qualifier", glu::MATRIXORDER_LAST },
3901 { "row_major", glu::MATRIXORDER_ROW_MAJOR },
3902 { "column_major", glu::MATRIXORDER_COLUMN_MAJOR },
3905 const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR);
3907 for (int qualifierNdx = 0; qualifierNdx < DE_LENGTH_OF_ARRAY(qualifiers); ++qualifierNdx)
3909 // Add layout qualifiers only for block members
3910 if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST || parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3912 ResourceDefinition::Node::SharedPtr subStructure = parentStructure;
3913 tcu::TestCaseGroup* const qualifierGroup = new tcu::TestCaseGroup(context.getTestContext(), qualifiers[qualifierNdx].name, "");
3915 targetGroup->addChild(qualifierGroup);
3917 if (qualifiers[qualifierNdx].order != glu::MATRIXORDER_LAST)
3920 layout.matrixOrder = qualifiers[qualifierNdx].order;
3921 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
3924 if (extendedBasicTypeCases && qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST)
3928 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "");
3929 qualifierGroup->addChild(blockGroup);
3931 generateVariableCases(context, subStructure, blockGroup, queryTarget, 1, false);
3932 generateMatrixVariableCases(context, subStructure, blockGroup, queryTarget, false);
3934 generateOpaqueTypeCases(context, subStructure, blockGroup, queryTarget, 2, false);
3939 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "");
3940 qualifierGroup->addChild(blockGroup);
3942 generateBufferBackedVariableAggregateTypeCases(context, subStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
3947 generateBufferBackedVariableAggregateTypeCases(context, subStructure, qualifierGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
3953 static void generateUniformMatrixStrideCaseBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, bool extendedBasicTypeCases, bool opaqueCases)
3958 glu::MatrixOrder order;
3961 { "no_qualifier", glu::MATRIXORDER_LAST },
3962 { "row_major", glu::MATRIXORDER_ROW_MAJOR },
3963 { "column_major", glu::MATRIXORDER_COLUMN_MAJOR },
3966 const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_MATRIX_STRIDE);
3968 for (int qualifierNdx = 0; qualifierNdx < DE_LENGTH_OF_ARRAY(qualifiers); ++qualifierNdx)
3970 // Add layout qualifiers only for block members
3971 if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST || parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3973 ResourceDefinition::Node::SharedPtr subStructure = parentStructure;
3974 tcu::TestCaseGroup* const qualifierGroup = new tcu::TestCaseGroup(context.getTestContext(), qualifiers[qualifierNdx].name, "");
3976 targetGroup->addChild(qualifierGroup);
3978 if (qualifiers[qualifierNdx].order != glu::MATRIXORDER_LAST)
3981 layout.matrixOrder = qualifiers[qualifierNdx].order;
3982 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
3985 if (extendedBasicTypeCases)
3989 if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST)
3991 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "");
3992 qualifierGroup->addChild(blockGroup);
3994 generateVariableCases(context, subStructure, blockGroup, queryTarget, 1, false);
3995 generateMatrixVariableCases(context, subStructure, blockGroup, queryTarget, false);
3997 generateOpaqueTypeCases(context, subStructure, blockGroup, queryTarget, 2, false);
4000 generateMatrixVariableCases(context, subStructure, qualifierGroup, queryTarget);
4004 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "");
4005 qualifierGroup->addChild(blockGroup);
4007 generateBufferBackedVariableAggregateTypeCases(context, subStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
4011 generateBufferBackedVariableAggregateTypeCases(context, subStructure, qualifierGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
4016 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))
4021 const char* description;
4024 bool extendedBasicTypeCases;
4025 glu::MatrixOrder order;
4028 { "default_block", "Default block", false, true, true, glu::MATRIXORDER_LAST },
4029 { "named_block", "Named uniform block", true, true, true, glu::MATRIXORDER_LAST },
4030 { "named_block_row_major", "Named uniform block", true, true, false, glu::MATRIXORDER_ROW_MAJOR },
4031 { "named_block_col_major", "Named uniform block", true, true, false, glu::MATRIXORDER_COLUMN_MAJOR },
4032 { "unnamed_block", "Unnamed uniform block", true, false, false, glu::MATRIXORDER_LAST },
4033 { "unnamed_block_row_major", "Unnamed uniform block", true, false, false, glu::MATRIXORDER_ROW_MAJOR },
4034 { "unnamed_block_col_major", "Unnamed uniform block", true, false, false, glu::MATRIXORDER_COLUMN_MAJOR },
4037 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
4038 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4040 for (int childNdx = 0; childNdx < (int)DE_LENGTH_OF_ARRAY(children); ++childNdx)
4042 ResourceDefinition::Node::SharedPtr subStructure = uniform;
4043 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), children[childNdx].name, children[childNdx].description);
4044 const bool addOpaqueCases = children[childNdx].extendedBasicTypeCases && !children[childNdx].block;
4046 targetGroup->addChild(blockGroup);
4048 if (children[childNdx].order != glu::MATRIXORDER_LAST)
4051 layout.matrixOrder = children[childNdx].order;
4052 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
4055 if (children[childNdx].block)
4056 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(subStructure, children[childNdx].namedBlock));
4058 blockContentGenerator(context, subStructure, blockGroup, children[childNdx].extendedBasicTypeCases, addOpaqueCases);
4062 static void generateBufferReferencedByShaderInterfaceBlockCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, bool extendedCases)
4064 const bool isDefaultBlock = (parentStructure->getType() != ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
4070 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(parentStructure, glu::TYPE_FLOAT));
4071 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
4072 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4073 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4074 const ResourceDefinition::Node::SharedPtr variableStruct (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
4076 targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "float"));
4077 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_array"));
4078 targetGroup->addChild(new ResourceTestCase(context, variableStruct, queryTarget, "float_struct"));
4086 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
4087 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_SAMPLER_2D));
4088 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(layout));
4089 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4090 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_SAMPLER_2D));
4091 const ResourceDefinition::Node::SharedPtr variableStruct (new ResourceDefinition::Variable(structMember, glu::TYPE_SAMPLER_2D));
4093 targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "sampler"));
4094 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "sampler_array"));
4095 targetGroup->addChild(new ResourceTestCase(context, variableStruct, queryTarget, "sampler_struct"));
4099 // .atomic_uint_array
4102 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
4103 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_UINT_ATOMIC_COUNTER));
4104 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(layout));
4105 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
4107 targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "atomic_uint"));
4108 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "atomic_uint_array"));
4113 // .float_array_struct
4115 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4116 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(structMember));
4117 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4119 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_array_struct"));
4122 // .float_struct_array
4124 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
4125 const ResourceDefinition::Node::SharedPtr arrayStructMember (new ResourceDefinition::StructMember(arrayElement));
4126 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(arrayStructMember, glu::TYPE_FLOAT));
4128 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_struct_array"));
4131 // .float_array_array
4133 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
4134 const ResourceDefinition::Node::SharedPtr subArrayElement (new ResourceDefinition::ArrayElement(arrayElement));
4135 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(subArrayElement, glu::TYPE_FLOAT));
4137 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_array_array"));
4140 // .float_struct_struct
4142 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4143 const ResourceDefinition::Node::SharedPtr subStructMember (new ResourceDefinition::StructMember(structMember));
4144 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(subStructMember, glu::TYPE_FLOAT));
4146 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_struct_struct"));
4149 if (queryTarget.interface == PROGRAMINTERFACE_BUFFER_VARIABLE)
4151 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
4153 // .float_unsized_array
4155 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4157 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_unsized_array"));
4160 // .float_unsized_struct_array
4162 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(arrayElement));
4163 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
4165 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_unsized_struct_array"));
4171 static void generateUniformReferencedByShaderSingleBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, int expandLevel)
4173 DE_UNREF(expandLevel);
4175 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
4176 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4177 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER);
4178 const bool singleShaderCase = parentStructure->getType() == ResourceDefinition::Node::TYPE_SHADER;
4182 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "default_block", "");
4183 targetGroup->addChild(blockGroup);
4185 generateBufferReferencedByShaderInterfaceBlockCases(context, uniform, blockGroup, queryTarget, singleShaderCase);
4190 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(uniform, true));
4191 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "uniform_block", "");
4193 targetGroup->addChild(blockGroup);
4195 generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, singleShaderCase);
4200 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(uniform, false));
4201 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "");
4203 targetGroup->addChild(blockGroup);
4205 generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, false);
4210 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(uniform));
4211 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4212 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "");
4214 targetGroup->addChild(blockGroup);
4216 generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, false);
4220 static void generateReferencedByShaderCaseBlocks (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion, void (*generateBlockContent)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, int expandLevel))
4225 glu::ShaderType stage;
4227 } singleStageCases[] =
4229 { "compute", glu::SHADERTYPE_COMPUTE, 3 },
4230 { "separable_vertex", glu::SHADERTYPE_VERTEX, 2 },
4231 { "separable_fragment", glu::SHADERTYPE_FRAGMENT, 2 },
4232 { "separable_tess_ctrl", glu::SHADERTYPE_TESSELLATION_CONTROL, 2 },
4233 { "separable_tess_eval", glu::SHADERTYPE_TESSELLATION_EVALUATION, 2 },
4234 { "separable_geometry", glu::SHADERTYPE_GEOMETRY, 2 },
4246 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT),
4251 "vertex_tess_fragment",
4252 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
4257 "vertex_geo_fragment",
4258 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY),
4263 "vertex_tess_geo_fragment",
4264 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
4270 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
4272 TestCaseGroup* const blockGroup = new TestCaseGroup(context, singleStageCases[ndx].name, "");
4273 const bool programSeparable = (singleStageCases[ndx].stage != glu::SHADERTYPE_COMPUTE);
4274 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(programSeparable));
4275 const ResourceDefinition::Node::SharedPtr stage (new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glslVersion));
4277 targetGroup->addChild(blockGroup);
4279 generateBlockContent(context, stage, blockGroup, singleStageCases[ndx].expandLevel);
4282 for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
4286 TestCaseGroup* const blockGroup = new TestCaseGroup(context, pipelines[pipelineNdx].name, "");
4287 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4288 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program,
4290 pipelines[pipelineNdx].flags,
4291 pipelines[pipelineNdx].flags);
4292 targetGroup->addChild(blockGroup);
4295 const ResourceDefinition::Node::SharedPtr shaders(shaderSet);
4296 generateBlockContent(context, shaders, blockGroup, pipelines[pipelineNdx].expandLevel);
4301 for (int selectedStageBit = 0; selectedStageBit < glu::SHADERTYPE_LAST; ++selectedStageBit)
4303 if (pipelines[pipelineNdx].flags & (1 << selectedStageBit))
4305 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4306 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program,
4308 pipelines[pipelineNdx].flags,
4309 (1u << selectedStageBit));
4310 const char* stageName = (selectedStageBit == glu::SHADERTYPE_VERTEX) ? ("vertex")
4311 : (selectedStageBit == glu::SHADERTYPE_FRAGMENT) ? ("fragment")
4312 : (selectedStageBit == glu::SHADERTYPE_GEOMETRY) ? ("geo")
4313 : (selectedStageBit == glu::SHADERTYPE_TESSELLATION_CONTROL) ? ("tess_ctrl")
4314 : (selectedStageBit == glu::SHADERTYPE_TESSELLATION_EVALUATION) ? ("tess_eval")
4316 const std::string setName = std::string() + pipelines[pipelineNdx].name + "_only_" + stageName;
4317 TestCaseGroup* const blockGroup = new TestCaseGroup(context, setName.c_str(), "");
4318 const ResourceDefinition::Node::SharedPtr shaders (shaderSet);
4320 generateBlockContent(context, shaders, blockGroup, pipelines[pipelineNdx].subExpandLevel);
4321 targetGroup->addChild(blockGroup);
4327 static glu::DataType generateRandomDataType (de::Random& rnd, bool excludeOpaqueTypes)
4329 static const glu::DataType s_types[] =
4335 glu::TYPE_FLOAT_VEC2,
4336 glu::TYPE_FLOAT_VEC3,
4337 glu::TYPE_FLOAT_VEC4,
4341 glu::TYPE_UINT_VEC2,
4342 glu::TYPE_UINT_VEC3,
4343 glu::TYPE_UINT_VEC4,
4344 glu::TYPE_BOOL_VEC2,
4345 glu::TYPE_BOOL_VEC3,
4346 glu::TYPE_BOOL_VEC4,
4347 glu::TYPE_FLOAT_MAT2,
4348 glu::TYPE_FLOAT_MAT2X3,
4349 glu::TYPE_FLOAT_MAT2X4,
4350 glu::TYPE_FLOAT_MAT3X2,
4351 glu::TYPE_FLOAT_MAT3,
4352 glu::TYPE_FLOAT_MAT3X4,
4353 glu::TYPE_FLOAT_MAT4X2,
4354 glu::TYPE_FLOAT_MAT4X3,
4355 glu::TYPE_FLOAT_MAT4,
4357 glu::TYPE_SAMPLER_2D,
4358 glu::TYPE_SAMPLER_CUBE,
4359 glu::TYPE_SAMPLER_2D_ARRAY,
4360 glu::TYPE_SAMPLER_3D,
4361 glu::TYPE_SAMPLER_2D_SHADOW,
4362 glu::TYPE_SAMPLER_CUBE_SHADOW,
4363 glu::TYPE_SAMPLER_2D_ARRAY_SHADOW,
4364 glu::TYPE_INT_SAMPLER_2D,
4365 glu::TYPE_INT_SAMPLER_CUBE,
4366 glu::TYPE_INT_SAMPLER_2D_ARRAY,
4367 glu::TYPE_INT_SAMPLER_3D,
4368 glu::TYPE_UINT_SAMPLER_2D,
4369 glu::TYPE_UINT_SAMPLER_CUBE,
4370 glu::TYPE_UINT_SAMPLER_2D_ARRAY,
4371 glu::TYPE_UINT_SAMPLER_3D,
4372 glu::TYPE_SAMPLER_2D_MULTISAMPLE,
4373 glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE,
4374 glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE,
4376 glu::TYPE_IMAGE_CUBE,
4377 glu::TYPE_IMAGE_2D_ARRAY,
4379 glu::TYPE_INT_IMAGE_2D,
4380 glu::TYPE_INT_IMAGE_CUBE,
4381 glu::TYPE_INT_IMAGE_2D_ARRAY,
4382 glu::TYPE_INT_IMAGE_3D,
4383 glu::TYPE_UINT_IMAGE_2D,
4384 glu::TYPE_UINT_IMAGE_CUBE,
4385 glu::TYPE_UINT_IMAGE_2D_ARRAY,
4386 glu::TYPE_UINT_IMAGE_3D,
4387 glu::TYPE_UINT_ATOMIC_COUNTER
4392 const glu::DataType type = s_types[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_types)-1)];
4394 if (!excludeOpaqueTypes ||
4395 glu::isDataTypeScalarOrVector(type) ||
4396 glu::isDataTypeMatrix(type))
4401 static ResourceDefinition::Node::SharedPtr generateRandomVariableDefinition (de::Random& rnd,
4402 const ResourceDefinition::Node::SharedPtr& parentStructure,
4403 glu::DataType baseType,
4404 const glu::Layout& layout,
4407 const int maxNesting = 4;
4408 ResourceDefinition::Node::SharedPtr currentStructure = parentStructure;
4409 const bool canBeInsideAStruct = layout.binding == -1 && !isDataTypeLayoutQualified(baseType);
4411 for (int nestNdx = 0; nestNdx < maxNesting; ++nestNdx)
4413 if (allowUnsized && nestNdx == 0 && rnd.getFloat() < 0.2)
4414 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
4415 else if (rnd.getFloat() < 0.3 && canBeInsideAStruct)
4416 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StructMember(currentStructure));
4417 else if (rnd.getFloat() < 0.3)
4418 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
4423 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Variable(currentStructure, baseType));
4426 static ResourceDefinition::Node::SharedPtr generateRandomCoreShaderSet (de::Random& rnd, glu::GLSLVersion glslVersion)
4428 if (rnd.getFloat() < 0.5f)
4431 const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
4432 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
4434 else if (rnd.getFloat() < 0.5f)
4436 // vertex and fragment
4437 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4438 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program, glslVersion);
4442 shaderSet->setStage(glu::SHADERTYPE_VERTEX, true);
4443 shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, rnd.getBool());
4447 shaderSet->setStage(glu::SHADERTYPE_VERTEX, rnd.getBool());
4448 shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, true);
4451 return ResourceDefinition::Node::SharedPtr(shaderSet);
4455 // separate vertex or fragment
4456 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
4457 const glu::ShaderType shaderType = (rnd.getBool()) ? (glu::SHADERTYPE_VERTEX) : (glu::SHADERTYPE_FRAGMENT);
4459 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, shaderType, glslVersion));
4463 static ResourceDefinition::Node::SharedPtr generateRandomExtShaderSet (de::Random& rnd, glu::GLSLVersion glslVersion)
4465 if (rnd.getFloat() < 0.5f)
4468 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4469 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program, glslVersion);
4471 shaderSet->setStage(glu::SHADERTYPE_VERTEX, rnd.getBool());
4472 shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, rnd.getBool());
4474 // tess shader are either both or neither present. Make cases interesting
4475 // by forcing one extended shader to always have reference
4478 shaderSet->setStage(glu::SHADERTYPE_GEOMETRY, true);
4482 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, rnd.getBool());
4483 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, rnd.getBool());
4488 shaderSet->setStage(glu::SHADERTYPE_GEOMETRY, rnd.getBool());
4492 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, true);
4493 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, rnd.getBool());
4497 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, rnd.getBool());
4498 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, true);
4502 return ResourceDefinition::Node::SharedPtr(shaderSet);
4507 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
4508 const int selector = rnd.getInt(0, 2);
4509 const glu::ShaderType shaderType = (selector == 0) ? (glu::SHADERTYPE_GEOMETRY)
4510 : (selector == 1) ? (glu::SHADERTYPE_TESSELLATION_CONTROL)
4511 : (selector == 2) ? (glu::SHADERTYPE_TESSELLATION_EVALUATION)
4512 : (glu::SHADERTYPE_LAST);
4514 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, shaderType, glslVersion));
4518 static ResourceDefinition::Node::SharedPtr generateRandomShaderSet (de::Random& rnd, glu::GLSLVersion glslVersion, bool onlyExtensionStages)
4520 if (!onlyExtensionStages)
4521 return generateRandomCoreShaderSet(rnd, glslVersion);
4523 return generateRandomExtShaderSet(rnd, glslVersion);
4526 static glu::Layout generateRandomUniformBlockLayout (de::Random& rnd)
4531 layout.binding = rnd.getInt(0, 5);
4534 layout.matrixOrder = (rnd.getBool()) ? (glu::MATRIXORDER_COLUMN_MAJOR) : (glu::MATRIXORDER_ROW_MAJOR);
4539 static glu::Layout generateRandomBufferBlockLayout (de::Random& rnd)
4541 return generateRandomUniformBlockLayout(rnd);
4544 static glu::Layout generateRandomVariableLayout (de::Random& rnd, glu::DataType type, bool interfaceBlockMember)
4548 if ((glu::isDataTypeAtomicCounter(type) || glu::isDataTypeImage(type) || glu::isDataTypeSampler(type)) && rnd.getBool())
4549 layout.binding = rnd.getInt(0, 5);
4551 if (glu::isDataTypeAtomicCounter(type) && rnd.getBool())
4552 layout.offset = rnd.getInt(0, 3) * 4;
4554 if (glu::isDataTypeMatrix(type) && interfaceBlockMember && rnd.getBool())
4555 layout.matrixOrder = (rnd.getBool()) ? (glu::MATRIXORDER_COLUMN_MAJOR) : (glu::MATRIXORDER_ROW_MAJOR);
4560 static void generateUniformRandomCase (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion, int index, bool onlyExtensionStages)
4562 de::Random rnd (index * 0x12345);
4563 const ResourceDefinition::Node::SharedPtr shader = generateRandomShaderSet(rnd, glslVersion, onlyExtensionStages);
4564 const bool interfaceBlock = rnd.getBool();
4565 const glu::DataType type = generateRandomDataType(rnd, interfaceBlock);
4566 const glu::Layout layout = generateRandomVariableLayout(rnd, type, interfaceBlock);
4567 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
4568 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4569 ResourceDefinition::Node::SharedPtr currentStructure = uniform;
4573 const bool namedBlock = rnd.getBool();
4575 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, generateRandomUniformBlockLayout(rnd)));
4577 if (namedBlock && rnd.getBool())
4578 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
4580 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(currentStructure, namedBlock));
4583 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, layout));
4584 currentStructure = generateRandomVariableDefinition(rnd, currentStructure, type, layout, false);
4586 targetGroup->addChild(new ResourceTestCase(context, currentStructure, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_UNIFORM_INTERFACE_MASK), de::toString(index).c_str()));
4589 static void generateUniformCaseRandomCases (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion)
4591 const int numBasicCases = 40;
4592 const int numTessGeoCases = 40;
4594 for (int ndx = 0; ndx < numBasicCases; ++ndx)
4595 generateUniformRandomCase(context, targetGroup, glslVersion, ndx, false);
4596 for (int ndx = 0; ndx < numTessGeoCases; ++ndx)
4597 generateUniformRandomCase(context, targetGroup, glslVersion, numBasicCases + ndx, true);
4600 class UniformInterfaceTestGroup : public TestCaseGroup
4603 UniformInterfaceTestGroup (Context& context);
4607 UniformInterfaceTestGroup::UniformInterfaceTestGroup (Context& context)
4608 : TestCaseGroup(context, "uniform", "Uniform interace")
4612 void UniformInterfaceTestGroup::init (void)
4614 glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
4615 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4616 const ResourceDefinition::Node::SharedPtr computeShader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
4620 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
4621 addChild(blockGroup);
4622 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformResourceListBlockContents);
4627 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Query array size");
4628 addChild(blockGroup);
4629 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockArraySizeContents);
4634 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_stride", "Query array stride");
4635 addChild(blockGroup);
4636 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockArrayStrideContents);
4639 // .atomic_counter_buffer_index
4641 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "atomic_counter_buffer_index", "Query atomic counter buffer index");
4642 addChild(blockGroup);
4643 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_DEFAULT | BLOCKFLAG_NAMED, generateUniformBlockAtomicCounterBufferIndexContents);
4648 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "block_index", "Query block index");
4649 addChild(blockGroup);
4650 generateUniformBlockBlockIndexContents(m_context, blockGroup, glslVersion);
4655 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Query location");
4656 addChild(blockGroup);
4657 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_DEFAULT | BLOCKFLAG_NAMED | BLOCKFLAG_UNNAMED, generateUniformBlockLocationContents);
4660 // .matrix_row_major
4662 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "matrix_row_major", "Query matrix row_major");
4663 addChild(blockGroup);
4664 generateUniformMatrixCaseBlocks(m_context, computeShader, blockGroup, generateUniformMatrixOrderCaseBlockContentCases);
4669 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "matrix_stride", "Query matrix stride");
4670 addChild(blockGroup);
4671 generateUniformMatrixCaseBlocks(m_context, computeShader, blockGroup, generateUniformMatrixStrideCaseBlockContentCases);
4676 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Query name length");
4677 addChild(blockGroup);
4678 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockNameLengthContents);
4683 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "offset", "Query offset");
4684 addChild(blockGroup);
4685 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockOffsetContents);
4688 // .referenced_by_shader
4690 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by_shader", "Query referenced by shader");
4691 addChild(blockGroup);
4692 generateReferencedByShaderCaseBlocks(m_context, blockGroup, glslVersion, generateUniformReferencedByShaderSingleBlockContentCases);
4697 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Query type");
4698 addChild(blockGroup);
4699 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockTypeContents);
4704 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random");
4705 addChild(blockGroup);
4706 generateUniformCaseRandomCases(m_context, blockGroup, glslVersion);
4710 static void generateBufferBackedInterfaceResourceListCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, const char* blockName)
4712 targetGroup->addChild(new ResourceListTestCase(context, targetResource, interface, blockName));
4715 static void generateBufferBackedInterfaceNameLengthCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, const char* blockName)
4717 targetGroup->addChild(new ResourceTestCase(context, targetResource, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_NAME_LENGTH), blockName));
4720 static void generateBufferBackedInterfaceResourceBasicBlockTypes (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion, glu::Storage storage, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup* const, ProgramInterface interface, const char* blockName))
4722 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4723 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
4724 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
4725 const ResourceDefinition::Node::SharedPtr storageQualifier (new ResourceDefinition::StorageQualifier(defaultBlock, storage));
4726 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(storageQualifier, glu::Layout(-1, 1)));
4727 const ProgramInterface programInterface = (storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) : (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK);
4731 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, true));
4732 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4734 blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "named_block");
4739 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, false));
4740 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4742 blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "unnamed_block");
4747 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding, 3));
4748 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4749 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4751 blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "block_array");
4754 // .block_array_single_element
4756 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding, 1));
4757 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4758 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4760 blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "block_array_single_element");
4764 static void generateBufferBackedInterfaceResourceBufferBindingCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion, glu::Storage storage)
4766 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4767 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
4768 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
4769 const ResourceDefinition::Node::SharedPtr storageQualifier (new ResourceDefinition::StorageQualifier(defaultBlock, storage));
4771 for (int ndx = 0; ndx < 2; ++ndx)
4773 const bool explicitBinding = (ndx == 1);
4774 const int bindingNdx = (explicitBinding) ? (1) : (-1);
4775 const std::string nameSuffix = (explicitBinding) ? ("_explicit_binding") : ("");
4776 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(storageQualifier, glu::Layout(-1, bindingNdx)));
4777 const ProgramInterface programInterface = (storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) : (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK);
4781 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, true));
4782 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4784 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("named_block" + nameSuffix).c_str()));
4789 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, false));
4790 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4792 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("unnamed_block" + nameSuffix).c_str()));
4797 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding, 3));
4798 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4799 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4801 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("block_array" + nameSuffix).c_str()));
4806 template <glu::Storage Storage>
4807 static void generateBufferBlockReferencedByShaderSingleBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
4809 const ProgramInterface programInterface = (Storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
4810 (Storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
4811 (PROGRAMINTERFACE_LAST);
4812 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
4813 const ResourceDefinition::Node::SharedPtr storage (new ResourceDefinition::StorageQualifier(defaultBlock, Storage));
4815 DE_UNREF(expandLevel);
4817 DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
4821 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, true));
4822 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4824 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "named_block"));
4829 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, false));
4830 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4832 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "unnamed_block"));
4837 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(storage, 3));
4838 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4839 const ResourceDefinition::Node::SharedPtr dummyVariable (new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4841 targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "block_array"));
4845 static void generateBufferBackedInterfaceResourceActiveVariablesCase (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
4847 targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "named_block", "Named block", storage, InterfaceBlockActiveVariablesTestCase::CASE_NAMED_BLOCK));
4848 targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "unnamed_block", "Unnamed block", storage, InterfaceBlockActiveVariablesTestCase::CASE_UNNAMED_BLOCK));
4849 targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "block_array", "Block array", storage, InterfaceBlockActiveVariablesTestCase::CASE_BLOCK_ARRAY));
4852 static void generateBufferBackedInterfaceResourceBufferDataSizeCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
4854 targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "named_block", "Named block", storage, InterfaceBlockDataSizeTestCase::CASE_NAMED_BLOCK));
4855 targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "unnamed_block", "Unnamed block", storage, InterfaceBlockDataSizeTestCase::CASE_UNNAMED_BLOCK));
4856 targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "block_array", "Block array", storage, InterfaceBlockDataSizeTestCase::CASE_BLOCK_ARRAY));
4859 class BufferBackedBlockInterfaceTestGroup : public TestCaseGroup
4862 BufferBackedBlockInterfaceTestGroup (Context& context, glu::Storage interfaceBlockStorage);
4866 static const char* getGroupName (glu::Storage storage);
4867 static const char* getGroupDescription (glu::Storage storage);
4869 const glu::Storage m_storage;
4872 BufferBackedBlockInterfaceTestGroup::BufferBackedBlockInterfaceTestGroup(Context& context, glu::Storage storage)
4873 : TestCaseGroup (context, getGroupName(storage), getGroupDescription(storage))
4874 , m_storage (storage)
4876 DE_ASSERT(storage == glu::STORAGE_BUFFER || storage == glu::STORAGE_UNIFORM);
4879 void BufferBackedBlockInterfaceTestGroup::init (void)
4881 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
4885 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
4886 addChild(blockGroup);
4887 generateBufferBackedInterfaceResourceBasicBlockTypes(m_context, blockGroup, glslVersion, m_storage, generateBufferBackedInterfaceResourceListCase);
4890 // .active_variables
4892 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "active_variables", "Active variables");
4893 addChild(blockGroup);
4894 generateBufferBackedInterfaceResourceActiveVariablesCase(m_context, blockGroup, m_storage);
4899 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "buffer_binding", "Buffer binding");
4900 addChild(blockGroup);
4901 generateBufferBackedInterfaceResourceBufferBindingCases(m_context, blockGroup, glslVersion, m_storage);
4904 // .buffer_data_size
4906 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "buffer_data_size", "Buffer data size");
4907 addChild(blockGroup);
4908 generateBufferBackedInterfaceResourceBufferDataSizeCases(m_context, blockGroup, m_storage);
4913 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
4914 addChild(blockGroup);
4915 generateBufferBackedInterfaceResourceBasicBlockTypes(m_context, blockGroup, glslVersion, m_storage, generateBufferBackedInterfaceNameLengthCase);
4920 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Referenced by shader");
4921 addChild(blockGroup);
4923 if (m_storage == glu::STORAGE_UNIFORM)
4924 generateReferencedByShaderCaseBlocks(m_context, blockGroup, glslVersion, generateBufferBlockReferencedByShaderSingleBlockContentCases<glu::STORAGE_UNIFORM>);
4925 else if (m_storage == glu::STORAGE_BUFFER)
4926 generateReferencedByShaderCaseBlocks(m_context, blockGroup, glslVersion, generateBufferBlockReferencedByShaderSingleBlockContentCases<glu::STORAGE_BUFFER>);
4932 const char* BufferBackedBlockInterfaceTestGroup::getGroupName (glu::Storage storage)
4936 case glu::STORAGE_UNIFORM: return "uniform_block";
4937 case glu::STORAGE_BUFFER: return "shader_storage_block";
4939 DE_FATAL("invalid storage enum value");
4944 const char* BufferBackedBlockInterfaceTestGroup::getGroupDescription (glu::Storage storage)
4948 case glu::STORAGE_UNIFORM: return "Uniform block interface";
4949 case glu::STORAGE_BUFFER: return "Shader storage block interface";
4951 DE_FATAL("invalid storage enum value");
4956 class AtomicCounterTestGroup : public TestCaseGroup
4959 AtomicCounterTestGroup (Context& context);
4963 AtomicCounterTestGroup::AtomicCounterTestGroup (Context& context)
4964 : TestCaseGroup(context, "atomic_counter_buffer", "Atomic counter buffer")
4968 void AtomicCounterTestGroup::init (void)
4978 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT)
4981 "vertex_tess_fragment",
4982 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION)
4985 "vertex_geo_fragment",
4986 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY)
4989 "vertex_tess_geo_fragment",
4990 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
4995 addChild(new AtomicCounterResourceListCase(m_context, "resource_list", "Resource list"));
4997 // .active_variables
4998 addChild(new AtomicCounterActiveVariablesCase(m_context, "active_variables", "Active variables"));
5001 addChild(new AtomicCounterBufferBindingCase(m_context, "buffer_binding", "Buffer binding"));
5003 // .buffer_data_size
5004 addChild(new AtomicCounterBufferDataSizeCase(m_context, "buffer_data_size", "Buffer binding"));
5007 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_compute", "", false, (1 << glu::SHADERTYPE_COMPUTE), (1 << glu::SHADERTYPE_COMPUTE)));
5008 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_vertex", "", true, (1 << glu::SHADERTYPE_VERTEX), (1 << glu::SHADERTYPE_VERTEX)));
5009 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_fragment", "", true, (1 << glu::SHADERTYPE_FRAGMENT), (1 << glu::SHADERTYPE_FRAGMENT)));
5010 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_geometry", "", true, (1 << glu::SHADERTYPE_GEOMETRY), (1 << glu::SHADERTYPE_GEOMETRY)));
5011 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_tess_ctrl", "", true, (1 << glu::SHADERTYPE_TESSELLATION_CONTROL), (1 << glu::SHADERTYPE_TESSELLATION_CONTROL)));
5012 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_tess_eval", "", true, (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION), (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION)));
5014 for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
5016 addChild(new AtomicCounterReferencedByCase(m_context, (std::string() + "referenced_by_" + pipelines[pipelineNdx].name).c_str(), "", false, pipelines[pipelineNdx].flags, pipelines[pipelineNdx].flags));
5018 for (deUint32 stageNdx = 0; stageNdx < glu::SHADERTYPE_LAST; ++stageNdx)
5020 const deUint32 currentBit = (1u << stageNdx);
5021 if (currentBit > pipelines[pipelineNdx].flags)
5023 if (currentBit & pipelines[pipelineNdx].flags)
5025 const char* stageName = (stageNdx == glu::SHADERTYPE_VERTEX) ? ("vertex")
5026 : (stageNdx == glu::SHADERTYPE_FRAGMENT) ? ("fragment")
5027 : (stageNdx == glu::SHADERTYPE_GEOMETRY) ? ("geo")
5028 : (stageNdx == glu::SHADERTYPE_TESSELLATION_CONTROL) ? ("tess_ctrl")
5029 : (stageNdx == glu::SHADERTYPE_TESSELLATION_EVALUATION) ? ("tess_eval")
5031 const std::string name = std::string() + "referenced_by_" + pipelines[pipelineNdx].name + "_only_" + stageName;
5033 addChild(new AtomicCounterReferencedByCase(m_context, name.c_str(), "", false, pipelines[pipelineNdx].flags, currentBit));
5039 static void generateProgramInputOutputShaderCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion, bool withCompute, bool inputCase, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, deUint32))
5044 glu::ShaderType stage;
5045 } singleStageCases[] =
5047 { "separable_vertex", glu::SHADERTYPE_VERTEX },
5048 { "separable_fragment", glu::SHADERTYPE_FRAGMENT },
5049 { "separable_tess_ctrl", glu::SHADERTYPE_TESSELLATION_CONTROL },
5050 { "separable_tess_eval", glu::SHADERTYPE_TESSELLATION_EVALUATION },
5051 { "separable_geometry", glu::SHADERTYPE_GEOMETRY },
5056 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "vertex_fragment", "Vertex and fragment");
5057 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(false));
5058 ResourceDefinition::ShaderSet* shaderSetPtr = new ResourceDefinition::ShaderSet(program, glslVersion);
5059 const ResourceDefinition::Node::SharedPtr shaderSet (shaderSetPtr);
5060 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shaderSet));
5062 shaderSetPtr->setStage(glu::SHADERTYPE_VERTEX, inputCase);
5063 shaderSetPtr->setStage(glu::SHADERTYPE_FRAGMENT, !inputCase);
5065 targetGroup->addChild(blockGroup);
5067 blockContentGenerator(context, defaultBlock, blockGroup, (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT));
5071 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
5073 TestCaseGroup* const blockGroup = new TestCaseGroup(context, singleStageCases[ndx].name, "");
5074 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
5075 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glslVersion));
5076 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
5078 targetGroup->addChild(blockGroup);
5079 blockContentGenerator(context, defaultBlock, blockGroup, (1 << singleStageCases[ndx].stage));
5085 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "compute", "Compute");
5086 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
5087 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
5088 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
5090 targetGroup->addChild(blockGroup);
5092 blockContentGenerator(context, defaultBlock, blockGroup, (1 << glu::SHADERTYPE_COMPUTE));
5095 // .interface_blocks
5099 const char* inputName;
5100 glu::ShaderType inputStage;
5101 glu::Storage inputStorage;
5102 const char* outputName;
5103 glu::ShaderType outputStage;
5104 glu::Storage outputStorage;
5109 glu::SHADERTYPE_FRAGMENT,
5112 glu::SHADERTYPE_VERTEX,
5117 glu::SHADERTYPE_TESSELLATION_EVALUATION,
5118 glu::STORAGE_PATCH_IN,
5120 glu::SHADERTYPE_TESSELLATION_CONTROL,
5121 glu::STORAGE_PATCH_OUT,
5125 tcu::TestCaseGroup* const ioBlocksGroup = new TestCaseGroup(context, "interface_blocks", "Interface blocks");
5126 targetGroup->addChild(ioBlocksGroup);
5131 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(ioBlockTypes); ++ndx)
5133 const char* const name = (inputCase) ? (ioBlockTypes[ndx].inputName) : (ioBlockTypes[ndx].outputName);
5134 const glu::ShaderType shaderType = (inputCase) ? (ioBlockTypes[ndx].inputStage) : (ioBlockTypes[ndx].outputStage);
5135 const glu::Storage storageType = (inputCase) ? (ioBlockTypes[ndx].inputStorage) : (ioBlockTypes[ndx].outputStorage);
5136 tcu::TestCaseGroup* const ioBlockGroup = new TestCaseGroup(context, name, "");
5137 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
5138 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, shaderType, glslVersion));
5139 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
5140 const ResourceDefinition::Node::SharedPtr storage (new ResourceDefinition::StorageQualifier(defaultBlock, storageType));
5142 ioBlocksGroup->addChild(ioBlockGroup);
5146 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, true));
5147 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block", "Named block");
5149 ioBlockGroup->addChild(blockGroup);
5151 blockContentGenerator(context, block, blockGroup, (1 << shaderType));
5154 // .named_block_explicit_location
5156 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(storage, glu::Layout(3)));
5157 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(layout, true));
5158 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block_explicit_location", "Named block with explicit location");
5160 ioBlockGroup->addChild(blockGroup);
5162 blockContentGenerator(context, block, blockGroup, (1 << shaderType));
5167 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, false));
5168 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "Unnamed block");
5170 ioBlockGroup->addChild(blockGroup);
5172 blockContentGenerator(context, block, blockGroup, (1 << shaderType));
5177 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(storage));
5178 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
5179 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "Block array");
5181 ioBlockGroup->addChild(blockGroup);
5183 blockContentGenerator(context, block, blockGroup, (1 << shaderType));
5189 static void generateProgramInputBlockContents (Context& context,
5190 const ResourceDefinition::Node::SharedPtr& parentStructure,
5191 tcu::TestCaseGroup* targetGroup,
5192 deUint32 presentShadersMask,
5194 void (*genCase)(Context& context,
5195 const ResourceDefinition::Node::SharedPtr& parentStructure,
5196 tcu::TestCaseGroup* targetGroup,
5197 ProgramInterface interface,
5200 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5201 const ResourceDefinition::Node::SharedPtr input = (inDefaultBlock)
5202 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
5203 : (parentStructure);
5204 const glu::ShaderType firstStage = getShaderMaskFirstStage(presentShadersMask);
5207 if (includeEmpty && inDefaultBlock)
5208 genCase(context, parentStructure, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "empty");
5210 if (firstStage == glu::SHADERTYPE_VERTEX)
5213 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5214 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5216 else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5220 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5221 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5225 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(input));
5226 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5227 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var_struct");
5231 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input));
5232 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5233 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var_array");
5236 else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
5237 firstStage == glu::SHADERTYPE_GEOMETRY)
5239 // arrayed interface
5243 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5244 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5245 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5247 // extension forbids use arrays of structs
5248 // extension forbids use arrays of arrays
5250 else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5252 // arrayed interface
5253 const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5257 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5258 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5259 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5261 // extension forbids use arrays of structs
5262 // extension forbids use arrays of arrays
5266 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchInput, glu::TYPE_FLOAT_VEC4));
5267 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var");
5269 // .patch_var_struct
5271 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchInput));
5272 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5273 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var_struct");
5277 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchInput));
5278 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5279 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var_array");
5282 else if (firstStage == glu::SHADERTYPE_COMPUTE)
5290 static void generateProgramOutputBlockContents (Context& context,
5291 const ResourceDefinition::Node::SharedPtr& parentStructure,
5292 tcu::TestCaseGroup* targetGroup,
5293 deUint32 presentShadersMask,
5295 void (*genCase)(Context& context,
5296 const ResourceDefinition::Node::SharedPtr& parentStructure,
5297 tcu::TestCaseGroup* targetGroup,
5298 ProgramInterface interface,
5301 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5302 const ResourceDefinition::Node::SharedPtr output = (inDefaultBlock)
5303 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
5304 : (parentStructure);
5305 const glu::ShaderType lastStage = getShaderMaskLastStage(presentShadersMask);
5308 if (includeEmpty && inDefaultBlock)
5309 genCase(context, parentStructure, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "empty");
5311 if (lastStage == glu::SHADERTYPE_VERTEX ||
5312 lastStage == glu::SHADERTYPE_GEOMETRY ||
5313 lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
5318 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5319 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5323 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
5324 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5325 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_struct");
5329 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5330 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5331 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_array");
5334 else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5338 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5339 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5343 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5344 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5345 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_array");
5348 else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5350 // arrayed interface
5351 const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5355 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5356 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5357 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5359 // extension forbids use arrays of structs
5360 // extension forbids use array of arrays
5364 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchOutput, glu::TYPE_FLOAT_VEC4));
5365 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var");
5367 // .patch_var_struct
5369 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchOutput));
5370 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5371 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var_struct");
5375 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchOutput));
5376 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5377 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var_array");
5380 else if (lastStage == glu::SHADERTYPE_COMPUTE)
5388 static void addProgramInputOutputResourceListCase (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramInterface programInterface, const char* name)
5390 ResourceListTestCase* const resourceListCase = new ResourceListTestCase(context, parentStructure, programInterface);
5392 DE_ASSERT(deStringEqual(name, resourceListCase->getName()));
5394 targetGroup->addChild(resourceListCase);
5397 static void generateProgramInputResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5399 generateProgramInputBlockContents(context, parentStructure, targetGroup, presentShadersMask, true, addProgramInputOutputResourceListCase);
5402 static void generateProgramOutputResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5404 generateProgramOutputBlockContents(context, parentStructure, targetGroup, presentShadersMask, true, addProgramInputOutputResourceListCase);
5407 template <ProgramResourcePropFlags TargetProp>
5408 static void addProgramInputOutputResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramInterface programInterface, const char* name)
5410 ResourceTestCase* const resourceTestCase = new ResourceTestCase(context, parentStructure, ProgramResourceQueryTestTarget(programInterface, TargetProp), name);
5411 targetGroup->addChild(resourceTestCase);
5414 template <ProgramResourcePropFlags TargetProp>
5415 static void generateProgramInputBasicBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5417 generateProgramInputBlockContents(context, parentStructure, targetGroup, presentShadersMask, false, addProgramInputOutputResourceTestCase<TargetProp>);
5420 template <ProgramResourcePropFlags TargetProp>
5421 static void generateProgramOutputBasicBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5423 generateProgramOutputBlockContents(context, parentStructure, targetGroup, presentShadersMask, false, addProgramInputOutputResourceTestCase<TargetProp>);
5426 static void generateProgramInputLocationBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5428 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5429 const ResourceDefinition::Node::SharedPtr input = (inDefaultBlock)
5430 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
5431 : (parentStructure);
5432 const glu::ShaderType firstStage = getShaderMaskFirstStage(presentShadersMask);
5434 if (firstStage == glu::SHADERTYPE_VERTEX)
5438 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5439 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5441 // .var_explicit_location
5443 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5444 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5445 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5448 else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5452 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5453 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5455 // .var_explicit_location
5457 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5458 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5459 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5463 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(input));
5464 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5465 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct"));
5467 // .var_struct_explicit_location
5469 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5470 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5471 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5472 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct_explicit_location"));
5476 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input));
5477 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5478 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
5480 // .var_array_explicit_location
5482 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5483 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5484 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5485 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
5488 else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
5489 firstStage == glu::SHADERTYPE_GEOMETRY)
5491 // arrayed interface
5495 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5496 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5497 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5499 // .var_explicit_location
5501 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5502 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5503 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5504 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5506 // extension forbids use arrays of structs
5507 // extension forbids use arrays of arrays
5509 else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5511 // arrayed interface
5512 const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5516 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5517 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5518 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5520 // .var_explicit_location
5522 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5523 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5524 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5525 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5527 // extension forbids use arrays of structs
5528 // extension forbids use arrays of arrays
5532 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchInput, glu::TYPE_FLOAT_VEC4));
5533 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var"));
5535 // .patch_var_explicit_location
5537 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
5538 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5539 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_explicit_location"));
5541 // .patch_var_struct
5543 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchInput));
5544 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5545 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct"));
5547 // .patch_var_struct_explicit_location
5549 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
5550 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5551 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5552 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct_explicit_location"));
5556 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchInput));
5557 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5558 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array"));
5560 // .patch_var_array_explicit_location
5562 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
5563 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5564 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5565 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array_explicit_location"));
5568 else if (firstStage == glu::SHADERTYPE_COMPUTE)
5576 static void generateProgramOutputLocationBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5578 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5579 const ResourceDefinition::Node::SharedPtr output = (inDefaultBlock)
5580 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
5581 : (parentStructure);
5582 const glu::ShaderType lastStage = getShaderMaskLastStage(presentShadersMask);
5584 if (lastStage == glu::SHADERTYPE_VERTEX ||
5585 lastStage == glu::SHADERTYPE_GEOMETRY ||
5586 lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
5591 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5592 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5594 // .var_explicit_location
5596 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5597 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5598 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5602 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
5603 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5604 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct"));
5606 // .var_struct_explicit_location
5608 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5609 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5610 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5611 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct_explicit_location"));
5615 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5616 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5617 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
5619 // .var_array_explicit_location
5621 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5622 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5623 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5624 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
5627 else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5631 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5632 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5634 // .var_explicit_location
5636 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5637 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5638 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5642 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5643 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5644 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
5646 // .var_array_explicit_location
5648 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(1)));
5649 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5650 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5651 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
5654 else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5656 // arrayed interface
5657 const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5661 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5662 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5663 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5665 // .var_explicit_location
5667 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5668 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5669 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5670 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5672 // extension forbids use arrays of structs
5673 // extension forbids use array of arrays
5677 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchOutput, glu::TYPE_FLOAT_VEC4));
5678 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var"));
5680 // .patch_var_explicit_location
5682 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
5683 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5684 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_explicit_location"));
5686 // .patch_var_struct
5688 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchOutput));
5689 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5690 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct"));
5692 // .patch_var_struct_explicit_location
5694 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
5695 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5696 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5697 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct_explicit_location"));
5701 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchOutput));
5702 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5703 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array"));
5705 // .patch_var_array_explicit_location
5707 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
5708 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5709 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5710 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array_explicit_location"));
5713 else if (lastStage == glu::SHADERTYPE_COMPUTE)
5721 static void generateProgramInputOutputReferencedByCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
5723 // all whole pipelines
5724 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_FRAGMENT));
5725 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_tess_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_TESS_FRAGMENT));
5726 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_geo_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_GEO_FRAGMENT));
5727 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_tess_geo_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_TESS_GEO_FRAGMENT));
5729 // all partial pipelines
5730 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_vertex", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_VERTEX));
5731 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_FRAGMENT));
5732 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_geometry", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_GEOMETRY));
5733 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_eval", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_EVAL));
5734 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_ctrl", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_CTRL));
5737 if (storage == glu::STORAGE_IN)
5738 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_eval_patch_in", "", glu::STORAGE_PATCH_IN, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_EVAL));
5739 else if (storage == glu::STORAGE_OUT)
5740 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_ctrl_patch_out", "", glu::STORAGE_PATCH_OUT, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_CTRL));
5745 template <ProgramInterface interface>
5746 static void generateProgramInputOutputTypeBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool allowMatrixCases, int expandLevel)
5755 { glu::TYPE_FLOAT, false, 0 },
5756 { glu::TYPE_INT, false, 1 },
5757 { glu::TYPE_UINT, false, 1 },
5758 { glu::TYPE_FLOAT_VEC2, false, 2 },
5759 { glu::TYPE_FLOAT_VEC3, false, 1 },
5760 { glu::TYPE_FLOAT_VEC4, false, 2 },
5761 { glu::TYPE_INT_VEC2, false, 0 },
5762 { glu::TYPE_INT_VEC3, false, 2 },
5763 { glu::TYPE_INT_VEC4, false, 2 },
5764 { glu::TYPE_UINT_VEC2, false, 2 },
5765 { glu::TYPE_UINT_VEC3, false, 2 },
5766 { glu::TYPE_UINT_VEC4, false, 0 },
5767 { glu::TYPE_FLOAT_MAT2, true, 2 },
5768 { glu::TYPE_FLOAT_MAT2X3, true, 2 },
5769 { glu::TYPE_FLOAT_MAT2X4, true, 2 },
5770 { glu::TYPE_FLOAT_MAT3X2, true, 0 },
5771 { glu::TYPE_FLOAT_MAT3, true, 2 },
5772 { glu::TYPE_FLOAT_MAT3X4, true, 2 },
5773 { glu::TYPE_FLOAT_MAT4X2, true, 2 },
5774 { glu::TYPE_FLOAT_MAT4X3, true, 2 },
5775 { glu::TYPE_FLOAT_MAT4, true, 2 },
5778 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
5780 if (!allowMatrixCases && variableTypes[ndx].isMatrix)
5783 if (variableTypes[ndx].level <= expandLevel)
5785 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
5786 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_TYPE)));
5791 static void generateProgramInputTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5793 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5794 const ResourceDefinition::Node::SharedPtr input = (inDefaultBlock)
5795 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
5796 : (parentStructure);
5797 const glu::ShaderType firstStage = getShaderMaskFirstStage(presentShadersMask);
5798 const int interfaceBlockExpansionReducement = (!inDefaultBlock) ? (1) : (0); // lesser expansions on block members to keep test counts reasonable
5800 if (firstStage == glu::SHADERTYPE_VERTEX)
5802 // Only basic types (and no booleans)
5803 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, input, targetGroup, true, 2 - interfaceBlockExpansionReducement);
5805 else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5807 const ResourceDefinition::Node::SharedPtr flatShading(new ResourceDefinition::InterpolationQualifier(input, glu::INTERPOLATION_FLAT));
5809 // Only basic types, arrays of basic types, struct of basic types (and no booleans)
5811 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5812 targetGroup->addChild(blockGroup);
5813 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, flatShading, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5816 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(flatShading));
5817 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
5819 targetGroup->addChild(blockGroup);
5820 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElement, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5823 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(flatShading));
5824 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Struct types");
5826 targetGroup->addChild(blockGroup);
5827 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, structMember, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5830 else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
5831 firstStage == glu::SHADERTYPE_GEOMETRY)
5833 // arrayed interface
5835 // Only basic types (and no booleans)
5836 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5837 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElement, targetGroup, true, 2);
5839 else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5841 // arrayed interface
5842 const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5846 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5847 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5849 targetGroup->addChild(blockGroup);
5850 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElem, blockGroup, true, 2);
5852 // extension forbids use arrays of structs
5853 // extension forbids use arrays of arrays
5857 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var", "Basic types, per-patch");
5859 targetGroup->addChild(blockGroup);
5860 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, patchInput, blockGroup, true, 1);
5862 // .patch_var_struct
5864 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchInput));
5865 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_struct", "Struct types, per-patch");
5867 targetGroup->addChild(blockGroup);
5868 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, structMbr, blockGroup, true, 1);
5872 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchInput));
5873 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_array", "Array types, per-patch");
5875 targetGroup->addChild(blockGroup);
5876 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElem, blockGroup, true, 1);
5879 else if (firstStage == glu::SHADERTYPE_COMPUTE)
5887 static void generateProgramOutputTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
5889 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5890 const ResourceDefinition::Node::SharedPtr output = (inDefaultBlock)
5891 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
5892 : (parentStructure);
5893 const glu::ShaderType lastStage = getShaderMaskLastStage(presentShadersMask);
5894 const int interfaceBlockExpansionReducement = (!inDefaultBlock) ? (1) : (0); // lesser expansions on block members to keep test counts reasonable
5896 if (lastStage == glu::SHADERTYPE_VERTEX ||
5897 lastStage == glu::SHADERTYPE_GEOMETRY ||
5898 lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
5901 const ResourceDefinition::Node::SharedPtr flatShading(new ResourceDefinition::InterpolationQualifier(output, glu::INTERPOLATION_FLAT));
5903 // Only basic types, arrays of basic types, struct of basic types (and no booleans)
5905 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5906 targetGroup->addChild(blockGroup);
5907 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, flatShading, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5910 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(flatShading));
5911 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
5912 const int typeExpansionReducement = (lastStage != glu::SHADERTYPE_VERTEX) ? (1) : (0); // lesser expansions on other stages
5913 const int expansionLevel = 2 - interfaceBlockExpansionReducement - typeExpansionReducement;
5915 targetGroup->addChild(blockGroup);
5916 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElement, blockGroup, true, expansionLevel);
5919 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(flatShading));
5920 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Struct types");
5921 const int typeExpansionReducement = (lastStage != glu::SHADERTYPE_VERTEX) ? (1) : (0); // lesser expansions on other stages
5922 const int expansionLevel = 2 - interfaceBlockExpansionReducement - typeExpansionReducement;
5924 targetGroup->addChild(blockGroup);
5925 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, structMember, blockGroup, true, expansionLevel);
5928 else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5930 // only basic type and basic type array (and no booleans or matrices)
5932 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5933 targetGroup->addChild(blockGroup);
5934 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, output, blockGroup, false, 2);
5937 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(output));
5938 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
5940 targetGroup->addChild(blockGroup);
5941 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElement, blockGroup, false, 2);
5944 else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5946 // arrayed interface
5947 const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5951 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5952 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5954 targetGroup->addChild(blockGroup);
5955 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElem, blockGroup, true, 2);
5957 // extension forbids use arrays of structs
5958 // extension forbids use arrays of arrays
5962 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var", "Basic types, per-patch");
5964 targetGroup->addChild(blockGroup);
5965 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, patchOutput, blockGroup, true, 1);
5967 // .patch_var_struct
5969 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchOutput));
5970 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_struct", "Struct types, per-patch");
5972 targetGroup->addChild(blockGroup);
5973 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, structMbr, blockGroup, true, 1);
5977 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchOutput));
5978 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_array", "Array types, per-patch");
5980 targetGroup->addChild(blockGroup);
5981 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElem, blockGroup, true, 1);
5984 else if (lastStage == glu::SHADERTYPE_COMPUTE)
5992 class ProgramInputTestGroup : public TestCaseGroup
5995 ProgramInputTestGroup (Context& context);
5999 ProgramInputTestGroup::ProgramInputTestGroup (Context& context)
6000 : TestCaseGroup(context, "program_input", "Program input")
6004 void ProgramInputTestGroup::init (void)
6006 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
6010 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
6011 addChild(blockGroup);
6012 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, true, true, generateProgramInputResourceListBlockContents);
6017 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Array size");
6018 addChild(blockGroup);
6019 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6024 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Location");
6025 addChild(blockGroup);
6026 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, generateProgramInputLocationBlockContents);
6031 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
6032 addChild(blockGroup);
6033 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6038 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Reference by shader");
6039 addChild(blockGroup);
6040 generateProgramInputOutputReferencedByCases(m_context, blockGroup, glu::STORAGE_IN);
6045 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Type");
6046 addChild(blockGroup);
6047 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, generateProgramInputTypeBlockContents);
6052 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "is_per_patch", "Is per patch");
6053 addChild(blockGroup);
6054 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
6058 class ProgramOutputTestGroup : public TestCaseGroup
6061 ProgramOutputTestGroup (Context& context);
6065 ProgramOutputTestGroup::ProgramOutputTestGroup (Context& context)
6066 : TestCaseGroup(context, "program_output", "Program output")
6070 void ProgramOutputTestGroup::init (void)
6072 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
6076 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
6077 addChild(blockGroup);
6078 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, true, false, generateProgramOutputResourceListBlockContents);
6083 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Array size");
6084 addChild(blockGroup);
6085 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6090 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Location");
6091 addChild(blockGroup);
6092 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, generateProgramOutputLocationBlockContents);
6097 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
6098 addChild(blockGroup);
6099 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6104 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Reference by shader");
6105 addChild(blockGroup);
6106 generateProgramInputOutputReferencedByCases(m_context, blockGroup, glu::STORAGE_OUT);
6111 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Type");
6112 addChild(blockGroup);
6113 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, generateProgramOutputTypeBlockContents);
6118 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "is_per_patch", "Is per patch");
6119 addChild(blockGroup);
6120 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
6124 static void generateTransformFeedbackShaderCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, bool))
6130 deUint32 lastStageBit;
6136 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT),
6137 (1 << glu::SHADERTYPE_VERTEX),
6141 "vertex_tess_fragment",
6142 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
6143 (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
6147 "vertex_geo_fragment",
6148 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY),
6149 (1 << glu::SHADERTYPE_GEOMETRY),
6153 "vertex_tess_geo_fragment",
6154 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
6155 (1 << glu::SHADERTYPE_GEOMETRY),
6162 glu::ShaderType stage;
6164 } singleStageCases[] =
6166 { "separable_vertex", glu::SHADERTYPE_VERTEX, false },
6167 { "separable_tess_eval", glu::SHADERTYPE_TESSELLATION_EVALUATION, true },
6168 { "separable_geometry", glu::SHADERTYPE_GEOMETRY, true },
6171 // monolithic pipeline
6172 for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
6174 TestCaseGroup* const blockGroup = new TestCaseGroup(context, pipelines[pipelineNdx].name, "");
6175 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6176 const ResourceDefinition::Node::SharedPtr shaderSet (new ResourceDefinition::ShaderSet(program,
6178 pipelines[pipelineNdx].stageBits,
6179 pipelines[pipelineNdx].lastStageBit));
6181 targetGroup->addChild(blockGroup);
6182 blockContentGenerator(context, shaderSet, blockGroup, pipelines[pipelineNdx].reducedSet);
6185 // separable pipeline
6186 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
6188 TestCaseGroup* const blockGroup = new TestCaseGroup(context, singleStageCases[ndx].name, "");
6189 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
6190 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glslVersion));
6192 targetGroup->addChild(blockGroup);
6193 blockContentGenerator(context, shader, blockGroup, singleStageCases[ndx].reducedSet);
6197 static void generateTransformFeedbackResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6199 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6200 const ResourceDefinition::Node::SharedPtr output (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6202 DE_UNREF(reducedSet);
6204 // .builtin_gl_position
6206 const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6207 targetGroup->addChild(new FeedbackResourceListTestCase(context, xfbTarget, "builtin_gl_position"));
6209 // .default_block_basic_type
6211 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6212 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6213 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_basic_type"));
6215 // .default_block_struct_member
6217 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
6218 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(structMbr));
6219 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6220 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_struct_member"));
6222 // .default_block_array
6224 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6225 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(xfbTarget));
6226 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6227 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_array"));
6229 // .default_block_array_element
6231 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
6232 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(arrayElem));
6233 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6234 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_array_element"));
6238 template <ProgramResourcePropFlags TargetProp>
6239 static void generateTransformFeedbackVariableBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6241 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6242 const ResourceDefinition::Node::SharedPtr output (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6244 DE_UNREF(reducedSet);
6246 // .builtin_gl_position
6248 const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6249 targetGroup->addChild(new ResourceTestCase(context, xfbTarget, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "builtin_gl_position"));
6251 // .default_block_basic_type
6253 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6254 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6255 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_basic_type"));
6257 // .default_block_struct_member
6259 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
6260 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(structMbr));
6261 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6262 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_struct_member"));
6264 // .default_block_array
6266 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6267 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(xfbTarget));
6268 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6269 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_array"));
6271 // .default_block_array_element
6273 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
6274 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(arrayElem));
6275 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6276 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_array_element"));
6280 static void generateTransformFeedbackVariableBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6288 { glu::TYPE_FLOAT, true },
6289 { glu::TYPE_INT, true },
6290 { glu::TYPE_UINT, true },
6292 { glu::TYPE_FLOAT_VEC2, false },
6293 { glu::TYPE_FLOAT_VEC3, true },
6294 { glu::TYPE_FLOAT_VEC4, false },
6296 { glu::TYPE_INT_VEC2, false },
6297 { glu::TYPE_INT_VEC3, true },
6298 { glu::TYPE_INT_VEC4, false },
6300 { glu::TYPE_UINT_VEC2, true },
6301 { glu::TYPE_UINT_VEC3, false },
6302 { glu::TYPE_UINT_VEC4, false },
6304 { glu::TYPE_FLOAT_MAT2, false },
6305 { glu::TYPE_FLOAT_MAT2X3, false },
6306 { glu::TYPE_FLOAT_MAT2X4, false },
6307 { glu::TYPE_FLOAT_MAT3X2, false },
6308 { glu::TYPE_FLOAT_MAT3, false },
6309 { glu::TYPE_FLOAT_MAT3X4, true },
6310 { glu::TYPE_FLOAT_MAT4X2, false },
6311 { glu::TYPE_FLOAT_MAT4X3, false },
6312 { glu::TYPE_FLOAT_MAT4, false },
6315 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6317 if (variableTypes[ndx].important || !reducedSet)
6319 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
6320 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, PROGRAMRESOURCEPROP_TYPE)));
6325 static void generateTransformFeedbackVariableTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6327 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6328 const ResourceDefinition::Node::SharedPtr output (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6329 const ResourceDefinition::Node::SharedPtr flatShading (new ResourceDefinition::InterpolationQualifier(output, glu::INTERPOLATION_FLAT));
6331 // Only builtins, basic types, arrays of basic types, struct of basic types (and no booleans)
6333 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6334 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "builtin", "Built-in outputs");
6336 targetGroup->addChild(blockGroup);
6337 blockGroup->addChild(new ResourceTestCase(context, xfbTarget, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, PROGRAMRESOURCEPROP_TYPE), "gl_position"));
6340 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(flatShading));
6341 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
6343 targetGroup->addChild(blockGroup);
6344 generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
6347 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(flatShading));
6348 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(arrayElement));
6349 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
6351 targetGroup->addChild(blockGroup);
6352 generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
6355 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(flatShading));
6356 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(xfbTarget));
6357 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "whole_array", "Whole array");
6359 targetGroup->addChild(blockGroup);
6360 generateTransformFeedbackVariableBasicTypeCases(context, arrayElement, blockGroup, reducedSet);
6363 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(flatShading));
6364 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(structMember));
6365 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Struct types");
6367 targetGroup->addChild(blockGroup);
6368 generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
6372 class TransformFeedbackVaryingTestGroup : public TestCaseGroup
6375 TransformFeedbackVaryingTestGroup (Context& context);
6379 TransformFeedbackVaryingTestGroup::TransformFeedbackVaryingTestGroup (Context& context)
6380 : TestCaseGroup(context, "transform_feedback_varying", "Transform feedback varyings")
6384 void TransformFeedbackVaryingTestGroup::init (void)
6386 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
6390 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "resource_list", "Resource list");
6391 addChild(blockGroup);
6392 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, glslVersion, generateTransformFeedbackResourceListBlockContents);
6397 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_size", "Array size");
6398 addChild(blockGroup);
6399 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, glslVersion, generateTransformFeedbackVariableBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6404 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "name_length", "Name length");
6405 addChild(blockGroup);
6406 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, glslVersion, generateTransformFeedbackVariableBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6411 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "type", "Type");
6412 addChild(blockGroup);
6413 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, glslVersion, generateTransformFeedbackVariableTypeBlockContents);
6417 static void generateBufferVariableBufferCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*))
6419 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6420 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
6421 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6422 const ResourceDefinition::Node::SharedPtr bufferStorage (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6423 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(bufferStorage, glu::Layout(-1, 0)));
6427 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, true));
6428 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block", "Named block");
6430 targetGroup->addChild(blockGroup);
6432 blockContentGenerator(context, buffer, blockGroup);
6437 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, false));
6438 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "Unnamed block");
6440 targetGroup->addChild(blockGroup);
6442 blockContentGenerator(context, buffer, blockGroup);
6447 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding));
6448 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
6449 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "Block array");
6451 targetGroup->addChild(blockGroup);
6453 blockContentGenerator(context, buffer, blockGroup);
6457 static void generateBufferVariableResourceListBlockContentsProxy (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
6459 generateBufferBackedResourceListBlockContentCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, 4);
6462 static void generateBufferVariableArraySizeSubCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramResourcePropFlags targetProp, bool sizedArray, bool extendedCases)
6464 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp);
6465 tcu::TestCaseGroup* aggregateGroup;
6470 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
6471 targetGroup->addChild(blockGroup);
6473 generateVariableCases(context, parentStructure, blockGroup, queryTarget, (sizedArray) ? (2) : (1), false);
6479 aggregateGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
6480 targetGroup->addChild(aggregateGroup);
6483 aggregateGroup = targetGroup;
6486 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_FLOAT, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6489 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_BOOL, (extendedCases && sizedArray) ? (1) : (0), !extendedCases);
6492 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_BOOL_VEC3, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6495 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_FLOAT_VEC4, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6498 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_INT_VEC2, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6501 template <ProgramResourcePropFlags TargetProp>
6502 static void generateBufferVariableArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
6504 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp);
6505 const bool namedNonArrayBlock = static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named && parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
6508 if (namedNonArrayBlock)
6510 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "non_array", "Non-array target");
6511 targetGroup->addChild(blockGroup);
6513 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 1, false);
6518 const ResourceDefinition::Node::SharedPtr sized (new ResourceDefinition::ArrayElement(parentStructure));
6519 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
6520 targetGroup->addChild(blockGroup);
6522 generateBufferVariableArraySizeSubCases(context, sized, blockGroup, TargetProp, true, namedNonArrayBlock);
6527 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6528 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unsized", "Unsized target");
6529 targetGroup->addChild(blockGroup);
6531 generateBufferVariableArraySizeSubCases(context, unsized, blockGroup, TargetProp, false, namedNonArrayBlock);
6535 static void generateBufferVariableBlockIndexCases (Context& context, glu::GLSLVersion glslVersion, tcu::TestCaseGroup* const targetGroup)
6537 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6538 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
6539 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6540 const ResourceDefinition::Node::SharedPtr bufferStorage (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6541 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(bufferStorage, glu::Layout(-1, 0)));
6545 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, true));
6546 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
6548 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "named_block"));
6553 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, false));
6554 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
6556 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "unnamed_block"));
6561 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding));
6562 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
6563 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
6565 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "block_array"));
6569 static void generateBufferVariableMatrixCaseBlocks (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, bool))
6574 const char* description;
6576 bool extendedBasicTypeCases;
6577 glu::MatrixOrder order;
6580 { "named_block", "Named uniform block", true, true, glu::MATRIXORDER_LAST },
6581 { "named_block_row_major", "Named uniform block", true, false, glu::MATRIXORDER_ROW_MAJOR },
6582 { "named_block_col_major", "Named uniform block", true, false, glu::MATRIXORDER_COLUMN_MAJOR },
6583 { "unnamed_block", "Unnamed uniform block", false, false, glu::MATRIXORDER_LAST },
6584 { "unnamed_block_row_major", "Unnamed uniform block", false, false, glu::MATRIXORDER_ROW_MAJOR },
6585 { "unnamed_block_col_major", "Unnamed uniform block", false, false, glu::MATRIXORDER_COLUMN_MAJOR },
6588 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6589 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
6590 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6591 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6593 for (int childNdx = 0; childNdx < (int)DE_LENGTH_OF_ARRAY(children); ++childNdx)
6595 ResourceDefinition::Node::SharedPtr parentStructure = buffer;
6596 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, children[childNdx].name, children[childNdx].description);
6598 targetGroup->addChild(blockGroup);
6600 if (children[childNdx].order != glu::MATRIXORDER_LAST)
6603 layout.matrixOrder = children[childNdx].order;
6604 parentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(parentStructure, layout));
6607 parentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(parentStructure, children[childNdx].namedBlock));
6609 blockContentGenerator(context, parentStructure, blockGroup, children[childNdx].extendedBasicTypeCases);
6613 static void generateBufferVariableMatrixVariableBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramResourcePropFlags targetProp)
6615 // all matrix types and some non-matrix
6617 static const glu::DataType variableTypes[] =
6621 glu::TYPE_FLOAT_MAT2,
6622 glu::TYPE_FLOAT_MAT2X3,
6623 glu::TYPE_FLOAT_MAT2X4,
6624 glu::TYPE_FLOAT_MAT3X2,
6625 glu::TYPE_FLOAT_MAT3,
6626 glu::TYPE_FLOAT_MAT3X4,
6627 glu::TYPE_FLOAT_MAT4X2,
6628 glu::TYPE_FLOAT_MAT4X3,
6629 glu::TYPE_FLOAT_MAT4,
6632 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6634 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx]));
6635 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp)));
6639 static void generateBufferVariableMatrixVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramResourcePropFlags targetProp)
6642 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp, glu::TYPE_FLOAT_MAT3X2, "", 2);
6646 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6647 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(unsized, glu::TYPE_FLOAT_MAT3X2));
6649 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp), "var_unsized_array"));
6653 template <ProgramResourcePropFlags TargetProp>
6654 static void generateBufferVariableMatrixCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool extendedTypeCases)
6657 if (extendedTypeCases)
6659 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "types", "Types");
6660 targetGroup->addChild(blockGroup);
6661 generateBufferVariableMatrixVariableBasicTypeCases(context, parentStructure, blockGroup, TargetProp);
6666 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "no_qualifier", "No qualifier");
6667 targetGroup->addChild(blockGroup);
6668 generateBufferVariableMatrixVariableCases(context, parentStructure, blockGroup, TargetProp);
6673 const ResourceDefinition::Node::SharedPtr matrixOrder(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, -1, glu::FORMATLAYOUT_LAST, glu::MATRIXORDER_COLUMN_MAJOR)));
6675 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "column_major", "Column major qualifier");
6676 targetGroup->addChild(blockGroup);
6677 generateBufferVariableMatrixVariableCases(context, matrixOrder, blockGroup, TargetProp);
6682 const ResourceDefinition::Node::SharedPtr matrixOrder(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, -1, glu::FORMATLAYOUT_LAST, glu::MATRIXORDER_ROW_MAJOR)));
6684 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "row_major", "Row major qualifier");
6685 targetGroup->addChild(blockGroup);
6686 generateBufferVariableMatrixVariableCases(context, matrixOrder, blockGroup, TargetProp);
6690 static void generateBufferVariableNameLengthCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
6694 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
6695 targetGroup->addChild(blockGroup);
6697 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 3);
6702 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6703 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unsized", "Unsized target");
6704 targetGroup->addChild(blockGroup);
6706 generateBufferBackedVariableAggregateTypeCases(context, unsized, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 2);
6710 static void generateBufferVariableOffsetCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
6714 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
6715 targetGroup->addChild(blockGroup);
6717 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_OFFSET, glu::TYPE_FLOAT, "", 3);
6722 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6723 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unsized", "Unsized target");
6724 targetGroup->addChild(blockGroup);
6726 generateBufferBackedVariableAggregateTypeCases(context, unsized, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_OFFSET, glu::TYPE_FLOAT, "", 2);
6730 static void generateBufferVariableReferencedByBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
6732 DE_UNREF(expandLevel);
6734 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER);
6735 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6736 const ResourceDefinition::Node::SharedPtr storage (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6737 const bool singleShaderCase = parentStructure->getType() == ResourceDefinition::Node::TYPE_SHADER;
6741 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(storage, true));
6742 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block", "Named block");
6744 targetGroup->addChild(blockGroup);
6746 generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, singleShaderCase);
6751 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(storage, false));
6752 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "Unnamed block");
6754 targetGroup->addChild(blockGroup);
6756 generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, false);
6761 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(storage));
6762 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
6763 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "Block array");
6765 targetGroup->addChild(blockGroup);
6767 generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, false);
6771 template <ProgramResourcePropFlags TargetProp>
6772 static void generateBufferVariableTopLevelCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
6774 // basic and aggregate types
6775 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp, glu::TYPE_FLOAT_VEC4, "", 3);
6777 // basic and aggregate types in an unsized array
6779 const ResourceDefinition::Node::SharedPtr unsized(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6781 generateBufferBackedVariableAggregateTypeCases(context, unsized, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp, glu::TYPE_FLOAT_VEC4, "_unsized_array", 2);
6785 static void generateBufferVariableTypeBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
6790 glu::DataType dataType;
6793 { 0, glu::TYPE_FLOAT },
6794 { 1, glu::TYPE_INT },
6795 { 1, glu::TYPE_UINT },
6796 { 1, glu::TYPE_BOOL },
6798 { 3, glu::TYPE_FLOAT_VEC2 },
6799 { 1, glu::TYPE_FLOAT_VEC3 },
6800 { 1, glu::TYPE_FLOAT_VEC4 },
6802 { 3, glu::TYPE_INT_VEC2 },
6803 { 2, glu::TYPE_INT_VEC3 },
6804 { 3, glu::TYPE_INT_VEC4 },
6806 { 3, glu::TYPE_UINT_VEC2 },
6807 { 2, glu::TYPE_UINT_VEC3 },
6808 { 3, glu::TYPE_UINT_VEC4 },
6810 { 3, glu::TYPE_BOOL_VEC2 },
6811 { 2, glu::TYPE_BOOL_VEC3 },
6812 { 3, glu::TYPE_BOOL_VEC4 },
6814 { 2, glu::TYPE_FLOAT_MAT2 },
6815 { 3, glu::TYPE_FLOAT_MAT2X3 },
6816 { 3, glu::TYPE_FLOAT_MAT2X4 },
6817 { 2, glu::TYPE_FLOAT_MAT3X2 },
6818 { 2, glu::TYPE_FLOAT_MAT3 },
6819 { 3, glu::TYPE_FLOAT_MAT3X4 },
6820 { 2, glu::TYPE_FLOAT_MAT4X2 },
6821 { 3, glu::TYPE_FLOAT_MAT4X3 },
6822 { 2, glu::TYPE_FLOAT_MAT4 },
6825 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6827 if (variableTypes[ndx].level <= expandLevel)
6829 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
6830 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_TYPE)));
6835 static void generateBufferVariableTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int depth = 3)
6840 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic type");
6841 targetGroup->addChild(blockGroup);
6842 generateBufferVariableTypeBasicTypeCases(context, parentStructure, blockGroup, depth);
6846 // flatten bottom-level
6847 generateBufferVariableTypeBasicTypeCases(context, parentStructure, targetGroup, depth);
6853 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
6854 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Arrays");
6856 targetGroup->addChild(blockGroup);
6857 generateBufferVariableTypeCases(context, arrayElement, blockGroup, depth-1);
6863 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
6864 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Structs");
6866 targetGroup->addChild(blockGroup);
6867 generateBufferVariableTypeCases(context, structMember, blockGroup, depth-1);
6871 static void generateBufferVariableTypeBlock (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion)
6873 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6874 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
6875 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6876 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6877 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(buffer, true));
6879 generateBufferVariableTypeCases(context, block, targetGroup);
6882 static void generateBufferVariableRandomCase (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion, int index, bool onlyExtensionStages)
6884 de::Random rnd (index * 0x12345);
6885 const ResourceDefinition::Node::SharedPtr shader = generateRandomShaderSet(rnd, glslVersion, onlyExtensionStages);
6886 const glu::DataType type = generateRandomDataType(rnd, true);
6887 const glu::Layout layout = generateRandomVariableLayout(rnd, type, true);
6888 const bool namedBlock = rnd.getBool();
6889 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6890 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6891 ResourceDefinition::Node::SharedPtr currentStructure (new ResourceDefinition::LayoutQualifier(buffer, generateRandomBufferBlockLayout(rnd)));
6893 if (namedBlock && rnd.getBool())
6894 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
6895 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(currentStructure, namedBlock));
6897 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, layout));
6898 currentStructure = generateRandomVariableDefinition(rnd, currentStructure, type, layout, true);
6900 targetGroup->addChild(new ResourceTestCase(context, currentStructure, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BUFFER_VARIABLE_MASK), de::toString(index).c_str()));
6903 static void generateBufferVariableRandomCases (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion)
6905 const int numBasicCases = 40;
6906 const int numTessGeoCases = 40;
6908 for (int ndx = 0; ndx < numBasicCases; ++ndx)
6909 generateBufferVariableRandomCase(context, targetGroup, glslVersion, ndx, false);
6910 for (int ndx = 0; ndx < numTessGeoCases; ++ndx)
6911 generateBufferVariableRandomCase(context, targetGroup, glslVersion, numBasicCases + ndx, true);
6914 class BufferVariableTestGroup : public TestCaseGroup
6917 BufferVariableTestGroup (Context& context);
6921 BufferVariableTestGroup::BufferVariableTestGroup (Context& context)
6922 : TestCaseGroup(context, "buffer_variable", "Buffer variable")
6926 void BufferVariableTestGroup::init (void)
6928 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
6932 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "resource_list", "Resource list");
6933 addChild(blockGroup);
6934 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableResourceListBlockContentsProxy);
6939 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_size", "Array size");
6940 addChild(blockGroup);
6941 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableArrayCases<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6946 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_stride", "Array stride");
6947 addChild(blockGroup);
6948 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableArrayCases<PROGRAMRESOURCEPROP_ARRAY_STRIDE>);
6953 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "block_index", "Block index");
6954 addChild(blockGroup);
6955 generateBufferVariableBlockIndexCases(m_context, glslVersion, blockGroup);
6960 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "is_row_major", "Is row major");
6961 addChild(blockGroup);
6962 generateBufferVariableMatrixCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableMatrixCases<PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR>);
6967 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "matrix_stride", "Matrix stride");
6968 addChild(blockGroup);
6969 generateBufferVariableMatrixCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableMatrixCases<PROGRAMRESOURCEPROP_MATRIX_STRIDE>);
6974 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "name_length", "Name length");
6975 addChild(blockGroup);
6976 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableNameLengthCases);
6981 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "offset", "Offset");
6982 addChild(blockGroup);
6983 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableOffsetCases);
6988 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "referenced_by", "Referenced by");
6989 addChild(blockGroup);
6990 generateReferencedByShaderCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableReferencedByBlockContents);
6993 // .top_level_array_size
6995 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "top_level_array_size", "Top-level array size");
6996 addChild(blockGroup);
6997 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableTopLevelCases<PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_SIZE>);
7000 // .top_level_array_stride
7002 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "top_level_array_stride", "Top-level array stride");
7003 addChild(blockGroup);
7004 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableTopLevelCases<PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_STRIDE>);
7009 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "type", "Type");
7010 addChild(blockGroup);
7011 generateBufferVariableTypeBlock(m_context, blockGroup, glslVersion);
7016 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "random", "Random");
7017 addChild(blockGroup);
7018 generateBufferVariableRandomCases(m_context, blockGroup, glslVersion);
7024 ProgramInterfaceQueryTests::ProgramInterfaceQueryTests (Context& context)
7025 : TestCaseGroup(context, "program_interface_query", "Program interface query tests")
7029 ProgramInterfaceQueryTests::~ProgramInterfaceQueryTests (void)
7033 void ProgramInterfaceQueryTests::init (void)
7037 // .buffer_limited_query
7039 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "buffer_limited_query", "Queries limited by the buffer size");
7043 group->addChild(new ResourceNameBufferLimitCase(m_context, "resource_name_query", "Test GetProgramResourceName with too small a buffer"));
7044 group->addChild(new ResourceQueryBufferLimitCase(m_context, "resource_query", "Test GetProgramResourceiv with too small a buffer"));
7050 addChild(new UniformInterfaceTestGroup(m_context));
7053 addChild(new BufferBackedBlockInterfaceTestGroup(m_context, glu::STORAGE_UNIFORM));
7055 // .atomic_counter_buffer
7056 addChild(new AtomicCounterTestGroup(m_context));
7059 addChild(new ProgramInputTestGroup(m_context));
7062 addChild(new ProgramOutputTestGroup(m_context));
7064 // .transform_feedback_varying
7065 addChild(new TransformFeedbackVaryingTestGroup(m_context));
7068 addChild(new BufferVariableTestGroup(m_context));
7070 // .shader_storage_block
7071 addChild(new BufferBackedBlockInterfaceTestGroup(m_context, glu::STORAGE_BUFFER));