Add shader storage negative coverage tests
authorJohn Richardson <john.richardson@mobica.com>
Wed, 26 Oct 2016 08:43:56 +0000 (09:43 +0100)
committerPyry Haulos <phaulos@google.com>
Wed, 14 Dec 2016 10:42:24 +0000 (10:42 +0000)
Tests groups added to:
- dEQP-GLES31.functional.debug.negative_coverage.*.

New tests:
- shader_storage.block_number_limits
- shader_storage.max_combined_block_number_limit

Extended tests:
- state.get_integeri_v
- state.get_integer64i_v
- shader.compile_compute_shader

Fixed tests:
- buffer.bind_buffer_base
- buffer.bind_buffer_range

Change-Id: Id71fb997e14ad026f0d6634298993f1638c67dde

Android.mk
android/cts/master/gles31-master.txt
modules/gles31/functional/CMakeLists.txt
modules/gles31/functional/es31fDebugTests.cpp
modules/gles31/functional/es31fNegativeBufferApiTests.cpp
modules/gles31/functional/es31fNegativeShaderApiTests.cpp
modules/gles31/functional/es31fNegativeShaderStorageTests.cpp [new file with mode: 0644]
modules/gles31/functional/es31fNegativeShaderStorageTests.hpp [new file with mode: 0644]
modules/gles31/functional/es31fNegativeStateApiTests.cpp

index 253f085..52c027d 100644 (file)
@@ -589,6 +589,7 @@ LOCAL_SRC_FILES := \
        modules/gles31/functional/es31fNegativeShaderDirectiveTests.cpp \
        modules/gles31/functional/es31fNegativeShaderFunctionTests.cpp \
        modules/gles31/functional/es31fNegativeShaderImageLoadStoreTests.cpp \
+       modules/gles31/functional/es31fNegativeShaderStorageTests.cpp \
        modules/gles31/functional/es31fNegativeStateApiTests.cpp \
        modules/gles31/functional/es31fNegativeTestShared.cpp \
        modules/gles31/functional/es31fNegativeTextureApiTests.cpp \
index 8204cb8..c53d4b0 100644 (file)
@@ -16763,6 +16763,8 @@ dEQP-GLES31.functional.debug.negative_coverage.callbacks.precise.precise_as_func
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.precise.precise_as_function_argument
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.advanced_blend.blend_qualifier_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.advanced_blend.attachment_advanced_equation
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_storage.block_number_limits
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_storage.max_combined_block_number_limit
 dEQP-GLES31.functional.debug.negative_coverage.log.buffer.bind_buffer
 dEQP-GLES31.functional.debug.negative_coverage.log.buffer.delete_buffers
 dEQP-GLES31.functional.debug.negative_coverage.log.buffer.gen_buffers
@@ -17209,6 +17211,8 @@ dEQP-GLES31.functional.debug.negative_coverage.log.precise.precise_as_function_n
 dEQP-GLES31.functional.debug.negative_coverage.log.precise.precise_as_function_argument
 dEQP-GLES31.functional.debug.negative_coverage.log.advanced_blend.blend_qualifier_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.log.advanced_blend.attachment_advanced_equation
+dEQP-GLES31.functional.debug.negative_coverage.log.shader_storage.block_number_limits
+dEQP-GLES31.functional.debug.negative_coverage.log.shader_storage.max_combined_block_number_limit
 dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.bind_buffer
 dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.delete_buffers
 dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.gen_buffers
@@ -17653,6 +17657,8 @@ dEQP-GLES31.functional.debug.negative_coverage.get_error.precise.precise_as_func
 dEQP-GLES31.functional.debug.negative_coverage.get_error.precise.precise_as_function_argument
 dEQP-GLES31.functional.debug.negative_coverage.get_error.advanced_blend.blend_qualifier_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.get_error.advanced_blend.attachment_advanced_equation
+dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_storage.block_number_limits
+dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_storage.max_combined_block_number_limit
 dEQP-GLES31.functional.debug.externally_generated.application_messages
 dEQP-GLES31.functional.debug.externally_generated.third_party_messages
 dEQP-GLES31.functional.debug.externally_generated.push_pop_stack
index 1f57b59..db7a8b9 100644 (file)
@@ -173,6 +173,8 @@ set(DEQP_GLES31_FUNCTIONAL_SRCS
        es31fCopyImageTests.cpp
        es31fDrawBuffersIndexedTests.hpp
        es31fDrawBuffersIndexedTests.cpp
+       es31fNegativeShaderStorageTests.cpp
+       es31fNegativeShaderStorageTests.hpp
        )
 
 add_library(deqp-gles31-functional STATIC ${DEQP_GLES31_FUNCTIONAL_SRCS})
index d6dde30..b44d7e5 100644 (file)
@@ -36,6 +36,7 @@
 #include "es31fNegativeShaderDirectiveTests.hpp"
 #include "es31fNegativePreciseTests.hpp"
 #include "es31fNegativeAdvancedBlendEquationTests.hpp"
+#include "es31fNegativeShaderStorageTests.hpp"
 
 #include "deUniquePtr.hpp"
 #include "deRandom.hpp"
@@ -2954,6 +2955,7 @@ void DebugTests::init (void)
        const vector<FunctionContainer> shaderDirectiveFuncs     = wrapCoreFunctions(NegativeTestShared::getNegativeShaderDirectiveTestFunctions());
        const vector<FunctionContainer> preciseFuncs                     = wrapCoreFunctions(NegativeTestShared::getNegativePreciseTestFunctions());
        const vector<FunctionContainer> advancedBlendFuncs               = wrapCoreFunctions(NegativeTestShared::getNegativeAdvancedBlendEquationTestFunctions());
+       const vector<FunctionContainer> shaderStorageFuncs               = wrapCoreFunctions(NegativeTestShared::getNegativeShaderStorageTestFunctions());
        const vector<FunctionContainer> externalFuncs                    = getUserMessageFuncs();
 
        {
@@ -3059,6 +3061,7 @@ void DebugTests::init (void)
                        host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_directive",                       "Negative Shader Directive Cases",                                      shaderDirectiveFuncs));
                        host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "precise",                                        "Negative Precise Cases",                                                       preciseFuncs));
                        host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "advanced_blend",                         "Negative Advanced Blend Equation Cases",                       advancedBlendFuncs));
+                       host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_storage",                         "Negative Shader Storage Cases",                                        shaderStorageFuncs));
                }
 
                {
@@ -3081,6 +3084,7 @@ void DebugTests::init (void)
                        host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_directive",            "Negative Shader Directive Cases",                                      shaderDirectiveFuncs));
                        host->addChild(createChildCases(CASETYPE_LOG, m_context, "precise",                                     "Negative Precise Cases",                                                       preciseFuncs));
                        host->addChild(createChildCases(CASETYPE_LOG, m_context, "advanced_blend",                      "Negative Advanced Blend Equation Cases",                       advancedBlendFuncs));
+                       host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_storage",                      "Negative Shader Storage Cases",                                        shaderStorageFuncs));
                }
 
                {
@@ -3103,6 +3107,7 @@ void DebugTests::init (void)
                        host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_directive",                       "Negative Shader Directive Cases",                                      shaderDirectiveFuncs));
                        host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "precise",                                        "Negative Precise Cases",                                                       preciseFuncs));
                        host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "advanced_blend",                         "Negative Advanced Blend Equation Cases",                       advancedBlendFuncs));
+                       host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_storage",                         "Negative Shader Storage Cases",                                        shaderStorageFuncs));
                }
        }
 
