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 bool checkSupport(Context& ctx)
214 auto ctxType = ctx.getRenderContext().getType();
215 return contextSupports(ctxType, glu::ApiType::es(3, 2)) ||
216 contextSupports(ctxType, glu::ApiType::core(4, 5));
219 static std::string specializeShader(Context& context, const char* code)
221 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(context.getRenderContext().getType());
222 std::map<std::string, std::string> specializationMap;
224 specializationMap["GLSL_VERSION_DECL"] = glu::getGLSLVersionDeclaration(glslVersion);
226 return tcu::StringTemplate(code).specialize(specializationMap);
229 namespace ResourceDefinition
241 TYPE_INTERFACE_BLOCK,
244 TYPE_STORAGE_QUALIFIER,
245 TYPE_LAYOUT_QUALIFIER,
247 TYPE_INTERPOLATION_QUALIFIER,
248 TYPE_TRANSFORM_FEEDBACK_TARGET,
253 typedef de::SharedPtr<const Node> SharedPtr;
255 Node (NodeType type, const SharedPtr& enclosingNode) : m_type(type), m_enclosingNode(enclosingNode) { DE_ASSERT(type < TYPE_LAST); }
256 virtual ~Node (void) { }
258 inline const Node* getEnclosingNode (void) const { return m_enclosingNode.get(); }
259 inline NodeType getType (void) const { return m_type; }
262 const NodeType m_type;
263 const SharedPtr m_enclosingNode;
266 class Program : public Node
269 Program (bool separable = false)
270 : Node (TYPE_PROGRAM, SharedPtr())
271 , m_separable (separable)
275 const bool m_separable;
278 class Shader : public Node
281 Shader (const SharedPtr& enclosingNode, glu::ShaderType type, glu::GLSLVersion version)
282 : Node (TYPE_SHADER, enclosingNode)
284 , m_version (version)
286 DE_ASSERT(enclosingNode->getType() == TYPE_PROGRAM);
287 DE_ASSERT(type < glu::SHADERTYPE_LAST);
290 const glu::ShaderType m_type;
291 const glu::GLSLVersion m_version;
294 class DefaultBlock : public Node
297 DefaultBlock (const SharedPtr& enclosing)
298 : Node(TYPE_DEFAULT_BLOCK, enclosing)
300 // enclosed by the shader
301 DE_ASSERT(enclosing->getType() == TYPE_SHADER ||
302 enclosing->getType() == TYPE_SHADER_SET);
306 class StorageQualifier : public Node
309 StorageQualifier (const SharedPtr& enclosing, glu::Storage storage)
310 : Node (TYPE_STORAGE_QUALIFIER, enclosing)
311 , m_storage (storage)
313 // not a part of any block
314 DE_ASSERT(enclosing->getType() == TYPE_DEFAULT_BLOCK);
317 const glu::Storage m_storage;
320 class Variable : public Node
323 Variable (const SharedPtr& enclosing, glu::DataType dataType)
324 : Node (TYPE_VARIABLE, enclosing)
325 , m_dataType (dataType)
327 DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER ||
328 enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
329 enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER ||
330 enclosing->getType() == TYPE_INTERFACE_BLOCK ||
331 enclosing->getType() == TYPE_ARRAY_ELEMENT ||
332 enclosing->getType() == TYPE_STRUCT_MEMBER ||
333 enclosing->getType() == TYPE_TRANSFORM_FEEDBACK_TARGET);
336 const glu::DataType m_dataType;
339 class InterfaceBlock : public Node
342 InterfaceBlock (const SharedPtr& enclosing, bool named)
343 : Node (TYPE_INTERFACE_BLOCK, enclosing)
346 // Must be storage qualified
347 const Node* storageNode = enclosing.get();
348 while (storageNode->getType() == TYPE_ARRAY_ELEMENT ||
349 storageNode->getType() == TYPE_LAYOUT_QUALIFIER)
351 storageNode = storageNode->getEnclosingNode();
354 DE_ASSERT(storageNode->getType() == TYPE_STORAGE_QUALIFIER);
355 DE_UNREF(storageNode);
361 class ArrayElement : public Node
364 ArrayElement (const SharedPtr& enclosing, int arraySize = DEFAULT_SIZE)
365 : Node (TYPE_ARRAY_ELEMENT, enclosing)
366 , m_arraySize (arraySize)
368 DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER ||
369 enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
370 enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER ||
371 enclosing->getType() == TYPE_INTERFACE_BLOCK ||
372 enclosing->getType() == TYPE_ARRAY_ELEMENT ||
373 enclosing->getType() == TYPE_STRUCT_MEMBER ||
374 enclosing->getType() == TYPE_TRANSFORM_FEEDBACK_TARGET);
377 const int m_arraySize;
386 class StructMember : public Node
389 StructMember (const SharedPtr& enclosing)
390 : Node(TYPE_STRUCT_MEMBER, enclosing)
392 DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER ||
393 enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
394 enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER ||
395 enclosing->getType() == TYPE_INTERFACE_BLOCK ||
396 enclosing->getType() == TYPE_ARRAY_ELEMENT ||
397 enclosing->getType() == TYPE_STRUCT_MEMBER ||
398 enclosing->getType() == TYPE_TRANSFORM_FEEDBACK_TARGET);
402 class LayoutQualifier : public Node
405 LayoutQualifier (const SharedPtr& enclosing, const glu::Layout& layout)
406 : Node (TYPE_LAYOUT_QUALIFIER, enclosing)
409 DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER ||
410 enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
411 enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER ||
412 enclosing->getType() == TYPE_DEFAULT_BLOCK ||
413 enclosing->getType() == TYPE_INTERFACE_BLOCK);
416 const glu::Layout m_layout;
419 class InterpolationQualifier : public Node
422 InterpolationQualifier (const SharedPtr& enclosing, const glu::Interpolation& interpolation)
423 : Node (TYPE_INTERPOLATION_QUALIFIER, enclosing)
424 , m_interpolation (interpolation)
426 DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER ||
427 enclosing->getType() == TYPE_LAYOUT_QUALIFIER ||
428 enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER ||
429 enclosing->getType() == TYPE_DEFAULT_BLOCK ||
430 enclosing->getType() == TYPE_INTERFACE_BLOCK);
433 const glu::Interpolation m_interpolation;
436 class ShaderSet : public Node
439 ShaderSet (const SharedPtr& enclosing, glu::GLSLVersion version);
440 ShaderSet (const SharedPtr& enclosing, glu::GLSLVersion version, deUint32 stagesPresentBits, deUint32 stagesReferencingBits);
442 void setStage (glu::ShaderType type, bool referencing);
443 bool isStagePresent (glu::ShaderType stage) const;
444 bool isStageReferencing (glu::ShaderType stage) const;
446 deUint32 getReferencingMask (void) const;
448 const glu::GLSLVersion m_version;
450 bool m_stagePresent[glu::SHADERTYPE_LAST];
451 bool m_stageReferencing[glu::SHADERTYPE_LAST];
454 ShaderSet::ShaderSet (const SharedPtr& enclosing, glu::GLSLVersion version)
455 : Node (TYPE_SHADER_SET, enclosing)
456 , m_version (version)
458 DE_ASSERT(enclosing->getType() == TYPE_PROGRAM);
460 deMemset(m_stagePresent, 0, sizeof(m_stagePresent));
461 deMemset(m_stageReferencing, 0, sizeof(m_stageReferencing));
464 ShaderSet::ShaderSet (const SharedPtr& enclosing,
465 glu::GLSLVersion version,
466 deUint32 stagesPresentBits,
467 deUint32 stagesReferencingBits)
468 : Node (TYPE_SHADER_SET, enclosing)
469 , m_version (version)
471 for (deUint32 stageNdx = 0; stageNdx < glu::SHADERTYPE_LAST; ++stageNdx)
473 const deUint32 stageMask = (1u << stageNdx);
474 const bool stagePresent = (stagesPresentBits & stageMask) != 0;
475 const bool stageReferencing = (stagesReferencingBits & stageMask) != 0;
477 DE_ASSERT(stagePresent || !stageReferencing);
479 m_stagePresent[stageNdx] = stagePresent;
480 m_stageReferencing[stageNdx] = stageReferencing;
484 void ShaderSet::setStage (glu::ShaderType type, bool referencing)
486 DE_ASSERT(type < glu::SHADERTYPE_LAST);
487 m_stagePresent[type] = true;
488 m_stageReferencing[type] = referencing;
491 bool ShaderSet::isStagePresent (glu::ShaderType stage) const
493 DE_ASSERT(stage < glu::SHADERTYPE_LAST);
494 return m_stagePresent[stage];
497 bool ShaderSet::isStageReferencing (glu::ShaderType stage) const
499 DE_ASSERT(stage < glu::SHADERTYPE_LAST);
500 return m_stageReferencing[stage];
503 deUint32 ShaderSet::getReferencingMask (void) const
506 for (deUint32 stage = 0; stage < glu::SHADERTYPE_LAST; ++stage)
508 if (m_stageReferencing[stage])
509 mask |= (1u << stage);
514 class TransformFeedbackTarget : public Node
517 TransformFeedbackTarget (const SharedPtr& enclosing, const char* builtinVarName = DE_NULL)
518 : Node (TYPE_TRANSFORM_FEEDBACK_TARGET, enclosing)
519 , m_builtinVarName (builtinVarName)
523 const char* const m_builtinVarName;
526 } // ResourceDefinition
528 static glu::Precision getDataTypeDefaultPrecision (const glu::DataType& type)
530 if (glu::isDataTypeBoolOrBVec(type))
531 return glu::PRECISION_LAST;
532 else if (glu::isDataTypeScalarOrVector(type) || glu::isDataTypeMatrix(type))
533 return glu::PRECISION_HIGHP;
534 else if (glu::isDataTypeSampler(type))
535 return glu::PRECISION_HIGHP;
536 else if (glu::isDataTypeImage(type))
537 return glu::PRECISION_HIGHP;
538 else if (type == glu::TYPE_UINT_ATOMIC_COUNTER)
539 return glu::PRECISION_HIGHP;
542 return glu::PRECISION_LAST;
545 static de::MovePtr<ProgramInterfaceDefinition::Program> generateProgramDefinitionFromResource (const ResourceDefinition::Node* resource)
547 de::MovePtr<ProgramInterfaceDefinition::Program> program (new ProgramInterfaceDefinition::Program());
548 const ResourceDefinition::Node* head = resource;
550 if (head->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
552 DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));
557 BINDING_INTERFACE_BLOCK,
558 BINDING_DEFAULT_BLOCK
562 int autoAssignArraySize = 0;
563 const glu::DataType basicType = static_cast<const ResourceDefinition::Variable*>(resource)->m_dataType;
564 BindingType boundObject = BINDING_VARIABLE;
565 glu::VariableDeclaration variable (glu::VarType(basicType, getDataTypeDefaultPrecision(basicType)), "target");
566 glu::InterfaceBlock interfaceBlock;
567 ProgramInterfaceDefinition::DefaultBlock defaultBlock;
568 std::vector<std::string> feedbackTargetVaryingPath;
569 bool feedbackTargetSet = false;
572 if (glu::isDataTypeImage(basicType))
574 variable.memoryAccessQualifierBits |= glu::MEMORYACCESSQUALIFIER_READONLY_BIT;
575 variable.layout.binding = 1;
577 if (basicType >= glu::TYPE_IMAGE_2D && basicType <= glu::TYPE_IMAGE_3D)
578 variable.layout.format = glu::FORMATLAYOUT_RGBA8;
579 else if (basicType >= glu::TYPE_INT_IMAGE_2D && basicType <= glu::TYPE_INT_IMAGE_3D)
580 variable.layout.format = glu::FORMATLAYOUT_RGBA8I;
581 else if (basicType >= glu::TYPE_UINT_IMAGE_2D && basicType <= glu::TYPE_UINT_IMAGE_3D)
582 variable.layout.format = glu::FORMATLAYOUT_RGBA8UI;
587 // atomic counter specific
588 if (basicType == glu::TYPE_UINT_ATOMIC_COUNTER)
589 variable.layout.binding = 1;
591 for (head = head->getEnclosingNode(); head; head = head->getEnclosingNode())
593 if (head->getType() == ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER)
595 const ResourceDefinition::StorageQualifier* qualifier = static_cast<const ResourceDefinition::StorageQualifier*>(head);
597 DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(head));
599 if (boundObject == BINDING_VARIABLE)
601 DE_ASSERT(variable.storage == glu::STORAGE_LAST);
602 variable.storage = qualifier->m_storage;
604 else if (boundObject == BINDING_INTERFACE_BLOCK)
606 DE_ASSERT(interfaceBlock.storage == glu::STORAGE_LAST);
607 interfaceBlock.storage = qualifier->m_storage;
612 else if (head->getType() == ResourceDefinition::Node::TYPE_LAYOUT_QUALIFIER)
614 const ResourceDefinition::LayoutQualifier* qualifier = static_cast<const ResourceDefinition::LayoutQualifier*>(head);
615 glu::Layout* targetLayout = DE_NULL;
617 DE_ASSERT(dynamic_cast<const ResourceDefinition::LayoutQualifier*>(head));
619 if (boundObject == BINDING_VARIABLE)
620 targetLayout = &variable.layout;
621 else if (boundObject == BINDING_INTERFACE_BLOCK)
622 targetLayout = &interfaceBlock.layout;
626 if (qualifier->m_layout.location != -1)
627 targetLayout->location = qualifier->m_layout.location;
629 if (qualifier->m_layout.binding != -1)
630 targetLayout->binding = qualifier->m_layout.binding;
632 if (qualifier->m_layout.offset != -1)
633 targetLayout->offset = qualifier->m_layout.offset;
635 if (qualifier->m_layout.format != glu::FORMATLAYOUT_LAST)
636 targetLayout->format = qualifier->m_layout.format;
638 if (qualifier->m_layout.matrixOrder != glu::MATRIXORDER_LAST)
639 targetLayout->matrixOrder = qualifier->m_layout.matrixOrder;
641 else if (head->getType() == ResourceDefinition::Node::TYPE_INTERPOLATION_QUALIFIER)
643 const ResourceDefinition::InterpolationQualifier* qualifier = static_cast<const ResourceDefinition::InterpolationQualifier*>(head);
645 DE_ASSERT(dynamic_cast<const ResourceDefinition::InterpolationQualifier*>(head));
647 if (boundObject == BINDING_VARIABLE)
648 variable.interpolation = qualifier->m_interpolation;
652 else if (head->getType() == ResourceDefinition::Node::TYPE_ARRAY_ELEMENT)
654 DE_ASSERT(dynamic_cast<const ResourceDefinition::ArrayElement*>(head));
656 const ResourceDefinition::ArrayElement* arrayElement = static_cast<const ResourceDefinition::ArrayElement*>(head);
659 // Vary array size per level
660 if (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::DEFAULT_SIZE)
662 if (--autoAssignArraySize <= 1)
663 autoAssignArraySize = 3;
665 arraySize = autoAssignArraySize;
667 else if (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::UNSIZED_ARRAY)
668 arraySize = glu::VarType::UNSIZED_ARRAY;
670 arraySize = arrayElement->m_arraySize;
672 if (boundObject == BINDING_VARIABLE)
673 variable.varType = glu::VarType(variable.varType, arraySize);
674 else if (boundObject == BINDING_INTERFACE_BLOCK)
675 interfaceBlock.dimensions.push_back(arraySize);
679 if (feedbackTargetSet)
680 feedbackTargetVaryingPath.back().append("[0]");
682 else if (head->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER)
684 DE_ASSERT(dynamic_cast<const ResourceDefinition::StructMember*>(head));
685 DE_ASSERT(boundObject == BINDING_VARIABLE);
687 // Struct members cannot contain any qualifiers except precision
688 DE_ASSERT(variable.interpolation == glu::INTERPOLATION_LAST);
689 DE_ASSERT(variable.layout == glu::Layout());
690 DE_ASSERT(variable.memoryAccessQualifierBits == 0);
691 DE_ASSERT(variable.storage == glu::STORAGE_LAST);
694 glu::StructType* structPtr = new glu::StructType(("StructType" + de::toString(structNdx++)).c_str());
695 structPtr->addMember(variable.name.c_str(), variable.varType);
697 variable = glu::VariableDeclaration(glu::VarType(structPtr), "target");
700 if (feedbackTargetSet)
701 feedbackTargetVaryingPath.push_back("target");
703 else if (head->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
705 DE_ASSERT(dynamic_cast<const ResourceDefinition::InterfaceBlock*>(head));
706 DE_ASSERT(boundObject == BINDING_VARIABLE);
708 const bool named = static_cast<const ResourceDefinition::InterfaceBlock*>(head)->m_named;
710 boundObject = BINDING_INTERFACE_BLOCK;
712 interfaceBlock.interfaceName = "TargetInterface";
713 interfaceBlock.instanceName = (named) ? ("targetInstance") : ("");
714 interfaceBlock.variables.push_back(variable);
716 if (feedbackTargetSet && !interfaceBlock.instanceName.empty())
717 feedbackTargetVaryingPath.push_back(interfaceBlock.interfaceName);
719 else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
721 DE_ASSERT(dynamic_cast<const ResourceDefinition::DefaultBlock*>(head));
722 DE_ASSERT(boundObject == BINDING_VARIABLE || boundObject == BINDING_INTERFACE_BLOCK);
724 if (boundObject == BINDING_VARIABLE)
725 defaultBlock.variables.push_back(variable);
726 else if (boundObject == BINDING_INTERFACE_BLOCK)
727 defaultBlock.interfaceBlocks.push_back(interfaceBlock);
731 boundObject = BINDING_DEFAULT_BLOCK;
733 else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER)
735 DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(head));
737 const ResourceDefinition::Shader* shaderDef = static_cast<const ResourceDefinition::Shader*>(head);
738 ProgramInterfaceDefinition::Shader* shader = program->addShader(shaderDef->m_type, shaderDef->m_version);
740 shader->getDefaultBlock() = defaultBlock;
742 else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER_SET)
744 DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(head));
746 const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(head);
748 for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
750 if (shaderDef->isStagePresent((glu::ShaderType)shaderType))
752 ProgramInterfaceDefinition::Shader* shader = program->addShader((glu::ShaderType)shaderType, shaderDef->m_version);
754 if (shaderDef->isStageReferencing((glu::ShaderType)shaderType))
755 shader->getDefaultBlock() = defaultBlock;
759 else if (head->getType() == ResourceDefinition::Node::TYPE_PROGRAM)
761 DE_ASSERT(dynamic_cast<const ResourceDefinition::Program*>(head));
763 const ResourceDefinition::Program* programDef = static_cast<const ResourceDefinition::Program*>(head);
765 program->setSeparable(programDef->m_separable);
767 DE_ASSERT(feedbackTargetSet == !feedbackTargetVaryingPath.empty());
768 if (!feedbackTargetVaryingPath.empty())
770 std::ostringstream buf;
772 for (std::vector<std::string>::reverse_iterator it = feedbackTargetVaryingPath.rbegin(); it != feedbackTargetVaryingPath.rend(); ++it)
774 if (it != feedbackTargetVaryingPath.rbegin())
779 program->addTransformFeedbackVarying(buf.str());
780 program->setTransformFeedbackMode(GL_INTERLEAVED_ATTRIBS);
784 else if (head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
786 DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(head));
788 const ResourceDefinition::TransformFeedbackTarget* feedbackTarget = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(head);
790 DE_ASSERT(feedbackTarget->m_builtinVarName == DE_NULL);
791 DE_UNREF(feedbackTarget);
793 feedbackTargetSet = true;
794 feedbackTargetVaryingPath.push_back(variable.name);
803 else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK ||
804 head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
806 const char* feedbackTargetVaryingName = DE_NULL;
808 // empty default block
810 for (; head; head = head->getEnclosingNode())
812 if (head->getType() == ResourceDefinition::Node::TYPE_SHADER)
814 DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(head));
816 const ResourceDefinition::Shader* shaderDef = static_cast<const ResourceDefinition::Shader*>(head);
818 program->addShader(shaderDef->m_type, shaderDef->m_version);
820 else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER_SET)
822 DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(head));
824 const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(head);
826 for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
827 if (shaderDef->isStagePresent((glu::ShaderType)shaderType))
828 program->addShader((glu::ShaderType)shaderType, shaderDef->m_version);
830 else if (head->getType() == ResourceDefinition::Node::TYPE_PROGRAM)
832 DE_ASSERT(dynamic_cast<const ResourceDefinition::Program*>(head));
834 const ResourceDefinition::Program* programDef = static_cast<const ResourceDefinition::Program*>(head);
836 program->setSeparable(programDef->m_separable);
837 if (feedbackTargetVaryingName)
839 program->addTransformFeedbackVarying(std::string(feedbackTargetVaryingName));
840 program->setTransformFeedbackMode(GL_INTERLEAVED_ATTRIBS);
844 else if (head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
846 DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(head));
848 const ResourceDefinition::TransformFeedbackTarget* feedbackTarget = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(head);
850 DE_ASSERT(feedbackTarget->m_builtinVarName != DE_NULL);
852 feedbackTargetVaryingName = feedbackTarget->m_builtinVarName;
854 else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
865 if (program->hasStage(glu::SHADERTYPE_GEOMETRY))
866 program->setGeometryNumOutputVertices(1);
867 if (program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
868 program->setTessellationNumOutputPatchVertices(1);
873 static void checkAndLogProgram (const glu::ShaderProgram& program, const ProgramInterfaceDefinition::Program* programDefinition, const glw::Functions& gl, tcu::TestLog& log)
875 const tcu::ScopedLogSection section(log, "Program", "Program");
880 log << tcu::TestLog::Message << "Program build failed, checking if program exceeded implementation limits" << tcu::TestLog::EndMessage;
881 checkProgramResourceUsage(programDefinition, gl, log);
884 throw tcu::TestError("could not build program");
888 // Resource list query case
890 class ResourceListTestCase : public TestCase
893 ResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, ProgramInterface interface, const char* name = DE_NULL);
894 ~ResourceListTestCase (void);
899 IterateResult iterate (void);
901 void queryResourceList (std::vector<std::string>& dst, glw::GLuint program);
902 bool verifyResourceList (const std::vector<std::string>& resourceList, const std::vector<std::string>& expectedResources);
903 bool verifyResourceIndexQuery (const std::vector<std::string>& resourceList, const std::vector<std::string>& referenceResources, glw::GLuint program);
904 bool verifyMaxNameLength (const std::vector<std::string>& referenceResourceList, glw::GLuint program);
906 static std::string genTestCaseName (ProgramInterface interface, const ResourceDefinition::Node*);
907 static bool isArrayedInterface (ProgramInterface interface, deUint32 stageBits);
909 const ProgramInterface m_programInterface;
910 ResourceDefinition::Node::SharedPtr m_targetResource;
911 ProgramInterfaceDefinition::Program* m_programDefinition;
914 ResourceListTestCase::ResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, ProgramInterface interface, const char* name)
915 : TestCase (context, (name == DE_NULL) ? (genTestCaseName(interface, targetResource.get()).c_str()) : (name), "")
916 , m_programInterface (interface)
917 , m_targetResource (targetResource)
918 , m_programDefinition (DE_NULL)
920 // GL_ATOMIC_COUNTER_BUFFER: no resource names
921 DE_ASSERT(m_programInterface != PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER);
924 ResourceListTestCase::~ResourceListTestCase (void)
929 void ResourceListTestCase::init (void)
931 m_programDefinition = generateProgramDefinitionFromResource(m_targetResource.get()).release();
932 const bool supportsES32orGL45 = checkSupport(m_context);
934 if ((m_programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION)) &&
935 !supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
937 throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
939 if (m_programDefinition->hasStage(glu::SHADERTYPE_GEOMETRY) &&
940 !supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
942 throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
944 if (programContainsIOBlocks(m_programDefinition) &&
945 !supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_shader_io_blocks"))
947 throw tcu::NotSupportedError("Test requires GL_EXT_shader_io_blocks extension");
951 void ResourceListTestCase::deinit (void)
953 m_targetResource.clear();
955 delete m_programDefinition;
956 m_programDefinition = DE_NULL;
959 ResourceListTestCase::IterateResult ResourceListTestCase::iterate (void)
961 const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_programDefinition));
963 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
964 checkAndLogProgram(program, m_programDefinition, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
966 // Check resource list
968 const tcu::ScopedLogSection section (m_testCtx.getLog(), "ResourceList", "Resource list");
969 std::vector<std::string> resourceList;
970 std::vector<std::string> expectedResources;
972 queryResourceList(resourceList, program.getProgram());
973 expectedResources = getProgramInterfaceResourceList(m_programDefinition, m_programInterface);
975 // verify the list and the expected list match
977 if (!verifyResourceList(resourceList, expectedResources))
978 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid resource list");
980 // verify GetProgramResourceIndex() matches the indices of the list
982 if (!verifyResourceIndexQuery(resourceList, expectedResources, program.getProgram()))
983 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GetProgramResourceIndex returned unexpected values");
985 // Verify MAX_NAME_LENGTH
986 if (!verifyMaxNameLength(resourceList, program.getProgram()))
987 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "MAX_NAME_LENGTH invalid");
993 void ResourceListTestCase::queryResourceList (std::vector<std::string>& dst, glw::GLuint program)
995 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
996 const glw::GLenum programInterface = getProgramInterfaceGLEnum(m_programInterface);
997 glw::GLint numActiveResources = 0;
998 glw::GLint maxNameLength = 0;
999 std::vector<char> buffer;
1001 m_testCtx.getLog() << tcu::TestLog::Message << "Querying " << glu::getProgramInterfaceName(programInterface) << " interface:" << tcu::TestLog::EndMessage;
1003 gl.getProgramInterfaceiv(program, programInterface, GL_ACTIVE_RESOURCES, &numActiveResources);
1004 gl.getProgramInterfaceiv(program, programInterface, GL_MAX_NAME_LENGTH, &maxNameLength);
1005 GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
1007 m_testCtx.getLog() << tcu::TestLog::Message
1008 << "\tGL_ACTIVE_RESOURCES = " << numActiveResources << "\n"
1009 << "\tGL_MAX_NAME_LENGTH = " << maxNameLength
1010 << tcu::TestLog::EndMessage;
1012 m_testCtx.getLog() << tcu::TestLog::Message << "Querying all active resources" << tcu::TestLog::EndMessage;
1014 buffer.resize(maxNameLength+1, '\0');
1016 for (int resourceNdx = 0; resourceNdx < numActiveResources; ++resourceNdx)
1018 glw::GLint written = 0;
1020 gl.getProgramResourceName(program, programInterface, resourceNdx, maxNameLength, &written, &buffer[0]);
1021 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource name");
1023 dst.push_back(std::string(&buffer[0], written));
1027 bool ResourceListTestCase::verifyResourceList (const std::vector<std::string>& resourceList, const std::vector<std::string>& expectedResources)
1031 // Log and compare resource lists
1033 m_testCtx.getLog() << tcu::TestLog::Message << "GL returned resources:" << tcu::TestLog::EndMessage;
1035 for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1037 // unusedZero is a uniform that may be added by
1038 // generateProgramInterfaceProgramSources. Omit it here to avoid
1039 // confusion about the output.
1040 if (resourceList[ndx] != getUnusedZeroUniformName())
1041 m_testCtx.getLog() << tcu::TestLog::Message << "\t" << ndx << ": " << resourceList[ndx] << tcu::TestLog::EndMessage;
1044 m_testCtx.getLog() << tcu::TestLog::Message << "Expected list of resources:" << tcu::TestLog::EndMessage;
1046 for (int ndx = 0; ndx < (int)expectedResources.size(); ++ndx)
1047 m_testCtx.getLog() << tcu::TestLog::Message << "\t" << ndx << ": " << expectedResources[ndx] << tcu::TestLog::EndMessage;
1049 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying resource list contents." << tcu::TestLog::EndMessage;
1051 for (int ndx = 0; ndx < (int)expectedResources.size(); ++ndx)
1053 if (!de::contains(resourceList.begin(), resourceList.end(), expectedResources[ndx]))
1055 m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource list did not contain active resource " << expectedResources[ndx] << tcu::TestLog::EndMessage;
1060 for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1062 if (!de::contains(expectedResources.begin(), expectedResources.end(), resourceList[ndx]))
1064 // Ignore all builtin variables or the variable unusedZero,
1065 // mismatch causes errors otherwise. unusedZero is a uniform that
1066 // may be added by generateProgramInterfaceProgramSources.
1067 if (deStringBeginsWith(resourceList[ndx].c_str(), "gl_") == DE_FALSE &&
1068 resourceList[ndx] != getUnusedZeroUniformName())
1070 m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource list contains unexpected resource name " << resourceList[ndx] << tcu::TestLog::EndMessage;
1074 m_testCtx.getLog() << tcu::TestLog::Message << "Note, resource list contains unknown built-in " << resourceList[ndx] << ". This variable is ignored." << tcu::TestLog::EndMessage;
1081 bool ResourceListTestCase::verifyResourceIndexQuery (const std::vector<std::string>& resourceList, const std::vector<std::string>& referenceResources, glw::GLuint program)
1083 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1084 const glw::GLenum programInterface = getProgramInterfaceGLEnum(m_programInterface);
1087 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying GetProgramResourceIndex returns correct indices for resource names." << tcu::TestLog::EndMessage;
1089 for (int ndx = 0; ndx < (int)referenceResources.size(); ++ndx)
1091 const glw::GLuint index = gl.getProgramResourceIndex(program, programInterface, referenceResources[ndx].c_str());
1092 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1094 if (index == GL_INVALID_INDEX)
1096 m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx] << "\" got index GL_INVALID_INDEX." << tcu::TestLog::EndMessage;
1099 else if ((int)index >= (int)resourceList.size())
1101 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;
1104 else if (resourceList[index] != referenceResources[ndx])
1106 m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx] << "\" got index (index = " << index << ") of another resource (" << resourceList[index] << ")." << tcu::TestLog::EndMessage;
1111 // Query for "name" should match "name[0]" except for XFB
1113 if (m_programInterface != PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING)
1115 for (int ndx = 0; ndx < (int)referenceResources.size(); ++ndx)
1117 if (de::endsWith(referenceResources[ndx], "[0]"))
1119 const std::string queryString = referenceResources[ndx].substr(0, referenceResources[ndx].length()-3);
1120 const glw::GLuint index = gl.getProgramResourceIndex(program, programInterface, queryString.c_str());
1121 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1123 if (index == GL_INVALID_INDEX)
1125 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" resulted in index GL_INVALID_INDEX." << tcu::TestLog::EndMessage;
1128 else if ((int)index >= (int)resourceList.size())
1130 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" resulted in index " << index << " (larger or equal to GL_ACTIVE_RESOURCES)." << tcu::TestLog::EndMessage;
1133 else if (resourceList[index] != queryString + "[0]")
1135 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" got index (index = " << index << ") of another resource (\"" << resourceList[index] << "\")." << tcu::TestLog::EndMessage;
1145 bool ResourceListTestCase::verifyMaxNameLength (const std::vector<std::string>& resourceList, glw::GLuint program)
1147 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1148 const glw::GLenum programInterface = getProgramInterfaceGLEnum(m_programInterface);
1149 glw::GLint maxNameLength = 0;
1150 glw::GLint expectedMaxNameLength = 0;
1152 gl.getProgramInterfaceiv(program, programInterface, GL_MAX_NAME_LENGTH, &maxNameLength);
1153 GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
1155 for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1156 expectedMaxNameLength = de::max(expectedMaxNameLength, (int)resourceList[ndx].size() + 1);
1158 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying MAX_NAME_LENGTH, expecting " << expectedMaxNameLength << " (i.e. consistent with the queried resource list)" << tcu::TestLog::EndMessage;
1160 if (expectedMaxNameLength != maxNameLength)
1162 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got " << maxNameLength << tcu::TestLog::EndMessage;
1169 std::string ResourceListTestCase::genTestCaseName (ProgramInterface interface, const ResourceDefinition::Node* root)
1171 bool isImplicitlySizedArray = false;
1172 bool hasVariable = false;
1173 bool accumulateName = true;
1174 std::string buf = "var";
1177 for (const ResourceDefinition::Node* node = root; node; node = node->getEnclosingNode())
1179 switch (node->getType())
1181 case ResourceDefinition::Node::TYPE_VARIABLE:
1187 case ResourceDefinition::Node::TYPE_STRUCT_MEMBER:
1194 case ResourceDefinition::Node::TYPE_ARRAY_ELEMENT:
1196 DE_ASSERT(dynamic_cast<const ResourceDefinition::ArrayElement*>(node));
1197 const ResourceDefinition::ArrayElement* arrayElement = static_cast<const ResourceDefinition::ArrayElement*>(node);
1199 isImplicitlySizedArray = (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::UNSIZED_ARRAY);
1206 case ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER:
1208 DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(node));
1209 const ResourceDefinition::StorageQualifier* storageDef = static_cast<const ResourceDefinition::StorageQualifier*>(node);
1211 if (storageDef->m_storage == glu::STORAGE_PATCH_IN ||
1212 storageDef->m_storage == glu::STORAGE_PATCH_OUT)
1220 case ResourceDefinition::Node::TYPE_SHADER:
1221 case ResourceDefinition::Node::TYPE_SHADER_SET:
1223 bool arrayedInterface;
1225 if (node->getType() == ResourceDefinition::Node::TYPE_SHADER)
1227 DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(node));
1228 const ResourceDefinition::Shader* shaderDef = static_cast<const ResourceDefinition::Shader*>(node);
1230 arrayedInterface = isArrayedInterface(interface, (1u << shaderDef->m_type));
1234 DE_ASSERT(node->getType() == ResourceDefinition::Node::TYPE_SHADER_SET);
1235 DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(node));
1236 const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(node);
1238 arrayedInterface = isArrayedInterface(interface, shaderDef->getReferencingMask());
1241 if (arrayedInterface && isImplicitlySizedArray)
1243 // omit implicit arrayness from name, i.e. remove trailing "_array"
1244 DE_ASSERT(de::endsWith(buf, "_array"));
1245 buf = buf.substr(0, buf.length() - 6);
1251 case ResourceDefinition::Node::TYPE_INTERFACE_BLOCK:
1253 accumulateName = false;
1263 return prefix + "empty";
1265 return prefix + buf;
1268 bool ResourceListTestCase::isArrayedInterface (ProgramInterface interface, deUint32 stageBits)
1270 if (interface == PROGRAMINTERFACE_PROGRAM_INPUT)
1272 const glu::ShaderType firstStage = getShaderMaskFirstStage(stageBits);
1273 return firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
1274 firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
1275 firstStage == glu::SHADERTYPE_GEOMETRY;
1277 else if (interface == PROGRAMINTERFACE_PROGRAM_OUTPUT)
1279 const glu::ShaderType lastStage = getShaderMaskLastStage(stageBits);
1280 return lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL;
1285 // Resouce property query case
1287 class ResourceTestCase : public ProgramInterfaceQueryTestCase
1290 ResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, const ProgramResourceQueryTestTarget& queryTarget, const char* name = DE_NULL);
1291 ~ResourceTestCase (void);
1296 const ProgramInterfaceDefinition::Program* getProgramDefinition (void) const;
1297 std::vector<std::string> getQueryTargetResources (void) const;
1299 static std::string genTestCaseName (const ResourceDefinition::Node*);
1300 static std::string genMultilineDescription (const ResourceDefinition::Node*);
1302 ResourceDefinition::Node::SharedPtr m_targetResource;
1303 ProgramInterfaceDefinition::Program* m_program;
1304 std::vector<std::string> m_targetResources;
1307 ResourceTestCase::ResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, const ProgramResourceQueryTestTarget& queryTarget, const char* name)
1308 : ProgramInterfaceQueryTestCase (context, (name == DE_NULL) ? (genTestCaseName(targetResource.get()).c_str()) : (name), "", queryTarget)
1309 , m_targetResource (targetResource)
1310 , m_program (DE_NULL)
1314 ResourceTestCase::~ResourceTestCase (void)
1319 void ResourceTestCase::init (void)
1322 << tcu::TestLog::Message
1323 << genMultilineDescription(m_targetResource.get())
1324 << tcu::TestLog::EndMessage;
1328 // Generate interface with target resource
1329 m_program = generateProgramDefinitionFromResource(m_targetResource.get()).release();
1330 m_targetResources = getProgramInterfaceResourceList(m_program, getTargetInterface());
1334 void ResourceTestCase::deinit (void)
1336 m_targetResource.clear();
1339 m_program = DE_NULL;
1341 m_targetResources = std::vector<std::string>();
1344 const ProgramInterfaceDefinition::Program* ResourceTestCase::getProgramDefinition (void) const
1349 std::vector<std::string> ResourceTestCase::getQueryTargetResources (void) const
1351 return m_targetResources;
1354 std::string ResourceTestCase::genTestCaseName (const ResourceDefinition::Node* resource)
1356 if (resource->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
1358 DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));
1360 const ResourceDefinition::Variable* variable = static_cast<const ResourceDefinition::Variable*>(resource);
1362 return convertGLTypeNameToTestName(glu::getDataTypeName(variable->m_dataType));
1369 std::string ResourceTestCase::genMultilineDescription (const ResourceDefinition::Node* resource)
1371 if (resource->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
1373 DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));
1375 const ResourceDefinition::Variable* varDef = static_cast<const ResourceDefinition::Variable*>(resource);
1376 std::ostringstream buf;
1377 std::ostringstream structureDescriptor;
1378 std::string uniformType;
1380 for (const ResourceDefinition::Node* node = resource; node; node = node->getEnclosingNode())
1382 if (node->getType() == ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER)
1384 DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(node));
1386 const ResourceDefinition::StorageQualifier* storageDef = static_cast<const ResourceDefinition::StorageQualifier*>(node);
1388 uniformType = std::string(" ") + glu::getStorageName(storageDef->m_storage);
1389 structureDescriptor << "\n\tdeclared as \"" << glu::getStorageName(storageDef->m_storage) << "\"";
1392 if (node->getType() == ResourceDefinition::Node::TYPE_ARRAY_ELEMENT)
1393 structureDescriptor << "\n\tarray";
1395 if (node->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER)
1396 structureDescriptor << "\n\tin a struct";
1398 if (node->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
1399 structureDescriptor << "\n\tin the default block";
1401 if (node->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
1402 structureDescriptor << "\n\tin an interface block";
1405 buf << "Querying properties of " << glu::getDataTypeName(varDef->m_dataType) << uniformType << " variable.\n"
1407 << "\t" << glu::getDataTypeName(varDef->m_dataType)
1408 << structureDescriptor.str();
1412 else if (resource->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
1414 DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(resource));
1416 const ResourceDefinition::TransformFeedbackTarget* xfbDef = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(resource);
1418 DE_ASSERT(xfbDef->m_builtinVarName);
1420 return std::string("Querying properties of a builtin variable ") + xfbDef->m_builtinVarName;
1427 class ResourceNameBufferLimitCase : public TestCase
1430 ResourceNameBufferLimitCase (Context& context, const char* name, const char* description);
1431 ~ResourceNameBufferLimitCase (void);
1434 IterateResult iterate (void);
1437 ResourceNameBufferLimitCase::ResourceNameBufferLimitCase (Context& context, const char* name, const char* description)
1438 : TestCase(context, name, description)
1442 ResourceNameBufferLimitCase::~ResourceNameBufferLimitCase (void)
1446 ResourceNameBufferLimitCase::IterateResult ResourceNameBufferLimitCase::iterate (void)
1448 static const char* const computeSource = "${GLSL_VERSION_DECL}\n"
1449 "layout(local_size_x = 1) in;\n"
1450 "uniform highp int u_uniformWithALongName;\n"
1451 "writeonly buffer OutputBufferBlock { highp int b_output_int; };\n"
1454 " b_output_int = u_uniformWithALongName;\n"
1457 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1458 const glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(specializeShader(m_context, computeSource)));
1459 glw::GLuint uniformIndex;
1461 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1465 const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program", "Program");
1467 m_testCtx.getLog() << program;
1468 if (!program.isOk())
1469 throw tcu::TestError("could not build program");
1472 uniformIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_uniformWithALongName");
1473 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1475 if (uniformIndex == GL_INVALID_INDEX)
1476 throw tcu::TestError("Uniform u_uniformWithALongName resource index was GL_INVALID_INDEX");
1478 // Query with different sized buffers, len("u_uniformWithALongName") == 22
1483 const char* description;
1488 { "Query to larger buffer", 24, true },
1489 { "Query to buffer the same size", 23, true },
1490 { "Query to one byte too small buffer", 22, true },
1491 { "Query to one byte buffer", 1, true },
1492 { "Query to zero sized buffer", 0, true },
1493 { "Query to one byte too small buffer, null length argument", 22, false },
1494 { "Query to one byte buffer, null length argument", 1, false },
1495 { "Query to zero sized buffer, null length argument", 0, false },
1498 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(querySizes); ++ndx)
1500 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Query", querySizes[ndx].description);
1501 const int uniformNameLen = 22;
1502 const int expectedWriteLen = (querySizes[ndx].querySize != 0) ? (de::min(uniformNameLen, (querySizes[ndx].querySize - 1))) : (0);
1504 glw::GLsizei written = -1;
1506 // One byte for guard
1507 DE_ASSERT((int)sizeof(buffer) > querySizes[ndx].querySize);
1509 deMemset(buffer, 'x', sizeof(buffer));
1511 if (querySizes[ndx].querySize)
1513 << tcu::TestLog::Message
1514 << "Querying uniform name to a buffer of size " << querySizes[ndx].querySize
1515 << ", expecting query to write " << expectedWriteLen << " bytes followed by a null terminator"
1516 << tcu::TestLog::EndMessage;
1519 << tcu::TestLog::Message
1520 << "Querying uniform name to a buffer of size " << querySizes[ndx].querySize
1521 << ", expecting query to write 0 bytes"
1522 << tcu::TestLog::EndMessage;
1524 gl.getProgramResourceName(program.getProgram(), GL_UNIFORM, uniformIndex, querySizes[ndx].querySize, (querySizes[ndx].returnLength) ? (&written) : (DE_NULL), buffer);
1525 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource name");
1527 if (querySizes[ndx].returnLength && written != expectedWriteLen)
1529 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected write length of " << expectedWriteLen << ", got " << written << tcu::TestLog::EndMessage;
1530 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected write lenght");
1532 else if (querySizes[ndx].querySize != 0 && buffer[expectedWriteLen] != 0)
1534 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected null terminator at " << expectedWriteLen << ", got dec=" << (int)buffer[expectedWriteLen] << tcu::TestLog::EndMessage;
1535 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Missing null terminator");
1537 else if (querySizes[ndx].querySize != 0 && buffer[expectedWriteLen+1] != 'x')
1539 m_testCtx.getLog() << tcu::TestLog::Message << "Error, guard at index " << (expectedWriteLen+1) << " was modified, got dec=" << (int)buffer[expectedWriteLen+1] << tcu::TestLog::EndMessage;
1540 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrote over buffer size");
1542 else if (querySizes[ndx].querySize == 0 && buffer[0] != 'x')
1544 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;
1545 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents were modified");
1553 class ResourceQueryBufferLimitCase : public TestCase
1556 ResourceQueryBufferLimitCase (Context& context, const char* name, const char* description);
1557 ~ResourceQueryBufferLimitCase (void);
1560 IterateResult iterate (void);
1563 ResourceQueryBufferLimitCase::ResourceQueryBufferLimitCase (Context& context, const char* name, const char* description)
1564 : TestCase(context, name, description)
1568 ResourceQueryBufferLimitCase::~ResourceQueryBufferLimitCase (void)
1572 ResourceQueryBufferLimitCase::IterateResult ResourceQueryBufferLimitCase::iterate (void)
1574 static const char* const computeSource = "${GLSL_VERSION_DECL}\n"
1575 "layout(local_size_x = 1) in;\n"
1576 "uniform highp int u_uniform;\n"
1577 "writeonly buffer OutputBufferBlock { highp int b_output_int; };\n"
1580 " b_output_int = u_uniform;\n"
1583 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1584 const glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(specializeShader(m_context, computeSource)));
1585 glw::GLuint uniformIndex;
1587 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1591 const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program", "Program");
1593 m_testCtx.getLog() << program;
1594 if (!program.isOk())
1595 throw tcu::TestError("could not build program");
1598 uniformIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_uniform");
1599 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1601 if (uniformIndex == GL_INVALID_INDEX)
1602 throw tcu::TestError("Uniform u_uniform resource index was GL_INVALID_INDEX");
1604 // Query uniform properties
1609 const char* description;
1615 { "Query to a larger buffer", 2, 3, true },
1616 { "Query to too small a buffer", 3, 2, true },
1617 { "Query to zero sized buffer", 3, 0, true },
1618 { "Query to a larger buffer, null length argument", 2, 3, false },
1619 { "Query to too small a buffer, null length argument", 3, 2, false },
1620 { "Query to zero sized buffer, null length argument", 3, 0, false },
1623 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(querySizes); ++ndx)
1625 const tcu::ScopedLogSection section (m_testCtx.getLog(), "QueryToLarger", querySizes[ndx].description);
1626 const glw::GLenum props[] = { GL_LOCATION, GL_LOCATION, GL_LOCATION };
1627 const int expectedWriteLen = de::min(querySizes[ndx].bufferSize, querySizes[ndx].numProps);
1628 int params[] = { 255, 255, 255, 255 };
1629 glw::GLsizei written = -1;
1631 DE_ASSERT(querySizes[ndx].numProps <= DE_LENGTH_OF_ARRAY(props));
1632 DE_ASSERT(querySizes[ndx].bufferSize < DE_LENGTH_OF_ARRAY(params)); // leave at least one element for overflow detection
1635 << tcu::TestLog::Message
1636 << "Querying " << querySizes[ndx].numProps << " uniform prop(s) to a buffer with size " << querySizes[ndx].bufferSize << ". Expecting query to return " << expectedWriteLen << " prop(s)"
1637 << tcu::TestLog::EndMessage;
1639 gl.getProgramResourceiv(program.getProgram(), GL_UNIFORM, uniformIndex, querySizes[ndx].numProps, props, querySizes[ndx].bufferSize, (querySizes[ndx].returnLength) ? (&written) : (DE_NULL), params);
1640 GLU_EXPECT_NO_ERROR(gl.getError(), "query program resources");
1642 if (querySizes[ndx].returnLength && written != expectedWriteLen)
1644 m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected write length of " << expectedWriteLen << ", got " << written << tcu::TestLog::EndMessage;
1645 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected write lenght");
1647 else if (params[expectedWriteLen] != 255)
1649 m_testCtx.getLog() << tcu::TestLog::Message << "Error, guard at index " << (expectedWriteLen) << " was modified. Was 255 before call, got dec=" << params[expectedWriteLen] << tcu::TestLog::EndMessage;
1650 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrote over buffer size");
1658 class InterfaceBlockBaseCase : public TestCase
1663 CASE_NAMED_BLOCK = 0,
1670 InterfaceBlockBaseCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
1671 ~InterfaceBlockBaseCase (void);
1678 const glu::Storage m_storage;
1679 const CaseType m_caseType;
1680 ProgramInterfaceDefinition::Program* m_program;
1683 InterfaceBlockBaseCase::InterfaceBlockBaseCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
1684 : TestCase (context, name, description)
1685 , m_storage (storage)
1686 , m_caseType (caseType)
1687 , m_program (DE_NULL)
1689 DE_ASSERT(storage == glu::STORAGE_UNIFORM || storage == glu::STORAGE_BUFFER);
1692 InterfaceBlockBaseCase::~InterfaceBlockBaseCase (void)
1697 void InterfaceBlockBaseCase::init (void)
1699 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
1700 ProgramInterfaceDefinition::Shader* shader;
1702 m_program = new ProgramInterfaceDefinition::Program();
1703 shader = m_program->addShader(glu::SHADERTYPE_COMPUTE, glslVersion);
1705 // PrecedingInterface
1707 glu::InterfaceBlock precedingInterfaceBlock;
1709 precedingInterfaceBlock.interfaceName = "PrecedingInterface";
1710 precedingInterfaceBlock.layout.binding = 0;
1711 precedingInterfaceBlock.storage = m_storage;
1712 precedingInterfaceBlock.instanceName = "precedingInstance";
1714 precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "precedingMember"));
1716 // Unsized array type
1717 if (m_storage == glu::STORAGE_BUFFER)
1718 precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY), "precedingMemberUnsizedArray"));
1720 precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 2), "precedingMemberArray"));
1722 shader->getDefaultBlock().interfaceBlocks.push_back(precedingInterfaceBlock);
1727 glu::InterfaceBlock targetInterfaceBlock;
1729 targetInterfaceBlock.interfaceName = "TargetInterface";
1730 targetInterfaceBlock.layout.binding = 1;
1731 targetInterfaceBlock.storage = m_storage;
1733 if (m_caseType == CASE_UNNAMED_BLOCK)
1734 targetInterfaceBlock.instanceName = "";
1736 targetInterfaceBlock.instanceName = "targetInstance";
1738 if (m_caseType == CASE_BLOCK_ARRAY)
1739 targetInterfaceBlock.dimensions.push_back(2);
1743 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "blockMemberBasic"));
1748 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 3), "blockMemberArray"));
1753 glu::StructType* structPtr = new glu::StructType("StructType");
1754 structPtr->addMember("structMemberBasic", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP));
1755 structPtr->addMember("structMemberArray", glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 2));
1757 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(structPtr), 2), "blockMemberStruct"));
1760 // Unsized array type
1761 if (m_storage == glu::STORAGE_BUFFER)
1762 targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY), "blockMemberUnsizedArray"));
1764 shader->getDefaultBlock().interfaceBlocks.push_back(targetInterfaceBlock);
1767 // TrailingInterface
1769 glu::InterfaceBlock trailingInterfaceBlock;
1771 trailingInterfaceBlock.interfaceName = "TrailingInterface";
1772 trailingInterfaceBlock.layout.binding = 3;
1773 trailingInterfaceBlock.storage = m_storage;
1774 trailingInterfaceBlock.instanceName = "trailingInstance";
1775 trailingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "trailingMember"));
1777 shader->getDefaultBlock().interfaceBlocks.push_back(trailingInterfaceBlock);
1780 DE_ASSERT(m_program->isValid());
1783 void InterfaceBlockBaseCase::deinit (void)
1786 m_program = DE_NULL;
1789 class InterfaceBlockActiveVariablesTestCase : public InterfaceBlockBaseCase
1792 InterfaceBlockActiveVariablesTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
1795 IterateResult iterate (void);
1798 InterfaceBlockActiveVariablesTestCase::InterfaceBlockActiveVariablesTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
1799 : InterfaceBlockBaseCase(context, name, description, storage, caseType)
1803 InterfaceBlockActiveVariablesTestCase::IterateResult InterfaceBlockActiveVariablesTestCase::iterate (void)
1805 const ProgramInterface programInterface = (m_storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
1806 (m_storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
1807 (PROGRAMINTERFACE_LAST);
1808 const glw::GLenum programGLInterfaceValue = getProgramInterfaceGLEnum(programInterface);
1809 const glw::GLenum programMemberInterfaceValue = (m_storage == glu::STORAGE_UNIFORM) ? (GL_UNIFORM) :
1810 (m_storage == glu::STORAGE_BUFFER) ? (GL_BUFFER_VARIABLE) :
1812 const std::vector<std::string> blockNames = getProgramInterfaceResourceList(m_program, programInterface);
1813 glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
1814 int expectedMaxNumActiveVariables = 0;
1816 DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
1818 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1819 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1821 // Verify all blocks
1823 for (int blockNdx = 0; blockNdx < (int)blockNames.size(); ++blockNdx)
1825 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Block", "Block \"" + blockNames[blockNdx] + "\"");
1826 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1827 const glw::GLuint resourceNdx = gl.getProgramResourceIndex(program.getProgram(), programGLInterfaceValue, blockNames[blockNdx].c_str());
1828 glw::GLint numActiveResources;
1829 std::vector<std::string> activeResourceNames;
1831 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1833 if (resourceNdx == GL_INVALID_INDEX)
1835 m_testCtx.getLog() << tcu::TestLog::Message << "Error, getProgramResourceIndex returned GL_INVALID_INDEX for \"" << blockNames[blockNdx] << "\"" << tcu::TestLog::EndMessage;
1836 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Resource not found");
1840 // query block information
1843 const glw::GLenum props[] = { GL_NUM_ACTIVE_VARIABLES };
1844 glw::GLint retBuffer[2] = { -1, -1 };
1845 glw::GLint written = -1;
1847 gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, DE_LENGTH_OF_ARRAY(props), props, 1, &written, retBuffer);
1848 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_NUM_ACTIVE_VARIABLES");
1850 numActiveResources = retBuffer[0];
1851 expectedMaxNumActiveVariables = de::max(expectedMaxNumActiveVariables, numActiveResources);
1852 m_testCtx.getLog() << tcu::TestLog::Message << "NUM_ACTIVE_VARIABLES = " << numActiveResources << tcu::TestLog::EndMessage;
1854 if (written == -1 || retBuffer[0] == -1)
1856 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for NUM_ACTIVE_VARIABLES did not return a value" << tcu::TestLog::EndMessage;
1857 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for NUM_ACTIVE_VARIABLES failed");
1860 else if (retBuffer[1] != -1)
1862 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for NUM_ACTIVE_VARIABLES returned too many values" << tcu::TestLog::EndMessage;
1863 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for NUM_ACTIVE_VARIABLES returned too many values");
1866 else if (retBuffer[0] < 0)
1868 m_testCtx.getLog() << tcu::TestLog::Message << "Error, NUM_ACTIVE_VARIABLES < 0" << tcu::TestLog::EndMessage;
1869 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "NUM_ACTIVE_VARIABLES < 0");
1874 // query block variable information
1877 const glw::GLenum props[] = { GL_ACTIVE_VARIABLES };
1878 std::vector<glw::GLint> activeVariableIndices (numActiveResources + 1, -1); // Allocate one extra trailing to detect wrong write lengths
1879 glw::GLint written = -1;
1881 gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, DE_LENGTH_OF_ARRAY(props), props, (glw::GLsizei)activeVariableIndices.size(), &written, &activeVariableIndices[0]);
1882 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_ACTIVE_VARIABLES");
1886 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for GL_ACTIVE_VARIABLES did not return any values" << tcu::TestLog::EndMessage;
1887 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES failed");
1890 else if (written != numActiveResources)
1892 m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for GL_ACTIVE_VARIABLES did not return NUM_ACTIVE_VARIABLES values" << tcu::TestLog::EndMessage;
1893 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES returned invalid number of values");
1896 else if (activeVariableIndices.back() != -1)
1898 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;
1899 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES returned too many values");
1905 tcu::MessageBuilder builder(&m_testCtx.getLog());
1907 builder << "Active variable indices: {";
1908 for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1912 builder << activeVariableIndices[varNdx];
1914 builder << "}" << tcu::TestLog::EndMessage;
1919 activeResourceNames.resize(numActiveResources);
1921 for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1923 const glw::GLenum nameProp = GL_NAME_LENGTH;
1924 glw::GLint nameLength = -1;
1925 std::vector<char> nameBuffer;
1928 gl.getProgramResourceiv(program.getProgram(), programMemberInterfaceValue, activeVariableIndices[varNdx], 1, &nameProp, 1, &written, &nameLength);
1929 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_NAME_LENGTH");
1931 if (nameLength <= 0 || written <= 0)
1933 m_testCtx.getLog() << tcu::TestLog::Message << "Error, GL_NAME_LENGTH query failed" << tcu::TestLog::EndMessage;
1934 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GL_NAME_LENGTH query failed");
1938 nameBuffer.resize(nameLength + 2, 'X'); // allocate more than required
1940 gl.getProgramResourceName(program.getProgram(), programMemberInterfaceValue, activeVariableIndices[varNdx], nameLength+1, &written, &nameBuffer[0]);
1941 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramResourceName");
1945 m_testCtx.getLog() << tcu::TestLog::Message << "Error, name query failed, no data written" << tcu::TestLog::EndMessage;
1946 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "name query failed");
1949 else if (written > nameLength)
1951 m_testCtx.getLog() << tcu::TestLog::Message << "Error, name query failed, query returned too much data" << tcu::TestLog::EndMessage;
1952 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "name query failed");
1956 activeResourceNames[varNdx] = std::string(&nameBuffer[0], written);
1959 // log collected names
1961 tcu::MessageBuilder builder(&m_testCtx.getLog());
1963 builder << "Active variables:\n";
1964 for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1965 builder << "\t" << activeResourceNames[varNdx] << "\n";
1966 builder << tcu::TestLog::EndMessage;
1972 glu::InterfaceBlock* block = DE_NULL;
1973 const std::string blockName = glu::parseVariableName(blockNames[blockNdx].c_str());
1974 std::vector<std::string> referenceList;
1976 for (int interfaceNdx = 0; interfaceNdx < (int)m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx)
1978 if (m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].interfaceName == blockName)
1980 block = &m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx];
1986 throw tcu::InternalError("could not find block referenced in the reference resource list");
1988 // generate reference list
1990 referenceList = getProgramInterfaceBlockMemberResourceList(*block);
1992 tcu::MessageBuilder builder(&m_testCtx.getLog());
1994 builder << "Expected variable names:\n";
1995 for (int varNdx = 0; varNdx < (int)referenceList.size(); ++varNdx)
1996 builder << "\t" << referenceList[varNdx] << "\n";
1997 builder << tcu::TestLog::EndMessage;
2002 bool listsIdentical = true;
2004 for (int ndx = 0; ndx < (int)referenceList.size(); ++ndx)
2006 if (!de::contains(activeResourceNames.begin(), activeResourceNames.end(), referenceList[ndx]))
2008 m_testCtx.getLog() << tcu::TestLog::Message << "Error, variable name list did not contain active variable " << referenceList[ndx] << tcu::TestLog::EndMessage;
2009 listsIdentical = false;
2013 for (int ndx = 0; ndx < (int)activeResourceNames.size(); ++ndx)
2015 if (!de::contains(referenceList.begin(), referenceList.end(), activeResourceNames[ndx]))
2017 m_testCtx.getLog() << tcu::TestLog::Message << "Error, variable name list contains unexpected resource \"" << activeResourceNames[ndx] << "\"" << tcu::TestLog::EndMessage;
2018 listsIdentical = false;
2023 m_testCtx.getLog() << tcu::TestLog::Message << "Lists identical" << tcu::TestLog::EndMessage;
2026 m_testCtx.getLog() << tcu::TestLog::Message << "Error, invalid active variable list" << tcu::TestLog::EndMessage;
2027 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid active variable list");
2034 // Max num active variables
2036 const tcu::ScopedLogSection section (m_testCtx.getLog(), "MaxNumActiveVariables", "MAX_NUM_ACTIVE_VARIABLES");
2037 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2038 glw::GLint maxNumActiveVariables = -1;
2040 gl.getProgramInterfaceiv(program.getProgram(), programGLInterfaceValue, GL_MAX_NUM_ACTIVE_VARIABLES, &maxNumActiveVariables);
2041 GLU_EXPECT_NO_ERROR(gl.getError(), "query MAX_NUM_ACTIVE_VARIABLES");
2043 m_testCtx.getLog() << tcu::TestLog::Message << "MAX_NUM_ACTIVE_VARIABLES = " << maxNumActiveVariables << tcu::TestLog::EndMessage;
2045 if (expectedMaxNumActiveVariables != maxNumActiveVariables)
2047 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected MAX_NUM_ACTIVE_VARIABLES" << tcu::TestLog::EndMessage;
2048 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected MAX_NUM_ACTIVE_VARIABLES");
2051 m_testCtx.getLog() << tcu::TestLog::Message << "MAX_NUM_ACTIVE_VARIABLES valid" << tcu::TestLog::EndMessage;
2057 class InterfaceBlockDataSizeTestCase : public InterfaceBlockBaseCase
2060 InterfaceBlockDataSizeTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
2063 IterateResult iterate (void);
2064 int getBlockMinDataSize (const std::string& blockName) const;
2065 int getBlockMinDataSize (const glu::InterfaceBlock& block) const;
2068 InterfaceBlockDataSizeTestCase::InterfaceBlockDataSizeTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
2069 : InterfaceBlockBaseCase(context, name, description, storage, caseType)
2073 InterfaceBlockDataSizeTestCase::IterateResult InterfaceBlockDataSizeTestCase::iterate (void)
2075 const ProgramInterface programInterface = (m_storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
2076 (m_storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
2077 (PROGRAMINTERFACE_LAST);
2078 const glw::GLenum programGLInterfaceValue = getProgramInterfaceGLEnum(programInterface);
2079 const std::vector<std::string> blockNames = getProgramInterfaceResourceList(m_program, programInterface);
2080 glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2082 DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
2084 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2085 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2087 // Verify all blocks
2088 for (int blockNdx = 0; blockNdx < (int)blockNames.size(); ++blockNdx)
2090 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Block", "Block \"" + blockNames[blockNdx] + "\"");
2091 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2092 const glw::GLuint resourceNdx = gl.getProgramResourceIndex(program.getProgram(), programGLInterfaceValue, blockNames[blockNdx].c_str());
2093 const int expectedMinDataSize = getBlockMinDataSize(blockNames[blockNdx]);
2094 glw::GLint queryDataSize = -1;
2096 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
2098 if (resourceNdx == GL_INVALID_INDEX)
2100 m_testCtx.getLog() << tcu::TestLog::Message << "Error, getProgramResourceIndex returned GL_INVALID_INDEX for \"" << blockNames[blockNdx] << "\"" << tcu::TestLog::EndMessage;
2101 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Resource not found");
2107 const glw::GLenum prop = GL_BUFFER_DATA_SIZE;
2109 gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, 1, &prop, 1, DE_NULL, &queryDataSize);
2110 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource BUFFER_DATA_SIZE");
2114 << tcu::TestLog::Message
2115 << "BUFFER_DATA_SIZE = " << queryDataSize << "\n"
2116 << "Buffer data size with tight packing: " << expectedMinDataSize
2117 << tcu::TestLog::EndMessage;
2119 if (queryDataSize < expectedMinDataSize)
2121 m_testCtx.getLog() << tcu::TestLog::Message << "Error, buffer size was less than minimum buffer data size" << tcu::TestLog::EndMessage;
2122 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer data size invalid");
2126 m_testCtx.getLog() << tcu::TestLog::Message << "Buffer size valid" << tcu::TestLog::EndMessage;
2132 int InterfaceBlockDataSizeTestCase::getBlockMinDataSize (const std::string& blockFullName) const
2134 const std::string blockName = glu::parseVariableName(blockFullName.c_str());
2136 for (int interfaceNdx = 0; interfaceNdx < (int)m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx)
2138 if (m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].interfaceName == blockName &&
2139 m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].storage == m_storage)
2140 return getBlockMinDataSize(m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx]);
2147 class AtomicCounterCase : public TestCase
2150 AtomicCounterCase (Context& context, const char* name, const char* description);
2151 ~AtomicCounterCase (void);
2158 int getNumAtomicCounterBuffers (void) const;
2159 int getMaxNumActiveVariables (void) const;
2160 int getBufferVariableCount (int binding) const;
2161 int getBufferMinimumDataSize (int binding) const;
2163 ProgramInterfaceDefinition::Program* m_program;
2166 AtomicCounterCase::AtomicCounterCase (Context& context, const char* name, const char* description)
2167 : TestCase (context, name, description)
2168 , m_program (DE_NULL)
2172 AtomicCounterCase::~AtomicCounterCase (void)
2177 void AtomicCounterCase::init (void)
2179 ProgramInterfaceDefinition::Shader* shader;
2180 glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
2182 m_program = new ProgramInterfaceDefinition::Program();
2183 shader = m_program->addShader(glu::SHADERTYPE_COMPUTE, glslVersion);
2186 glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding1_counter1", glu::STORAGE_UNIFORM);
2187 decl.layout.binding = 1;
2188 shader->getDefaultBlock().variables.push_back(decl);
2191 glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding1_counter2", glu::STORAGE_UNIFORM);
2192 decl.layout.binding = 1;
2193 decl.layout.offset = 8;
2195 shader->getDefaultBlock().variables.push_back(decl);
2198 glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding2_counter1", glu::STORAGE_UNIFORM);
2199 decl.layout.binding = 2;
2200 shader->getDefaultBlock().variables.push_back(decl);
2203 DE_ASSERT(m_program->isValid());
2206 void AtomicCounterCase::deinit (void)
2209 m_program = DE_NULL;
2212 int AtomicCounterCase::getNumAtomicCounterBuffers (void) const
2214 std::set<int> buffers;
2216 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2218 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2219 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()))
2221 buffers.insert(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding);
2225 return (int)buffers.size();
2228 int AtomicCounterCase::getMaxNumActiveVariables (void) const
2231 std::map<int,int> numBufferVars;
2233 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2235 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2236 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()))
2238 const int binding = m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding;
2240 if (numBufferVars.find(binding) == numBufferVars.end())
2241 numBufferVars[binding] = 1;
2243 ++numBufferVars[binding];
2247 for (std::map<int,int>::const_iterator it = numBufferVars.begin(); it != numBufferVars.end(); ++it)
2248 maxVars = de::max(maxVars, it->second);
2253 int AtomicCounterCase::getBufferVariableCount (int binding) const
2257 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2259 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2260 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()) &&
2261 m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding == binding)
2268 int AtomicCounterCase::getBufferMinimumDataSize (int binding) const
2271 int currentOffset = 0;
2273 for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2275 if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2276 glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()) &&
2277 m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding == binding)
2279 const int thisOffset = (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.offset != -1) ? (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.offset) : (currentOffset);
2280 currentOffset = thisOffset + 4;
2282 minSize = de::max(minSize, thisOffset + 4);
2289 class AtomicCounterResourceListCase : public AtomicCounterCase
2292 AtomicCounterResourceListCase (Context& context, const char* name, const char* description);
2295 IterateResult iterate (void);
2298 AtomicCounterResourceListCase::AtomicCounterResourceListCase (Context& context, const char* name, const char* description)
2299 : AtomicCounterCase(context, name, description)
2303 AtomicCounterResourceListCase::IterateResult AtomicCounterResourceListCase::iterate (void)
2305 const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2307 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2308 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2311 const tcu::ScopedLogSection section (m_testCtx.getLog(), "ActiveResources", "ACTIVE_RESOURCES");
2312 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2313 glw::GLint numActiveResources = -1;
2314 const int numExpectedActiveResources = 2; // 2 buffer bindings
2316 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying ACTIVE_RESOURCES, expecting " << numExpectedActiveResources << tcu::TestLog::EndMessage;
2318 gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &numActiveResources);
2319 GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_ACTIVE_RESOURCES");
2321 m_testCtx.getLog() << tcu::TestLog::Message << "ACTIVE_RESOURCES = " << numActiveResources << tcu::TestLog::EndMessage;
2323 if (numActiveResources != numExpectedActiveResources)
2325 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected ACTIVE_RESOURCES" << tcu::TestLog::EndMessage;
2326 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected ACTIVE_RESOURCES");
2329 m_testCtx.getLog() << tcu::TestLog::Message << "ACTIVE_RESOURCES valid" << tcu::TestLog::EndMessage;
2335 class AtomicCounterActiveVariablesCase : public AtomicCounterCase
2338 AtomicCounterActiveVariablesCase (Context& context, const char* name, const char* description);
2341 IterateResult iterate (void);
2344 AtomicCounterActiveVariablesCase::AtomicCounterActiveVariablesCase (Context& context, const char* name, const char* description)
2345 : AtomicCounterCase(context, name, description)
2349 AtomicCounterActiveVariablesCase::IterateResult AtomicCounterActiveVariablesCase::iterate (void)
2351 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2352 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2353 const int numAtomicBuffers = getNumAtomicCounterBuffers();
2354 const int expectedMaxNumActiveVariables = getMaxNumActiveVariables();
2356 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2357 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2359 // check active variables
2361 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Interface", "ATOMIC_COUNTER_BUFFER interface");
2362 glw::GLint queryActiveResources = -1;
2363 glw::GLint queryMaxNumActiveVariables = -1;
2365 gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &queryActiveResources);
2366 gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, &queryMaxNumActiveVariables);
2367 GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
2370 << tcu::TestLog::Message
2371 << "GL_ACTIVE_RESOURCES = " << queryActiveResources << "\n"
2372 << "GL_MAX_NUM_ACTIVE_VARIABLES = " << queryMaxNumActiveVariables << "\n"
2373 << tcu::TestLog::EndMessage;
2375 if (queryActiveResources != numAtomicBuffers)
2377 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected GL_ACTIVE_RESOURCES, expected " << numAtomicBuffers << tcu::TestLog::EndMessage;
2378 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected GL_ACTIVE_RESOURCES");
2381 if (queryMaxNumActiveVariables != expectedMaxNumActiveVariables)
2383 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected GL_MAX_NUM_ACTIVE_VARIABLES, expected " << expectedMaxNumActiveVariables << tcu::TestLog::EndMessage;
2384 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected GL_MAX_NUM_ACTIVE_VARIABLES");
2388 // Check each buffer
2389 for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2391 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
2392 std::vector<glw::GLint> activeVariables;
2393 std::vector<std::string> memberNames;
2395 // Find active variables
2397 const glw::GLenum numActiveVariablesProp = GL_NUM_ACTIVE_VARIABLES;
2398 const glw::GLenum activeVariablesProp = GL_ACTIVE_VARIABLES;
2399 glw::GLint numActiveVariables = -2;
2400 glw::GLint written = -1;
2402 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &numActiveVariablesProp, 1, &written, &numActiveVariables);
2403 GLU_EXPECT_NO_ERROR(gl.getError(), "query num active variables");
2405 if (numActiveVariables <= 0)
2407 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected NUM_ACTIVE_VARIABLES: " << numActiveVariables << tcu::TestLog::EndMessage;
2408 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected NUM_ACTIVE_VARIABLES");
2414 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for NUM_ACTIVE_VARIABLES returned no values" << tcu::TestLog::EndMessage;
2415 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "NUM_ACTIVE_VARIABLES query failed");
2419 m_testCtx.getLog() << tcu::TestLog::Message << "GL_NUM_ACTIVE_VARIABLES = " << numActiveVariables << tcu::TestLog::EndMessage;
2422 activeVariables.resize(numActiveVariables + 1, -2);
2424 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &activeVariablesProp, numActiveVariables, &written, &activeVariables[0]);
2425 GLU_EXPECT_NO_ERROR(gl.getError(), "query active variables");
2427 if (written != numActiveVariables)
2429 m_testCtx.getLog() << tcu::TestLog::Message << "Error, unexpected number of ACTIVE_VARIABLES, NUM_ACTIVE_VARIABLES = " << numActiveVariables << ", query returned " << written << " values" << tcu::TestLog::EndMessage;
2430 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected ACTIVE_VARIABLES");
2434 if (activeVariables.back() != -2)
2436 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for ACTIVE_VARIABLES wrote over target buffer bounds" << tcu::TestLog::EndMessage;
2437 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "ACTIVE_VARIABLES query failed");
2441 activeVariables.pop_back();
2446 tcu::MessageBuilder builder(&m_testCtx.getLog());
2448 builder << "Active variable indices: {";
2449 for (int varNdx = 0; varNdx < (int)activeVariables.size(); ++varNdx)
2453 builder << activeVariables[varNdx];
2455 builder << "}" << tcu::TestLog::EndMessage;
2458 // collect member names
2459 for (int ndx = 0; ndx < (int)activeVariables.size(); ++ndx)
2461 const glw::GLenum nameLengthProp = GL_NAME_LENGTH;
2462 glw::GLint nameLength = -1;
2463 glw::GLint written = -1;
2464 std::vector<char> nameBuf;
2466 gl.getProgramResourceiv(program.getProgram(), GL_UNIFORM, activeVariables[ndx], 1, &nameLengthProp, 1, &written, &nameLength);
2467 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer variable name length");
2469 if (written <= 0 || nameLength == -1)
2471 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for GL_NAME_LENGTH returned no values" << tcu::TestLog::EndMessage;
2472 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GL_NAME_LENGTH query failed");
2476 nameBuf.resize(nameLength + 2, 'X'); // +2 to tolerate potential off-by-ones in some implementations, name queries will check these cases better
2479 gl.getProgramResourceName(program.getProgram(), GL_UNIFORM, activeVariables[ndx], (int)nameBuf.size(), &written, &nameBuf[0]);
2480 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer variable name");
2484 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for resource name returned no name" << tcu::TestLog::EndMessage;
2485 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Name query failed");
2489 memberNames.push_back(std::string(&nameBuf[0], written));
2494 tcu::MessageBuilder builder(&m_testCtx.getLog());
2496 builder << "Active variables:\n";
2497 for (int varNdx = 0; varNdx < (int)memberNames.size(); ++varNdx)
2499 builder << "\t" << memberNames[varNdx] << "\n";
2501 builder << tcu::TestLog::EndMessage;
2504 // check names are all in the same buffer
2506 bool bindingsValid = true;
2508 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying names" << tcu::TestLog::EndMessage;
2510 for (int nameNdx = 0; nameNdx < (int)memberNames.size(); ++nameNdx)
2512 int prevBinding = -1;
2514 for (int varNdx = 0; varNdx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++varNdx)
2516 if (m_program->getShaders()[0]->getDefaultBlock().variables[varNdx].name == memberNames[nameNdx])
2518 const int varBinding = m_program->getShaders()[0]->getDefaultBlock().variables[varNdx].layout.binding;
2520 if (prevBinding == -1 || prevBinding == varBinding)
2521 prevBinding = varBinding;
2523 bindingsValid = false;
2527 if (prevBinding == -1)
2529 m_testCtx.getLog() << tcu::TestLog::Message << "Error, could not find variable with name \"" << memberNames[nameNdx] << "\"" << tcu::TestLog::EndMessage;
2530 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Variable name invalid");
2532 else if (getBufferVariableCount(prevBinding) != (int)memberNames.size())
2535 << tcu::TestLog::Message
2536 << "Error, unexpected variable count for binding " << prevBinding
2537 << ". Expected " << getBufferVariableCount(prevBinding) << ", got " << (int)memberNames.size()
2538 << tcu::TestLog::EndMessage;
2539 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Variable names invalid");
2545 m_testCtx.getLog() << tcu::TestLog::Message << "Error, all resource do not share the same buffer" << tcu::TestLog::EndMessage;
2546 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Active variables invalid");
2555 class AtomicCounterBufferBindingCase : public AtomicCounterCase
2558 AtomicCounterBufferBindingCase (Context& context, const char* name, const char* description);
2561 IterateResult iterate (void);
2564 AtomicCounterBufferBindingCase::AtomicCounterBufferBindingCase (Context& context, const char* name, const char* description)
2565 : AtomicCounterCase(context, name, description)
2569 AtomicCounterBufferBindingCase::IterateResult AtomicCounterBufferBindingCase::iterate (void)
2571 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2572 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2573 const int numAtomicBuffers = getNumAtomicCounterBuffers();
2575 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2576 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2578 // check every buffer
2579 for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2581 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
2582 const glw::GLenum bufferBindingProp = GL_BUFFER_BINDING;
2583 glw::GLint bufferBinding = -1;
2584 glw::GLint written = -1;
2586 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &bufferBindingProp, 1, &written, &bufferBinding);
2587 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2591 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for BUFFER_BINDING returned no values." << tcu::TestLog::EndMessage;
2592 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "BUFFER_BINDING query failed");
2595 m_testCtx.getLog() << tcu::TestLog::Message << "GL_BUFFER_BINDING = " << bufferBinding << tcu::TestLog::EndMessage;
2597 // no such buffer binding?
2598 if (getBufferVariableCount(bufferBinding) == 0)
2600 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_BINDING = " << bufferBinding << ", but such buffer does not exist." << tcu::TestLog::EndMessage;
2601 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2608 class AtomicCounterBufferDataSizeCase : public AtomicCounterCase
2611 AtomicCounterBufferDataSizeCase (Context& context, const char* name, const char* description);
2614 IterateResult iterate (void);
2617 AtomicCounterBufferDataSizeCase::AtomicCounterBufferDataSizeCase (Context& context, const char* name, const char* description)
2618 : AtomicCounterCase(context, name, description)
2622 AtomicCounterBufferDataSizeCase::IterateResult AtomicCounterBufferDataSizeCase::iterate (void)
2624 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2625 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2626 const int numAtomicBuffers = getNumAtomicCounterBuffers();
2628 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2629 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2631 // check every buffer
2632 for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2634 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
2635 const glw::GLenum props[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE };
2636 glw::GLint values[] = { -1, -1 };
2637 glw::GLint written = -1;
2638 int bufferMinDataSize;
2640 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, DE_LENGTH_OF_ARRAY(props), props, DE_LENGTH_OF_ARRAY(values), &written, values);
2641 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2645 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for (BUFFER_BINDING, BUFFER_DATA_SIZE) returned " << written << " value(s)." << tcu::TestLog::EndMessage;
2646 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
2651 << tcu::TestLog::Message
2652 << "GL_BUFFER_BINDING = " << values[0] << "\n"
2653 << "GL_BUFFER_DATA_SIZE = " << values[1]
2654 << tcu::TestLog::EndMessage;
2656 bufferMinDataSize = getBufferMinimumDataSize(values[0]);
2657 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying data size, expected greater than or equal to " << bufferMinDataSize << tcu::TestLog::EndMessage;
2659 // no such buffer binding?
2660 if (bufferMinDataSize == -1)
2662 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_BINDING = " << values[0] << ", but such buffer does not exist." << tcu::TestLog::EndMessage;
2663 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2665 else if (values[1] < bufferMinDataSize)
2667 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;
2668 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2671 m_testCtx.getLog() << tcu::TestLog::Message << "Data size valid" << tcu::TestLog::EndMessage;
2677 class AtomicCounterReferencedByCase : public TestCase
2680 AtomicCounterReferencedByCase (Context& context,
2682 const char* description,
2684 deUint32 presentStagesMask,
2685 deUint32 activeStagesMask);
2686 ~AtomicCounterReferencedByCase (void);
2691 IterateResult iterate (void);
2693 const bool m_separable;
2694 const deUint32 m_presentStagesMask;
2695 const deUint32 m_activeStagesMask;
2696 ProgramInterfaceDefinition::Program* m_program;
2699 AtomicCounterReferencedByCase::AtomicCounterReferencedByCase (Context& context,
2701 const char* description,
2703 deUint32 presentStagesMask,
2704 deUint32 activeStagesMask)
2705 : TestCase (context, name, description)
2706 , m_separable (separable)
2707 , m_presentStagesMask (presentStagesMask)
2708 , m_activeStagesMask (activeStagesMask)
2709 , m_program (DE_NULL)
2711 DE_ASSERT((activeStagesMask & presentStagesMask) == activeStagesMask);
2714 AtomicCounterReferencedByCase::~AtomicCounterReferencedByCase (void)
2719 void AtomicCounterReferencedByCase::init (void)
2721 const deUint32 geometryMask = (1 << glu::SHADERTYPE_GEOMETRY);
2722 const deUint32 tessellationMask = (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION);
2723 glu::VariableDeclaration atomicVar (glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "targetCounter", glu::STORAGE_UNIFORM);
2724 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
2725 const bool supportsES32orGL45 = checkSupport(m_context);
2727 if ((m_presentStagesMask & tessellationMask) != 0 && !supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
2728 throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
2729 if ((m_presentStagesMask & geometryMask) != 0 && !supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
2730 throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
2732 atomicVar.layout.binding = 1;
2734 m_program = new ProgramInterfaceDefinition::Program();
2735 m_program->setSeparable(m_separable);
2737 for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
2739 if (m_activeStagesMask & (1 << shaderType))
2740 m_program->addShader((glu::ShaderType)shaderType, glslVersion)->getDefaultBlock().variables.push_back(atomicVar);
2741 else if (m_presentStagesMask & (1 << shaderType))
2742 m_program->addShader((glu::ShaderType)shaderType, glslVersion);
2745 if (m_program->hasStage(glu::SHADERTYPE_GEOMETRY))
2746 m_program->setGeometryNumOutputVertices(1);
2747 if (m_program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
2748 m_program->setTessellationNumOutputPatchVertices(1);
2750 DE_ASSERT(m_program->isValid());
2753 void AtomicCounterReferencedByCase::deinit (void)
2756 m_program = DE_NULL;
2759 AtomicCounterReferencedByCase::IterateResult AtomicCounterReferencedByCase::iterate (void)
2761 const glu::RenderContext& rc = m_context.getRenderContext();
2762 const bool isES32orGL45 = glu::contextSupports(rc.getType(), glu::ApiType::es(3, 2)) ||
2763 glu::contextSupports(rc.getType(), glu::ApiType::core(4, 5));
2767 glw::GLenum propName;
2768 glu::ShaderType shaderType;
2769 const char* extension;
2772 { GL_REFERENCED_BY_VERTEX_SHADER, glu::SHADERTYPE_VERTEX, DE_NULL },
2773 { GL_REFERENCED_BY_FRAGMENT_SHADER, glu::SHADERTYPE_FRAGMENT, DE_NULL },
2774 { GL_REFERENCED_BY_COMPUTE_SHADER, glu::SHADERTYPE_COMPUTE, DE_NULL },
2775 { GL_REFERENCED_BY_TESS_CONTROL_SHADER, glu::SHADERTYPE_TESSELLATION_CONTROL, (isES32orGL45 ? DE_NULL : "GL_EXT_tessellation_shader") },
2776 { GL_REFERENCED_BY_TESS_EVALUATION_SHADER, glu::SHADERTYPE_TESSELLATION_EVALUATION, (isES32orGL45 ? DE_NULL : "GL_EXT_tessellation_shader") },
2777 { GL_REFERENCED_BY_GEOMETRY_SHADER, glu::SHADERTYPE_GEOMETRY, (isES32orGL45 ? DE_NULL : "GL_EXT_geometry_shader") },
2780 const glw::Functions& gl = rc.getFunctions();
2781 const glu::ShaderProgram program (rc, generateProgramInterfaceProgramSources(m_program));
2783 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2784 checkAndLogProgram(program, m_program, rc.getFunctions(), m_testCtx.getLog());
2787 for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(targetProps); ++propNdx)
2789 if (targetProps[propNdx].extension == DE_NULL || m_context.getContextInfo().isExtensionSupported(targetProps[propNdx].extension))
2791 const glw::GLenum prop = targetProps[propNdx].propName;
2792 const glw::GLint expected = ((m_activeStagesMask & (1 << targetProps[propNdx].shaderType)) != 0) ? (GL_TRUE) : (GL_FALSE);
2793 glw::GLint value = -1;
2794 glw::GLint written = -1;
2796 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying " << glu::getProgramResourcePropertyName(prop) << ", expecting " << glu::getBooleanName(expected) << tcu::TestLog::EndMessage;
2798 gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, 0, 1, &prop, 1, &written, &value);
2799 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2803 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for referenced_by_* returned invalid number of values." << tcu::TestLog::EndMessage;
2804 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
2808 m_testCtx.getLog() << tcu::TestLog::Message << glu::getProgramResourcePropertyName(prop) << " = " << glu::getBooleanStr(value) << tcu::TestLog::EndMessage;
2810 if (value != expected)
2812 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected value" << tcu::TestLog::EndMessage;
2813 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected property value");
2822 class ProgramInputOutputReferencedByCase : public TestCase
2827 CASE_VERTEX_FRAGMENT = 0,
2828 CASE_VERTEX_GEO_FRAGMENT,
2829 CASE_VERTEX_TESS_FRAGMENT,
2830 CASE_VERTEX_TESS_GEO_FRAGMENT,
2832 CASE_SEPARABLE_VERTEX,
2833 CASE_SEPARABLE_FRAGMENT,
2834 CASE_SEPARABLE_GEOMETRY,
2835 CASE_SEPARABLE_TESS_CTRL,
2836 CASE_SEPARABLE_TESS_EVAL,
2840 ProgramInputOutputReferencedByCase (Context& context, const char* name, const char* description, glu::Storage targetStorage, CaseType caseType);
2841 ~ProgramInputOutputReferencedByCase (void);
2846 IterateResult iterate (void);
2848 const CaseType m_caseType;
2849 const glu::Storage m_targetStorage;
2850 ProgramInterfaceDefinition::Program* m_program;
2853 ProgramInputOutputReferencedByCase::ProgramInputOutputReferencedByCase (Context& context, const char* name, const char* description, glu::Storage targetStorage, CaseType caseType)
2854 : TestCase (context, name, description)
2855 , m_caseType (caseType)
2856 , m_targetStorage (targetStorage)
2857 , m_program (DE_NULL)
2859 DE_ASSERT(caseType < CASE_LAST);
2862 ProgramInputOutputReferencedByCase::~ProgramInputOutputReferencedByCase (void)
2867 void ProgramInputOutputReferencedByCase::init (void)
2869 const bool hasTessellationShader = (m_caseType == CASE_VERTEX_TESS_FRAGMENT) ||
2870 (m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT) ||
2871 (m_caseType == CASE_SEPARABLE_TESS_CTRL) ||
2872 (m_caseType == CASE_SEPARABLE_TESS_EVAL);
2873 const bool hasGeometryShader = (m_caseType == CASE_VERTEX_GEO_FRAGMENT) ||
2874 (m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT) ||
2875 (m_caseType == CASE_SEPARABLE_GEOMETRY);
2876 const bool supportsES32orGL45 = checkSupport(m_context);
2878 if (hasTessellationShader && !supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
2879 throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
2880 if (hasGeometryShader && !supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
2881 throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
2883 glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
2884 m_program = new ProgramInterfaceDefinition::Program();
2886 if (m_caseType == CASE_SEPARABLE_VERTEX ||
2887 m_caseType == CASE_SEPARABLE_FRAGMENT ||
2888 m_caseType == CASE_SEPARABLE_GEOMETRY ||
2889 m_caseType == CASE_SEPARABLE_TESS_CTRL ||
2890 m_caseType == CASE_SEPARABLE_TESS_EVAL)
2892 const bool isInputCase = (m_targetStorage == glu::STORAGE_IN || m_targetStorage == glu::STORAGE_PATCH_IN);
2893 const bool perPatchStorage = (m_targetStorage == glu::STORAGE_PATCH_IN || m_targetStorage == glu::STORAGE_PATCH_OUT);
2894 const char* varName = (isInputCase) ? ("shaderInput") : ("shaderOutput");
2895 const glu::VariableDeclaration targetDecl (glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), varName, m_targetStorage);
2896 const glu::ShaderType shaderType = (m_caseType == CASE_SEPARABLE_VERTEX) ? (glu::SHADERTYPE_VERTEX)
2897 : (m_caseType == CASE_SEPARABLE_FRAGMENT) ? (glu::SHADERTYPE_FRAGMENT)
2898 : (m_caseType == CASE_SEPARABLE_GEOMETRY) ? (glu::SHADERTYPE_GEOMETRY)
2899 : (m_caseType == CASE_SEPARABLE_TESS_CTRL) ? (glu::SHADERTYPE_TESSELLATION_CONTROL)
2900 : (m_caseType == CASE_SEPARABLE_TESS_EVAL) ? (glu::SHADERTYPE_TESSELLATION_EVALUATION)
2901 : (glu::SHADERTYPE_LAST);
2902 const bool arrayedInterface = (isInputCase) ? ((shaderType == glu::SHADERTYPE_GEOMETRY) ||
2903 (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL) ||
2904 (shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION))
2905 : (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL);
2907 m_program->setSeparable(true);
2909 if (arrayedInterface && !perPatchStorage)
2911 const glu::VariableDeclaration targetDeclArr(glu::VarType(targetDecl.varType, glu::VarType::UNSIZED_ARRAY), varName, m_targetStorage);
2912 m_program->addShader(shaderType, glslVersion)->getDefaultBlock().variables.push_back(targetDeclArr);
2916 m_program->addShader(shaderType, glslVersion)->getDefaultBlock().variables.push_back(targetDecl);
2919 else if (m_caseType == CASE_VERTEX_FRAGMENT ||
2920 m_caseType == CASE_VERTEX_GEO_FRAGMENT ||
2921 m_caseType == CASE_VERTEX_TESS_FRAGMENT ||
2922 m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
2924 ProgramInterfaceDefinition::Shader* vertex = m_program->addShader(glu::SHADERTYPE_VERTEX, glslVersion);
2925 ProgramInterfaceDefinition::Shader* fragment = m_program->addShader(glu::SHADERTYPE_FRAGMENT, glslVersion);
2927 m_program->setSeparable(false);
2929 vertex->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2932 vertex->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2935 glu::INTERPOLATION_LAST,
2938 fragment->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2941 glu::INTERPOLATION_LAST,
2943 fragment->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2946 glu::INTERPOLATION_LAST,
2949 if (m_caseType == CASE_VERTEX_TESS_FRAGMENT || m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
2951 ProgramInterfaceDefinition::Shader* tessCtrl = m_program->addShader(glu::SHADERTYPE_TESSELLATION_CONTROL, glslVersion);
2952 ProgramInterfaceDefinition::Shader* tessEval = m_program->addShader(glu::SHADERTYPE_TESSELLATION_EVALUATION, glslVersion);
2954 tessCtrl->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2957 glu::INTERPOLATION_LAST,
2959 tessCtrl->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2962 glu::INTERPOLATION_LAST,
2965 tessEval->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2968 glu::INTERPOLATION_LAST,
2970 tessEval->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2973 glu::INTERPOLATION_LAST,
2977 if (m_caseType == CASE_VERTEX_GEO_FRAGMENT || m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
2979 ProgramInterfaceDefinition::Shader* geometry = m_program->addShader(glu::SHADERTYPE_GEOMETRY, glslVersion);
2981 geometry->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2984 glu::INTERPOLATION_LAST,
2986 geometry->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2989 glu::INTERPOLATION_LAST,
2996 if (m_program->hasStage(glu::SHADERTYPE_GEOMETRY))
2997 m_program->setGeometryNumOutputVertices(1);
2998 if (m_program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
2999 m_program->setTessellationNumOutputPatchVertices(1);
3001 DE_ASSERT(m_program->isValid());
3004 void ProgramInputOutputReferencedByCase::deinit (void)
3007 m_program = DE_NULL;
3010 ProgramInputOutputReferencedByCase::IterateResult ProgramInputOutputReferencedByCase::iterate (void)
3014 glw::GLenum propName;
3015 glu::ShaderType shaderType;
3016 const char* extension;
3019 { GL_REFERENCED_BY_VERTEX_SHADER, glu::SHADERTYPE_VERTEX, DE_NULL },
3020 { GL_REFERENCED_BY_FRAGMENT_SHADER, glu::SHADERTYPE_FRAGMENT, DE_NULL },
3021 { GL_REFERENCED_BY_COMPUTE_SHADER, glu::SHADERTYPE_COMPUTE, DE_NULL },
3022 { GL_REFERENCED_BY_TESS_CONTROL_SHADER, glu::SHADERTYPE_TESSELLATION_CONTROL, "GL_EXT_tessellation_shader" },
3023 { GL_REFERENCED_BY_TESS_EVALUATION_SHADER, glu::SHADERTYPE_TESSELLATION_EVALUATION, "GL_EXT_tessellation_shader" },
3024 { GL_REFERENCED_BY_GEOMETRY_SHADER, glu::SHADERTYPE_GEOMETRY, "GL_EXT_geometry_shader" },
3027 const bool isInputCase = (m_targetStorage == glu::STORAGE_IN || m_targetStorage == glu::STORAGE_PATCH_IN);
3028 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3029 const glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
3030 const std::string targetResourceName = (isInputCase) ? ("shaderInput") : ("shaderOutput");
3031 const glw::GLenum programGLInterface = (isInputCase) ? (GL_PROGRAM_INPUT) : (GL_PROGRAM_OUTPUT);
3032 glw::GLuint resourceIndex;
3034 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3035 checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
3037 // find target resource index
3039 resourceIndex = gl.getProgramResourceIndex(program.getProgram(), programGLInterface, targetResourceName.c_str());
3040 GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
3042 if (resourceIndex == GL_INVALID_INDEX)
3044 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for resource \"" << targetResourceName << "\" index returned invalid index." << tcu::TestLog::EndMessage;
3045 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "could not find target resource");
3050 for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(targetProps); ++propNdx)
3052 if (targetProps[propNdx].extension == DE_NULL || m_context.getContextInfo().isExtensionSupported(targetProps[propNdx].extension))
3054 const glw::GLenum prop = targetProps[propNdx].propName;
3055 const bool expected = (isInputCase) ? (targetProps[propNdx].shaderType == m_program->getFirstStage()) : (targetProps[propNdx].shaderType == m_program->getLastStage());
3056 glw::GLint value = -1;
3057 glw::GLint written = -1;
3059 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying " << glu::getProgramResourcePropertyName(prop) << ", expecting " << ((expected) ? ("TRUE") : ("FALSE")) << tcu::TestLog::EndMessage;
3061 gl.getProgramResourceiv(program.getProgram(), programGLInterface, resourceIndex, 1, &prop, 1, &written, &value);
3062 GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
3066 m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for referenced_by_* returned invalid number of values." << tcu::TestLog::EndMessage;
3067 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
3071 m_testCtx.getLog() << tcu::TestLog::Message << glu::getProgramResourcePropertyName(prop) << " = " << glu::getBooleanStr(value) << tcu::TestLog::EndMessage;
3073 if (value != ((expected) ? (GL_TRUE) : (GL_FALSE)))
3075 m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected value" << tcu::TestLog::EndMessage;
3076 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected property value");
3085 class FeedbackResourceListTestCase : public ResourceListTestCase
3088 FeedbackResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& resource, const char* name);
3089 ~FeedbackResourceListTestCase (void);
3092 IterateResult iterate (void);
3095 FeedbackResourceListTestCase::FeedbackResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& resource, const char* name)
3096 : ResourceListTestCase(context, resource, PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, name)
3100 FeedbackResourceListTestCase::~FeedbackResourceListTestCase (void)
3105 FeedbackResourceListTestCase::IterateResult FeedbackResourceListTestCase::iterate (void)
3107 const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_programDefinition));
3109 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3111 // Feedback varyings
3113 tcu::MessageBuilder builder(&m_testCtx.getLog());
3114 builder << "Transform feedback varyings: {";
3115 for (int ndx = 0; ndx < (int)m_programDefinition->getTransformFeedbackVaryings().size(); ++ndx)
3119 builder << "\"" << m_programDefinition->getTransformFeedbackVaryings()[ndx] << "\"";
3121 builder << "}" << tcu::TestLog::EndMessage;
3124 checkAndLogProgram(program, m_programDefinition, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
3126 // Check resource list
3128 const tcu::ScopedLogSection section (m_testCtx.getLog(), "ResourceList", "Resource list");
3129 std::vector<std::string> resourceList;
3130 std::vector<std::string> expectedResources;
3132 queryResourceList(resourceList, program.getProgram());
3133 expectedResources = getProgramInterfaceResourceList(m_programDefinition, m_programInterface);
3135 // verify the list and the expected list match
3137 if (!verifyResourceList(resourceList, expectedResources))
3138 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid resource list");
3140 // verify GetProgramResourceIndex() matches the indices of the list
3142 if (!verifyResourceIndexQuery(resourceList, expectedResources, program.getProgram()))
3143 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GetProgramResourceIndex returned unexpected values");
3145 // Verify MAX_NAME_LENGTH
3146 if (!verifyMaxNameLength(resourceList, program.getProgram()))
3147 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "MAX_NAME_LENGTH invalid");
3153 int InterfaceBlockDataSizeTestCase::getBlockMinDataSize (const glu::InterfaceBlock& block) const
3157 for (int ndx = 0; ndx < (int)block.variables.size(); ++ndx)
3158 dataSize += getVarTypeSize(block.variables[ndx].varType);
3163 static bool isDataTypeLayoutQualified (glu::DataType type)
3165 return glu::isDataTypeImage(type) || glu::isDataTypeAtomicCounter(type);
3168 static void generateVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3, bool createTestGroup = true)
3173 glu::DataType dataType;
3176 { 0, glu::TYPE_FLOAT },
3177 { 1, glu::TYPE_INT },
3178 { 1, glu::TYPE_UINT },
3179 { 1, glu::TYPE_BOOL },
3181 { 3, glu::TYPE_FLOAT_VEC2 },
3182 { 1, glu::TYPE_FLOAT_VEC3 },
3183 { 1, glu::TYPE_FLOAT_VEC4 },
3185 { 3, glu::TYPE_INT_VEC2 },
3186 { 2, glu::TYPE_INT_VEC3 },
3187 { 3, glu::TYPE_INT_VEC4 },
3189 { 3, glu::TYPE_UINT_VEC2 },
3190 { 2, glu::TYPE_UINT_VEC3 },
3191 { 3, glu::TYPE_UINT_VEC4 },
3193 { 3, glu::TYPE_BOOL_VEC2 },
3194 { 2, glu::TYPE_BOOL_VEC3 },
3195 { 3, glu::TYPE_BOOL_VEC4 },
3197 { 2, glu::TYPE_FLOAT_MAT2 },
3198 { 3, glu::TYPE_FLOAT_MAT2X3 },
3199 { 3, glu::TYPE_FLOAT_MAT2X4 },
3200 { 2, glu::TYPE_FLOAT_MAT3X2 },
3201 { 2, glu::TYPE_FLOAT_MAT3 },
3202 { 3, glu::TYPE_FLOAT_MAT3X4 },
3203 { 2, glu::TYPE_FLOAT_MAT4X2 },
3204 { 3, glu::TYPE_FLOAT_MAT4X3 },
3205 { 2, glu::TYPE_FLOAT_MAT4 },
3208 tcu::TestCaseGroup* group;
3210 if (createTestGroup)
3212 group = new tcu::TestCaseGroup(context.getTestContext(), "basic_type", "Basic variable");
3213 targetGroup->addChild(group);
3216 group = targetGroup;
3218 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3220 if (variableTypes[ndx].level <= expandLevel)
3222 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
3223 group->addChild(new ResourceTestCase(context, variable, queryTarget));
3228 static void generateOpaqueTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3, bool createTestGroup = true)
3233 glu::DataType dataType;
3236 { 0, glu::TYPE_SAMPLER_2D },
3237 { 2, glu::TYPE_SAMPLER_CUBE },
3238 { 1, glu::TYPE_SAMPLER_2D_ARRAY },
3239 { 1, glu::TYPE_SAMPLER_3D },
3240 { 2, glu::TYPE_SAMPLER_2D_SHADOW },
3241 { 3, glu::TYPE_SAMPLER_CUBE_SHADOW },
3242 { 3, glu::TYPE_SAMPLER_2D_ARRAY_SHADOW },
3243 { 1, glu::TYPE_INT_SAMPLER_2D },
3244 { 3, glu::TYPE_INT_SAMPLER_CUBE },
3245 { 3, glu::TYPE_INT_SAMPLER_2D_ARRAY },
3246 { 3, glu::TYPE_INT_SAMPLER_3D },
3247 { 2, glu::TYPE_UINT_SAMPLER_2D },
3248 { 3, glu::TYPE_UINT_SAMPLER_CUBE },
3249 { 3, glu::TYPE_UINT_SAMPLER_2D_ARRAY },
3250 { 3, glu::TYPE_UINT_SAMPLER_3D },
3251 { 2, glu::TYPE_SAMPLER_2D_MULTISAMPLE },
3252 { 2, glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE },
3253 { 3, glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE },
3254 { 1, glu::TYPE_IMAGE_2D },
3255 { 3, glu::TYPE_IMAGE_CUBE },
3256 { 3, glu::TYPE_IMAGE_2D_ARRAY },
3257 { 3, glu::TYPE_IMAGE_3D },
3258 { 3, glu::TYPE_INT_IMAGE_2D },
3259 { 3, glu::TYPE_INT_IMAGE_CUBE },
3260 { 1, glu::TYPE_INT_IMAGE_2D_ARRAY },
3261 { 3, glu::TYPE_INT_IMAGE_3D },
3262 { 2, glu::TYPE_UINT_IMAGE_2D },
3263 { 3, glu::TYPE_UINT_IMAGE_CUBE },
3264 { 3, glu::TYPE_UINT_IMAGE_2D_ARRAY },
3265 { 3, glu::TYPE_UINT_IMAGE_3D },
3266 { 1, glu::TYPE_UINT_ATOMIC_COUNTER },
3269 bool isStructMember = false;
3272 for (const ResourceDefinition::Node* node = parentStructure.get(); node; node = node->getEnclosingNode())
3274 // Don't insert inside a interface block
3275 if (node->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3278 isStructMember |= (node->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER);
3283 tcu::TestCaseGroup* group;
3285 if (createTestGroup)
3287 group = new tcu::TestCaseGroup(context.getTestContext(), "opaque_type", "Opaque types");
3288 targetGroup->addChild(group);
3291 group = targetGroup;
3293 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3295 if (variableTypes[ndx].level > expandLevel)
3298 // Layout qualifiers are not allowed on struct members
3299 if (isDataTypeLayoutQualified(variableTypes[ndx].dataType) && isStructMember)
3303 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
3304 group->addChild(new ResourceTestCase(context, variable, queryTarget));
3310 static void generateCompoundVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3);
3312 static void generateVariableArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3)
3314 if (expandLevel > 0)
3316 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3317 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3319 targetGroup->addChild(blockGroup);
3321 // Arrays of basic variables
3322 generateVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3324 // Arrays of opaque types
3325 generateOpaqueTypeCases(context, arrayElement, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3328 generateVariableArrayCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3330 // Arrays of structs
3331 generateCompoundVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3335 static void generateCompoundVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
3337 if (expandLevel > 0)
3339 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3340 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "struct", "Structs");
3342 targetGroup->addChild(blockGroup);
3344 // Struct containing basic variable
3345 generateVariableCases(context, structMember, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3347 // Struct containing opaque types
3348 generateOpaqueTypeCases(context, structMember, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3350 // Struct containing arrays
3351 generateVariableArrayCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3353 // Struct containing struct
3354 generateCompoundVariableCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3358 // Resource list cases
3362 BLOCKFLAG_DEFAULT = 0x01,
3363 BLOCKFLAG_NAMED = 0x02,
3364 BLOCKFLAG_UNNAMED = 0x04,
3365 BLOCKFLAG_ARRAY = 0x08,
3367 BLOCKFLAG_ALL = 0x0F
3370 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))
3372 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
3373 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
3376 if (blockFlags & BLOCKFLAG_DEFAULT)
3378 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "default_block", "Default block");
3379 targetGroup->addChild(blockGroup);
3381 blockContentGenerator(context, uniform, blockGroup);
3385 if (blockFlags & BLOCKFLAG_NAMED)
3387 const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(uniform, true));
3389 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "named_block", "Named uniform block");
3390 targetGroup->addChild(blockGroup);
3392 blockContentGenerator(context, block, blockGroup);
3396 if (blockFlags & BLOCKFLAG_UNNAMED)
3398 const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(uniform, false));
3400 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "unnamed_block", "Unnamed uniform block");
3401 targetGroup->addChild(blockGroup);
3403 blockContentGenerator(context, block, blockGroup);
3407 if (blockFlags & BLOCKFLAG_ARRAY)
3409 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(uniform));
3410 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
3412 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "block_array", "Uniform block array");
3413 targetGroup->addChild(blockGroup);
3415 blockContentGenerator(context, block, blockGroup);
3419 static void generateBufferBackedResourceListBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, int depth)
3423 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, glu::TYPE_FLOAT_VEC4));
3424 targetGroup->addChild(new ResourceListTestCase(context, variable, interface));
3430 const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
3431 generateBufferBackedResourceListBlockContentCases(context, structMember, targetGroup, interface, depth - 1);
3437 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
3438 generateBufferBackedResourceListBlockContentCases(context, arrayElement, targetGroup, interface, depth - 1);
3442 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)
3446 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, dataType));
3447 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, targetProp), ("var" + nameSuffix).c_str()));
3453 const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
3454 generateBufferBackedVariableAggregateTypeCases(context, structMember, targetGroup, interface, targetProp, dataType, "_struct" + nameSuffix, depth - 1);
3460 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
3461 generateBufferBackedVariableAggregateTypeCases(context, arrayElement, targetGroup, interface, targetProp, dataType, "_array" + nameSuffix, depth - 1);
3465 static void generateUniformResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3467 generateBufferBackedResourceListBlockContentCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, 4);
3470 static void generateUniformBlockArraySizeContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3472 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ARRAY_SIZE);
3473 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3474 const bool namedNonArrayBlock = isInterfaceBlock &&
3475 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3476 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3478 if (!isInterfaceBlock || namedNonArrayBlock)
3482 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3483 targetGroup->addChild(blockGroup);
3485 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3486 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3491 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3492 targetGroup->addChild(blockGroup);
3494 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_ARRAY_SIZE, glu::TYPE_FLOAT, "", 3);
3500 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, queryTarget.interface, PROGRAMRESOURCEPROP_ARRAY_SIZE, glu::TYPE_FLOAT, "", 2);
3504 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)
3508 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, type));
3509 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_ARRAY_STRIDE), namePrefix.c_str()));
3512 if (expandLevel > 0)
3514 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3515 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3518 generateBufferBackedArrayStrideTypeAggregateSubCases(context, structMember, targetGroup, namePrefix + "_struct", interface, type, expandLevel - 1);
3521 generateBufferBackedArrayStrideTypeAggregateSubCases(context, arrayElement, targetGroup, namePrefix + "_array", interface, type, expandLevel - 1);
3525 static void generateBufferBackedArrayStrideTypeAggregateCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, glu::DataType type, int expandLevel, bool includeBaseCase)
3527 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3528 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3529 const std::string namePrefix = glu::getDataTypeName(type);
3531 if (expandLevel == 0 || includeBaseCase)
3533 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, type));
3534 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_ARRAY_STRIDE), namePrefix.c_str()));
3536 if (expandLevel >= 1)
3539 if (!glu::isDataTypeAtomicCounter(type))
3540 generateBufferBackedArrayStrideTypeAggregateSubCases(context, structMember, targetGroup, namePrefix + "_struct", interface, type, expandLevel - 1);
3543 generateBufferBackedArrayStrideTypeAggregateSubCases(context, arrayElement, targetGroup, namePrefix + "_array", interface, type, expandLevel - 1);
3547 static void generateUniformBlockArrayStrideContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3549 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ARRAY_STRIDE);
3550 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3551 const bool namedNonArrayBlock = isInterfaceBlock &&
3552 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3553 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3555 if (!isInterfaceBlock || namedNonArrayBlock)
3559 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3560 targetGroup->addChild(blockGroup);
3562 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3563 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3568 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3569 targetGroup->addChild(blockGroup);
3572 if (!isInterfaceBlock)
3573 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_SAMPLER_2D, 1, false);
3575 // .atomic_counter_*
3576 if (!isInterfaceBlock)
3578 const ResourceDefinition::Node::SharedPtr layout(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
3579 generateBufferBackedArrayStrideTypeAggregateCases(context, layout, blockGroup, queryTarget.interface, glu::TYPE_UINT_ATOMIC_COUNTER, 1, false);
3583 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_FLOAT, 2, false);
3586 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_BOOL, 1, false);
3589 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_BOOL_VEC3, 2, false);
3592 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_FLOAT_VEC3, 2, false);
3595 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_INT_VEC3, 2, false);
3600 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3601 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3602 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3606 static void generateUniformBlockLocationContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3608 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_LOCATION);
3609 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3611 if (!isInterfaceBlock)
3613 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 3);
3614 generateOpaqueTypeCases(context, parentStructure, targetGroup, queryTarget, 3);
3615 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 2);
3616 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 2);
3619 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1, false);
3622 static void generateUniformBlockBlockIndexContents (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion)
3624 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
3625 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
3626 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
3627 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
3628 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(uniform, glu::Layout(-1, 0)));
3632 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(uniform, glu::TYPE_FLOAT_VEC4));
3634 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "default_block"));
3639 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, true));
3640 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3642 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "named_block"));
3647 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, false));
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), "unnamed_block"));
3655 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding));
3656 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
3657 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3659 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "block_array"));
3663 static void generateUniformBlockAtomicCounterBufferIndexContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3665 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ATOMIC_COUNTER_BUFFER_INDEX);
3666 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3668 if (!isInterfaceBlock)
3670 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 3);
3671 generateOpaqueTypeCases(context, parentStructure, targetGroup, queryTarget, 3);
3675 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3676 const ResourceDefinition::Node::SharedPtr arrayArrayElement (new ResourceDefinition::ArrayElement(arrayElement));
3677 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3678 const ResourceDefinition::Node::SharedPtr elementvariable (new ResourceDefinition::Variable(arrayArrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3679 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3681 targetGroup->addChild(blockGroup);
3683 blockGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "var_array"));
3684 blockGroup->addChild(new ResourceTestCase(context, elementvariable, queryTarget, "var_array_array"));
3688 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1, false);
3691 static void generateUniformBlockNameLengthContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3693 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3694 const bool namedNonArrayBlock = isInterfaceBlock &&
3695 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3696 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3698 if (!isInterfaceBlock || namedNonArrayBlock)
3699 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 2);
3701 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 1);
3704 static void generateUniformBlockTypeContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3706 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_TYPE);
3707 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3708 const bool namedNonArrayBlock = isInterfaceBlock &&
3709 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3710 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3712 if (!isInterfaceBlock || namedNonArrayBlock)
3716 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3717 targetGroup->addChild(blockGroup);
3719 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3720 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3723 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3724 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3729 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3730 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3731 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3735 static void generateUniformBlockOffsetContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3737 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_OFFSET);
3738 const bool isInterfaceBlock = (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3739 const bool namedNonArrayBlock = isInterfaceBlock &&
3740 static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named &&
3741 parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3743 if (!isInterfaceBlock)
3747 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3748 targetGroup->addChild(blockGroup);
3750 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3751 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3756 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3757 targetGroup->addChild(blockGroup);
3759 // .atomic_uint_struct
3760 // .atomic_uint_array
3762 const ResourceDefinition::Node::SharedPtr offset (new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, 4)));
3763 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(offset));
3764 const ResourceDefinition::Node::SharedPtr elementVariable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3766 blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "atomic_uint_array"));
3772 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3773 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3774 const ResourceDefinition::Node::SharedPtr memberVariable (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
3775 const ResourceDefinition::Node::SharedPtr elementVariable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
3777 blockGroup->addChild(new ResourceTestCase(context, memberVariable, queryTarget, "float_struct"));
3778 blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "float_array"));
3782 else if (namedNonArrayBlock)
3786 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3787 targetGroup->addChild(blockGroup);
3789 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3790 generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3795 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3796 targetGroup->addChild(blockGroup);
3801 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3802 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::StructMember(parentStructure));
3803 const ResourceDefinition::Node::SharedPtr memberVariable (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
3804 const ResourceDefinition::Node::SharedPtr elementVariable (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
3806 blockGroup->addChild(new ResourceTestCase(context, memberVariable, queryTarget, "float_struct"));
3807 blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "float_array"));
3813 generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3814 generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3815 generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3819 static void generateMatrixVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, bool createTestGroup = true, int expandLevel = 2)
3827 { 0, glu::TYPE_FLOAT_MAT2 },
3828 { 1, glu::TYPE_FLOAT_MAT2X3 },
3829 { 2, glu::TYPE_FLOAT_MAT2X4 },
3830 { 2, glu::TYPE_FLOAT_MAT3X2 },
3831 { 1, glu::TYPE_FLOAT_MAT3 },
3832 { 0, glu::TYPE_FLOAT_MAT3X4 },
3833 { 2, glu::TYPE_FLOAT_MAT4X2 },
3834 { 1, glu::TYPE_FLOAT_MAT4X3 },
3835 { 0, glu::TYPE_FLOAT_MAT4 },
3838 tcu::TestCaseGroup* group;
3840 if (createTestGroup)
3842 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "matrix", "Basic matrix type");
3843 targetGroup->addChild(blockGroup);
3847 group = targetGroup;
3849 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3851 if (variableTypes[ndx].priority < expandLevel)
3853 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
3854 group->addChild(new ResourceTestCase(context, variable, queryTarget));
3859 static void generateMatrixStructCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel);
3861 static void generateMatrixArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
3863 if (expandLevel > 0)
3865 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
3866 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3868 targetGroup->addChild(blockGroup);
3870 // Arrays of basic variables
3871 generateMatrixVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel != 1, expandLevel);
3874 generateMatrixArrayCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3876 // Arrays of structs
3877 generateMatrixStructCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3881 static void generateMatrixStructCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
3883 if (expandLevel > 0)
3885 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
3886 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "struct", "Structs");
3888 targetGroup->addChild(blockGroup);
3890 // Struct containing basic variable
3891 generateMatrixVariableCases(context, structMember, blockGroup, queryTarget, expandLevel != 1, expandLevel);
3893 // Struct containing arrays
3894 generateMatrixArrayCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3896 // Struct containing struct
3897 generateMatrixStructCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3901 static void generateUniformMatrixOrderCaseBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, bool extendedBasicTypeCases, bool opaqueCases)
3906 glu::MatrixOrder order;
3909 { "no_qualifier", glu::MATRIXORDER_LAST },
3910 { "row_major", glu::MATRIXORDER_ROW_MAJOR },
3911 { "column_major", glu::MATRIXORDER_COLUMN_MAJOR },
3914 const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR);
3916 for (int qualifierNdx = 0; qualifierNdx < DE_LENGTH_OF_ARRAY(qualifiers); ++qualifierNdx)
3918 // Add layout qualifiers only for block members
3919 if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST || parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3921 ResourceDefinition::Node::SharedPtr subStructure = parentStructure;
3922 tcu::TestCaseGroup* const qualifierGroup = new tcu::TestCaseGroup(context.getTestContext(), qualifiers[qualifierNdx].name, "");
3924 targetGroup->addChild(qualifierGroup);
3926 if (qualifiers[qualifierNdx].order != glu::MATRIXORDER_LAST)
3929 layout.matrixOrder = qualifiers[qualifierNdx].order;
3930 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
3933 if (extendedBasicTypeCases && qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST)
3937 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "");
3938 qualifierGroup->addChild(blockGroup);
3940 generateVariableCases(context, subStructure, blockGroup, queryTarget, 1, false);
3941 generateMatrixVariableCases(context, subStructure, blockGroup, queryTarget, false);
3943 generateOpaqueTypeCases(context, subStructure, blockGroup, queryTarget, 2, false);
3948 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "");
3949 qualifierGroup->addChild(blockGroup);
3951 generateBufferBackedVariableAggregateTypeCases(context, subStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
3956 generateBufferBackedVariableAggregateTypeCases(context, subStructure, qualifierGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
3962 static void generateUniformMatrixStrideCaseBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, bool extendedBasicTypeCases, bool opaqueCases)
3967 glu::MatrixOrder order;
3970 { "no_qualifier", glu::MATRIXORDER_LAST },
3971 { "row_major", glu::MATRIXORDER_ROW_MAJOR },
3972 { "column_major", glu::MATRIXORDER_COLUMN_MAJOR },
3975 const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_MATRIX_STRIDE);
3977 for (int qualifierNdx = 0; qualifierNdx < DE_LENGTH_OF_ARRAY(qualifiers); ++qualifierNdx)
3979 // Add layout qualifiers only for block members
3980 if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST || parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3982 ResourceDefinition::Node::SharedPtr subStructure = parentStructure;
3983 tcu::TestCaseGroup* const qualifierGroup = new tcu::TestCaseGroup(context.getTestContext(), qualifiers[qualifierNdx].name, "");
3985 targetGroup->addChild(qualifierGroup);
3987 if (qualifiers[qualifierNdx].order != glu::MATRIXORDER_LAST)
3990 layout.matrixOrder = qualifiers[qualifierNdx].order;
3991 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
3994 if (extendedBasicTypeCases)
3998 if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST)
4000 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "");
4001 qualifierGroup->addChild(blockGroup);
4003 generateVariableCases(context, subStructure, blockGroup, queryTarget, 1, false);
4004 generateMatrixVariableCases(context, subStructure, blockGroup, queryTarget, false);
4006 generateOpaqueTypeCases(context, subStructure, blockGroup, queryTarget, 2, false);
4009 generateMatrixVariableCases(context, subStructure, qualifierGroup, queryTarget);
4013 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "");
4014 qualifierGroup->addChild(blockGroup);
4016 generateBufferBackedVariableAggregateTypeCases(context, subStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
4020 generateBufferBackedVariableAggregateTypeCases(context, subStructure, qualifierGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
4025 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))
4030 const char* description;
4033 bool extendedBasicTypeCases;
4034 glu::MatrixOrder order;
4037 { "default_block", "Default block", false, true, true, glu::MATRIXORDER_LAST },
4038 { "named_block", "Named uniform block", true, true, true, glu::MATRIXORDER_LAST },
4039 { "named_block_row_major", "Named uniform block", true, true, false, glu::MATRIXORDER_ROW_MAJOR },
4040 { "named_block_col_major", "Named uniform block", true, true, false, glu::MATRIXORDER_COLUMN_MAJOR },
4041 { "unnamed_block", "Unnamed uniform block", true, false, false, glu::MATRIXORDER_LAST },
4042 { "unnamed_block_row_major", "Unnamed uniform block", true, false, false, glu::MATRIXORDER_ROW_MAJOR },
4043 { "unnamed_block_col_major", "Unnamed uniform block", true, false, false, glu::MATRIXORDER_COLUMN_MAJOR },
4046 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
4047 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4049 for (int childNdx = 0; childNdx < (int)DE_LENGTH_OF_ARRAY(children); ++childNdx)
4051 ResourceDefinition::Node::SharedPtr subStructure = uniform;
4052 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), children[childNdx].name, children[childNdx].description);
4053 const bool addOpaqueCases = children[childNdx].extendedBasicTypeCases && !children[childNdx].block;
4055 targetGroup->addChild(blockGroup);
4057 if (children[childNdx].order != glu::MATRIXORDER_LAST)
4060 layout.matrixOrder = children[childNdx].order;
4061 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
4064 if (children[childNdx].block)
4065 subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(subStructure, children[childNdx].namedBlock));
4067 blockContentGenerator(context, subStructure, blockGroup, children[childNdx].extendedBasicTypeCases, addOpaqueCases);
4071 static void generateBufferReferencedByShaderInterfaceBlockCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, bool extendedCases)
4073 const bool isDefaultBlock = (parentStructure->getType() != ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
4079 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(parentStructure, glu::TYPE_FLOAT));
4080 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
4081 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4082 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4083 const ResourceDefinition::Node::SharedPtr variableStruct (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
4085 targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "float"));
4086 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_array"));
4087 targetGroup->addChild(new ResourceTestCase(context, variableStruct, queryTarget, "float_struct"));
4095 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
4096 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_SAMPLER_2D));
4097 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(layout));
4098 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4099 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_SAMPLER_2D));
4100 const ResourceDefinition::Node::SharedPtr variableStruct (new ResourceDefinition::Variable(structMember, glu::TYPE_SAMPLER_2D));
4102 targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "sampler"));
4103 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "sampler_array"));
4104 targetGroup->addChild(new ResourceTestCase(context, variableStruct, queryTarget, "sampler_struct"));
4108 // .atomic_uint_array
4111 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
4112 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_UINT_ATOMIC_COUNTER));
4113 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(layout));
4114 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
4116 targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "atomic_uint"));
4117 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "atomic_uint_array"));
4122 // .float_array_struct
4124 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4125 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(structMember));
4126 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4128 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_array_struct"));
4131 // .float_struct_array
4133 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
4134 const ResourceDefinition::Node::SharedPtr arrayStructMember (new ResourceDefinition::StructMember(arrayElement));
4135 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(arrayStructMember, glu::TYPE_FLOAT));
4137 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_struct_array"));
4140 // .float_array_array
4142 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
4143 const ResourceDefinition::Node::SharedPtr subArrayElement (new ResourceDefinition::ArrayElement(arrayElement));
4144 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(subArrayElement, glu::TYPE_FLOAT));
4146 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_array_array"));
4149 // .float_struct_struct
4151 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
4152 const ResourceDefinition::Node::SharedPtr subStructMember (new ResourceDefinition::StructMember(structMember));
4153 const ResourceDefinition::Node::SharedPtr variableArrayStruct (new ResourceDefinition::Variable(subStructMember, glu::TYPE_FLOAT));
4155 targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_struct_struct"));
4158 if (queryTarget.interface == PROGRAMINTERFACE_BUFFER_VARIABLE)
4160 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
4162 // .float_unsized_array
4164 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4166 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_unsized_array"));
4169 // .float_unsized_struct_array
4171 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(arrayElement));
4172 const ResourceDefinition::Node::SharedPtr variableArray (new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
4174 targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_unsized_struct_array"));
4180 static void generateUniformReferencedByShaderSingleBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, int expandLevel)
4182 DE_UNREF(expandLevel);
4184 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
4185 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4186 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER);
4187 const bool singleShaderCase = parentStructure->getType() == ResourceDefinition::Node::TYPE_SHADER;
4191 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "default_block", "");
4192 targetGroup->addChild(blockGroup);
4194 generateBufferReferencedByShaderInterfaceBlockCases(context, uniform, blockGroup, queryTarget, singleShaderCase);
4199 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(uniform, true));
4200 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "uniform_block", "");
4202 targetGroup->addChild(blockGroup);
4204 generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, singleShaderCase);
4209 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(uniform, false));
4210 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "");
4212 targetGroup->addChild(blockGroup);
4214 generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, false);
4219 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(uniform));
4220 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4221 TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "");
4223 targetGroup->addChild(blockGroup);
4225 generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, false);
4229 static void generateReferencedByShaderCaseBlocks (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion, void (*generateBlockContent)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, int expandLevel))
4234 glu::ShaderType stage;
4236 } singleStageCases[] =
4238 { "compute", glu::SHADERTYPE_COMPUTE, 3 },
4239 { "separable_vertex", glu::SHADERTYPE_VERTEX, 2 },
4240 { "separable_fragment", glu::SHADERTYPE_FRAGMENT, 2 },
4241 { "separable_tess_ctrl", glu::SHADERTYPE_TESSELLATION_CONTROL, 2 },
4242 { "separable_tess_eval", glu::SHADERTYPE_TESSELLATION_EVALUATION, 2 },
4243 { "separable_geometry", glu::SHADERTYPE_GEOMETRY, 2 },
4255 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT),
4260 "vertex_tess_fragment",
4261 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
4266 "vertex_geo_fragment",
4267 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY),
4272 "vertex_tess_geo_fragment",
4273 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
4279 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
4281 TestCaseGroup* const blockGroup = new TestCaseGroup(context, singleStageCases[ndx].name, "");
4282 const bool programSeparable = (singleStageCases[ndx].stage != glu::SHADERTYPE_COMPUTE);
4283 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(programSeparable));
4284 const ResourceDefinition::Node::SharedPtr stage (new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glslVersion));
4286 targetGroup->addChild(blockGroup);
4288 generateBlockContent(context, stage, blockGroup, singleStageCases[ndx].expandLevel);
4291 for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
4295 TestCaseGroup* const blockGroup = new TestCaseGroup(context, pipelines[pipelineNdx].name, "");
4296 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4297 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program,
4299 pipelines[pipelineNdx].flags,
4300 pipelines[pipelineNdx].flags);
4301 targetGroup->addChild(blockGroup);
4304 const ResourceDefinition::Node::SharedPtr shaders(shaderSet);
4305 generateBlockContent(context, shaders, blockGroup, pipelines[pipelineNdx].expandLevel);
4310 for (int selectedStageBit = 0; selectedStageBit < glu::SHADERTYPE_LAST; ++selectedStageBit)
4312 if (pipelines[pipelineNdx].flags & (1 << selectedStageBit))
4314 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4315 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program,
4317 pipelines[pipelineNdx].flags,
4318 (1u << selectedStageBit));
4319 const char* stageName = (selectedStageBit == glu::SHADERTYPE_VERTEX) ? ("vertex")
4320 : (selectedStageBit == glu::SHADERTYPE_FRAGMENT) ? ("fragment")
4321 : (selectedStageBit == glu::SHADERTYPE_GEOMETRY) ? ("geo")
4322 : (selectedStageBit == glu::SHADERTYPE_TESSELLATION_CONTROL) ? ("tess_ctrl")
4323 : (selectedStageBit == glu::SHADERTYPE_TESSELLATION_EVALUATION) ? ("tess_eval")
4325 const std::string setName = std::string() + pipelines[pipelineNdx].name + "_only_" + stageName;
4326 TestCaseGroup* const blockGroup = new TestCaseGroup(context, setName.c_str(), "");
4327 const ResourceDefinition::Node::SharedPtr shaders (shaderSet);
4329 generateBlockContent(context, shaders, blockGroup, pipelines[pipelineNdx].subExpandLevel);
4330 targetGroup->addChild(blockGroup);
4336 static glu::DataType generateRandomDataType (de::Random& rnd, bool excludeOpaqueTypes)
4338 static const glu::DataType s_types[] =
4344 glu::TYPE_FLOAT_VEC2,
4345 glu::TYPE_FLOAT_VEC3,
4346 glu::TYPE_FLOAT_VEC4,
4350 glu::TYPE_UINT_VEC2,
4351 glu::TYPE_UINT_VEC3,
4352 glu::TYPE_UINT_VEC4,
4353 glu::TYPE_BOOL_VEC2,
4354 glu::TYPE_BOOL_VEC3,
4355 glu::TYPE_BOOL_VEC4,
4356 glu::TYPE_FLOAT_MAT2,
4357 glu::TYPE_FLOAT_MAT2X3,
4358 glu::TYPE_FLOAT_MAT2X4,
4359 glu::TYPE_FLOAT_MAT3X2,
4360 glu::TYPE_FLOAT_MAT3,
4361 glu::TYPE_FLOAT_MAT3X4,
4362 glu::TYPE_FLOAT_MAT4X2,
4363 glu::TYPE_FLOAT_MAT4X3,
4364 glu::TYPE_FLOAT_MAT4,
4366 glu::TYPE_SAMPLER_2D,
4367 glu::TYPE_SAMPLER_CUBE,
4368 glu::TYPE_SAMPLER_2D_ARRAY,
4369 glu::TYPE_SAMPLER_3D,
4370 glu::TYPE_SAMPLER_2D_SHADOW,
4371 glu::TYPE_SAMPLER_CUBE_SHADOW,
4372 glu::TYPE_SAMPLER_2D_ARRAY_SHADOW,
4373 glu::TYPE_INT_SAMPLER_2D,
4374 glu::TYPE_INT_SAMPLER_CUBE,
4375 glu::TYPE_INT_SAMPLER_2D_ARRAY,
4376 glu::TYPE_INT_SAMPLER_3D,
4377 glu::TYPE_UINT_SAMPLER_2D,
4378 glu::TYPE_UINT_SAMPLER_CUBE,
4379 glu::TYPE_UINT_SAMPLER_2D_ARRAY,
4380 glu::TYPE_UINT_SAMPLER_3D,
4381 glu::TYPE_SAMPLER_2D_MULTISAMPLE,
4382 glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE,
4383 glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE,
4385 glu::TYPE_IMAGE_CUBE,
4386 glu::TYPE_IMAGE_2D_ARRAY,
4388 glu::TYPE_INT_IMAGE_2D,
4389 glu::TYPE_INT_IMAGE_CUBE,
4390 glu::TYPE_INT_IMAGE_2D_ARRAY,
4391 glu::TYPE_INT_IMAGE_3D,
4392 glu::TYPE_UINT_IMAGE_2D,
4393 glu::TYPE_UINT_IMAGE_CUBE,
4394 glu::TYPE_UINT_IMAGE_2D_ARRAY,
4395 glu::TYPE_UINT_IMAGE_3D,
4396 glu::TYPE_UINT_ATOMIC_COUNTER
4401 const glu::DataType type = s_types[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_types)-1)];
4403 if (!excludeOpaqueTypes ||
4404 glu::isDataTypeScalarOrVector(type) ||
4405 glu::isDataTypeMatrix(type))
4410 static ResourceDefinition::Node::SharedPtr generateRandomVariableDefinition (de::Random& rnd,
4411 const ResourceDefinition::Node::SharedPtr& parentStructure,
4412 glu::DataType baseType,
4413 const glu::Layout& layout,
4416 const int maxNesting = 4;
4417 ResourceDefinition::Node::SharedPtr currentStructure = parentStructure;
4418 const bool canBeInsideAStruct = layout.binding == -1 && !isDataTypeLayoutQualified(baseType);
4420 for (int nestNdx = 0; nestNdx < maxNesting; ++nestNdx)
4422 if (allowUnsized && nestNdx == 0 && rnd.getFloat() < 0.2)
4423 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
4424 else if (rnd.getFloat() < 0.3 && canBeInsideAStruct)
4425 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StructMember(currentStructure));
4426 else if (rnd.getFloat() < 0.3)
4427 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
4432 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Variable(currentStructure, baseType));
4435 static ResourceDefinition::Node::SharedPtr generateRandomCoreShaderSet (de::Random& rnd, glu::GLSLVersion glslVersion)
4437 if (rnd.getFloat() < 0.5f)
4440 const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
4441 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
4443 else if (rnd.getFloat() < 0.5f)
4445 // vertex and fragment
4446 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4447 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program, glslVersion);
4451 shaderSet->setStage(glu::SHADERTYPE_VERTEX, true);
4452 shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, rnd.getBool());
4456 shaderSet->setStage(glu::SHADERTYPE_VERTEX, rnd.getBool());
4457 shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, true);
4460 return ResourceDefinition::Node::SharedPtr(shaderSet);
4464 // separate vertex or fragment
4465 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
4466 const glu::ShaderType shaderType = (rnd.getBool()) ? (glu::SHADERTYPE_VERTEX) : (glu::SHADERTYPE_FRAGMENT);
4468 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, shaderType, glslVersion));
4472 static ResourceDefinition::Node::SharedPtr generateRandomExtShaderSet (de::Random& rnd, glu::GLSLVersion glslVersion)
4474 if (rnd.getFloat() < 0.5f)
4477 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4478 ResourceDefinition::ShaderSet* shaderSet = new ResourceDefinition::ShaderSet(program, glslVersion);
4480 shaderSet->setStage(glu::SHADERTYPE_VERTEX, rnd.getBool());
4481 shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, rnd.getBool());
4483 // tess shader are either both or neither present. Make cases interesting
4484 // by forcing one extended shader to always have reference
4487 shaderSet->setStage(glu::SHADERTYPE_GEOMETRY, true);
4491 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, rnd.getBool());
4492 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, rnd.getBool());
4497 shaderSet->setStage(glu::SHADERTYPE_GEOMETRY, rnd.getBool());
4501 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, true);
4502 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, rnd.getBool());
4506 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, rnd.getBool());
4507 shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, true);
4511 return ResourceDefinition::Node::SharedPtr(shaderSet);
4516 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
4517 const int selector = rnd.getInt(0, 2);
4518 const glu::ShaderType shaderType = (selector == 0) ? (glu::SHADERTYPE_GEOMETRY)
4519 : (selector == 1) ? (glu::SHADERTYPE_TESSELLATION_CONTROL)
4520 : (selector == 2) ? (glu::SHADERTYPE_TESSELLATION_EVALUATION)
4521 : (glu::SHADERTYPE_LAST);
4523 return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, shaderType, glslVersion));
4527 static ResourceDefinition::Node::SharedPtr generateRandomShaderSet (de::Random& rnd, glu::GLSLVersion glslVersion, bool onlyExtensionStages)
4529 if (!onlyExtensionStages)
4530 return generateRandomCoreShaderSet(rnd, glslVersion);
4532 return generateRandomExtShaderSet(rnd, glslVersion);
4535 static glu::Layout generateRandomUniformBlockLayout (de::Random& rnd)
4540 layout.binding = rnd.getInt(0, 5);
4543 layout.matrixOrder = (rnd.getBool()) ? (glu::MATRIXORDER_COLUMN_MAJOR) : (glu::MATRIXORDER_ROW_MAJOR);
4548 static glu::Layout generateRandomBufferBlockLayout (de::Random& rnd)
4550 return generateRandomUniformBlockLayout(rnd);
4553 static glu::Layout generateRandomVariableLayout (de::Random& rnd, glu::DataType type, bool interfaceBlockMember)
4557 if ((glu::isDataTypeAtomicCounter(type) || glu::isDataTypeImage(type) || glu::isDataTypeSampler(type)) && rnd.getBool())
4558 layout.binding = rnd.getInt(0, 5);
4560 if (glu::isDataTypeAtomicCounter(type) && rnd.getBool())
4561 layout.offset = rnd.getInt(0, 3) * 4;
4563 if (glu::isDataTypeMatrix(type) && interfaceBlockMember && rnd.getBool())
4564 layout.matrixOrder = (rnd.getBool()) ? (glu::MATRIXORDER_COLUMN_MAJOR) : (glu::MATRIXORDER_ROW_MAJOR);
4569 static void generateUniformRandomCase (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion, int index, bool onlyExtensionStages)
4571 de::Random rnd (index * 0x12345);
4572 const ResourceDefinition::Node::SharedPtr shader = generateRandomShaderSet(rnd, glslVersion, onlyExtensionStages);
4573 const bool interfaceBlock = rnd.getBool();
4574 const glu::DataType type = generateRandomDataType(rnd, interfaceBlock);
4575 const glu::Layout layout = generateRandomVariableLayout(rnd, type, interfaceBlock);
4576 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
4577 const ResourceDefinition::Node::SharedPtr uniform (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4578 ResourceDefinition::Node::SharedPtr currentStructure = uniform;
4582 const bool namedBlock = rnd.getBool();
4584 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, generateRandomUniformBlockLayout(rnd)));
4586 if (namedBlock && rnd.getBool())
4587 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
4589 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(currentStructure, namedBlock));
4592 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, layout));
4593 currentStructure = generateRandomVariableDefinition(rnd, currentStructure, type, layout, false);
4595 targetGroup->addChild(new ResourceTestCase(context, currentStructure, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_UNIFORM_INTERFACE_MASK), de::toString(index).c_str()));
4598 static void generateUniformCaseRandomCases (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion)
4600 const int numBasicCases = 40;
4601 const int numTessGeoCases = 40;
4603 for (int ndx = 0; ndx < numBasicCases; ++ndx)
4604 generateUniformRandomCase(context, targetGroup, glslVersion, ndx, false);
4605 for (int ndx = 0; ndx < numTessGeoCases; ++ndx)
4606 generateUniformRandomCase(context, targetGroup, glslVersion, numBasicCases + ndx, true);
4609 class UniformInterfaceTestGroup : public TestCaseGroup
4612 UniformInterfaceTestGroup (Context& context);
4616 UniformInterfaceTestGroup::UniformInterfaceTestGroup (Context& context)
4617 : TestCaseGroup(context, "uniform", "Uniform interace")
4621 void UniformInterfaceTestGroup::init (void)
4623 glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
4624 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4625 const ResourceDefinition::Node::SharedPtr computeShader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
4629 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
4630 addChild(blockGroup);
4631 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformResourceListBlockContents);
4636 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Query array size");
4637 addChild(blockGroup);
4638 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockArraySizeContents);
4643 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_stride", "Query array stride");
4644 addChild(blockGroup);
4645 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockArrayStrideContents);
4648 // .atomic_counter_buffer_index
4650 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "atomic_counter_buffer_index", "Query atomic counter buffer index");
4651 addChild(blockGroup);
4652 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_DEFAULT | BLOCKFLAG_NAMED, generateUniformBlockAtomicCounterBufferIndexContents);
4657 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "block_index", "Query block index");
4658 addChild(blockGroup);
4659 generateUniformBlockBlockIndexContents(m_context, blockGroup, glslVersion);
4664 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Query location");
4665 addChild(blockGroup);
4666 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_DEFAULT | BLOCKFLAG_NAMED | BLOCKFLAG_UNNAMED, generateUniformBlockLocationContents);
4669 // .matrix_row_major
4671 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "matrix_row_major", "Query matrix row_major");
4672 addChild(blockGroup);
4673 generateUniformMatrixCaseBlocks(m_context, computeShader, blockGroup, generateUniformMatrixOrderCaseBlockContentCases);
4678 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "matrix_stride", "Query matrix stride");
4679 addChild(blockGroup);
4680 generateUniformMatrixCaseBlocks(m_context, computeShader, blockGroup, generateUniformMatrixStrideCaseBlockContentCases);
4685 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Query name length");
4686 addChild(blockGroup);
4687 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockNameLengthContents);
4692 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "offset", "Query offset");
4693 addChild(blockGroup);
4694 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockOffsetContents);
4697 // .referenced_by_shader
4699 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by_shader", "Query referenced by shader");
4700 addChild(blockGroup);
4701 generateReferencedByShaderCaseBlocks(m_context, blockGroup, glslVersion, generateUniformReferencedByShaderSingleBlockContentCases);
4706 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Query type");
4707 addChild(blockGroup);
4708 generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockTypeContents);
4713 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random");
4714 addChild(blockGroup);
4715 generateUniformCaseRandomCases(m_context, blockGroup, glslVersion);
4719 static void generateBufferBackedInterfaceResourceListCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, const char* blockName)
4721 targetGroup->addChild(new ResourceListTestCase(context, targetResource, interface, blockName));
4724 static void generateBufferBackedInterfaceNameLengthCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, const char* blockName)
4726 targetGroup->addChild(new ResourceTestCase(context, targetResource, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_NAME_LENGTH), blockName));
4729 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))
4731 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4732 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
4733 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
4734 const ResourceDefinition::Node::SharedPtr storageQualifier (new ResourceDefinition::StorageQualifier(defaultBlock, storage));
4735 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(storageQualifier, glu::Layout(-1, 1)));
4736 const ProgramInterface programInterface = (storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) : (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK);
4740 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, true));
4741 const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4743 blockContentGenerator(context, unusedVariable, targetGroup, programInterface, "named_block");
4748 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, false));
4749 const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4751 blockContentGenerator(context, unusedVariable, targetGroup, programInterface, "unnamed_block");
4756 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding, 3));
4757 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4758 const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4760 blockContentGenerator(context, unusedVariable, targetGroup, programInterface, "block_array");
4763 // .block_array_single_element
4765 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding, 1));
4766 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4767 const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4769 blockContentGenerator(context, unusedVariable, targetGroup, programInterface, "block_array_single_element");
4773 static void generateBufferBackedInterfaceResourceBufferBindingCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion, glu::Storage storage)
4775 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
4776 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
4777 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
4778 const ResourceDefinition::Node::SharedPtr storageQualifier (new ResourceDefinition::StorageQualifier(defaultBlock, storage));
4780 for (int ndx = 0; ndx < 2; ++ndx)
4782 const bool explicitBinding = (ndx == 1);
4783 const int bindingNdx = (explicitBinding) ? (1) : (-1);
4784 const std::string nameSuffix = (explicitBinding) ? ("_explicit_binding") : ("");
4785 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(storageQualifier, glu::Layout(-1, bindingNdx)));
4786 const ProgramInterface programInterface = (storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) : (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK);
4790 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, true));
4791 const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4793 targetGroup->addChild(new ResourceTestCase(context, unusedVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("named_block" + nameSuffix).c_str()));
4798 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(binding, false));
4799 const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4801 targetGroup->addChild(new ResourceTestCase(context, unusedVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("unnamed_block" + nameSuffix).c_str()));
4806 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding, 3));
4807 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4808 const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4810 targetGroup->addChild(new ResourceTestCase(context, unusedVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("block_array" + nameSuffix).c_str()));
4815 template <glu::Storage Storage>
4816 static void generateBufferBlockReferencedByShaderSingleBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
4818 const ProgramInterface programInterface = (Storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
4819 (Storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
4820 (PROGRAMINTERFACE_LAST);
4821 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
4822 const ResourceDefinition::Node::SharedPtr storage (new ResourceDefinition::StorageQualifier(defaultBlock, Storage));
4824 DE_UNREF(expandLevel);
4826 DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
4830 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, true));
4831 const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4833 targetGroup->addChild(new ResourceTestCase(context, unusedVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "named_block"));
4838 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, false));
4839 const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4841 targetGroup->addChild(new ResourceTestCase(context, unusedVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "unnamed_block"));
4846 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(storage, 3));
4847 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
4848 const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4850 targetGroup->addChild(new ResourceTestCase(context, unusedVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "block_array"));
4854 static void generateBufferBackedInterfaceResourceActiveVariablesCase (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
4856 targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "named_block", "Named block", storage, InterfaceBlockActiveVariablesTestCase::CASE_NAMED_BLOCK));
4857 targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "unnamed_block", "Unnamed block", storage, InterfaceBlockActiveVariablesTestCase::CASE_UNNAMED_BLOCK));
4858 targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "block_array", "Block array", storage, InterfaceBlockActiveVariablesTestCase::CASE_BLOCK_ARRAY));
4861 static void generateBufferBackedInterfaceResourceBufferDataSizeCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
4863 targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "named_block", "Named block", storage, InterfaceBlockDataSizeTestCase::CASE_NAMED_BLOCK));
4864 targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "unnamed_block", "Unnamed block", storage, InterfaceBlockDataSizeTestCase::CASE_UNNAMED_BLOCK));
4865 targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "block_array", "Block array", storage, InterfaceBlockDataSizeTestCase::CASE_BLOCK_ARRAY));
4868 class BufferBackedBlockInterfaceTestGroup : public TestCaseGroup
4871 BufferBackedBlockInterfaceTestGroup (Context& context, glu::Storage interfaceBlockStorage);
4875 static const char* getGroupName (glu::Storage storage);
4876 static const char* getGroupDescription (glu::Storage storage);
4878 const glu::Storage m_storage;
4881 BufferBackedBlockInterfaceTestGroup::BufferBackedBlockInterfaceTestGroup(Context& context, glu::Storage storage)
4882 : TestCaseGroup (context, getGroupName(storage), getGroupDescription(storage))
4883 , m_storage (storage)
4885 DE_ASSERT(storage == glu::STORAGE_BUFFER || storage == glu::STORAGE_UNIFORM);
4888 void BufferBackedBlockInterfaceTestGroup::init (void)
4890 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
4894 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
4895 addChild(blockGroup);
4896 generateBufferBackedInterfaceResourceBasicBlockTypes(m_context, blockGroup, glslVersion, m_storage, generateBufferBackedInterfaceResourceListCase);
4899 // .active_variables
4901 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "active_variables", "Active variables");
4902 addChild(blockGroup);
4903 generateBufferBackedInterfaceResourceActiveVariablesCase(m_context, blockGroup, m_storage);
4908 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "buffer_binding", "Buffer binding");
4909 addChild(blockGroup);
4910 generateBufferBackedInterfaceResourceBufferBindingCases(m_context, blockGroup, glslVersion, m_storage);
4913 // .buffer_data_size
4915 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "buffer_data_size", "Buffer data size");
4916 addChild(blockGroup);
4917 generateBufferBackedInterfaceResourceBufferDataSizeCases(m_context, blockGroup, m_storage);
4922 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
4923 addChild(blockGroup);
4924 generateBufferBackedInterfaceResourceBasicBlockTypes(m_context, blockGroup, glslVersion, m_storage, generateBufferBackedInterfaceNameLengthCase);
4929 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Referenced by shader");
4930 addChild(blockGroup);
4932 if (m_storage == glu::STORAGE_UNIFORM)
4933 generateReferencedByShaderCaseBlocks(m_context, blockGroup, glslVersion, generateBufferBlockReferencedByShaderSingleBlockContentCases<glu::STORAGE_UNIFORM>);
4934 else if (m_storage == glu::STORAGE_BUFFER)
4935 generateReferencedByShaderCaseBlocks(m_context, blockGroup, glslVersion, generateBufferBlockReferencedByShaderSingleBlockContentCases<glu::STORAGE_BUFFER>);
4941 const char* BufferBackedBlockInterfaceTestGroup::getGroupName (glu::Storage storage)
4945 case glu::STORAGE_UNIFORM: return "uniform_block";
4946 case glu::STORAGE_BUFFER: return "shader_storage_block";
4948 DE_FATAL("invalid storage enum value");
4953 const char* BufferBackedBlockInterfaceTestGroup::getGroupDescription (glu::Storage storage)
4957 case glu::STORAGE_UNIFORM: return "Uniform block interface";
4958 case glu::STORAGE_BUFFER: return "Shader storage block interface";
4960 DE_FATAL("invalid storage enum value");
4965 class AtomicCounterTestGroup : public TestCaseGroup
4968 AtomicCounterTestGroup (Context& context);
4972 AtomicCounterTestGroup::AtomicCounterTestGroup (Context& context)
4973 : TestCaseGroup(context, "atomic_counter_buffer", "Atomic counter buffer")
4977 void AtomicCounterTestGroup::init (void)
4987 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT)
4990 "vertex_tess_fragment",
4991 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION)
4994 "vertex_geo_fragment",
4995 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY)
4998 "vertex_tess_geo_fragment",
4999 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
5004 addChild(new AtomicCounterResourceListCase(m_context, "resource_list", "Resource list"));
5006 // .active_variables
5007 addChild(new AtomicCounterActiveVariablesCase(m_context, "active_variables", "Active variables"));
5010 addChild(new AtomicCounterBufferBindingCase(m_context, "buffer_binding", "Buffer binding"));
5012 // .buffer_data_size
5013 addChild(new AtomicCounterBufferDataSizeCase(m_context, "buffer_data_size", "Buffer binding"));
5016 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_compute", "", false, (1 << glu::SHADERTYPE_COMPUTE), (1 << glu::SHADERTYPE_COMPUTE)));
5017 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_vertex", "", true, (1 << glu::SHADERTYPE_VERTEX), (1 << glu::SHADERTYPE_VERTEX)));
5018 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_fragment", "", true, (1 << glu::SHADERTYPE_FRAGMENT), (1 << glu::SHADERTYPE_FRAGMENT)));
5019 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_geometry", "", true, (1 << glu::SHADERTYPE_GEOMETRY), (1 << glu::SHADERTYPE_GEOMETRY)));
5020 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_tess_ctrl", "", true, (1 << glu::SHADERTYPE_TESSELLATION_CONTROL), (1 << glu::SHADERTYPE_TESSELLATION_CONTROL)));
5021 addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_tess_eval", "", true, (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION), (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION)));
5023 for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
5025 addChild(new AtomicCounterReferencedByCase(m_context, (std::string() + "referenced_by_" + pipelines[pipelineNdx].name).c_str(), "", false, pipelines[pipelineNdx].flags, pipelines[pipelineNdx].flags));
5027 for (deUint32 stageNdx = 0; stageNdx < glu::SHADERTYPE_LAST; ++stageNdx)
5029 const deUint32 currentBit = (1u << stageNdx);
5030 if (currentBit > pipelines[pipelineNdx].flags)
5032 if (currentBit & pipelines[pipelineNdx].flags)
5034 const char* stageName = (stageNdx == glu::SHADERTYPE_VERTEX) ? ("vertex")
5035 : (stageNdx == glu::SHADERTYPE_FRAGMENT) ? ("fragment")
5036 : (stageNdx == glu::SHADERTYPE_GEOMETRY) ? ("geo")
5037 : (stageNdx == glu::SHADERTYPE_TESSELLATION_CONTROL) ? ("tess_ctrl")
5038 : (stageNdx == glu::SHADERTYPE_TESSELLATION_EVALUATION) ? ("tess_eval")
5040 const std::string name = std::string() + "referenced_by_" + pipelines[pipelineNdx].name + "_only_" + stageName;
5042 addChild(new AtomicCounterReferencedByCase(m_context, name.c_str(), "", false, pipelines[pipelineNdx].flags, currentBit));
5048 static void generateProgramInputOutputShaderCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion, bool withCompute, bool inputCase, bool isGL45, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, deUint32, bool))
5053 glu::ShaderType stage;
5054 } singleStageCases[] =
5056 { "separable_vertex", glu::SHADERTYPE_VERTEX },
5057 { "separable_fragment", glu::SHADERTYPE_FRAGMENT },
5058 { "separable_tess_ctrl", glu::SHADERTYPE_TESSELLATION_CONTROL },
5059 { "separable_tess_eval", glu::SHADERTYPE_TESSELLATION_EVALUATION },
5060 { "separable_geometry", glu::SHADERTYPE_GEOMETRY },
5065 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "vertex_fragment", "Vertex and fragment");
5066 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(false));
5067 ResourceDefinition::ShaderSet* shaderSetPtr = new ResourceDefinition::ShaderSet(program, glslVersion);
5068 const ResourceDefinition::Node::SharedPtr shaderSet (shaderSetPtr);
5069 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shaderSet));
5071 shaderSetPtr->setStage(glu::SHADERTYPE_VERTEX, inputCase);
5072 shaderSetPtr->setStage(glu::SHADERTYPE_FRAGMENT, !inputCase);
5074 targetGroup->addChild(blockGroup);
5076 blockContentGenerator(context, defaultBlock, blockGroup, (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT), isGL45);
5080 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
5082 TestCaseGroup* const blockGroup = new TestCaseGroup(context, singleStageCases[ndx].name, "");
5083 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
5084 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glslVersion));
5085 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
5087 targetGroup->addChild(blockGroup);
5088 blockContentGenerator(context, defaultBlock, blockGroup, (1 << singleStageCases[ndx].stage), isGL45);
5094 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "compute", "Compute");
5095 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
5096 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
5097 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
5099 targetGroup->addChild(blockGroup);
5101 blockContentGenerator(context, defaultBlock, blockGroup, (1 << glu::SHADERTYPE_COMPUTE), isGL45);
5104 // .interface_blocks
5108 const char* inputName;
5109 glu::ShaderType inputStage;
5110 glu::Storage inputStorage;
5111 const char* outputName;
5112 glu::ShaderType outputStage;
5113 glu::Storage outputStorage;
5118 glu::SHADERTYPE_FRAGMENT,
5121 glu::SHADERTYPE_VERTEX,
5126 glu::SHADERTYPE_TESSELLATION_EVALUATION,
5127 glu::STORAGE_PATCH_IN,
5129 glu::SHADERTYPE_TESSELLATION_CONTROL,
5130 glu::STORAGE_PATCH_OUT,
5134 tcu::TestCaseGroup* const ioBlocksGroup = new TestCaseGroup(context, "interface_blocks", "Interface blocks");
5135 targetGroup->addChild(ioBlocksGroup);
5140 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(ioBlockTypes); ++ndx)
5142 const char* const name = (inputCase) ? (ioBlockTypes[ndx].inputName) : (ioBlockTypes[ndx].outputName);
5143 const glu::ShaderType shaderType = (inputCase) ? (ioBlockTypes[ndx].inputStage) : (ioBlockTypes[ndx].outputStage);
5144 const glu::Storage storageType = (inputCase) ? (ioBlockTypes[ndx].inputStorage) : (ioBlockTypes[ndx].outputStorage);
5145 tcu::TestCaseGroup* const ioBlockGroup = new TestCaseGroup(context, name, "");
5146 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
5147 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, shaderType, glslVersion));
5148 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
5149 const ResourceDefinition::Node::SharedPtr storage (new ResourceDefinition::StorageQualifier(defaultBlock, storageType));
5151 ioBlocksGroup->addChild(ioBlockGroup);
5155 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, true));
5156 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block", "Named block");
5158 ioBlockGroup->addChild(blockGroup);
5160 blockContentGenerator(context, block, blockGroup, (1 << shaderType), isGL45);
5163 // .named_block_explicit_location
5165 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(storage, glu::Layout(3)));
5166 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(layout, true));
5167 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block_explicit_location", "Named block with explicit location");
5169 ioBlockGroup->addChild(blockGroup);
5171 blockContentGenerator(context, block, blockGroup, (1 << shaderType), isGL45);
5177 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(storage, false));
5178 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "Unnamed block");
5180 ioBlockGroup->addChild(blockGroup);
5182 blockContentGenerator(context, block, blockGroup, (1 << shaderType), isGL45);
5187 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(storage));
5188 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(arrayElement, true));
5189 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "Block array");
5191 ioBlockGroup->addChild(blockGroup);
5193 blockContentGenerator(context, block, blockGroup, (1 << shaderType), isGL45);
5199 static void generateProgramInputBlockContents (Context& context,
5200 const ResourceDefinition::Node::SharedPtr& parentStructure,
5201 tcu::TestCaseGroup* targetGroup,
5202 deUint32 presentShadersMask,
5204 void (*genCase)(Context& context,
5205 const ResourceDefinition::Node::SharedPtr& parentStructure,
5206 tcu::TestCaseGroup* targetGroup,
5207 ProgramInterface interface,
5210 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5211 const ResourceDefinition::Node::SharedPtr input = (inDefaultBlock)
5212 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
5213 : (parentStructure);
5214 const glu::ShaderType firstStage = getShaderMaskFirstStage(presentShadersMask);
5217 if (includeEmpty && inDefaultBlock)
5218 genCase(context, parentStructure, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "empty");
5220 if (firstStage == glu::SHADERTYPE_VERTEX)
5223 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5224 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5226 else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5230 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5231 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5235 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(input));
5236 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5237 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var_struct");
5241 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input));
5242 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5243 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var_array");
5246 else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
5247 firstStage == glu::SHADERTYPE_GEOMETRY)
5249 // arrayed interface
5253 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5254 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5255 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5257 // extension forbids use arrays of structs
5258 // extension forbids use arrays of arrays
5260 else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5262 // arrayed interface
5263 const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5267 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5268 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5269 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5271 // extension forbids use arrays of structs
5272 // extension forbids use arrays of arrays
5276 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchInput, glu::TYPE_FLOAT_VEC4));
5277 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var");
5279 // .patch_var_struct
5281 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchInput));
5282 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5283 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var_struct");
5287 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchInput));
5288 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5289 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var_array");
5292 else if (firstStage == glu::SHADERTYPE_COMPUTE)
5300 static void generateProgramOutputBlockContents (Context& context,
5301 const ResourceDefinition::Node::SharedPtr& parentStructure,
5302 tcu::TestCaseGroup* targetGroup,
5303 deUint32 presentShadersMask,
5305 void (*genCase)(Context& context,
5306 const ResourceDefinition::Node::SharedPtr& parentStructure,
5307 tcu::TestCaseGroup* targetGroup,
5308 ProgramInterface interface,
5311 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5312 const ResourceDefinition::Node::SharedPtr output = (inDefaultBlock)
5313 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
5314 : (parentStructure);
5315 const glu::ShaderType lastStage = getShaderMaskLastStage(presentShadersMask);
5318 if (includeEmpty && inDefaultBlock)
5319 genCase(context, parentStructure, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "empty");
5321 if (lastStage == glu::SHADERTYPE_VERTEX ||
5322 lastStage == glu::SHADERTYPE_GEOMETRY ||
5323 lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
5328 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5329 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5333 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
5334 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5335 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_struct");
5339 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5340 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5341 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_array");
5344 else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5348 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5349 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5353 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5354 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5355 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_array");
5358 else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5360 // arrayed interface
5361 const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5365 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5366 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5367 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5369 // extension forbids use arrays of structs
5370 // extension forbids use array of arrays
5374 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchOutput, glu::TYPE_FLOAT_VEC4));
5375 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var");
5377 // .patch_var_struct
5379 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchOutput));
5380 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5381 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var_struct");
5385 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchOutput));
5386 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5387 genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var_array");
5390 else if (lastStage == glu::SHADERTYPE_COMPUTE)
5398 static void addProgramInputOutputResourceListCase (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramInterface programInterface, const char* name)
5400 ResourceListTestCase* const resourceListCase = new ResourceListTestCase(context, parentStructure, programInterface);
5402 DE_ASSERT(deStringEqual(name, resourceListCase->getName()));
5404 targetGroup->addChild(resourceListCase);
5407 static void generateProgramInputResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask, bool isGL45)
5410 generateProgramInputBlockContents(context, parentStructure, targetGroup, presentShadersMask, true, addProgramInputOutputResourceListCase);
5413 static void generateProgramOutputResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask, bool isGL45)
5416 generateProgramOutputBlockContents(context, parentStructure, targetGroup, presentShadersMask, true, addProgramInputOutputResourceListCase);
5419 template <ProgramResourcePropFlags TargetProp>
5420 static void addProgramInputOutputResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramInterface programInterface, const char* name)
5422 ResourceTestCase* const resourceTestCase = new ResourceTestCase(context, parentStructure, ProgramResourceQueryTestTarget(programInterface, TargetProp), name);
5423 targetGroup->addChild(resourceTestCase);
5426 template <ProgramResourcePropFlags TargetProp>
5427 static void generateProgramInputBasicBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask, bool isGL45)
5430 generateProgramInputBlockContents(context, parentStructure, targetGroup, presentShadersMask, false, addProgramInputOutputResourceTestCase<TargetProp>);
5433 template <ProgramResourcePropFlags TargetProp>
5434 static void generateProgramOutputBasicBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask, bool isGL45)
5437 generateProgramOutputBlockContents(context, parentStructure, targetGroup, presentShadersMask, false, addProgramInputOutputResourceTestCase<TargetProp>);
5440 static void generateProgramInputLocationBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask, bool isGL45)
5443 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5444 const ResourceDefinition::Node::SharedPtr input = (inDefaultBlock)
5445 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
5446 : (parentStructure);
5447 const glu::ShaderType firstStage = getShaderMaskFirstStage(presentShadersMask);
5449 const bool inBlockArray = DE_TRUE == deStringEqual("block_array", targetGroup->getName());
5451 if (firstStage == glu::SHADERTYPE_VERTEX)
5455 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5456 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5458 // .var_explicit_location
5460 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5461 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5462 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5465 else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5469 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5470 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5472 // .var_explicit_location
5475 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5476 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5477 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5481 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(input));
5482 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5483 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct"));
5485 // .var_struct_explicit_location
5488 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5489 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5490 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5491 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct_explicit_location"));
5495 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input));
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_array"));
5499 // .var_array_explicit_location
5502 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5503 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5504 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5505 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
5508 else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
5509 firstStage == glu::SHADERTYPE_GEOMETRY)
5511 // arrayed interface
5515 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5516 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5517 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5519 // .var_explicit_location
5521 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5522 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5523 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5524 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5526 // extension forbids use arrays of structs
5527 // extension forbids use arrays of arrays
5529 else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5531 // arrayed interface
5532 const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5536 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5537 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5538 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5540 // .var_explicit_location
5542 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5543 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5544 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5545 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5547 // extension forbids use arrays of structs
5548 // extension forbids use arrays of arrays
5552 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchInput, glu::TYPE_FLOAT_VEC4));
5553 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var"));
5555 // .patch_var_explicit_location
5557 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
5558 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5559 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_explicit_location"));
5561 // .patch_var_struct
5563 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchInput));
5564 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5565 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct"));
5567 // .patch_var_struct_explicit_location
5569 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
5570 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5571 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5572 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct_explicit_location"));
5576 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchInput));
5577 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5578 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array"));
5580 // .patch_var_array_explicit_location
5582 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
5583 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5584 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5585 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array_explicit_location"));
5588 else if (firstStage == glu::SHADERTYPE_COMPUTE)
5596 static void generateProgramOutputLocationBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask, bool isGL45)
5599 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5600 const ResourceDefinition::Node::SharedPtr output = (inDefaultBlock)
5601 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
5602 : (parentStructure);
5603 const glu::ShaderType lastStage = getShaderMaskLastStage(presentShadersMask);
5605 const bool inBlockArray = DE_TRUE == deStringEqual("block_array", targetGroup->getName());
5607 if (lastStage == glu::SHADERTYPE_VERTEX ||
5608 lastStage == glu::SHADERTYPE_GEOMETRY ||
5609 lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
5614 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5615 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5617 // .var_explicit_location
5620 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5621 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5622 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5626 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
5627 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5628 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct"));
5630 // .var_struct_explicit_location
5633 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5634 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5635 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5636 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct_explicit_location"));
5640 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5641 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5642 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
5644 // .var_array_explicit_location
5647 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5648 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5649 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5650 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
5653 else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5657 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5658 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5660 // .var_explicit_location
5663 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5664 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5665 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5669 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
5670 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5671 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
5673 // .var_array_explicit_location
5676 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(1)));
5677 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5678 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5679 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
5682 else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5684 // arrayed interface
5685 const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5689 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5690 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5691 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5693 // .var_explicit_location
5695 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5696 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5697 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5698 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5700 // extension forbids use arrays of structs
5701 // extension forbids use array of arrays
5705 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(patchOutput, glu::TYPE_FLOAT_VEC4));
5706 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var"));
5708 // .patch_var_explicit_location
5710 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
5711 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5712 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_explicit_location"));
5714 // .patch_var_struct
5716 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchOutput));
5717 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5718 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct"));
5720 // .patch_var_struct_explicit_location
5722 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
5723 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(layout));
5724 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5725 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct_explicit_location"));
5729 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchOutput));
5730 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5731 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array"));
5733 // .patch_var_array_explicit_location
5735 const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
5736 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout));
5737 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5738 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array_explicit_location"));
5741 else if (lastStage == glu::SHADERTYPE_COMPUTE)
5749 static void generateProgramInputOutputReferencedByCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
5751 // all whole pipelines
5752 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_FRAGMENT));
5753 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_tess_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_TESS_FRAGMENT));
5754 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_geo_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_GEO_FRAGMENT));
5755 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_tess_geo_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_VERTEX_TESS_GEO_FRAGMENT));
5757 // all partial pipelines
5758 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_vertex", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_VERTEX));
5759 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_fragment", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_FRAGMENT));
5760 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_geometry", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_GEOMETRY));
5761 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_eval", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_EVAL));
5762 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_ctrl", "", storage, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_CTRL));
5765 if (storage == glu::STORAGE_IN)
5766 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_eval_patch_in", "", glu::STORAGE_PATCH_IN, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_EVAL));
5767 else if (storage == glu::STORAGE_OUT)
5768 targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_ctrl_patch_out", "", glu::STORAGE_PATCH_OUT, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_CTRL));
5773 template <ProgramInterface interface>
5774 static void generateProgramInputOutputTypeBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool allowMatrixCases, int expandLevel)
5783 { glu::TYPE_FLOAT, false, 0 },
5784 { glu::TYPE_INT, false, 1 },
5785 { glu::TYPE_UINT, false, 1 },
5786 { glu::TYPE_FLOAT_VEC2, false, 2 },
5787 { glu::TYPE_FLOAT_VEC3, false, 1 },
5788 { glu::TYPE_FLOAT_VEC4, false, 2 },
5789 { glu::TYPE_INT_VEC2, false, 0 },
5790 { glu::TYPE_INT_VEC3, false, 2 },
5791 { glu::TYPE_INT_VEC4, false, 2 },
5792 { glu::TYPE_UINT_VEC2, false, 2 },
5793 { glu::TYPE_UINT_VEC3, false, 2 },
5794 { glu::TYPE_UINT_VEC4, false, 0 },
5795 { glu::TYPE_FLOAT_MAT2, true, 2 },
5796 { glu::TYPE_FLOAT_MAT2X3, true, 2 },
5797 { glu::TYPE_FLOAT_MAT2X4, true, 2 },
5798 { glu::TYPE_FLOAT_MAT3X2, true, 0 },
5799 { glu::TYPE_FLOAT_MAT3, true, 2 },
5800 { glu::TYPE_FLOAT_MAT3X4, true, 2 },
5801 { glu::TYPE_FLOAT_MAT4X2, true, 2 },
5802 { glu::TYPE_FLOAT_MAT4X3, true, 2 },
5803 { glu::TYPE_FLOAT_MAT4, true, 2 },
5806 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
5808 if (!allowMatrixCases && variableTypes[ndx].isMatrix)
5811 if (variableTypes[ndx].level <= expandLevel)
5813 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
5814 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_TYPE)));
5819 static void generateProgramInputTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask, bool isGL45)
5822 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5823 const ResourceDefinition::Node::SharedPtr input = (inDefaultBlock)
5824 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
5825 : (parentStructure);
5826 const glu::ShaderType firstStage = getShaderMaskFirstStage(presentShadersMask);
5827 const int interfaceBlockExpansionReducement = (!inDefaultBlock) ? (1) : (0); // lesser expansions on block members to keep test counts reasonable
5829 if (firstStage == glu::SHADERTYPE_VERTEX)
5831 // Only basic types (and no booleans)
5832 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, input, targetGroup, true, 2 - interfaceBlockExpansionReducement);
5834 else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5836 const ResourceDefinition::Node::SharedPtr flatShading(new ResourceDefinition::InterpolationQualifier(input, glu::INTERPOLATION_FLAT));
5838 // Only basic types, arrays of basic types, struct of basic types (and no booleans)
5840 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5841 targetGroup->addChild(blockGroup);
5842 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, flatShading, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5845 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(flatShading));
5846 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
5848 targetGroup->addChild(blockGroup);
5849 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElement, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5852 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(flatShading));
5853 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Struct types");
5855 targetGroup->addChild(blockGroup);
5856 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, structMember, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5859 else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
5860 firstStage == glu::SHADERTYPE_GEOMETRY)
5862 // arrayed interface
5864 // Only basic types (and no booleans)
5865 const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5866 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElement, targetGroup, true, 2);
5868 else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5870 // arrayed interface
5871 const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5875 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5876 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5878 targetGroup->addChild(blockGroup);
5879 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElem, blockGroup, true, 2);
5881 // extension forbids use arrays of structs
5882 // extension forbids use arrays of arrays
5886 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var", "Basic types, per-patch");
5888 targetGroup->addChild(blockGroup);
5889 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, patchInput, blockGroup, true, 1);
5891 // .patch_var_struct
5893 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchInput));
5894 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_struct", "Struct types, per-patch");
5896 targetGroup->addChild(blockGroup);
5897 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, structMbr, blockGroup, true, 1);
5901 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchInput));
5902 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_array", "Array types, per-patch");
5904 targetGroup->addChild(blockGroup);
5905 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElem, blockGroup, true, 1);
5908 else if (firstStage == glu::SHADERTYPE_COMPUTE)
5916 static void generateProgramOutputTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask, bool isGL45)
5919 const bool inDefaultBlock = parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5920 const ResourceDefinition::Node::SharedPtr output = (inDefaultBlock)
5921 ? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
5922 : (parentStructure);
5923 const glu::ShaderType lastStage = getShaderMaskLastStage(presentShadersMask);
5924 const int interfaceBlockExpansionReducement = (!inDefaultBlock) ? (1) : (0); // lesser expansions on block members to keep test counts reasonable
5926 if (lastStage == glu::SHADERTYPE_VERTEX ||
5927 lastStage == glu::SHADERTYPE_GEOMETRY ||
5928 lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION ||
5931 const ResourceDefinition::Node::SharedPtr flatShading(new ResourceDefinition::InterpolationQualifier(output, glu::INTERPOLATION_FLAT));
5933 // Only basic types, arrays of basic types, struct of basic types (and no booleans)
5935 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5936 targetGroup->addChild(blockGroup);
5937 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, flatShading, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5940 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(flatShading));
5941 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
5942 const int typeExpansionReducement = (lastStage != glu::SHADERTYPE_VERTEX) ? (1) : (0); // lesser expansions on other stages
5943 const int expansionLevel = 2 - interfaceBlockExpansionReducement - typeExpansionReducement;
5945 targetGroup->addChild(blockGroup);
5946 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElement, blockGroup, true, expansionLevel);
5949 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(flatShading));
5950 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Struct types");
5951 const int typeExpansionReducement = (lastStage != glu::SHADERTYPE_VERTEX) ? (1) : (0); // lesser expansions on other stages
5952 const int expansionLevel = 2 - interfaceBlockExpansionReducement - typeExpansionReducement;
5954 targetGroup->addChild(blockGroup);
5955 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, structMember, blockGroup, true, expansionLevel);
5958 else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5960 // only basic type and basic type array (and no booleans or matrices)
5962 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5963 targetGroup->addChild(blockGroup);
5964 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, output, blockGroup, false, 2);
5967 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(output));
5968 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
5970 targetGroup->addChild(blockGroup);
5971 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElement, blockGroup, false, 2);
5974 else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5976 // arrayed interface
5977 const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5981 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5982 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5984 targetGroup->addChild(blockGroup);
5985 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElem, blockGroup, true, 2);
5987 // extension forbids use arrays of structs
5988 // extension forbids use arrays of arrays
5992 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var", "Basic types, per-patch");
5994 targetGroup->addChild(blockGroup);
5995 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, patchOutput, blockGroup, true, 1);
5997 // .patch_var_struct
5999 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(patchOutput));
6000 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_struct", "Struct types, per-patch");
6002 targetGroup->addChild(blockGroup);
6003 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, structMbr, blockGroup, true, 1);
6007 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(patchOutput));
6008 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "patch_var_array", "Array types, per-patch");
6010 targetGroup->addChild(blockGroup);
6011 generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElem, blockGroup, true, 1);
6014 else if (lastStage == glu::SHADERTYPE_COMPUTE)
6022 class ProgramInputTestGroup : public TestCaseGroup
6025 ProgramInputTestGroup (Context& context, bool is_GL45);
6032 ProgramInputTestGroup::ProgramInputTestGroup (Context& context, bool is_GL45)
6033 : TestCaseGroup(context, "program_input", "Program input")
6038 void ProgramInputTestGroup::init (void)
6040 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
6044 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
6045 addChild(blockGroup);
6046 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, true, true, m_isGL45, generateProgramInputResourceListBlockContents);
6051 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Array size");
6052 addChild(blockGroup);
6053 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, m_isGL45, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6058 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Location");
6059 addChild(blockGroup);
6060 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, m_isGL45, generateProgramInputLocationBlockContents);
6065 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
6066 addChild(blockGroup);
6067 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, m_isGL45, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6072 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Reference by shader");
6073 addChild(blockGroup);
6074 generateProgramInputOutputReferencedByCases(m_context, blockGroup, glu::STORAGE_IN);
6079 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Type");
6080 addChild(blockGroup);
6081 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, m_isGL45, generateProgramInputTypeBlockContents);
6086 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "is_per_patch", "Is per patch");
6087 addChild(blockGroup);
6088 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, m_isGL45, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
6092 class ProgramOutputTestGroup : public TestCaseGroup
6095 ProgramOutputTestGroup (Context& context, bool is_GL45);
6102 ProgramOutputTestGroup::ProgramOutputTestGroup (Context& context, bool is_GL45)
6103 : TestCaseGroup(context, "program_output", "Program output")
6108 void ProgramOutputTestGroup::init (void)
6110 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
6114 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
6115 addChild(blockGroup);
6116 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, true, false, m_isGL45, generateProgramOutputResourceListBlockContents);
6121 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Array size");
6122 addChild(blockGroup);
6123 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, m_isGL45, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6128 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Location");
6129 addChild(blockGroup);
6130 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, m_isGL45, generateProgramOutputLocationBlockContents);
6135 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
6136 addChild(blockGroup);
6137 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, m_isGL45, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6142 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Reference by shader");
6143 addChild(blockGroup);
6144 generateProgramInputOutputReferencedByCases(m_context, blockGroup, glu::STORAGE_OUT);
6149 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Type");
6150 addChild(blockGroup);
6151 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, m_isGL45, generateProgramOutputTypeBlockContents);
6156 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "is_per_patch", "Is per patch");
6157 addChild(blockGroup);
6158 generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, m_isGL45, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
6162 static void generateTransformFeedbackShaderCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, bool))
6168 deUint32 lastStageBit;
6174 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT),
6175 (1 << glu::SHADERTYPE_VERTEX),
6179 "vertex_tess_fragment",
6180 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
6181 (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
6185 "vertex_geo_fragment",
6186 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY),
6187 (1 << glu::SHADERTYPE_GEOMETRY),
6191 "vertex_tess_geo_fragment",
6192 (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
6193 (1 << glu::SHADERTYPE_GEOMETRY),
6200 glu::ShaderType stage;
6202 } singleStageCases[] =
6204 { "separable_vertex", glu::SHADERTYPE_VERTEX, false },
6205 { "separable_tess_eval", glu::SHADERTYPE_TESSELLATION_EVALUATION, true },
6206 { "separable_geometry", glu::SHADERTYPE_GEOMETRY, true },
6209 // monolithic pipeline
6210 for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
6212 TestCaseGroup* const blockGroup = new TestCaseGroup(context, pipelines[pipelineNdx].name, "");
6213 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6214 const ResourceDefinition::Node::SharedPtr shaderSet (new ResourceDefinition::ShaderSet(program,
6216 pipelines[pipelineNdx].stageBits,
6217 pipelines[pipelineNdx].lastStageBit));
6219 targetGroup->addChild(blockGroup);
6220 blockContentGenerator(context, shaderSet, blockGroup, pipelines[pipelineNdx].reducedSet);
6223 // separable pipeline
6224 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
6226 TestCaseGroup* const blockGroup = new TestCaseGroup(context, singleStageCases[ndx].name, "");
6227 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program(true));
6228 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glslVersion));
6230 targetGroup->addChild(blockGroup);
6231 blockContentGenerator(context, shader, blockGroup, singleStageCases[ndx].reducedSet);
6235 static void generateTransformFeedbackResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6237 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6238 const ResourceDefinition::Node::SharedPtr output (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6240 DE_UNREF(reducedSet);
6242 // .builtin_gl_position
6244 const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6245 targetGroup->addChild(new FeedbackResourceListTestCase(context, xfbTarget, "builtin_gl_position"));
6247 // .default_block_basic_type
6249 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6250 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6251 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_basic_type"));
6253 // .default_block_struct_member
6255 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
6256 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(structMbr));
6257 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6258 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_struct_member"));
6260 // .default_block_array
6262 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6263 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(xfbTarget));
6264 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6265 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_array"));
6267 // .default_block_array_element
6269 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
6270 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(arrayElem));
6271 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6272 targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_array_element"));
6276 template <ProgramResourcePropFlags TargetProp>
6277 static void generateTransformFeedbackVariableBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6279 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6280 const ResourceDefinition::Node::SharedPtr output (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6282 DE_UNREF(reducedSet);
6284 // .builtin_gl_position
6286 const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6287 targetGroup->addChild(new ResourceTestCase(context, xfbTarget, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "builtin_gl_position"));
6289 // .default_block_basic_type
6291 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6292 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6293 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_basic_type"));
6295 // .default_block_struct_member
6297 const ResourceDefinition::Node::SharedPtr structMbr (new ResourceDefinition::StructMember(output));
6298 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(structMbr));
6299 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6300 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_struct_member"));
6302 // .default_block_array
6304 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(output));
6305 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(xfbTarget));
6306 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6307 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_array"));
6309 // .default_block_array_element
6311 const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(output));
6312 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(arrayElem));
6313 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6314 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_array_element"));
6318 static void generateTransformFeedbackVariableBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6326 { glu::TYPE_FLOAT, true },
6327 { glu::TYPE_INT, true },
6328 { glu::TYPE_UINT, true },
6330 { glu::TYPE_FLOAT_VEC2, false },
6331 { glu::TYPE_FLOAT_VEC3, true },
6332 { glu::TYPE_FLOAT_VEC4, false },
6334 { glu::TYPE_INT_VEC2, false },
6335 { glu::TYPE_INT_VEC3, true },
6336 { glu::TYPE_INT_VEC4, false },
6338 { glu::TYPE_UINT_VEC2, true },
6339 { glu::TYPE_UINT_VEC3, false },
6340 { glu::TYPE_UINT_VEC4, false },
6342 { glu::TYPE_FLOAT_MAT2, false },
6343 { glu::TYPE_FLOAT_MAT2X3, false },
6344 { glu::TYPE_FLOAT_MAT2X4, false },
6345 { glu::TYPE_FLOAT_MAT3X2, false },
6346 { glu::TYPE_FLOAT_MAT3, false },
6347 { glu::TYPE_FLOAT_MAT3X4, true },
6348 { glu::TYPE_FLOAT_MAT4X2, false },
6349 { glu::TYPE_FLOAT_MAT4X3, false },
6350 { glu::TYPE_FLOAT_MAT4, false },
6353 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6355 if (variableTypes[ndx].important || !reducedSet)
6357 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
6358 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, PROGRAMRESOURCEPROP_TYPE)));
6363 static void generateTransformFeedbackVariableTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6365 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6366 const ResourceDefinition::Node::SharedPtr output (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6367 const ResourceDefinition::Node::SharedPtr flatShading (new ResourceDefinition::InterpolationQualifier(output, glu::INTERPOLATION_FLAT));
6369 // Only builtins, basic types, arrays of basic types, struct of basic types (and no booleans)
6371 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6372 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "builtin", "Built-in outputs");
6374 targetGroup->addChild(blockGroup);
6375 blockGroup->addChild(new ResourceTestCase(context, xfbTarget, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, PROGRAMRESOURCEPROP_TYPE), "gl_position"));
6378 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(flatShading));
6379 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
6381 targetGroup->addChild(blockGroup);
6382 generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
6385 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(flatShading));
6386 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(arrayElement));
6387 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Array types");
6389 targetGroup->addChild(blockGroup);
6390 generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
6393 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(flatShading));
6394 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(xfbTarget));
6395 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "whole_array", "Whole array");
6397 targetGroup->addChild(blockGroup);
6398 generateTransformFeedbackVariableBasicTypeCases(context, arrayElement, blockGroup, reducedSet);
6401 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(flatShading));
6402 const ResourceDefinition::Node::SharedPtr xfbTarget (new ResourceDefinition::TransformFeedbackTarget(structMember));
6403 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Struct types");
6405 targetGroup->addChild(blockGroup);
6406 generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
6410 class TransformFeedbackVaryingTestGroup : public TestCaseGroup
6413 TransformFeedbackVaryingTestGroup (Context& context);
6417 TransformFeedbackVaryingTestGroup::TransformFeedbackVaryingTestGroup (Context& context)
6418 : TestCaseGroup(context, "transform_feedback_varying", "Transform feedback varyings")
6422 void TransformFeedbackVaryingTestGroup::init (void)
6424 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
6428 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "resource_list", "Resource list");
6429 addChild(blockGroup);
6430 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, glslVersion, generateTransformFeedbackResourceListBlockContents);
6435 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_size", "Array size");
6436 addChild(blockGroup);
6437 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, glslVersion, generateTransformFeedbackVariableBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6442 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "name_length", "Name length");
6443 addChild(blockGroup);
6444 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, glslVersion, generateTransformFeedbackVariableBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6449 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "type", "Type");
6450 addChild(blockGroup);
6451 generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, glslVersion, generateTransformFeedbackVariableTypeBlockContents);
6455 static void generateBufferVariableBufferCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*))
6457 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6458 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
6459 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6460 const ResourceDefinition::Node::SharedPtr bufferStorage (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6461 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(bufferStorage, glu::Layout(-1, 0)));
6465 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, true));
6466 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block", "Named block");
6468 targetGroup->addChild(blockGroup);
6470 blockContentGenerator(context, buffer, blockGroup);
6475 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, false));
6476 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "Unnamed block");
6478 targetGroup->addChild(blockGroup);
6480 blockContentGenerator(context, buffer, blockGroup);
6485 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding));
6486 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
6487 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "Block array");
6489 targetGroup->addChild(blockGroup);
6491 blockContentGenerator(context, buffer, blockGroup);
6495 static void generateBufferVariableResourceListBlockContentsProxy (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
6497 generateBufferBackedResourceListBlockContentCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, 4);
6500 static void generateBufferVariableArraySizeSubCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramResourcePropFlags targetProp, bool sizedArray, bool extendedCases)
6502 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp);
6503 tcu::TestCaseGroup* aggregateGroup;
6508 tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
6509 targetGroup->addChild(blockGroup);
6511 generateVariableCases(context, parentStructure, blockGroup, queryTarget, (sizedArray) ? (2) : (1), false);
6517 aggregateGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
6518 targetGroup->addChild(aggregateGroup);
6521 aggregateGroup = targetGroup;
6524 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_FLOAT, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6527 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_BOOL, (extendedCases && sizedArray) ? (1) : (0), !extendedCases);
6530 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_BOOL_VEC3, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6533 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_FLOAT_VEC4, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6536 generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_INT_VEC2, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6539 template <ProgramResourcePropFlags TargetProp>
6540 static void generateBufferVariableArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
6542 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp);
6543 const bool namedNonArrayBlock = static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named && parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
6546 if (namedNonArrayBlock)
6548 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "non_array", "Non-array target");
6549 targetGroup->addChild(blockGroup);
6551 generateVariableCases(context, parentStructure, blockGroup, queryTarget, 1, false);
6556 const ResourceDefinition::Node::SharedPtr sized (new ResourceDefinition::ArrayElement(parentStructure));
6557 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
6558 targetGroup->addChild(blockGroup);
6560 generateBufferVariableArraySizeSubCases(context, sized, blockGroup, TargetProp, true, namedNonArrayBlock);
6565 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6566 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unsized", "Unsized target");
6567 targetGroup->addChild(blockGroup);
6569 generateBufferVariableArraySizeSubCases(context, unsized, blockGroup, TargetProp, false, namedNonArrayBlock);
6573 static void generateBufferVariableBlockIndexCases (Context& context, glu::GLSLVersion glslVersion, tcu::TestCaseGroup* const targetGroup)
6575 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6576 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
6577 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6578 const ResourceDefinition::Node::SharedPtr bufferStorage (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6579 const ResourceDefinition::Node::SharedPtr binding (new ResourceDefinition::LayoutQualifier(bufferStorage, glu::Layout(-1, 0)));
6583 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, true));
6584 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
6586 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "named_block"));
6591 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(binding, false));
6592 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
6594 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "unnamed_block"));
6599 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(binding));
6600 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
6601 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
6603 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "block_array"));
6607 static void generateBufferVariableMatrixCaseBlocks (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, bool))
6612 const char* description;
6614 bool extendedBasicTypeCases;
6615 glu::MatrixOrder order;
6618 { "named_block", "Named uniform block", true, true, glu::MATRIXORDER_LAST },
6619 { "named_block_row_major", "Named uniform block", true, false, glu::MATRIXORDER_ROW_MAJOR },
6620 { "named_block_col_major", "Named uniform block", true, false, glu::MATRIXORDER_COLUMN_MAJOR },
6621 { "unnamed_block", "Unnamed uniform block", false, false, glu::MATRIXORDER_LAST },
6622 { "unnamed_block_row_major", "Unnamed uniform block", false, false, glu::MATRIXORDER_ROW_MAJOR },
6623 { "unnamed_block_col_major", "Unnamed uniform block", false, false, glu::MATRIXORDER_COLUMN_MAJOR },
6626 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6627 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
6628 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6629 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6631 for (int childNdx = 0; childNdx < (int)DE_LENGTH_OF_ARRAY(children); ++childNdx)
6633 ResourceDefinition::Node::SharedPtr parentStructure = buffer;
6634 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, children[childNdx].name, children[childNdx].description);
6636 targetGroup->addChild(blockGroup);
6638 if (children[childNdx].order != glu::MATRIXORDER_LAST)
6641 layout.matrixOrder = children[childNdx].order;
6642 parentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(parentStructure, layout));
6645 parentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(parentStructure, children[childNdx].namedBlock));
6647 blockContentGenerator(context, parentStructure, blockGroup, children[childNdx].extendedBasicTypeCases);
6651 static void generateBufferVariableMatrixVariableBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramResourcePropFlags targetProp)
6653 // all matrix types and some non-matrix
6655 static const glu::DataType variableTypes[] =
6659 glu::TYPE_FLOAT_MAT2,
6660 glu::TYPE_FLOAT_MAT2X3,
6661 glu::TYPE_FLOAT_MAT2X4,
6662 glu::TYPE_FLOAT_MAT3X2,
6663 glu::TYPE_FLOAT_MAT3,
6664 glu::TYPE_FLOAT_MAT3X4,
6665 glu::TYPE_FLOAT_MAT4X2,
6666 glu::TYPE_FLOAT_MAT4X3,
6667 glu::TYPE_FLOAT_MAT4,
6670 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6672 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx]));
6673 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp)));
6677 static void generateBufferVariableMatrixVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramResourcePropFlags targetProp)
6680 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp, glu::TYPE_FLOAT_MAT3X2, "", 2);
6684 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6685 const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(unsized, glu::TYPE_FLOAT_MAT3X2));
6687 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp), "var_unsized_array"));
6691 template <ProgramResourcePropFlags TargetProp>
6692 static void generateBufferVariableMatrixCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool extendedTypeCases)
6695 if (extendedTypeCases)
6697 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "types", "Types");
6698 targetGroup->addChild(blockGroup);
6699 generateBufferVariableMatrixVariableBasicTypeCases(context, parentStructure, blockGroup, TargetProp);
6704 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "no_qualifier", "No qualifier");
6705 targetGroup->addChild(blockGroup);
6706 generateBufferVariableMatrixVariableCases(context, parentStructure, blockGroup, TargetProp);
6711 const ResourceDefinition::Node::SharedPtr matrixOrder(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, -1, glu::FORMATLAYOUT_LAST, glu::MATRIXORDER_COLUMN_MAJOR)));
6713 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "column_major", "Column major qualifier");
6714 targetGroup->addChild(blockGroup);
6715 generateBufferVariableMatrixVariableCases(context, matrixOrder, blockGroup, TargetProp);
6720 const ResourceDefinition::Node::SharedPtr matrixOrder(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, -1, glu::FORMATLAYOUT_LAST, glu::MATRIXORDER_ROW_MAJOR)));
6722 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "row_major", "Row major qualifier");
6723 targetGroup->addChild(blockGroup);
6724 generateBufferVariableMatrixVariableCases(context, matrixOrder, blockGroup, TargetProp);
6728 static void generateBufferVariableNameLengthCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
6732 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
6733 targetGroup->addChild(blockGroup);
6735 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 3);
6740 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6741 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unsized", "Unsized target");
6742 targetGroup->addChild(blockGroup);
6744 generateBufferBackedVariableAggregateTypeCases(context, unsized, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 2);
6748 static void generateBufferVariableOffsetCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
6752 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
6753 targetGroup->addChild(blockGroup);
6755 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_OFFSET, glu::TYPE_FLOAT, "", 3);
6760 const ResourceDefinition::Node::SharedPtr unsized (new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6761 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unsized", "Unsized target");
6762 targetGroup->addChild(blockGroup);
6764 generateBufferBackedVariableAggregateTypeCases(context, unsized, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_OFFSET, glu::TYPE_FLOAT, "", 2);
6768 static void generateBufferVariableReferencedByBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
6770 DE_UNREF(expandLevel);
6772 const ProgramResourceQueryTestTarget queryTarget (PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER);
6773 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(parentStructure));
6774 const ResourceDefinition::Node::SharedPtr storage (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6775 const bool singleShaderCase = parentStructure->getType() == ResourceDefinition::Node::TYPE_SHADER;
6779 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(storage, true));
6780 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "named_block", "Named block");
6782 targetGroup->addChild(blockGroup);
6784 generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, singleShaderCase);
6789 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(storage, false));
6790 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "unnamed_block", "Unnamed block");
6792 targetGroup->addChild(blockGroup);
6794 generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, false);
6799 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(storage));
6800 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::InterfaceBlock(arrayElement, true));
6801 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "block_array", "Block array");
6803 targetGroup->addChild(blockGroup);
6805 generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, false);
6809 template <ProgramResourcePropFlags TargetProp>
6810 static void generateBufferVariableTopLevelCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
6812 // basic and aggregate types
6813 generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp, glu::TYPE_FLOAT_VEC4, "", 3);
6815 // basic and aggregate types in an unsized array
6817 const ResourceDefinition::Node::SharedPtr unsized(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6819 generateBufferBackedVariableAggregateTypeCases(context, unsized, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp, glu::TYPE_FLOAT_VEC4, "_unsized_array", 2);
6823 static void generateBufferVariableTypeBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
6828 glu::DataType dataType;
6831 { 0, glu::TYPE_FLOAT },
6832 { 1, glu::TYPE_INT },
6833 { 1, glu::TYPE_UINT },
6834 { 1, glu::TYPE_BOOL },
6836 { 3, glu::TYPE_FLOAT_VEC2 },
6837 { 1, glu::TYPE_FLOAT_VEC3 },
6838 { 1, glu::TYPE_FLOAT_VEC4 },
6840 { 3, glu::TYPE_INT_VEC2 },
6841 { 2, glu::TYPE_INT_VEC3 },
6842 { 3, glu::TYPE_INT_VEC4 },
6844 { 3, glu::TYPE_UINT_VEC2 },
6845 { 2, glu::TYPE_UINT_VEC3 },
6846 { 3, glu::TYPE_UINT_VEC4 },
6848 { 3, glu::TYPE_BOOL_VEC2 },
6849 { 2, glu::TYPE_BOOL_VEC3 },
6850 { 3, glu::TYPE_BOOL_VEC4 },
6852 { 2, glu::TYPE_FLOAT_MAT2 },
6853 { 3, glu::TYPE_FLOAT_MAT2X3 },
6854 { 3, glu::TYPE_FLOAT_MAT2X4 },
6855 { 2, glu::TYPE_FLOAT_MAT3X2 },
6856 { 2, glu::TYPE_FLOAT_MAT3 },
6857 { 3, glu::TYPE_FLOAT_MAT3X4 },
6858 { 2, glu::TYPE_FLOAT_MAT4X2 },
6859 { 3, glu::TYPE_FLOAT_MAT4X3 },
6860 { 2, glu::TYPE_FLOAT_MAT4 },
6863 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6865 if (variableTypes[ndx].level <= expandLevel)
6867 const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
6868 targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_TYPE)));
6873 static void generateBufferVariableTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int depth = 3)
6878 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic type");
6879 targetGroup->addChild(blockGroup);
6880 generateBufferVariableTypeBasicTypeCases(context, parentStructure, blockGroup, depth);
6884 // flatten bottom-level
6885 generateBufferVariableTypeBasicTypeCases(context, parentStructure, targetGroup, depth);
6891 const ResourceDefinition::Node::SharedPtr arrayElement (new ResourceDefinition::ArrayElement(parentStructure));
6892 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "array", "Arrays");
6894 targetGroup->addChild(blockGroup);
6895 generateBufferVariableTypeCases(context, arrayElement, blockGroup, depth-1);
6901 const ResourceDefinition::Node::SharedPtr structMember (new ResourceDefinition::StructMember(parentStructure));
6902 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "struct", "Structs");
6904 targetGroup->addChild(blockGroup);
6905 generateBufferVariableTypeCases(context, structMember, blockGroup, depth-1);
6909 static void generateBufferVariableTypeBlock (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion)
6911 const ResourceDefinition::Node::SharedPtr program (new ResourceDefinition::Program());
6912 const ResourceDefinition::Node::SharedPtr shader (new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
6913 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6914 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6915 const ResourceDefinition::Node::SharedPtr block (new ResourceDefinition::InterfaceBlock(buffer, true));
6917 generateBufferVariableTypeCases(context, block, targetGroup);
6920 static void generateBufferVariableRandomCase (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion, int index, bool onlyExtensionStages)
6922 de::Random rnd (index * 0x12345);
6923 const ResourceDefinition::Node::SharedPtr shader = generateRandomShaderSet(rnd, glslVersion, onlyExtensionStages);
6924 const glu::DataType type = generateRandomDataType(rnd, true);
6925 const glu::Layout layout = generateRandomVariableLayout(rnd, type, true);
6926 const bool namedBlock = rnd.getBool();
6927 const ResourceDefinition::Node::SharedPtr defaultBlock (new ResourceDefinition::DefaultBlock(shader));
6928 const ResourceDefinition::Node::SharedPtr buffer (new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6929 ResourceDefinition::Node::SharedPtr currentStructure (new ResourceDefinition::LayoutQualifier(buffer, generateRandomBufferBlockLayout(rnd)));
6931 if (namedBlock && rnd.getBool())
6932 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
6933 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(currentStructure, namedBlock));
6935 currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, layout));
6936 currentStructure = generateRandomVariableDefinition(rnd, currentStructure, type, layout, true);
6938 targetGroup->addChild(new ResourceTestCase(context, currentStructure, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BUFFER_VARIABLE_MASK), de::toString(index).c_str()));
6941 static void generateBufferVariableRandomCases (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion)
6943 const int numBasicCases = 40;
6944 const int numTessGeoCases = 40;
6946 for (int ndx = 0; ndx < numBasicCases; ++ndx)
6947 generateBufferVariableRandomCase(context, targetGroup, glslVersion, ndx, false);
6948 for (int ndx = 0; ndx < numTessGeoCases; ++ndx)
6949 generateBufferVariableRandomCase(context, targetGroup, glslVersion, numBasicCases + ndx, true);
6952 class BufferVariableTestGroup : public TestCaseGroup
6955 BufferVariableTestGroup (Context& context);
6959 BufferVariableTestGroup::BufferVariableTestGroup (Context& context)
6960 : TestCaseGroup(context, "buffer_variable", "Buffer variable")
6964 void BufferVariableTestGroup::init (void)
6966 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
6970 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "resource_list", "Resource list");
6971 addChild(blockGroup);
6972 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableResourceListBlockContentsProxy);
6977 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_size", "Array size");
6978 addChild(blockGroup);
6979 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableArrayCases<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6984 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_stride", "Array stride");
6985 addChild(blockGroup);
6986 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableArrayCases<PROGRAMRESOURCEPROP_ARRAY_STRIDE>);
6991 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "block_index", "Block index");
6992 addChild(blockGroup);
6993 generateBufferVariableBlockIndexCases(m_context, glslVersion, blockGroup);
6998 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "is_row_major", "Is row major");
6999 addChild(blockGroup);
7000 generateBufferVariableMatrixCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableMatrixCases<PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR>);
7005 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "matrix_stride", "Matrix stride");
7006 addChild(blockGroup);
7007 generateBufferVariableMatrixCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableMatrixCases<PROGRAMRESOURCEPROP_MATRIX_STRIDE>);
7012 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "name_length", "Name length");
7013 addChild(blockGroup);
7014 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableNameLengthCases);
7019 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "offset", "Offset");
7020 addChild(blockGroup);
7021 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableOffsetCases);
7026 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "referenced_by", "Referenced by");
7027 addChild(blockGroup);
7028 generateReferencedByShaderCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableReferencedByBlockContents);
7031 // .top_level_array_size
7033 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "top_level_array_size", "Top-level array size");
7034 addChild(blockGroup);
7035 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableTopLevelCases<PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_SIZE>);
7038 // .top_level_array_stride
7040 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "top_level_array_stride", "Top-level array stride");
7041 addChild(blockGroup);
7042 generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableTopLevelCases<PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_STRIDE>);
7047 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "type", "Type");
7048 addChild(blockGroup);
7049 generateBufferVariableTypeBlock(m_context, blockGroup, glslVersion);
7054 tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "random", "Random");
7055 addChild(blockGroup);
7056 generateBufferVariableRandomCases(m_context, blockGroup, glslVersion);
7062 ProgramInterfaceQueryTests::ProgramInterfaceQueryTests (Context& context, bool is_GL45)
7063 : TestCaseGroup(context, "program_interface_query", "Program interface query tests")
7064 , m_isGL45 (is_GL45)
7068 ProgramInterfaceQueryTests::~ProgramInterfaceQueryTests (void)
7072 void ProgramInterfaceQueryTests::init (void)
7076 // .buffer_limited_query
7078 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "buffer_limited_query", "Queries limited by the buffer size");
7082 group->addChild(new ResourceNameBufferLimitCase(m_context, "resource_name_query", "Test GetProgramResourceName with too small a buffer"));
7083 group->addChild(new ResourceQueryBufferLimitCase(m_context, "resource_query", "Test GetProgramResourceiv with too small a buffer"));
7089 addChild(new UniformInterfaceTestGroup(m_context));
7092 addChild(new BufferBackedBlockInterfaceTestGroup(m_context, glu::STORAGE_UNIFORM));
7094 // .atomic_counter_buffer
7095 addChild(new AtomicCounterTestGroup(m_context));
7098 addChild(new ProgramInputTestGroup(m_context, m_isGL45));
7101 addChild(new ProgramOutputTestGroup(m_context, m_isGL45));
7103 // .transform_feedback_varying
7104 addChild(new TransformFeedbackVaryingTestGroup(m_context));
7107 addChild(new BufferVariableTestGroup(m_context));
7109 // .shader_storage_block
7110 addChild(new BufferBackedBlockInterfaceTestGroup(m_context, glu::STORAGE_BUFFER));