From 51e20f1e2525f27b6e0ab81ffe7469fd4b33e5e7 Mon Sep 17 00:00:00 2001 From: John Richardson Date: Wed, 26 Oct 2016 09:43:56 +0100 Subject: [PATCH] Add shader storage negative coverage tests 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 | 1 + android/cts/master/gles31-master.txt | 6 + modules/gles31/functional/CMakeLists.txt | 2 + modules/gles31/functional/es31fDebugTests.cpp | 5 + .../functional/es31fNegativeBufferApiTests.cpp | 32 +- .../functional/es31fNegativeShaderApiTests.cpp | 143 +++++++-- .../functional/es31fNegativeShaderStorageTests.cpp | 324 +++++++++++++++++++++ .../functional/es31fNegativeShaderStorageTests.hpp | 45 +++ .../functional/es31fNegativeStateApiTests.cpp | 26 +- 9 files changed, 529 insertions(+), 55 deletions(-) create mode 100644 modules/gles31/functional/es31fNegativeShaderStorageTests.cpp create mode 100644 modules/gles31/functional/es31fNegativeShaderStorageTests.hpp diff --git a/Android.mk b/Android.mk index 253f085..52c027d 100644 --- a/Android.mk +++ b/Android.mk @@ -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 \ diff --git a/android/cts/master/gles31-master.txt b/android/cts/master/gles31-master.txt index 8204cb8..c53d4b0 100644 --- a/android/cts/master/gles31-master.txt +++ b/android/cts/master/gles31-master.txt @@ -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 diff --git a/modules/gles31/functional/CMakeLists.txt b/modules/gles31/functional/CMakeLists.txt index 1f57b59..db7a8b9 100644 --- a/modules/gles31/functional/CMakeLists.txt +++ b/modules/gles31/functional/CMakeLists.txt @@ -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}) diff --git a/modules/gles31/functional/es31fDebugTests.cpp b/modules/gles31/functional/es31fDebugTests.cpp index d6dde30..b44d7e5 100644 --- a/modules/gles31/functional/es31fDebugTests.cpp +++ b/modules/gles31/functional/es31fDebugTests.cpp @@ -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 shaderDirectiveFuncs = wrapCoreFunctions(NegativeTestShared::getNegativeShaderDirectiveTestFunctions()); const vector preciseFuncs = wrapCoreFunctions(NegativeTestShared::getNegativePreciseTestFunctions()); const vector advancedBlendFuncs = wrapCoreFunctions(NegativeTestShared::getNegativeAdvancedBlendEquationTestFunctions()); + const vector shaderStorageFuncs = wrapCoreFunctions(NegativeTestShared::getNegativeShaderStorageTestFunctions()); const vector 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)); } } diff --git a/modules/gles31/functional/es31fNegativeBufferApiTests.cpp b/modules/gles31/functional/es31fNegativeBufferApiTests.cpp index e4b67cd..309a507 100644 --- a/modules/gles31/functional/es31fNegativeBufferApiTests.cpp +++ b/modules/gles31/functional/es31fNegativeBufferApiTests.cpp @@ -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); } diff --git a/modules/gles31/functional/es31fNegativeShaderApiTests.cpp b/modules/gles31/functional/es31fNegativeShaderApiTests.cpp index 7c3fc0f..a80d6ca 100644 --- a/modules/gles31/functional/es31fNegativeShaderApiTests.cpp +++ b/modules/gles31/functional/es31fNegativeShaderApiTests.cpp @@ -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 index 0000000..773d728 --- /dev/null +++ b/modules/gles31/functional/es31fNegativeShaderStorageTests.cpp @@ -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(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 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(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 index 0000000..13cbd1f --- /dev/null +++ b/modules/gles31/functional/es31fNegativeShaderStorageTests.hpp @@ -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 getNegativeShaderStorageTestFunctions (void); + +} // NegativeTestShared +} // Functional +} // gles31 +} // deqp + +#endif // _ES31FNEGATIVESHADERSTORAGETESTS_HPP diff --git a/modules/gles31/functional/es31fNegativeStateApiTests.cpp b/modules/gles31/functional/es31fNegativeStateApiTests.cpp index 1f1cfeb..19184c6 100644 --- a/modules/gles31/functional/es31fNegativeStateApiTests.cpp +++ b/modules/gles31/functional/es31fNegativeStateApiTests.cpp @@ -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) -- 2.7.4