From 9fa944ae1829441ef58596701ddc9c3d07b50f04 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jarkko=20P=C3=B6yry?= Date: Fri, 24 Oct 2014 13:14:21 -0700 Subject: [PATCH] Reduce and verify fragment output PIQ test draw buffer usage. - Check GL_MAX_DRAW_BUFFERS implementation limit and usage if shader build fails. - Reduce required GL_MAX_DRAW_BUFFERS from 5 to 4 in explicit location fragment output array tests. - Fix various max binding resource usage checks. Bug: 18094242 Change-Id: I17e091eb1939fd7ec94789be70be5a069970b697 --- .../es31fProgramInterfaceDefinitionUtil.cpp | 42 +++++++++++++++++++--- .../es31fProgramInterfaceDefinitionUtil.hpp | 1 + .../es31fProgramInterfaceQueryTestCase.cpp | 3 +- .../functional/es31fProgramInterfaceQueryTests.cpp | 2 +- 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/modules/gles31/functional/es31fProgramInterfaceDefinitionUtil.cpp b/modules/gles31/functional/es31fProgramInterfaceDefinitionUtil.cpp index ccc0d80..5dca33b 100644 --- a/modules/gles31/functional/es31fProgramInterfaceDefinitionUtil.cpp +++ b/modules/gles31/functional/es31fProgramInterfaceDefinitionUtil.cpp @@ -893,6 +893,35 @@ static int getNumMaxXFBOutputComponents (const ProgramInterfaceDefinition::Progr return numComponents; } +static int getFragmentOutputMaxLocation (const ProgramInterfaceDefinition::Shader* shader) +{ + DE_ASSERT(shader->getType() == glu::SHADERTYPE_FRAGMENT); + + int maxOutputLocation = -1; + + for (int ndx = 0; ndx < (int)shader->getDefaultBlock().variables.size(); ++ndx) + { + if (shader->getDefaultBlock().variables[ndx].storage == glu::STORAGE_OUT) + { + // missing location qualifier means location == 0 + const int outputLocation = (shader->getDefaultBlock().variables[ndx].layout.location == -1) + ? (0) + : (shader->getDefaultBlock().variables[ndx].layout.location); + + // only basic types or arrays of basic types possible + DE_ASSERT(!shader->getDefaultBlock().variables[ndx].varType.isStructType()); + + const int locationSlotsTaken = (shader->getDefaultBlock().variables[ndx].varType.isArrayType()) + ? (shader->getDefaultBlock().variables[ndx].varType.getArraySize()) + : (1); + + maxOutputLocation = de::max(maxOutputLocation, outputLocation + locationSlotsTaken - 1); + } + } + + return maxOutputLocation; +} + } // anonymous std::vector getProgramInterfaceBlockMemberResourceList (const glu::InterfaceBlock& interfaceBlock) @@ -1315,27 +1344,28 @@ ProgramInterfaceDefinition::ProgramResourceUsage getCombinedProgramResourceUsage { ProgramInterfaceDefinition::ProgramResourceUsage retVal; - retVal.uniformBufferMaxBinding = 0; + retVal.uniformBufferMaxBinding = -1; // max binding is inclusive upper bound. Allow 0 bindings by using negative value retVal.uniformBufferMaxSize = 0; retVal.numUniformBlocks = 0; retVal.numCombinedVertexUniformComponents = 0; retVal.numCombinedFragmentUniformComponents = 0; - retVal.shaderStorageBufferMaxBinding = 0; + retVal.shaderStorageBufferMaxBinding = -1; // see above retVal.shaderStorageBufferMaxSize = 0; retVal.numShaderStorageBlocks = 0; retVal.numVaryingComponents = 0; retVal.numVaryingVectors = 0; retVal.numCombinedSamplers = 0; - retVal.atomicCounterBufferMaxBinding = 0; + retVal.atomicCounterBufferMaxBinding = -1; // see above retVal.atomicCounterBufferMaxSize = 0; retVal.numAtomicCounterBuffers = 0; retVal.numAtomicCounters = 0; - retVal.maxImageBinding = 0; + retVal.maxImageBinding = -1; // see above retVal.numCombinedImages = 0; retVal.numCombinedOutputResources = 0; retVal.numXFBInterleavedComponents = 0; retVal.numXFBSeparateAttribs = 0; retVal.numXFBSeparateComponents = 0; + retVal.fragmentOutputMaxBinding = -1; // see above for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx) { @@ -1372,8 +1402,12 @@ ProgramInterfaceDefinition::ProgramResourceUsage getCombinedProgramResourceUsage retVal.numCombinedOutputResources += getNumTypeInstances(shader, glu::STORAGE_UNIFORM, glu::isDataTypeImage); retVal.numCombinedOutputResources += getNumShaderBlocks(shader, glu::STORAGE_BUFFER); + if (shader->getType() == glu::SHADERTYPE_FRAGMENT) + { retVal.numCombinedOutputResources += getNumVectors(shader, glu::STORAGE_OUT); + retVal.fragmentOutputMaxBinding = de::max(retVal.fragmentOutputMaxBinding, getFragmentOutputMaxLocation(shader)); + } } if (program->getTransformFeedbackMode() == GL_INTERLEAVED_ATTRIBS) diff --git a/modules/gles31/functional/es31fProgramInterfaceDefinitionUtil.hpp b/modules/gles31/functional/es31fProgramInterfaceDefinitionUtil.hpp index 0117013..ac24fce 100644 --- a/modules/gles31/functional/es31fProgramInterfaceDefinitionUtil.hpp +++ b/modules/gles31/functional/es31fProgramInterfaceDefinitionUtil.hpp @@ -147,6 +147,7 @@ struct ProgramResourceUsage int numXFBInterleavedComponents; int numXFBSeparateAttribs; int numXFBSeparateComponents; + int fragmentOutputMaxBinding; }; } // ProgramInterfaceDefinition diff --git a/modules/gles31/functional/es31fProgramInterfaceQueryTestCase.cpp b/modules/gles31/functional/es31fProgramInterfaceQueryTestCase.cpp index 728d13a..a8a86e9 100644 --- a/modules/gles31/functional/es31fProgramInterfaceQueryTestCase.cpp +++ b/modules/gles31/functional/es31fProgramInterfaceQueryTestCase.cpp @@ -2117,7 +2117,7 @@ static bool checkProgramCombinedResourceUsage (const ProgramInterfaceDefinition: { GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE, usage.atomicCounterBufferMaxSize }, { GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS, usage.numAtomicCounterBuffers }, { GL_MAX_COMBINED_ATOMIC_COUNTERS, usage.numAtomicCounters }, - { GL_MAX_IMAGE_UNITS, usage.maxImageBinding }, + { GL_MAX_IMAGE_UNITS, usage.maxImageBinding+1 }, { GL_MAX_COMBINED_IMAGE_UNIFORMS, usage.numCombinedImages }, { GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, usage.shaderStorageBufferMaxBinding+1 }, { GL_MAX_SHADER_STORAGE_BLOCK_SIZE, usage.shaderStorageBufferMaxSize }, @@ -2125,6 +2125,7 @@ static bool checkProgramCombinedResourceUsage (const ProgramInterfaceDefinition: { GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, usage.numXFBInterleavedComponents }, { GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, usage.numXFBSeparateAttribs }, { GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, usage.numXFBSeparateComponents }, + { GL_MAX_DRAW_BUFFERS, usage.fragmentOutputMaxBinding+1 }, }; bool allOk = true; diff --git a/modules/gles31/functional/es31fProgramInterfaceQueryTests.cpp b/modules/gles31/functional/es31fProgramInterfaceQueryTests.cpp index cf22cb1..1df5f89 100644 --- a/modules/gles31/functional/es31fProgramInterfaceQueryTests.cpp +++ b/modules/gles31/functional/es31fProgramInterfaceQueryTests.cpp @@ -4839,7 +4839,7 @@ static void generateProgramOutputLocationBlockContents (Context& context, const } // .var_array_explicit_location { - const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(2))); + const ResourceDefinition::Node::SharedPtr layout (new ResourceDefinition::LayoutQualifier(output, glu::Layout(1))); const ResourceDefinition::Node::SharedPtr arrayElem (new ResourceDefinition::ArrayElement(layout)); const ResourceDefinition::Node::SharedPtr variable (new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4)); targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location")); -- 2.7.4