From: Kenneth Russell Date: Mon, 23 Jul 2018 22:26:47 +0000 (-0700) Subject: Add cases for structs as inout and out parameters. X-Git-Tag: upstream/1.3.5~2548 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3b0365b1a090c4e15f72b2cb877ee15f65c8befe;p=platform%2Fupstream%2FVK-GL-CTS.git Add cases for structs as inout and out parameters. Structs with lowp, mediump and highp (when supported in fragment shaders) members are tested as inout and out parameters in both ES 2.0 and 3.0 shaders. The highp variant of this test catches a bug which was found by the Three.js community in https://github.com/mrdoob/three.js/issues/14137 . Similar tests were integrated into the WebGL conformance suite in https://github.com/KhronosGroup/WebGL/pull/2663 . Verified on: Qualcomm Adreno 308 (LG Aristo) - bug reproduces in both ES2 and ES3 highp fragment shaders Qualcomm Adreno 540 (Pixel 2), NVIDIA Tegra (SHIELD Tablet) - all tests pass New tests: dEQP-GLES[23].functional.shaders.struct.local.parameter_inout_* dEQP-GLES[23].functional.shaders.struct.local.parameter_out_* VK-GL-CTS Issue 1280 Change-Id: Ie332aede0ad52453815d9e123145ec035009430b --- diff --git a/android/cts/master/gles2-master.txt b/android/cts/master/gles2-master.txt index ecf56bb..8217ac7 100644 --- a/android/cts/master/gles2-master.txt +++ b/android/cts/master/gles2-master.txt @@ -6813,8 +6813,20 @@ dEQP-GLES2.functional.shaders.struct.local.nested_struct_array_dynamic_index_ver dEQP-GLES2.functional.shaders.struct.local.nested_struct_array_dynamic_index_fragment dEQP-GLES2.functional.shaders.struct.local.parameter_vertex dEQP-GLES2.functional.shaders.struct.local.parameter_fragment +dEQP-GLES2.functional.shaders.struct.local.parameter_inout_lowp_vertex +dEQP-GLES2.functional.shaders.struct.local.parameter_inout_lowp_fragment +dEQP-GLES2.functional.shaders.struct.local.parameter_inout_mediump_vertex +dEQP-GLES2.functional.shaders.struct.local.parameter_inout_mediump_fragment +dEQP-GLES2.functional.shaders.struct.local.parameter_inout_highp_vertex +dEQP-GLES2.functional.shaders.struct.local.parameter_inout_highp_fragment dEQP-GLES2.functional.shaders.struct.local.parameter_nested_vertex dEQP-GLES2.functional.shaders.struct.local.parameter_nested_fragment +dEQP-GLES2.functional.shaders.struct.local.parameter_out_lowp_vertex +dEQP-GLES2.functional.shaders.struct.local.parameter_out_lowp_fragment +dEQP-GLES2.functional.shaders.struct.local.parameter_out_mediump_vertex +dEQP-GLES2.functional.shaders.struct.local.parameter_out_mediump_fragment +dEQP-GLES2.functional.shaders.struct.local.parameter_out_highp_vertex +dEQP-GLES2.functional.shaders.struct.local.parameter_out_highp_fragment dEQP-GLES2.functional.shaders.struct.local.return_vertex dEQP-GLES2.functional.shaders.struct.local.return_fragment dEQP-GLES2.functional.shaders.struct.local.return_nested_vertex diff --git a/android/cts/master/gles3-master.txt b/android/cts/master/gles3-master.txt index 3c0b885..e345d89 100644 --- a/android/cts/master/gles3-master.txt +++ b/android/cts/master/gles3-master.txt @@ -16255,8 +16255,20 @@ dEQP-GLES3.functional.shaders.struct.local.nested_struct_array_dynamic_index_ver dEQP-GLES3.functional.shaders.struct.local.nested_struct_array_dynamic_index_fragment dEQP-GLES3.functional.shaders.struct.local.parameter_vertex dEQP-GLES3.functional.shaders.struct.local.parameter_fragment +dEQP-GLES3.functional.shaders.struct.local.parameter_inout_lowp_vertex +dEQP-GLES3.functional.shaders.struct.local.parameter_inout_lowp_fragment +dEQP-GLES3.functional.shaders.struct.local.parameter_inout_mediump_vertex +dEQP-GLES3.functional.shaders.struct.local.parameter_inout_mediump_fragment +dEQP-GLES3.functional.shaders.struct.local.parameter_inout_highp_vertex +dEQP-GLES3.functional.shaders.struct.local.parameter_inout_highp_fragment dEQP-GLES3.functional.shaders.struct.local.parameter_nested_vertex dEQP-GLES3.functional.shaders.struct.local.parameter_nested_fragment +dEQP-GLES3.functional.shaders.struct.local.parameter_out_lowp_vertex +dEQP-GLES3.functional.shaders.struct.local.parameter_out_lowp_fragment +dEQP-GLES3.functional.shaders.struct.local.parameter_out_mediump_vertex +dEQP-GLES3.functional.shaders.struct.local.parameter_out_mediump_fragment +dEQP-GLES3.functional.shaders.struct.local.parameter_out_highp_vertex +dEQP-GLES3.functional.shaders.struct.local.parameter_out_highp_fragment dEQP-GLES3.functional.shaders.struct.local.return_vertex dEQP-GLES3.functional.shaders.struct.local.return_fragment dEQP-GLES3.functional.shaders.struct.local.return_nested_vertex diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/gles2-master.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/gles2-master.txt index 1fb12a5..18357ce 100644 --- a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/gles2-master.txt +++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/gles2-master.txt @@ -7657,8 +7657,20 @@ dEQP-GLES2.functional.shaders.struct.local.nested_struct_array_dynamic_index_ver dEQP-GLES2.functional.shaders.struct.local.nested_struct_array_dynamic_index_fragment dEQP-GLES2.functional.shaders.struct.local.parameter_vertex dEQP-GLES2.functional.shaders.struct.local.parameter_fragment +dEQP-GLES2.functional.shaders.struct.local.parameter_inout_lowp_vertex +dEQP-GLES2.functional.shaders.struct.local.parameter_inout_lowp_fragment +dEQP-GLES2.functional.shaders.struct.local.parameter_inout_mediump_vertex +dEQP-GLES2.functional.shaders.struct.local.parameter_inout_mediump_fragment +dEQP-GLES2.functional.shaders.struct.local.parameter_inout_highp_vertex +dEQP-GLES2.functional.shaders.struct.local.parameter_inout_highp_fragment dEQP-GLES2.functional.shaders.struct.local.parameter_nested_vertex dEQP-GLES2.functional.shaders.struct.local.parameter_nested_fragment +dEQP-GLES2.functional.shaders.struct.local.parameter_out_lowp_vertex +dEQP-GLES2.functional.shaders.struct.local.parameter_out_lowp_fragment +dEQP-GLES2.functional.shaders.struct.local.parameter_out_mediump_vertex +dEQP-GLES2.functional.shaders.struct.local.parameter_out_mediump_fragment +dEQP-GLES2.functional.shaders.struct.local.parameter_out_highp_vertex +dEQP-GLES2.functional.shaders.struct.local.parameter_out_highp_fragment dEQP-GLES2.functional.shaders.struct.local.return_vertex dEQP-GLES2.functional.shaders.struct.local.return_fragment dEQP-GLES2.functional.shaders.struct.local.return_nested_vertex diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/gles3-master.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/gles3-master.txt index d4b8d2a..78a5977 100644 --- a/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/gles3-master.txt +++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/3.2.5.x/gles3-master.txt @@ -16469,8 +16469,20 @@ dEQP-GLES3.functional.shaders.struct.local.nested_struct_array_dynamic_index_ver dEQP-GLES3.functional.shaders.struct.local.nested_struct_array_dynamic_index_fragment dEQP-GLES3.functional.shaders.struct.local.parameter_vertex dEQP-GLES3.functional.shaders.struct.local.parameter_fragment +dEQP-GLES3.functional.shaders.struct.local.parameter_inout_lowp_vertex +dEQP-GLES3.functional.shaders.struct.local.parameter_inout_lowp_fragment +dEQP-GLES3.functional.shaders.struct.local.parameter_inout_mediump_vertex +dEQP-GLES3.functional.shaders.struct.local.parameter_inout_mediump_fragment +dEQP-GLES3.functional.shaders.struct.local.parameter_inout_highp_vertex +dEQP-GLES3.functional.shaders.struct.local.parameter_inout_highp_fragment dEQP-GLES3.functional.shaders.struct.local.parameter_nested_vertex dEQP-GLES3.functional.shaders.struct.local.parameter_nested_fragment +dEQP-GLES3.functional.shaders.struct.local.parameter_out_lowp_vertex +dEQP-GLES3.functional.shaders.struct.local.parameter_out_lowp_fragment +dEQP-GLES3.functional.shaders.struct.local.parameter_out_mediump_vertex +dEQP-GLES3.functional.shaders.struct.local.parameter_out_mediump_fragment +dEQP-GLES3.functional.shaders.struct.local.parameter_out_highp_vertex +dEQP-GLES3.functional.shaders.struct.local.parameter_out_highp_fragment dEQP-GLES3.functional.shaders.struct.local.return_vertex dEQP-GLES3.functional.shaders.struct.local.return_fragment dEQP-GLES3.functional.shaders.struct.local.return_nested_vertex diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles2-master.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles2-master.txt index 35e5c28..ab7641d 100644 --- a/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles2-master.txt +++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles2-master.txt @@ -7799,8 +7799,20 @@ dEQP-GLES2.functional.shaders.struct.local.nested_struct_array_dynamic_index_ver dEQP-GLES2.functional.shaders.struct.local.nested_struct_array_dynamic_index_fragment dEQP-GLES2.functional.shaders.struct.local.parameter_vertex dEQP-GLES2.functional.shaders.struct.local.parameter_fragment +dEQP-GLES2.functional.shaders.struct.local.parameter_inout_lowp_vertex +dEQP-GLES2.functional.shaders.struct.local.parameter_inout_lowp_fragment +dEQP-GLES2.functional.shaders.struct.local.parameter_inout_mediump_vertex +dEQP-GLES2.functional.shaders.struct.local.parameter_inout_mediump_fragment +dEQP-GLES2.functional.shaders.struct.local.parameter_inout_highp_vertex +dEQP-GLES2.functional.shaders.struct.local.parameter_inout_highp_fragment dEQP-GLES2.functional.shaders.struct.local.parameter_nested_vertex dEQP-GLES2.functional.shaders.struct.local.parameter_nested_fragment +dEQP-GLES2.functional.shaders.struct.local.parameter_out_lowp_vertex +dEQP-GLES2.functional.shaders.struct.local.parameter_out_lowp_fragment +dEQP-GLES2.functional.shaders.struct.local.parameter_out_mediump_vertex +dEQP-GLES2.functional.shaders.struct.local.parameter_out_mediump_fragment +dEQP-GLES2.functional.shaders.struct.local.parameter_out_highp_vertex +dEQP-GLES2.functional.shaders.struct.local.parameter_out_highp_fragment dEQP-GLES2.functional.shaders.struct.local.return_vertex dEQP-GLES2.functional.shaders.struct.local.return_fragment dEQP-GLES2.functional.shaders.struct.local.return_nested_vertex diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles3-master.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles3-master.txt index 89fb870..abc800e 100644 --- a/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles3-master.txt +++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles3-master.txt @@ -16471,8 +16471,20 @@ dEQP-GLES3.functional.shaders.struct.local.nested_struct_array_dynamic_index_ver dEQP-GLES3.functional.shaders.struct.local.nested_struct_array_dynamic_index_fragment dEQP-GLES3.functional.shaders.struct.local.parameter_vertex dEQP-GLES3.functional.shaders.struct.local.parameter_fragment +dEQP-GLES3.functional.shaders.struct.local.parameter_inout_lowp_vertex +dEQP-GLES3.functional.shaders.struct.local.parameter_inout_lowp_fragment +dEQP-GLES3.functional.shaders.struct.local.parameter_inout_mediump_vertex +dEQP-GLES3.functional.shaders.struct.local.parameter_inout_mediump_fragment +dEQP-GLES3.functional.shaders.struct.local.parameter_inout_highp_vertex +dEQP-GLES3.functional.shaders.struct.local.parameter_inout_highp_fragment dEQP-GLES3.functional.shaders.struct.local.parameter_nested_vertex dEQP-GLES3.functional.shaders.struct.local.parameter_nested_fragment +dEQP-GLES3.functional.shaders.struct.local.parameter_out_lowp_vertex +dEQP-GLES3.functional.shaders.struct.local.parameter_out_lowp_fragment +dEQP-GLES3.functional.shaders.struct.local.parameter_out_mediump_vertex +dEQP-GLES3.functional.shaders.struct.local.parameter_out_mediump_fragment +dEQP-GLES3.functional.shaders.struct.local.parameter_out_highp_vertex +dEQP-GLES3.functional.shaders.struct.local.parameter_out_highp_fragment dEQP-GLES3.functional.shaders.struct.local.return_vertex dEQP-GLES3.functional.shaders.struct.local.return_fragment dEQP-GLES3.functional.shaders.struct.local.return_nested_vertex diff --git a/modules/gles2/functional/es2fShaderStructTests.cpp b/modules/gles2/functional/es2fShaderStructTests.cpp index 21d84c5..b7354d8 100644 --- a/modules/gles2/functional/es2fShaderStructTests.cpp +++ b/modules/gles2/functional/es2fShaderStructTests.cpp @@ -56,6 +56,7 @@ enum CaseFlags FLAG_USES_TEXTURES = (1<<0), FLAG_REQUIRES_DYNAMIC_LOOPS = (1<<1), FLAG_REQUIRES_DYNAMIC_INDEXING = (1<<2), + FLAG_REQUIRES_HIGHP_FRAGMENT = (1<<3), }; typedef void (*SetupUniformsFunc) (const glw::Functions& gl, deUint32 programID, const tcu::Vec4& constCoords); @@ -122,6 +123,10 @@ void ShaderStructCase::init (void) if (m_flags & FLAG_REQUIRES_DYNAMIC_INDEXING) throw tcu::NotSupportedError("Dynamic indexing not supported"); + if (!m_isVertexCase && (m_flags & FLAG_REQUIRES_HIGHP_FRAGMENT) && + !m_ctxInfo.isFragmentHighPrecisionSupported()) + throw tcu::NotSupportedError("Highp in fragment shaders not supported"); + throw; } @@ -148,7 +153,7 @@ void ShaderStructCase::setupUniforms (int programID, const tcu::Vec4& constCoord m_setupUniforms(m_renderCtx.getFunctions(), programID, constCoords); } -static ShaderStructCase* createStructCase (Context& context, const char* name, const char* description, bool isVertexCase, deUint32 flags, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms, const LineStream& shaderSrc) +static ShaderStructCase* createStructCase (Context& context, const char* name, const char* description, bool isVertexCase, deUint32 flags, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms, const LineStream& shaderSrc, const std::map* additionalParams) { static const char* defaultVertSrc = "attribute highp vec4 a_position;\n" @@ -185,6 +190,8 @@ static ShaderStructCase* createStructCase (Context& context, const char* name, c spParams["DST"] = "gl_FragColor"; spParams["ASSIGN_POS"] = ""; } + if (additionalParams) + spParams.insert(additionalParams->begin(), additionalParams->end()); if (isVertexCase) return new ShaderStructCase(context, name, description, isVertexCase, flags, evalFunc, setupUniforms, StringTemplate(shaderSrc.str()).specialize(spParams).c_str(), defaultFragSrc); @@ -209,13 +216,16 @@ public: void LocalStructTests::init (void) { - #define LOCAL_STRUCT_CASE(NAME, DESCRIPTION, FLAGS, SHADER_SRC, EVAL_FUNC_BODY) \ + #define LOCAL_STRUCT_CASE_PARAMETERIZED(NAME, DESCRIPTION, FLAGS, SHADER_SRC, EVAL_FUNC_BODY, PARAMS) \ do { \ struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY }; /* NOLINT(EVAL_FUNC_BODY) */ \ - addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, FLAGS, &Eval_##NAME::eval, DE_NULL, SHADER_SRC)); \ - addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, FLAGS,&Eval_##NAME::eval, DE_NULL, SHADER_SRC)); \ + addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, FLAGS, &Eval_##NAME::eval, DE_NULL, SHADER_SRC, PARAMS)); \ + addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, FLAGS,&Eval_##NAME::eval, DE_NULL, SHADER_SRC, PARAMS));\ } while (deGetFalse()) + #define LOCAL_STRUCT_CASE(NAME, DESCRIPTION, FLAGS, SHADER_SRC, EVAL_FUNC_BODY) \ + LOCAL_STRUCT_CASE_PARAMETERIZED(NAME, DESCRIPTION, FLAGS, SHADER_SRC, EVAL_FUNC_BODY, DE_NULL) + LOCAL_STRUCT_CASE(basic, "Basic struct usage", 0, LineStream() << "${DECLARATIONS}" @@ -526,6 +536,61 @@ void LocalStructTests::init (void) c.color.xyz() = c.coords.swizzle(0,1,2); }); + LineStream inoutSrc; + inoutSrc + << "${DECLARATIONS}" + << "" + << "struct S {" + << " ${PRECISION} vec3 red;" + << " ${PRECISION} vec3 blue;" + << "};" + << "" + << "void modify (inout S s)" + << "{" + << " s.red += vec3(0.5, 0.0, 0.0);" + << " s.blue += vec3(0.0, 0.0, 0.5);" + << "}" + << "" + << "void main (void)" + << "{" + << " S s;" + << " s.red = vec3(0.5, 0.0, 0.0);" + << " s.blue = vec3(0.0, 0.0, 0.5);" + << " modify(s);" + << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);" + << " if (s.red == vec3(1.0, 0.0, 0.0) && s.blue == vec3(0.0, 0.0, 1.0))" + << " ${DST} = vec4(1.0, 1.0, 1.0, 1.0);" + << " ${ASSIGN_POS}" + << "}"; + + std::map precisionParams; + precisionParams["PRECISION"] = "lowp"; + LOCAL_STRUCT_CASE_PARAMETERIZED( + parameter_inout_lowp, "Struct with lowp members as an inout function parameter", 0, + inoutSrc, + { + c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0); + }, + &precisionParams); + + precisionParams["PRECISION"] = "mediump"; + LOCAL_STRUCT_CASE_PARAMETERIZED( + parameter_inout_mediump, "Struct with mediump members as an inout function parameter", 0, + inoutSrc, + { + c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0); + }, + &precisionParams); + + precisionParams["PRECISION"] = "highp"; + LOCAL_STRUCT_CASE_PARAMETERIZED( + parameter_inout_highp, "Struct with highp members as an inout function parameter", FLAG_REQUIRES_HIGHP_FRAGMENT, + inoutSrc, + { + c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0); + }, + &precisionParams); + LOCAL_STRUCT_CASE(parameter_nested, "Nested struct as a function parameter", 0, LineStream() << "${DECLARATIONS}" @@ -558,6 +623,58 @@ void LocalStructTests::init (void) c.color.xyz() = c.coords.swizzle(0,1,2); }); + LineStream outSrc; + outSrc + << "${DECLARATIONS}" + << "" + << "struct S {" + << " ${PRECISION} vec3 red;" + << " ${PRECISION} vec3 blue;" + << "};" + << "" + << "void modify (out S s)" + << "{" + << " s.red = vec3(1.0, 0.0, 0.0);" + << " s.blue = vec3(0.0, 0.0, 1.0);" + << "}" + << "" + << "void main (void)" + << "{" + << " S s;" + << " modify(s);" + << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);" + << " if (s.red == vec3(1.0, 0.0, 0.0) && s.blue == vec3(0.0, 0.0, 1.0))" + << " ${DST} = vec4(1.0, 1.0, 1.0, 1.0);" + << " ${ASSIGN_POS}" + << "}", + + + precisionParams["PRECISION"] = "lowp"; + LOCAL_STRUCT_CASE_PARAMETERIZED( + parameter_out_lowp, "Struct with lowp members as an out function parameter", 0, + outSrc, + { + c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0); + }, + &precisionParams); + + precisionParams["PRECISION"] = "mediump"; + LOCAL_STRUCT_CASE_PARAMETERIZED(parameter_out_mediump, "Struct with mediump members as an out function parameter", 0, + outSrc, + { + c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0); + }, + &precisionParams); + + precisionParams["PRECISION"] = "highp"; + LOCAL_STRUCT_CASE_PARAMETERIZED( + parameter_out_highp, "Struct with highp members as an out function parameter", FLAG_REQUIRES_HIGHP_FRAGMENT, + outSrc, + { + c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0); + }, + &precisionParams); + LOCAL_STRUCT_CASE(return, "Struct as a return value", 0, LineStream() << "${DECLARATIONS}" @@ -1221,8 +1338,8 @@ void UniformStructTests::init (void) static void setUniforms (const glw::Functions& gl, deUint32 programID, const tcu::Vec4& constCoords) SET_UNIFORMS_BODY /* NOLINT(SET_UNIFORMS_BODY) */ \ }; \ struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY }; /* NOLINT(EVAL_FUNC_BODY) */ \ - addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, FLAGS, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC)); \ - addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, FLAGS, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC)); \ + addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, FLAGS, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC, DE_NULL)); \ + addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, FLAGS, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC, DE_NULL));\ } while (deGetFalse()) UNIFORM_STRUCT_CASE(basic, "Basic struct usage", 0, diff --git a/modules/gles3/functional/es3fShaderStructTests.cpp b/modules/gles3/functional/es3fShaderStructTests.cpp index 66b9559..526db73 100644 --- a/modules/gles3/functional/es3fShaderStructTests.cpp +++ b/modules/gles3/functional/es3fShaderStructTests.cpp @@ -115,7 +115,7 @@ void ShaderStructCase::setupUniforms (int programID, const tcu::Vec4& constCoord m_setupUniforms(m_renderCtx.getFunctions(), programID, constCoords); } -static ShaderStructCase* createStructCase (Context& context, const char* name, const char* description, bool isVertexCase, bool usesTextures, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms, const LineStream& shaderSrc) +static ShaderStructCase* createStructCase (Context& context, const char* name, const char* description, bool isVertexCase, bool usesTextures, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms, const LineStream& shaderSrc, const std::map* additionalParams) { static const char* defaultVertSrc = "#version 300 es\n" @@ -159,6 +159,8 @@ static ShaderStructCase* createStructCase (Context& context, const char* name, c spParams["DST"] = "o_color"; spParams["ASSIGN_POS"] = ""; } + if (additionalParams) + spParams.insert(additionalParams->begin(), additionalParams->end()); if (isVertexCase) return new ShaderStructCase(context, name, description, isVertexCase, usesTextures, evalFunc, setupUniforms, StringTemplate(shaderSrc.str()).specialize(spParams).c_str(), defaultFragSrc); @@ -183,13 +185,16 @@ public: void LocalStructTests::init (void) { - #define LOCAL_STRUCT_CASE(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY) \ + #define LOCAL_STRUCT_CASE_PARAMETERIZED(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY, PARAMS) \ do { \ struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY }; /* NOLINT(EVAL_FUNC_BODY) */ \ - addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, false, &Eval_##NAME::eval, DE_NULL, SHADER_SRC)); \ - addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, false,&Eval_##NAME::eval, DE_NULL, SHADER_SRC)); \ + addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, false, &Eval_##NAME::eval, DE_NULL, SHADER_SRC, PARAMS)); \ + addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, false,&Eval_##NAME::eval, DE_NULL, SHADER_SRC, PARAMS));\ } while (deGetFalse()) + #define LOCAL_STRUCT_CASE(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY) \ + LOCAL_STRUCT_CASE_PARAMETERIZED(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY, DE_NULL) + LOCAL_STRUCT_CASE(basic, "Basic struct usage", LineStream() << "${HEADER}" @@ -500,6 +505,63 @@ void LocalStructTests::init (void) c.color.xyz() = c.coords.swizzle(0,1,2); }); + LineStream inoutSrc; + inoutSrc + << "${HEADER}" + << "" + << "struct S {" + << " ${PRECISION} vec3 red;" + << " ${PRECISION} vec3 blue;" + << "};" + << "" + << "void modify (inout S s)" + << "{" + << " s.red += vec3(0.5, 0.0, 0.0);" + << " s.blue += vec3(0.0, 0.0, 0.5);" + << "}" + << "" + << "void main (void)" + << "{" + << " S s;" + << " s.red = vec3(0.5, 0.0, 0.0);" + << " s.blue = vec3(0.0, 0.0, 0.5);" + << " modify(s);" + << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);" + << " if (s.red == vec3(1.0, 0.0, 0.0) && s.blue == vec3(0.0, 0.0, 1.0))" + << " ${DST} = vec4(1.0, 1.0, 1.0, 1.0);" + << " ${ASSIGN_POS}" + << "}"; + + + std::map precisionParams; + + precisionParams["PRECISION"] = "lowp"; + LOCAL_STRUCT_CASE_PARAMETERIZED( + parameter_inout_lowp, "Struct with lowp members as an inout function parameter", + inoutSrc, + { + c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0); + }, + &precisionParams); + + precisionParams["PRECISION"] = "mediump"; + LOCAL_STRUCT_CASE_PARAMETERIZED( + parameter_inout_mediump, "Struct with mediump members as an inout function parameter", + inoutSrc, + { + c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0); + }, + &precisionParams); + + precisionParams["PRECISION"] = "highp"; + LOCAL_STRUCT_CASE_PARAMETERIZED( + parameter_inout_highp, "Struct with highp members as an inout function parameter", + inoutSrc, + { + c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0); + }, + &precisionParams); + LOCAL_STRUCT_CASE(parameter_nested, "Nested struct as a function parameter", LineStream() << "${HEADER}" @@ -532,6 +594,58 @@ void LocalStructTests::init (void) c.color.xyz() = c.coords.swizzle(0,1,2); }); + LineStream outSrc; + outSrc + << "${HEADER}" + << "" + << "struct S {" + << " ${PRECISION} vec3 red;" + << " ${PRECISION} vec3 blue;" + << "};" + << "" + << "void modify (out S s)" + << "{" + << " s.red = vec3(1.0, 0.0, 0.0);" + << " s.blue = vec3(0.0, 0.0, 1.0);" + << "}" + << "" + << "void main (void)" + << "{" + << " S s;" + << " modify(s);" + << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);" + << " if (s.red == vec3(1.0, 0.0, 0.0) && s.blue == vec3(0.0, 0.0, 1.0))" + << " ${DST} = vec4(1.0, 1.0, 1.0, 1.0);" + << " ${ASSIGN_POS}" + << "}"; + + precisionParams["PRECISION"] = "lowp"; + LOCAL_STRUCT_CASE_PARAMETERIZED( + parameter_out_lowp, "Struct with lowp members as an out function parameter", + outSrc, + { + c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0); + }, + &precisionParams); + + precisionParams["PRECISION"] = "mediump"; + LOCAL_STRUCT_CASE_PARAMETERIZED( + parameter_out_mediump, "Struct with mediump members as an out function parameter", + outSrc, + { + c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0); + }, + &precisionParams); + + precisionParams["PRECISION"] = "highp"; + LOCAL_STRUCT_CASE_PARAMETERIZED( + parameter_out_highp, "Struct with highp members as an out function parameter", + outSrc, + { + c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0); + }, + &precisionParams); + LOCAL_STRUCT_CASE(return, "Struct as a return value", LineStream() << "${HEADER}" @@ -1228,8 +1342,8 @@ void UniformStructTests::init (void) static void setUniforms (const glw::Functions& gl, deUint32 programID, const tcu::Vec4& constCoords) SET_UNIFORMS_BODY /* NOLINT(SET_UNIFORMS_BODY) */ \ }; \ struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY }; /* NOLINT(EVAL_FUNC_BODY) */ \ - addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, TEXTURES, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC)); \ - addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, TEXTURES, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC)); \ + addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, TEXTURES, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC, DE_NULL));\ + addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, TEXTURES, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC, DE_NULL));\ } while (deGetFalse()) UNIFORM_STRUCT_CASE(basic, "Basic struct usage", false,