Skip to content

Commit

Permalink
Add cases for structs as inout and out parameters.
Browse files Browse the repository at this point in the history
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 mrdoob/three.js#14137 .
Similar tests were integrated into the WebGL conformance suite in
KhronosGroup/WebGL#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
(cherry picked from commit 3b0365b)
  • Loading branch information
kenrussell authored and chrisforbes committed Aug 25, 2018
1 parent 69740b4 commit e9540af
Show file tree
Hide file tree
Showing 6 changed files with 291 additions and 12 deletions.
12 changes: 12 additions & 0 deletions android/cts/master/gles2-master.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions android/cts/master/gles3-master.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16259,8 +16259,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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7800,8 +7800,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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16431,8 +16431,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
Expand Down
129 changes: 123 additions & 6 deletions modules/gles2/functional/es2fShaderStructTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand All @@ -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<std::string, std::string>* additionalParams)
{
static const char* defaultVertSrc =
"attribute highp vec4 a_position;\n"
Expand Down Expand Up @@ -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);
Expand All @@ -209,13 +216,16 @@ class LocalStructTests : public TestCaseGroup

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}"
Expand Down Expand Up @@ -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<std::string, std::string> 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}"
Expand Down Expand Up @@ -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}"
Expand Down Expand Up @@ -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,
Expand Down
Loading

0 comments on commit e9540af

Please sign in to comment.