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 \
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
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
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
es31fCopyImageTests.cpp
es31fDrawBuffersIndexedTests.hpp
es31fDrawBuffersIndexedTests.cpp
+ es31fNegativeShaderStorageTests.cpp
+ es31fNegativeShaderStorageTests.hpp
)
add_library(deqp-gles31-functional STATIC ${DEQP_GLES31_FUNCTIONAL_SRCS})
#include "es31fNegativeShaderDirectiveTests.hpp"
#include "es31fNegativePreciseTests.hpp"
#include "es31fNegativeAdvancedBlendEquationTests.hpp"
+#include "es31fNegativeShaderStorageTests.hpp"
#include "deUniquePtr.hpp"
#include "deRandom.hpp"
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();
{
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));
}
{
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));
}
{
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));
}
}
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);
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);
}
}
}
-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);
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();
}
--- /dev/null
+/*-------------------------------------------------------------------------
+ * 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
--- /dev/null
+#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
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);
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);
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)