index e4b67cd..309a507 100644 (file)
@@ -446,15 +446,19 @@ void bind_buffer_range (NegativeTestContext& ctx)
                ctx.endSection();
 
                ctx.beginSection("GL_INVALID_VALUE is generated if target is GL_ATOMIC_COUNTER_BUFFER and offset is not multiples of 4.");
-               ctx.glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, bufTF, 5, 0);
+               ctx.glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, bufTF, 5, 4);
                ctx.expectError(GL_INVALID_VALUE);
                ctx.endSection();
 
-               ctx.beginSection("GL_INVALID_VALUE is generated if target is GL_SHADER_STORAGE_BUFFER and offset is not a multiple of the value of GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT.");
                ctx.glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &ssAlignment);
-               ctx.glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, bufTF, ssAlignment+1, 0);
-               ctx.expectError(GL_INVALID_VALUE);
-               ctx.endSection();
+
+               if (ssAlignment != 1)
+               {
+                       ctx.beginSection("GL_INVALID_VALUE is generated if target is GL_SHADER_STORAGE_BUFFER and offset is not a multiple of the value of GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT.");
+                       ctx.glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, bufTF, ssAlignment+1, 4);
+                       ctx.expectError(GL_INVALID_VALUE);
+                       ctx.endSection();
+               }
        }
 
        ctx.glDeleteBuffers(1, &bufU);
@@ -497,24 +501,6 @@ void bind_buffer_base (NegativeTestContext& ctx)
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
 
-       if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)))
-       {
-               int maxACize = 0x1234;
-               int maxSSize = 0x1234;
-
-               ctx.beginSection("GL_INVALID_VALUE is generated if target is GL_ATOMIC_COUNTER_BUFFER and index is greater than or equal to GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS.");
-               ctx.glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &maxACize);
-               ctx.glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, maxACize, bufU, 0, 4);
-               ctx.expectError(GL_INVALID_VALUE);
-               ctx.endSection();
-
-               ctx.beginSection("GL_INVALID_VALUE is generated if target is GL_SHADER_STORAGE_BUFFER and index is greater than or equal to GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS.");
-               ctx.glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &maxSSize);
-               ctx.glBindBufferRange(GL_SHADER_STORAGE_BUFFER, maxSSize, bufU, 0, 4);
-               ctx.expectError(GL_INVALID_VALUE);
-               ctx.endSection();
-       }
-
        ctx.glDeleteBuffers(1, &bufU);
        ctx.glDeleteBuffers(1, &bufTF);
 }
index 7c3fc0f..a80d6ca 100644 (file)
@@ -2334,7 +2334,7 @@ void link_compute_shader (NegativeTestContext& ctx)
        }
 }
 
