From 04ba289d6eebc1d74b389d92a66a9f14091fe830 Mon Sep 17 00:00:00 2001 From: Michael Hadley Date: Thu, 1 Dec 2016 17:52:17 +0000 Subject: [PATCH] Add SSBO block tests New Tests: - dEQP-GLES31.functional.debug.negative_coverage.callbacks.ssbo_block.ssbo_block.* Change-Id: I60d52bc34d9211e93332dcc719535f1f5e4a0596 --- Android.mk | 1 + android/cts/master/gles31-master.txt | 6 + modules/gles31/functional/CMakeLists.txt | 2 + modules/gles31/functional/es31fDebugTests.cpp | 5 + .../functional/es31fNegativeSSBOBlockTests.cpp | 617 +++++++++++++++++++++ .../functional/es31fNegativeSSBOBlockTests.hpp | 44 ++ 6 files changed, 675 insertions(+) create mode 100644 modules/gles31/functional/es31fNegativeSSBOBlockTests.cpp create mode 100644 modules/gles31/functional/es31fNegativeSSBOBlockTests.hpp diff --git a/Android.mk b/Android.mk index fa93f8b..a947dc2 100644 --- a/Android.mk +++ b/Android.mk @@ -591,6 +591,7 @@ LOCAL_SRC_FILES := \ modules/gles31/functional/es31fNegativeShaderImageLoadStoreTests.cpp \ modules/gles31/functional/es31fNegativeShaderStorageTests.cpp \ modules/gles31/functional/es31fNegativeStateApiTests.cpp \ + modules/gles31/functional/es31fNegativeSSBOBlockTests.cpp \ modules/gles31/functional/es31fNegativeTessellationTests.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 1e716dc..939f1e4 100644 --- a/android/cts/master/gles31-master.txt +++ b/android/cts/master/gles31-master.txt @@ -16769,6 +16769,8 @@ dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_directive.shader dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_directive.tessellation_shader dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_directive.texture_buffer dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_directive.texture_cube_map_array +dEQP-GLES31.functional.debug.negative_coverage.callbacks.ssbo_block.ssbo_block_interface_matching_tests +dEQP-GLES31.functional.debug.negative_coverage.callbacks.ssbo_block.ssbo_using_shared_qualifier_tests dEQP-GLES31.functional.debug.negative_coverage.callbacks.precise.precise_as_variable_name dEQP-GLES31.functional.debug.negative_coverage.callbacks.precise.precise_as_function_name dEQP-GLES31.functional.debug.negative_coverage.callbacks.precise.precise_as_function_argument @@ -17224,6 +17226,8 @@ dEQP-GLES31.functional.debug.negative_coverage.log.shader_directive.shader_io_bl dEQP-GLES31.functional.debug.negative_coverage.log.shader_directive.tessellation_shader dEQP-GLES31.functional.debug.negative_coverage.log.shader_directive.texture_buffer dEQP-GLES31.functional.debug.negative_coverage.log.shader_directive.texture_cube_map_array +dEQP-GLES31.functional.debug.negative_coverage.log.ssbo_block.ssbo_block_interface_matching_tests +dEQP-GLES31.functional.debug.negative_coverage.log.ssbo_block.ssbo_using_shared_qualifier_tests dEQP-GLES31.functional.debug.negative_coverage.log.precise.precise_as_variable_name dEQP-GLES31.functional.debug.negative_coverage.log.precise.precise_as_function_name dEQP-GLES31.functional.debug.negative_coverage.log.precise.precise_as_function_argument @@ -17677,6 +17681,8 @@ dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.shader dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.tessellation_shader dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.texture_buffer dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.texture_cube_map_array +dEQP-GLES31.functional.debug.negative_coverage.get_error.ssbo_block.ssbo_block_interface_matching_tests +dEQP-GLES31.functional.debug.negative_coverage.get_error.ssbo_block.ssbo_using_shared_qualifier_tests dEQP-GLES31.functional.debug.negative_coverage.get_error.precise.precise_as_variable_name dEQP-GLES31.functional.debug.negative_coverage.get_error.precise.precise_as_function_name dEQP-GLES31.functional.debug.negative_coverage.get_error.precise.precise_as_function_argument diff --git a/modules/gles31/functional/CMakeLists.txt b/modules/gles31/functional/CMakeLists.txt index 4cf4687..8c6edea 100644 --- a/modules/gles31/functional/CMakeLists.txt +++ b/modules/gles31/functional/CMakeLists.txt @@ -177,6 +177,8 @@ set(DEQP_GLES31_FUNCTIONAL_SRCS es31fDrawBuffersIndexedTests.cpp es31fNegativeShaderStorageTests.cpp es31fNegativeShaderStorageTests.hpp + es31fNegativeSSBOBlockTests.cpp + es31fNegativeSSBOBlockTests.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 5fd3b68..d41addb 100644 --- a/modules/gles31/functional/es31fDebugTests.cpp +++ b/modules/gles31/functional/es31fDebugTests.cpp @@ -34,6 +34,7 @@ #include "es31fNegativeShaderImageLoadStoreTests.hpp" #include "es31fNegativeShaderFunctionTests.hpp" #include "es31fNegativeShaderDirectiveTests.hpp" +#include "es31fNegativeSSBOBlockTests.hpp" #include "es31fNegativePreciseTests.hpp" #include "es31fNegativeAdvancedBlendEquationTests.hpp" #include "es31fNegativeShaderStorageTests.hpp" @@ -2955,6 +2956,7 @@ void DebugTests::init (void) const vector imageAtomicExchangeFuncs = wrapCoreFunctions(NegativeTestShared::getNegativeShaderImageAtomicExchangeTestFunctions()); const vector shaderFunctionFuncs = wrapCoreFunctions(NegativeTestShared::getNegativeShaderFunctionTestFunctions()); const vector shaderDirectiveFuncs = wrapCoreFunctions(NegativeTestShared::getNegativeShaderDirectiveTestFunctions()); + const vector ssboBlockFuncs = wrapCoreFunctions(NegativeTestShared::getNegativeSSBOBlockTestFunctions()); const vector preciseFuncs = wrapCoreFunctions(NegativeTestShared::getNegativePreciseTestFunctions()); const vector advancedBlendFuncs = wrapCoreFunctions(NegativeTestShared::getNegativeAdvancedBlendEquationTestFunctions()); const vector shaderStorageFuncs = wrapCoreFunctions(NegativeTestShared::getNegativeShaderStorageTestFunctions()); @@ -3061,6 +3063,7 @@ void DebugTests::init (void) host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_image_exchange", "Negative Shader Image Atomic Exchange API Cases", imageAtomicExchangeFuncs)); host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_function", "Negative Shader Function Cases", shaderFunctionFuncs)); host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_directive", "Negative Shader Directive Cases", shaderDirectiveFuncs)); + host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "ssbo_block", "Negative SSBO Block Cases", ssboBlockFuncs)); 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)); @@ -3085,6 +3088,7 @@ void DebugTests::init (void) host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_image_exchange", "Negative Shader Image Atomic Exchange API Cases", imageAtomicExchangeFuncs)); host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_function", "Negative Shader Function Cases", shaderFunctionFuncs)); host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_directive", "Negative Shader Directive Cases", shaderDirectiveFuncs)); + host->addChild(createChildCases(CASETYPE_LOG, m_context, "ssbo_block", "Negative SSBO Block Cases", ssboBlockFuncs)); 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)); @@ -3109,6 +3113,7 @@ void DebugTests::init (void) host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_image_exchange", "Negative Shader Image Atomic Exchange API Cases", imageAtomicExchangeFuncs)); host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_function", "Negative Shader Function Cases", shaderFunctionFuncs)); host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_directive", "Negative Shader Directive Cases", shaderDirectiveFuncs)); + host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "ssbo_block", "Negative SSBO Block Cases", ssboBlockFuncs)); 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/es31fNegativeSSBOBlockTests.cpp b/modules/gles31/functional/es31fNegativeSSBOBlockTests.cpp new file mode 100644 index 0000000..bddd035 --- /dev/null +++ b/modules/gles31/functional/es31fNegativeSSBOBlockTests.cpp @@ -0,0 +1,617 @@ +/*------------------------------------------------------------------------- +* 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 Buffer Object (SSBO) tests. +*//*--------------------------------------------------------------------*/ +#include "es31fNegativeSSBOBlockTests.hpp" +#include "glwDefs.hpp" +#include "glwEnums.hpp" +#include "tcuStringTemplate.hpp" +#include "gluShaderProgram.hpp" +#include + +namespace deqp +{ +namespace gles31 +{ +namespace Functional +{ +namespace NegativeTestShared +{ +namespace +{ +using tcu::TestLog; +using glu::CallLogWrapper; +using namespace glw; +namespace args +{ +enum ArgMember +{ + ARGMEMBER_FORMAT = 0, + ARGMEMBER_BINDING_POINT, + ARGMEMBER_MATRIX_ORDER, + ARGMEMBER_MEMBER_TYPE, + ARGMEMBER_NAME, + ARGMEMBER_FIXED_ARRAY, + ARGMEMBER_VARIABLE_ARRAY, + ARGMEMBER_REORDER +}; + +// key pair ssbo arg data +struct SsboArgData +{ + ArgMember member; + std::string data; + + SsboArgData(const ArgMember& member_, const std::string& data_) + { + member = member_; + data = data_; + } +}; + +// class which manages string based argument used to build varying ssbo interface blocks and members +class SsboArgs +{ +public: + SsboArgs(const std::string version, tcu::TestLog& log); + + void setSingleValue (const SsboArgData argData); + bool setAllValues (const std::vector argDataList); + + const std::string& getContextVersion (void) const; + const std::string& getStdFormat (void) const; + const std::string& getBindingPoint (void) const; + const std::string& getMatrixOrder (void) const; + const std::string& getMemberType (void) const; + const std::string& getMemberName (void) const; + const std::string& getMemberFixedArrayName (void) const; + const std::string& getMemberVariableArray (void) const; + bool getMemberReorder (void) const; + int getNumberMembers (void) const; + + void resetValues (void); + + std::map populateArgsMap (void) const; + +private: + std::string m_negativeContextVersion; + std::string m_stdFormat; + std::string m_bindingPoint; + std::string m_matrixOrder; + std::string m_memberType; + std::string m_memberName; + std::string m_memberFixedArrayerName; + std::string m_memberVariableArray; + bool m_memberReorder; + int m_numberMembers; + tcu::TestLog& m_testLog; + + void setDefaultValues (void); +}; + +//constructor which ensure a proper context is passed into the struct +SsboArgs::SsboArgs(const std::string version, tcu::TestLog& log) + : m_negativeContextVersion (version) + , m_numberMembers (8) + , m_testLog (log) +{ + setDefaultValues(); +} + +void SsboArgs::setSingleValue (const SsboArgData argData) +{ + std::string message; + + switch (argData.member) + { + case ARGMEMBER_FORMAT: + m_stdFormat = argData.data; + return; + case ARGMEMBER_BINDING_POINT: + m_bindingPoint = argData.data; + return; + case ARGMEMBER_MATRIX_ORDER: + m_matrixOrder = argData.data; + return; + case ARGMEMBER_MEMBER_TYPE: + m_memberType = argData.data; + return; + case ARGMEMBER_NAME: + m_memberName = argData.data; + return; + case ARGMEMBER_FIXED_ARRAY: + m_memberFixedArrayerName = argData.data; + return; + case ARGMEMBER_VARIABLE_ARRAY: + m_memberVariableArray = argData.data; + return; + case ARGMEMBER_REORDER: + if (argData.data == "true") + { + m_memberReorder = true; + } + return; + default: + message = "auto loop argument data member not recognised."; + m_testLog << tcu::TestLog::Message << message << tcu::TestLog::EndMessage; + } +} + +bool SsboArgs::setAllValues (const std::vector argDataList) +{ + std::string message; + + if ((argDataList.size() == 0) || (argDataList.size() > (size_t)m_numberMembers)) + { + message = "set of args does not match the number of args struct changeable members."; + m_testLog << tcu::TestLog::Message << message << tcu::TestLog::EndMessage; + + return false; + } + else + { + for (unsigned int idx = 0; idx < argDataList.size(); idx++) + { + setSingleValue(argDataList[idx]); + } + } + + return true; +} + +const std::string& SsboArgs::getContextVersion (void) const +{ + return m_negativeContextVersion; +} + +const std::string& SsboArgs::getStdFormat (void) const +{ + return m_stdFormat; +} + +const std::string& SsboArgs::getBindingPoint (void) const +{ + return m_bindingPoint; +} + +const std::string& SsboArgs::getMatrixOrder (void) const +{ + return m_matrixOrder; +} + +const std::string& SsboArgs::getMemberType (void) const +{ + return m_memberType; +} + +const std::string& SsboArgs::getMemberName (void) const +{ + return m_memberName; +} + +const std::string& SsboArgs::getMemberFixedArrayName (void) const +{ + return m_memberFixedArrayerName; +} + +const std::string& SsboArgs::getMemberVariableArray (void) const +{ + return m_memberVariableArray; +} + +bool SsboArgs::getMemberReorder (void) const +{ + return m_memberReorder; +} + +int SsboArgs::getNumberMembers (void) const +{ + return m_numberMembers; +} + +void SsboArgs::resetValues (void) +{ + setDefaultValues(); +} + +//converts SsboArgs member variable into a map object to be used by tcu::StringTemplate +std::map SsboArgs::populateArgsMap (void) const +{ + std::map argsMap; + + // key placeholders located at specific points in the ssbo block + argsMap["NEGATIVE_CONTEXT_VERSION"] = m_negativeContextVersion; + argsMap["STD_FORMAT"] = m_stdFormat; + argsMap["BINDING_POINT"] = m_bindingPoint; + argsMap["MATRIX_ORDER"] = m_matrixOrder; + argsMap["MEMBER_TYPE"] = m_memberType; + argsMap["MEMBER_NAME"] = m_memberName; + argsMap["MEMBER_FIXED_ARRAY"] = m_memberFixedArrayerName; + argsMap["MEMBER_VARIABLE_ARRAY"] = m_memberVariableArray; + + return argsMap; +} + +// default values i.e. same shader template +void SsboArgs::setDefaultValues (void) +{ + m_stdFormat = "std430"; + m_bindingPoint = "0"; + m_matrixOrder = "column_major"; + m_memberType = "int"; + m_memberName = "matrix"; + m_memberFixedArrayerName = "10"; + m_memberVariableArray = ""; + m_memberReorder = false; +} +} // args + +std::string generateVaryingSSBOShader(const glw::GLenum shaderType, const args::SsboArgs& args, tcu::TestLog& log) +{ + std::map argsMap; + std::ostringstream source; + std::string sourceString; + std::stringstream ssboString; + std::string message; + + if (args.getMemberReorder()) + { + ssboString << " mediump vec4 array_1[${MEMBER_FIXED_ARRAY}];\n" + << " highp mat4 ${MEMBER_NAME};\n" + << " lowp ${MEMBER_TYPE} data;\n" + << " mediump float array_2[${MEMBER_VARIABLE_ARRAY}];\n"; + } + else + { + ssboString << " lowp ${MEMBER_TYPE} data;\n" + << " highp mat4 ${MEMBER_NAME};\n" + << " mediump vec4 array_1[${MEMBER_FIXED_ARRAY}];\n" + << " mediump float array_2[${MEMBER_VARIABLE_ARRAY}];\n"; + } + + argsMap = args.populateArgsMap(); + + switch (shaderType) + { + case GL_VERTEX_SHADER: + { + source << "${NEGATIVE_CONTEXT_VERSION}\n" + << "layout (location = 0) in highp vec4 position;\n" + << "layout (location = 1) in mediump vec4 colour;\n" + << "out mediump vec4 vertex_colour;\n" + << "layout (${STD_FORMAT}, binding = ${BINDING_POINT}, ${MATRIX_ORDER}) buffer ssbo_block\n" + << "{\n"; + + source << ssboString.str(); + + source << "} ssbo;\n" + << "void main()\n" + << "{\n" + << " mediump vec4 variable;\n" + << " gl_Position = ssbo.${MEMBER_NAME} * position;\n" + << " for (int idx = 0; idx < ${MEMBER_FIXED_ARRAY}; idx++)\n" + << " {\n" + << " variable += ssbo.array_1[idx];\n" + << " }\n" + << " vertex_colour = colour + variable;\n" + << "}\n"; + + sourceString = source.str(); + sourceString = tcu::StringTemplate(sourceString).specialize(argsMap); + + return sourceString; + } + + case GL_FRAGMENT_SHADER: + { + source << "${NEGATIVE_CONTEXT_VERSION}\n" + << "in mediump vec4 vertex_colour;\n" + << "layout (location = 0) out mediump vec4 fragment_colour;\n" + << "layout (${STD_FORMAT}, binding = ${BINDING_POINT}, ${MATRIX_ORDER}) buffer ssbo_block\n" + << "{\n"; + + source << ssboString.str(); + + source << "} ssbo;\n" + << "void main()\n" + << "{\n" + << " mediump vec4 variable;\n" + << " variable * ssbo.${MEMBER_NAME};\n" + << " for (int idx = 0; idx < ${MEMBER_FIXED_ARRAY}; idx++)\n" + << " {\n" + << " variable += ssbo.array_1[idx];\n" + << " }\n" + << " fragment_colour = vertex_colour + variable;\n" + << "}\n"; + + sourceString = source.str(); + sourceString = tcu::StringTemplate(sourceString).specialize(argsMap); + + return sourceString; + } + + case GL_GEOMETRY_SHADER: + { + // TODO: + return sourceString; + } + + case GL_TESS_CONTROL_SHADER: + { + // TODO: + return sourceString; + } + + case GL_TESS_EVALUATION_SHADER: + { + // TODO: + return sourceString; + } + + case GL_COMPUTE_SHADER: + { + // TODO: + return sourceString; + } + + default: + { + message = "shader type not recognised."; + log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage; + } + } + + return std::string(); +} + +void logProgramInfo(NegativeTestContext& ctx, GLint program) +{ + GLint maxLength = 0; + std::string message; + tcu::TestLog& log = ctx.getLog(); + + ctx.glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); + + message = "Program log:"; + log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage; + + if (maxLength == 0) + { + message = "No available info log."; + log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage; + return; + } + + std::vector infoLog(maxLength); + ctx.glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]); + + std::string programLogMessage(&infoLog[0], maxLength); + log << tcu::TestLog::Message << programLogMessage << tcu::TestLog::EndMessage; +} + +void ssbo_block_matching(NegativeTestContext& ctx) +{ + 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; + tcu::TestLog& log = ctx.getLog(); + std::string message; + std::string versionString(glu::getGLSLVersionDeclaration(version)); + args::SsboArgs ssboArgs(versionString, log); + GLint shaderVertexGL; + std::string shaderVertexString; + const char* shaderVertexCharPtr; + + // List of arguments used to create varying ssbo objects in the fragment shader + const args::SsboArgData argDataArrayFrag[] = { args::SsboArgData(args::ARGMEMBER_FORMAT, "std140"), + args::SsboArgData(args::ARGMEMBER_BINDING_POINT, "10"), + args::SsboArgData(args::ARGMEMBER_MATRIX_ORDER, "row_major"), + args::SsboArgData(args::ARGMEMBER_MEMBER_TYPE, "vec2"), + args::SsboArgData(args::ARGMEMBER_NAME, "name_changed"), + args::SsboArgData(args::ARGMEMBER_FIXED_ARRAY, "20"), + args::SsboArgData(args::ARGMEMBER_VARIABLE_ARRAY, "5"), + args::SsboArgData(args::ARGMEMBER_REORDER, "true") }; + std::vector argDataVectorFrag(argDataArrayFrag, argDataArrayFrag + sizeof(argDataArrayFrag) / sizeof(argDataArrayFrag[0])); + + // create default vertex shader + shaderVertexString = generateVaryingSSBOShader(GL_VERTEX_SHADER, ssboArgs, log); + shaderVertexCharPtr = shaderVertexString.c_str(); + shaderVertexGL = ctx.glCreateShader(GL_VERTEX_SHADER); + + // log + message = shaderVertexString; + log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage; + + // compile + ctx.glShaderSource(shaderVertexGL, 1, &shaderVertexCharPtr, DE_NULL); + ctx.glCompileShader(shaderVertexGL); + + for (std::size_t idx = 0; idx < argDataVectorFrag.size(); ++idx) + { + GLint linkStatus = -1; + GLint program; + GLint shaderFragmentGL; + std::string shaderFragmentString; + const char* shaderFragmentCharPtr; + + ctx.beginSection("Multiple shaders created using SSBO's sharing the same name but not matching layouts"); + + program = ctx.glCreateProgram(); + + // reset args to default and make a single change + ssboArgs.resetValues(); + ssboArgs.setSingleValue(argDataVectorFrag[idx]); + + // create fragment shader + shaderFragmentString = generateVaryingSSBOShader(GL_FRAGMENT_SHADER, ssboArgs, log); + shaderFragmentCharPtr = shaderFragmentString.c_str(); + shaderFragmentGL = ctx.glCreateShader(GL_FRAGMENT_SHADER); + + // log + message = shaderFragmentString; + log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage; + + // compile + ctx.glShaderSource(shaderFragmentGL, 1, &shaderFragmentCharPtr, DE_NULL); + ctx.glCompileShader(shaderFragmentGL); + + // attach shaders to program and attempt to link + ctx.glAttachShader(program, shaderVertexGL); + ctx.glAttachShader(program, shaderFragmentGL); + ctx.glLinkProgram(program); + ctx.glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); + + logProgramInfo(ctx, program); + + if (linkStatus == GL_TRUE) + { + ctx.fail("Program should not have linked"); + } + + // clean up resources + ctx.glDeleteShader(shaderFragmentGL); + ctx.glDeleteProgram(program); + + ctx.endSection(); + } + + // clean up default resources + ctx.glDeleteShader(shaderVertexGL); +} + +void ssbo_block_shared_qualifier(NegativeTestContext& ctx) +{ + 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; + tcu::TestLog& log = ctx.getLog(); + std::string message; + std::string versionString(glu::getGLSLVersionDeclaration(version)); + args::SsboArgs ssboArgs(versionString, log); + bool result; + GLint shaderVertexGL; + std::string shaderVertexString; + const char* shaderVertexCharPtr; + + // default args used in vertex shader ssbo + const args::SsboArgData argDataArrayVert[] = { args::SsboArgData(args::ARGMEMBER_FORMAT, "shared"), + args::SsboArgData(args::ARGMEMBER_BINDING_POINT, "0"), + args::SsboArgData(args::ARGMEMBER_MATRIX_ORDER, "column_major"), + args::SsboArgData(args::ARGMEMBER_FIXED_ARRAY, "10"), + args::SsboArgData(args::ARGMEMBER_VARIABLE_ARRAY, "10"), + args::SsboArgData(args::ARGMEMBER_REORDER, "false") }; + std::vector argDataVectorVert(argDataArrayVert, argDataArrayVert + sizeof(argDataArrayVert) / sizeof(argDataArrayVert[0])); + + // args changed in fragment shader ssbo + const args::SsboArgData argDataArrayFrag[] = { args::SsboArgData(args::ARGMEMBER_MATRIX_ORDER, "row_major"), + args::SsboArgData(args::ARGMEMBER_VARIABLE_ARRAY, ""), + args::SsboArgData(args::ARGMEMBER_FIXED_ARRAY, "20") }; + std::vector argDataVectorFrag(argDataArrayFrag, argDataArrayFrag + sizeof(argDataArrayFrag) / sizeof(argDataArrayFrag[0])); + + // set default vertex ssbo args + result = ssboArgs.setAllValues(argDataVectorVert); + + if (result == false) + { + message = "Invalid use of args.setAllValues()"; + log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage; + return; + } + + // create default vertex shader + shaderVertexString = generateVaryingSSBOShader(GL_VERTEX_SHADER, ssboArgs, log); + shaderVertexCharPtr = shaderVertexString.c_str(); + shaderVertexGL = ctx.glCreateShader(GL_VERTEX_SHADER); + + // log + message = shaderVertexString; + log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage; + + // compile + ctx.glShaderSource(shaderVertexGL, 1, &shaderVertexCharPtr, DE_NULL); + ctx.glCompileShader(shaderVertexGL); + + for (std::size_t idx = 0; idx < argDataVectorFrag.size(); idx++) + { + GLint linkStatus = -1; + GLint program; + GLint shaderFragmentGL; + std::string shaderFragmentString; + const char* shaderFragmentCharPtr; + + ctx.beginSection("Multiple shaders created using SSBO's sharing the same name but not matching layouts"); + + program = ctx.glCreateProgram(); + + // reset args to default and make a single change + ssboArgs.setAllValues(argDataVectorVert); + ssboArgs.setSingleValue(argDataVectorFrag[idx]); + + // create fragment shader + shaderFragmentString = generateVaryingSSBOShader(GL_FRAGMENT_SHADER, ssboArgs, log); + shaderFragmentCharPtr = shaderFragmentString.c_str(); + shaderFragmentGL = ctx.glCreateShader(GL_FRAGMENT_SHADER); + + // log + message = shaderFragmentString; + log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage; + + // compile + ctx.glShaderSource(shaderFragmentGL, 1, &shaderFragmentCharPtr, DE_NULL); + ctx.glCompileShader(shaderFragmentGL); + + // attach shaders to the program and attempt to link + ctx.glAttachShader(program, shaderVertexGL); + ctx.glAttachShader(program, shaderFragmentGL); + ctx.glLinkProgram(program); + ctx.glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); + + logProgramInfo(ctx, program); + + if (linkStatus == GL_TRUE) + { + ctx.fail("Program should not have linked"); + } + + // clean up resources + ctx.glDeleteShader(shaderFragmentGL); + ctx.glDeleteProgram(program); + + ctx.endSection(); + } + + // clean up default resources + ctx.glDeleteShader(shaderVertexGL); +} +} // anonymous + +std::vector getNegativeSSBOBlockTestFunctions (void) +{ + const FunctionContainer funcs[] = + { + { ssbo_block_matching, "ssbo_block_interface_matching_tests", "Invalid Shader Linkage" }, + { ssbo_block_shared_qualifier, "ssbo_using_shared_qualifier_tests", "Invalid Shader Linkage" }, + }; + + return std::vector(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs)); +} +} // NegativeTestShared +} //Functional +} //gles31 +} //deqp diff --git a/modules/gles31/functional/es31fNegativeSSBOBlockTests.hpp b/modules/gles31/functional/es31fNegativeSSBOBlockTests.hpp new file mode 100644 index 0000000..db1d3bb --- /dev/null +++ b/modules/gles31/functional/es31fNegativeSSBOBlockTests.hpp @@ -0,0 +1,44 @@ +#ifndef _ES31FNEGATIVESSBOBLOCKTESTS_HPP +#define _ES31FNEGATIVESSBOBLOCKTESTS_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 Block Object (SSBO) API tests. +*//*--------------------------------------------------------------------*/ +#include "tcuDefs.hpp" +#include "es31fNegativeTestShared.hpp" + +namespace deqp +{ +namespace gles31 +{ +namespace Functional +{ +namespace NegativeTestShared +{ + +std::vector getNegativeSSBOBlockTestFunctions (void); + +} // NegativeTestShared +} // Functional +} // gles31 +} // deqp + +#endif // _ES31FNEGATIVESSBOBLOCKTESTS_HPP \ No newline at end of file -- 2.7.4