-void compile_compute_shader_helper (NegativeTestContext& ctx, const char** computeShaderSource, GLint* compileStatus)
+void compile_compute_shader_helper (NegativeTestContext& ctx, const char* const* computeShaderSource, GLint* compileStatus)
 {
        GLuint shader = ctx.glCreateShader(GL_COMPUTE_SHADER);
 
@@ -2351,68 +2351,155 @@ void compile_compute_shader (NegativeTestContext& ctx)
        ctx.beginSection("Compile Computer Shader");
 
        {
-               const char* computeShaderSource         =       "#version 300 es\n"
-                                                                                               "void main (void)\n"
-                                                                                               "{\n"
-                                                                                               "}\n\0";
+               const char* const computeShaderSource           =       "#version 300 es\n"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "}\n";
 
                compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
                if (compileStatus != GL_FALSE)
                        ctx.fail("Compute Shader should not have compiled with #version 300 es.");
        }
        {
-               const char* computeShaderSource         =       "#version 310 es\n"
-                                                                                               "buffer SSBO { vec4 data }"
-                                                                                               "void main (void)\n"
-                                                                                               "{\n"
-                                                                                               "}\n\0";
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "buffer SSBO { vec4 data }"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "}\n";
 
                compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
                if (compileStatus != GL_FALSE)
                        ctx.fail("Compute Shader should not have compiled: incorrect SSBO syntax.");
        }
        {
-               const char* computeShaderSource         =       "#version 310 es\n"
-                                                                                               "buffer SSBO { vec4 data;};"
-                                                                                               "uniform mat4 data;"
-                                                                                               "void main (void)\n"
-                                                                                               "{\n"
-                                                                                               "}\n\0";
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "buffer SSBO { vec4 data;};"
+                                                                                                               "uniform mat4 data;"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "}\n";
 
                compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
                if (compileStatus != GL_FALSE)
                        ctx.fail("Compute Shader should not have compiled: buffer variable redefinition.");
        }
        {
-               const char* computeShaderSource         =       "#version 310 es\n"
-                                                                                               "buffer SSBO { vec4 data[]; vec4 moreData;};"
-                                                                                               "void main (void)\n"
-                                                                                               "{\n"
-                                                                                               "}\n\0";
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "buffer SSBO { vec4 data[]; vec4 moreData;};"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "}\n";
 
                compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
                if (compileStatus != GL_FALSE)
                        ctx.fail("Compute Shader should not have compiled: unspecified length buffer member not at the end.");
        }
        {
-               const char* computeShaderSource         =       "#version 310 es\n"
-                                                                                               "in vec4 data;"
-                                                                                               "void main (void)\n"
-                                                                                               "{\n"
-                                                                                               "}\n\0";
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "in vec4 data;"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "}\n";
 
                compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
                if (compileStatus != GL_FALSE)
                        ctx.fail("Compute Shader should not have compiled: input qualifier used.");
        }
        {
-               const char* computeShaderSource         =       "#version 310 es\n"
-                                                                                               "shared uint data = 0;";
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "shared uint data = 0;";
 
                compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
                if (compileStatus != GL_FALSE)
                        ctx.fail("Compute Shader should not have compiled: shared-qualified variable initialized.");
        }
+       {
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "buffer SSBO { vec4 data; vec4 moreData[];} ssbo;"
+                                                                                                               "void test (vec4 data[10]) {}"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "    test(ssbo.moreData);"
+                                                                                                               "}\n";
+
+               compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
+               if (compileStatus != GL_FALSE)
+                       ctx.fail("Compute Shader should not have compiled: unspecified length buffer member passed as argument to function.");
+       }
+       {
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "buffer SSBO { vec4 data; vec4 moreData[];} ssbo;"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "    vec4 var = ssbo.moreData[-1];"
+                                                                                                               "}\n";
+
+               compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
+               if (compileStatus != GL_FALSE)
+                       ctx.fail("Compute Shader should not have compiled: unspecified length buffer member indexed with negative constant expression.");
+       }
+       {
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "layout(binding=-1) buffer SSBO { vec4 data;};"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "}\n";
+
+               compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
+               if (compileStatus != GL_FALSE)
+                       ctx.fail("Compute Shader should not have compiled: binding point less than zero.");
+       }
+       {
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "layout(binding=1) buffer;"
+                                                                                                               "layout(binding=2) buffer SSBO { vec4 data;};"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "}\n";
+
+               compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
+               if (compileStatus != GL_FALSE)
+                       ctx.fail("Compute Shader should not have compiled: binding point specified for global scope.");
+       }
+       {
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "buffer SSBO {"
+                                                                                                               "       layout(binding=1) vec4 data;"
+                                                                                                               "       layout(binding=2) vec4 moreData[];"
+                                                                                                               "} ssbo;"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "}\n";
+
+               compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
+               if (compileStatus != GL_FALSE)
+                       ctx.fail("Compute Shader should not have compiled: binding point specified for block member declarations.");
+       }
+       {
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "readonly buffer SSBO {vec4 data;} ssbo;"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                                       "ssbo.data = vec4(1, 1, 1, 1);"
+                                                                                                               "}\n";
+
+               compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
+               if (compileStatus != GL_FALSE)
+                       ctx.fail("Compute Shader should not have compiled: writing to buffer block qualified with readonly.");
+       }
+       {
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "writeonly buffer SSBO {vec4 data;} ssbo;"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                                       "vec4 var = ssbo.data;"
+                                                                                                               "}\n";
+
+               compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
+               if (compileStatus != GL_FALSE)
+                       ctx.fail("Compute Shader should not have compiled: reading from buffer block qualified with writeonly.");
+       }
+
        ctx.endSection();
 }
 
diff --git a/modules/gles31/functional/es31fNegativeShaderStorageTests.cpp b/modules/gles31/functional/es31fNegativeShaderStorageTests.cpp
new file mode 100644 (file)
index 0000000..773d728
--- /dev/null
@@ -0,0 +1,324 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Negative Shader Storage Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "es31fNegativeShaderStorageTests.hpp"
+
+#include "gluShaderProgram.hpp"
+#include "glwDefs.hpp"
+#include "glwEnums.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+namespace
+{
+
+void verifyProgram(NegativeTestContext& ctx, glu::ProgramSources sources)
+{
+       tcu::TestLog&                           log                     = ctx.getLog();
+       const glu::ShaderProgram        program         (ctx.getRenderContext(), sources);
+       bool                                            testFailed      = false;
+
+       log << program;
+
+       testFailed = program.getProgramInfo().linkOk;
+
+       if (testFailed)
+       {
+               const char* const message("Program was not expected to link.");
+               log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+               ctx.fail(message);
+       }
+}
+
+const char* getShaderExtensionDeclaration (glw::GLenum glShaderType)
+{
+       switch (glShaderType)
+       {
+               case GL_TESS_CONTROL_SHADER:
+               case GL_TESS_EVALUATION_SHADER: return "#extension GL_EXT_tessellation_shader : require\n";
+               case GL_GEOMETRY_SHADER:                return "#extension GL_EXT_geometry_shader : require\n";
+               default:
+                       return "";
+       }
+}
+
+glu::ShaderType getGLUShaderType (glw::GLenum glShaderType)
+{
+       switch (glShaderType)
+       {
+               case GL_VERTEX_SHADER:                   return glu::SHADERTYPE_VERTEX;
+               case GL_FRAGMENT_SHADER:                 return glu::SHADERTYPE_FRAGMENT;
+               case GL_TESS_CONTROL_SHADER:     return glu::SHADERTYPE_TESSELLATION_CONTROL;
+               case GL_TESS_EVALUATION_SHADER:  return glu::SHADERTYPE_TESSELLATION_EVALUATION;
+               case GL_GEOMETRY_SHADER:                 return glu::SHADERTYPE_GEOMETRY;
+               case GL_COMPUTE_SHADER:                  return glu::SHADERTYPE_COMPUTE;
+               default:
+                       DE_FATAL("Unknown shader type");
+                       return glu::SHADERTYPE_LAST;
+       }
+}
+
+glw::GLenum getMaxSSBlockSizeEnum (glw::GLenum glShaderType)
+{
+       switch (glShaderType)
+       {
+               case GL_VERTEX_SHADER:                   return GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
+               case GL_FRAGMENT_SHADER:                 return GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
+               case GL_TESS_CONTROL_SHADER:     return GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
+               case GL_TESS_EVALUATION_SHADER:  return GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
+               case GL_GEOMETRY_SHADER:                 return GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
+               case GL_COMPUTE_SHADER:                  return GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
+               default:
+                        DE_FATAL("Unknown shader type");
+                        return -1;
+       }
+}
+
+int getMaxSSBlockSize (NegativeTestContext& ctx, glw::GLenum glShaderType)
+{
+       int maxSSBlocks = 0;
+       ctx.glGetIntegerv(getMaxSSBlockSizeEnum(glShaderType), &maxSSBlocks);
+
+       return maxSSBlocks;
+}
+
+std::string genBlockSource (NegativeTestContext& ctx, deInt64 numSSBlocks, glw::GLenum shaderType)
+{
+       const bool                              isES32          = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       const glu::GLSLVersion  version         = isES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
+       std::ostringstream              source;
+
+       source  << glu::getGLSLVersionDeclaration(version) << "\n"
+                       << ((isES32) ? "" : getShaderExtensionDeclaration(shaderType));
+
+       switch (shaderType)
+       {
+               case GL_VERTEX_SHADER:
+               case GL_FRAGMENT_SHADER:
+                       break;
+
+               case GL_COMPUTE_SHADER:
+                       source << "layout (local_size_x = 1) in;\n";
+                       break;
+
+               case GL_GEOMETRY_SHADER:
+                       source << "layout(points) in;\n"
+                                  << "layout(line_strip, max_vertices = 3) out;\n";
+                       break;
+
+               case GL_TESS_CONTROL_SHADER:
+                       source << "layout(vertices = 10) out;\n";
+                       break;
+
+               case GL_TESS_EVALUATION_SHADER:
+                       source << "layout(triangles) in;\n";
+                       break;
+
+               default:
+                       DE_FATAL("Unknown shader type");
+                       break;
+       }
+
+       source  << "\n"
+                       << "layout(std430, binding = 0) buffer Block {\n"
+                       << "    int value;\n"
+                       << "} sb_in[" << numSSBlocks << "];\n"
+                       << "void main(void) { sb_in[0].value = 1; }\n";
+
+       return source.str();
+}
+
+std::string genCommonSource (NegativeTestContext& ctx, glw::GLenum shaderType)
+{
+       const bool                              isES32          = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       const glu::GLSLVersion  version         = isES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
+       std::ostringstream              source;
+
+       source << glu::getGLSLVersionDeclaration(version) << "\n"
+                  << ((isES32) ? "" : getShaderExtensionDeclaration(shaderType));
+
+       switch (shaderType)
+       {
+               case GL_TESS_CONTROL_SHADER:
+                       source  << "layout(vertices = 3) out;\n"
+                                       << "void main() {}\n";
+                       break;
+
+               case GL_TESS_EVALUATION_SHADER:
+                       source  << "layout(triangles, equal_spacing, cw) in;\n"
+                                       << "void main() {}\n";
+                       break;
+
+               default:
+                       source  << "void main() {}\n";
+                       break;
+       }
+
+       return source.str();
+}
+
+int genMaxSSBlocksSource (NegativeTestContext& ctx, glw::GLenum glShaderType, glu::ProgramSources& sources)
+{
+       int             maxSSBlocks                             = getMaxSSBlockSize(ctx, glShaderType);
+       const   std::string shaderSrc   = genBlockSource(ctx, (maxSSBlocks), glShaderType);
+
+       sources.sources[getGLUShaderType(glShaderType)].push_back(shaderSrc);
+
+       return maxSSBlocks;
+}
+
+void block_number_limits (NegativeTestContext& ctx)
+{
+       const glw::GLenum glShaderTypes[] =
+       {
+               GL_VERTEX_SHADER,
+               GL_FRAGMENT_SHADER,
+               GL_TESS_CONTROL_SHADER,
+               GL_TESS_EVALUATION_SHADER,
+               GL_GEOMETRY_SHADER,
+               GL_COMPUTE_SHADER,
+       };
+
+       const std::string       vertSource                      = genCommonSource(ctx, GL_VERTEX_SHADER);
+       const std::string       fragSource                      = genCommonSource(ctx, GL_FRAGMENT_SHADER);
+       const std::string       tessControlSource       = genCommonSource(ctx, GL_TESS_CONTROL_SHADER);
+       const std::string       tessEvalSource          = genCommonSource(ctx, GL_TESS_EVALUATION_SHADER);
+
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(glShaderTypes); ndx++)
+       {
+               ctx.beginSection("maxShaderStorageBlocks: Exceed limits");
+
+               int                                     maxSSBlocks                     = getMaxSSBlockSize(ctx, glShaderTypes[ndx]);
+               std::string                     source                          = genBlockSource(ctx, maxSSBlocks+1, glShaderTypes[ndx]);
+
+               glu::ProgramSources sources;
+
+               if (maxSSBlocks == 0 || !ctx.isShaderSupported(static_cast<glu::ShaderType>(getGLUShaderType(glShaderTypes[ndx]))))
+               {
+                       ctx.endSection();
+                       continue;
+               }
+
+               switch (glShaderTypes[ndx])
+               {
+                       case GL_VERTEX_SHADER:
+                               sources << glu::VertexSource(source)
+                                               << glu::FragmentSource(fragSource);
+                               break;
+
+                       case GL_FRAGMENT_SHADER:
+                               sources << glu::VertexSource(vertSource)
+                                               << glu::FragmentSource(source);
+                               break;
+
+                       case GL_TESS_CONTROL_SHADER:
+                               sources << glu::VertexSource(vertSource)
+                                               << glu::FragmentSource(fragSource)
+                                               << glu::TessellationControlSource(source)
+                                               << glu::TessellationEvaluationSource(tessEvalSource);
+                               break;
+
+                       case GL_TESS_EVALUATION_SHADER:
+                               sources << glu::VertexSource(vertSource)
+                                               << glu::FragmentSource(fragSource)
+                                               << glu::TessellationControlSource(tessControlSource)
+                                               << glu::TessellationEvaluationSource(source);
+                               break;
+
+                       case GL_GEOMETRY_SHADER:
+                               sources << glu::VertexSource(vertSource)
+                                               << glu::FragmentSource(fragSource)
+                                               << glu::GeometrySource(source);
+                               break;
+
+                       case GL_COMPUTE_SHADER:
+                               sources << glu::ComputeSource(source);
+                               break;
+
+                       default:
+                               DE_FATAL("Unknown shader type");
+                               break;
+               }
+
+               verifyProgram(ctx, sources);
+               ctx.endSection();
+       }
+}
+
+void max_combined_block_number_limit (NegativeTestContext& ctx)
+{
+       ctx.beginSection("maxCombinedShaderStorageBlocks: Exceed limits");
+
+       glu::ProgramSources sources;
+
+       int combinedSSBlocks    = 0;
+       int maxCombinedSSBlocks = 0;
+
+       combinedSSBlocks += genMaxSSBlocksSource(ctx, GL_VERTEX_SHADER, sources);
+       combinedSSBlocks += genMaxSSBlocksSource(ctx, GL_FRAGMENT_SHADER, sources);
+
+       if ((ctx.isShaderSupported(glu::SHADERTYPE_TESSELLATION_CONTROL)) && (ctx.isShaderSupported(glu::SHADERTYPE_TESSELLATION_EVALUATION)))
+       {
+               combinedSSBlocks += genMaxSSBlocksSource(ctx, GL_TESS_CONTROL_SHADER, sources);
+               combinedSSBlocks += genMaxSSBlocksSource(ctx, GL_TESS_EVALUATION_SHADER, sources);
+       }
+
+       if (ctx.isShaderSupported(glu::SHADERTYPE_GEOMETRY))
+               combinedSSBlocks += genMaxSSBlocksSource(ctx, GL_GEOMETRY_SHADER, sources);
+
+       ctx.glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &maxCombinedSSBlocks);
+
+       ctx.getLog() << tcu::TestLog::Message << "GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: " << maxCombinedSSBlocks << tcu::TestLog::EndMessage;
+       ctx.getLog() << tcu::TestLog::Message << "Combined shader storage blocks: " << combinedSSBlocks << tcu::TestLog::EndMessage;
+
+       if (combinedSSBlocks > maxCombinedSSBlocks)
+               verifyProgram(ctx, sources);
+       else
+               ctx.getLog() << tcu::TestLog::Message << "Test skipped: Combined shader storage blocks < GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: " << tcu::TestLog::EndMessage;
+
+       ctx.endSection();
+}
+
+} // anonymous
+
+std::vector<FunctionContainer> getNegativeShaderStorageTestFunctions ()
+{
+       const FunctionContainer funcs[] =
+       {
+               { block_number_limits,                          "block_number_limits",                          "Invalid shader linkage" },
+               { max_combined_block_number_limit,      "max_combined_block_number_limit",      "Invalid shader linkage" },
+       };
+
+       return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
+}
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
diff --git a/modules/gles31/functional/es31fNegativeShaderStorageTests.hpp b/modules/gles31/functional/es31fNegativeShaderStorageTests.hpp
new file mode 100644 (file)
index 0000000..13cbd1f
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _ES31FNEGATIVESHADERSTORAGETESTS_HPP
+#define _ES31FNEGATIVESHADERSTORAGETESTS_HPP
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Negative Shader Storage Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "es31fNegativeTestShared.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+
+std::vector<FunctionContainer> getNegativeShaderStorageTestFunctions (void);
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
+
+#endif // _ES31FNEGATIVESHADERSTORAGETESTS_HPP
index 1f1cfeb..19184c6 100644 (file)
@@ -184,8 +184,9 @@ void get_integer64v (NegativeTestContext& ctx)
 
 void get_integeri_v (NegativeTestContext& ctx)
 {
-       GLint data                                              = -1;
-       GLint maxUniformBufferBindings  = 0;
+       GLint data                                                              = -1;
+       GLint maxUniformBufferBindings                  =  0;
+       GLint maxShaderStorageBufferBindings    =  0;
 
        ctx.beginSection("GL_INVALID_ENUM is generated if name is not an accepted value.");
        ctx.glGetIntegeri_v(-1, 0, &data);
@@ -198,12 +199,20 @@ void get_integeri_v (NegativeTestContext& ctx)
        ctx.glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, maxUniformBufferBindings, &data);
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_VALUE is generated if index is outside of the valid range for the indexed state target.");
+       ctx.glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &maxShaderStorageBufferBindings);
+       ctx.expectError(GL_NO_ERROR);
+       ctx.glGetIntegeri_v(GL_SHADER_STORAGE_BUFFER_BINDING, maxShaderStorageBufferBindings, &data);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.endSection();
 }
 
 void get_integer64i_v (NegativeTestContext& ctx)
 {
-       GLint64 data                                            = (GLint64)-1;
-       GLint   maxUniformBufferBindings        = 0;
+       GLint64 data                                                    = (GLint64)-1;
+       GLint   maxUniformBufferBindings                = 0;
+       GLint   maxShaderStorageBufferBindings  = 0;
 
        ctx.beginSection("GL_INVALID_ENUM is generated if name is not an accepted value.");
        ctx.glGetInteger64i_v(-1, 0, &data);
@@ -216,6 +225,15 @@ void get_integer64i_v (NegativeTestContext& ctx)
        ctx.glGetInteger64i_v(GL_UNIFORM_BUFFER_START, maxUniformBufferBindings, &data);
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_VALUE is generated if index is outside of the valid range for the indexed state target.");
+       ctx.glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &maxShaderStorageBufferBindings);
+       ctx.expectError(GL_NO_ERROR);
+       ctx.glGetInteger64i_v(GL_SHADER_STORAGE_BUFFER_START, maxShaderStorageBufferBindings, &data);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.glGetInteger64i_v(GL_SHADER_STORAGE_BUFFER_SIZE, maxShaderStorageBufferBindings, &data);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.endSection();
 }
 
 void get_string (NegativeTestContext& ctx)