You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
592 lines
18 KiB
592 lines
18 KiB
/*-------------------------------------------------------------------------
|
|
* drawElements Quality Program OpenGL ES 3.0 Module
|
|
* -------------------------------------------------
|
|
*
|
|
* Copyright 2014 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 gl_FragDepth tests.
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "es3fFragDepthTests.hpp"
|
|
#include "tcuVector.hpp"
|
|
#include "tcuTestLog.hpp"
|
|
#include "tcuSurface.hpp"
|
|
#include "tcuImageCompare.hpp"
|
|
#include "tcuRenderTarget.hpp"
|
|
#include "gluPixelTransfer.hpp"
|
|
#include "gluShaderProgram.hpp"
|
|
#include "gluDrawUtil.hpp"
|
|
#include "deRandom.hpp"
|
|
#include "deMath.h"
|
|
#include "deString.h"
|
|
|
|
// For setupDefaultUniforms()
|
|
#include "glsShaderRenderCase.hpp"
|
|
|
|
#include "glwEnums.hpp"
|
|
#include "glwFunctions.hpp"
|
|
|
|
namespace deqp
|
|
{
|
|
namespace gles3
|
|
{
|
|
namespace Functional
|
|
{
|
|
|
|
using tcu::Vec2;
|
|
using tcu::Vec3;
|
|
using tcu::Vec4;
|
|
using tcu::TestLog;
|
|
using std::string;
|
|
using std::vector;
|
|
|
|
typedef float (*EvalFragDepthFunc) (const Vec2& coord);
|
|
|
|
static const char* s_vertexShaderSrc =
|
|
"#version 300 es\n"
|
|
"in highp vec4 a_position;\n"
|
|
"in highp vec2 a_coord;\n"
|
|
"out highp vec2 v_coord;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" gl_Position = a_position;\n"
|
|
" v_coord = a_coord;\n"
|
|
"}\n";
|
|
static const char* s_defaultFragmentShaderSrc =
|
|
"#version 300 es\n"
|
|
"uniform highp vec4 u_color;\n"
|
|
"layout(location = 0) out mediump vec4 o_color;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" o_color = u_color;\n"
|
|
"}\n";
|
|
|
|
template <typename T>
|
|
static inline bool compare (deUint32 func, T a, T b)
|
|
{
|
|
switch (func)
|
|
{
|
|
case GL_NEVER: return false;
|
|
case GL_ALWAYS: return true;
|
|
case GL_LESS: return a < b;
|
|
case GL_LEQUAL: return a <= b;
|
|
case GL_EQUAL: return a == b;
|
|
case GL_NOTEQUAL: return a != b;
|
|
case GL_GEQUAL: return a >= b;
|
|
case GL_GREATER: return a > b;
|
|
default:
|
|
DE_ASSERT(DE_FALSE);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
class FragDepthCompareCase : public TestCase
|
|
{
|
|
public:
|
|
FragDepthCompareCase (Context& context, const char* name, const char* desc, const char* fragSrc, EvalFragDepthFunc evalFunc, deUint32 compareFunc);
|
|
~FragDepthCompareCase (void);
|
|
|
|
IterateResult iterate (void);
|
|
|
|
private:
|
|
string m_fragSrc;
|
|
EvalFragDepthFunc m_evalFunc;
|
|
deUint32 m_compareFunc;
|
|
};
|
|
|
|
FragDepthCompareCase::FragDepthCompareCase (Context& context, const char* name, const char* desc, const char* fragSrc, EvalFragDepthFunc evalFunc, deUint32 compareFunc)
|
|
: TestCase (context, name, desc)
|
|
, m_fragSrc (fragSrc)
|
|
, m_evalFunc (evalFunc)
|
|
, m_compareFunc (compareFunc)
|
|
{
|
|
}
|
|
|
|
FragDepthCompareCase::~FragDepthCompareCase (void)
|
|
{
|
|
}
|
|
|
|
FragDepthCompareCase::IterateResult FragDepthCompareCase::iterate (void)
|
|
{
|
|
TestLog& log = m_testCtx.getLog();
|
|
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
|
|
de::Random rnd (deStringHash(getName()));
|
|
const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
|
|
int viewportW = de::min(128, renderTarget.getWidth());
|
|
int viewportH = de::min(128, renderTarget.getHeight());
|
|
int viewportX = rnd.getInt(0, renderTarget.getWidth()-viewportW);
|
|
int viewportY = rnd.getInt(0, renderTarget.getHeight()-viewportH);
|
|
tcu::Surface renderedFrame (viewportW, viewportH);
|
|
tcu::Surface referenceFrame (viewportW, viewportH);
|
|
const float constDepth = 0.1f;
|
|
|
|
if (renderTarget.getDepthBits() == 0)
|
|
throw tcu::NotSupportedError("Depth buffer is required", "", __FILE__, __LINE__);
|
|
|
|
gl.viewport(viewportX, viewportY, viewportW, viewportH);
|
|
gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
|
|
gl.enable(GL_DEPTH_TEST);
|
|
|
|
static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 };
|
|
|
|
// Fill viewport with 2 quads - one with constant depth and another with d = [-1..1]
|
|
{
|
|
glu::ShaderProgram basicQuadProgram(m_context.getRenderContext(), glu::makeVtxFragSources(s_vertexShaderSrc, s_defaultFragmentShaderSrc));
|
|
|
|
if (!basicQuadProgram.isOk())
|
|
{
|
|
log << basicQuadProgram;
|
|
TCU_FAIL("Compile failed");
|
|
}
|
|
|
|
const float constDepthCoord[] =
|
|
{
|
|
-1.0f, -1.0f, constDepth, 1.0f,
|
|
-1.0f, +1.0f, constDepth, 1.0f,
|
|
0.0f, -1.0f, constDepth, 1.0f,
|
|
0.0f, +1.0f, constDepth, 1.0f
|
|
};
|
|
const float varyingDepthCoord[] =
|
|
{
|
|
0.0f, -1.0f, +1.0f, 1.0f,
|
|
0.0f, +1.0f, 0.0f, 1.0f,
|
|
+1.0f, -1.0f, 0.0f, 1.0f,
|
|
+1.0f, +1.0f, -1.0f, 1.0f
|
|
};
|
|
|
|
gl.useProgram(basicQuadProgram.getProgram());
|
|
gl.uniform4f(gl.getUniformLocation(basicQuadProgram.getProgram(), "u_color"), 0.0f, 0.0f, 1.0f, 1.0f);
|
|
gl.depthFunc(GL_ALWAYS);
|
|
|
|
{
|
|
glu::VertexArrayBinding posBinding = glu::va::Float("a_position", 4, 4, 0, &constDepthCoord[0]);
|
|
glu::draw(m_context.getRenderContext(), basicQuadProgram.getProgram(), 1, &posBinding,
|
|
glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
|
|
}
|
|
|
|
{
|
|
glu::VertexArrayBinding posBinding = glu::va::Float("a_position", 4, 4, 0, &varyingDepthCoord[0]);
|
|
glu::draw(m_context.getRenderContext(), basicQuadProgram.getProgram(), 1, &posBinding,
|
|
glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
|
|
}
|
|
|
|
GLU_EXPECT_NO_ERROR(gl.getError(), "Draw base quads");
|
|
}
|
|
|
|
// Render with depth test.
|
|
{
|
|
glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(s_vertexShaderSrc, m_fragSrc.c_str()));
|
|
log << program;
|
|
|
|
if (!program.isOk())
|
|
TCU_FAIL("Compile failed");
|
|
|
|
const float coord[] =
|
|
{
|
|
0.0f, 0.0f,
|
|
0.0f, 1.0f,
|
|
1.0f, 0.0f,
|
|
1.0f, 1.0f
|
|
};
|
|
const float position[] =
|
|
{
|
|
-1.0f, -1.0f, +1.0f, 1.0f,
|
|
-1.0f, +1.0f, 0.0f, 1.0f,
|
|
+1.0f, -1.0f, 0.0f, 1.0f,
|
|
+1.0f, +1.0f, -1.0f, 1.0f
|
|
};
|
|
|
|
gl.useProgram(program.getProgram());
|
|
gl.depthFunc(m_compareFunc);
|
|
gl.uniform4f(gl.getUniformLocation(program.getProgram(), "u_color"), 0.0f, 1.0f, 0.0f, 1.0f);
|
|
|
|
// Setup default helper uniforms.
|
|
gls::setupDefaultUniforms(m_context.getRenderContext(), program.getProgram());
|
|
|
|
{
|
|
glu::VertexArrayBinding vertexArrays[] =
|
|
{
|
|
glu::va::Float("a_position", 4, 4, 0, &position[0]),
|
|
glu::va::Float("a_coord", 2, 4, 0, &coord[0])
|
|
};
|
|
glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
|
|
glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
|
|
}
|
|
|
|
GLU_EXPECT_NO_ERROR(gl.getError(), "Draw test quad");
|
|
}
|
|
|
|
glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedFrame.getAccess());
|
|
|
|
// Render reference.
|
|
for (int y = 0; y < referenceFrame.getHeight(); y++)
|
|
{
|
|
float yf = ((float)y + 0.5f) / (float)referenceFrame.getHeight();
|
|
int half = de::clamp((int)((float)referenceFrame.getWidth()*0.5f + 0.5f), 0, referenceFrame.getWidth());
|
|
|
|
// Fill left half - comparison to constant 0.5
|
|
for (int x = 0; x < half; x++)
|
|
{
|
|
float xf = ((float)x + 0.5f) / (float)referenceFrame.getWidth();
|
|
float d = m_evalFunc(Vec2(xf, yf));
|
|
bool dpass = compare(m_compareFunc, d, constDepth*0.5f + 0.5f);
|
|
|
|
referenceFrame.setPixel(x, y, dpass ? tcu::RGBA::green() : tcu::RGBA::blue());
|
|
}
|
|
|
|
// Fill right half - comparison to interpolated depth
|
|
for (int x = half; x < referenceFrame.getWidth(); x++)
|
|
{
|
|
float xf = ((float)x + 0.5f) / (float)referenceFrame.getWidth();
|
|
float xh = ((float)(x - half) + 0.5f) / (float)(referenceFrame.getWidth()-half);
|
|
float rd = 1.0f - (xh + yf) * 0.5f;
|
|
float d = m_evalFunc(Vec2(xf, yf));
|
|
bool dpass = compare(m_compareFunc, d, rd);
|
|
|
|
referenceFrame.setPixel(x, y, dpass ? tcu::RGBA::green() : tcu::RGBA::blue());
|
|
}
|
|
}
|
|
|
|
bool isOk = tcu::fuzzyCompare(log, "Result", "Image comparison result", referenceFrame, renderedFrame, 0.05f, tcu::COMPARE_LOG_RESULT);
|
|
m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
|
|
isOk ? "Pass" : "Fail");
|
|
return STOP;
|
|
}
|
|
|
|
class FragDepthWriteCase : public TestCase
|
|
{
|
|
public:
|
|
FragDepthWriteCase (Context& context, const char* name, const char* desc, const char* fragSrc, EvalFragDepthFunc evalFunc);
|
|
~FragDepthWriteCase (void);
|
|
|
|
IterateResult iterate (void);
|
|
|
|
private:
|
|
string m_fragSrc;
|
|
EvalFragDepthFunc m_evalFunc;
|
|
};
|
|
|
|
FragDepthWriteCase::FragDepthWriteCase (Context& context, const char* name, const char* desc, const char* fragSrc, EvalFragDepthFunc evalFunc)
|
|
: TestCase (context, name, desc)
|
|
, m_fragSrc (fragSrc)
|
|
, m_evalFunc (evalFunc)
|
|
{
|
|
}
|
|
|
|
FragDepthWriteCase::~FragDepthWriteCase (void)
|
|
{
|
|
}
|
|
|
|
FragDepthWriteCase::IterateResult FragDepthWriteCase::iterate (void)
|
|
{
|
|
TestLog& log = m_testCtx.getLog();
|
|
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
|
|
de::Random rnd (deStringHash(getName()));
|
|
const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
|
|
int viewportW = de::min(128, renderTarget.getWidth());
|
|
int viewportH = de::min(128, renderTarget.getHeight());
|
|
int viewportX = rnd.getInt(0, renderTarget.getWidth()-viewportW);
|
|
int viewportY = rnd.getInt(0, renderTarget.getHeight()-viewportH);
|
|
tcu::Surface renderedFrame (viewportW, viewportH);
|
|
tcu::Surface referenceFrame (viewportW, viewportH);
|
|
const int numDepthSteps = 16;
|
|
const float depthStep = 1.0f/(float)(numDepthSteps-1);
|
|
|
|
if (renderTarget.getDepthBits() == 0)
|
|
throw tcu::NotSupportedError("Depth buffer is required", "", __FILE__, __LINE__);
|
|
|
|
gl.viewport(viewportX, viewportY, viewportW, viewportH);
|
|
gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
|
|
gl.enable(GL_DEPTH_TEST);
|
|
gl.depthFunc(GL_LESS);
|
|
|
|
static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 };
|
|
|
|
// Render with given shader.
|
|
{
|
|
glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(s_vertexShaderSrc, m_fragSrc.c_str()));
|
|
log << program;
|
|
|
|
if (!program.isOk())
|
|
TCU_FAIL("Compile failed");
|
|
|
|
const float coord[] =
|
|
{
|
|
0.0f, 0.0f,
|
|
0.0f, 1.0f,
|
|
1.0f, 0.0f,
|
|
1.0f, 1.0f
|
|
};
|
|
const float position[] =
|
|
{
|
|
-1.0f, -1.0f, +1.0f, 1.0f,
|
|
-1.0f, +1.0f, 0.0f, 1.0f,
|
|
+1.0f, -1.0f, 0.0f, 1.0f,
|
|
+1.0f, +1.0f, -1.0f, 1.0f
|
|
};
|
|
|
|
gl.useProgram(program.getProgram());
|
|
gl.uniform4f(gl.getUniformLocation(program.getProgram(), "u_color"), 0.0f, 1.0f, 0.0f, 1.0f);
|
|
|
|
// Setup default helper uniforms.
|
|
gls::setupDefaultUniforms(m_context.getRenderContext(), program.getProgram());
|
|
|
|
{
|
|
glu::VertexArrayBinding vertexArrays[] =
|
|
{
|
|
glu::va::Float("a_position", 4, 4, 0, &position[0]),
|
|
glu::va::Float("a_coord", 2, 4, 0, &coord[0])
|
|
};
|
|
glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
|
|
glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
|
|
}
|
|
|
|
GLU_EXPECT_NO_ERROR(gl.getError(), "Draw test quad");
|
|
}
|
|
|
|
// Visualize by rendering full-screen quads with increasing depth and color.
|
|
{
|
|
glu::ShaderProgram program (m_context.getRenderContext(), glu::makeVtxFragSources(s_vertexShaderSrc, s_defaultFragmentShaderSrc));
|
|
if (!program.isOk())
|
|
{
|
|
log << program;
|
|
TCU_FAIL("Compile failed");
|
|
}
|
|
|
|
int posLoc = gl.getAttribLocation(program.getProgram(), "a_position");
|
|
int colorLoc = gl.getUniformLocation(program.getProgram(), "u_color");
|
|
|
|
gl.useProgram(program.getProgram());
|
|
gl.depthMask(GL_FALSE);
|
|
|
|
for (int stepNdx = 0; stepNdx < numDepthSteps; stepNdx++)
|
|
{
|
|
float f = (float)stepNdx*depthStep;
|
|
float depth = f*2.0f - 1.0f;
|
|
Vec4 color = Vec4(f, f, f, 1.0f);
|
|
|
|
const float position[] =
|
|
{
|
|
-1.0f, -1.0f, depth, 1.0f,
|
|
-1.0f, +1.0f, depth, 1.0f,
|
|
+1.0f, -1.0f, depth, 1.0f,
|
|
+1.0f, +1.0f, depth, 1.0f
|
|
};
|
|
glu::VertexArrayBinding posBinding = glu::va::Float(posLoc, 4, 4, 0, &position[0]);
|
|
|
|
gl.uniform4fv(colorLoc, 1, color.getPtr());
|
|
glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
|
|
glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
|
|
}
|
|
|
|
GLU_EXPECT_NO_ERROR(gl.getError(), "Visualization draw");
|
|
}
|
|
|
|
glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedFrame.getAccess());
|
|
|
|
// Render reference.
|
|
for (int y = 0; y < referenceFrame.getHeight(); y++)
|
|
{
|
|
for (int x = 0; x < referenceFrame.getWidth(); x++)
|
|
{
|
|
float xf = ((float)x + 0.5f) / (float)referenceFrame.getWidth();
|
|
float yf = ((float)y + 0.5f) / (float)referenceFrame.getHeight();
|
|
float d = m_evalFunc(Vec2(xf, yf));
|
|
int step = (int)deFloatFloor(d / depthStep);
|
|
int col = de::clamp(deRoundFloatToInt32((float)step*depthStep*255.0f), 0, 255);
|
|
|
|
referenceFrame.setPixel(x, y, tcu::RGBA(col, col, col, 0xff));
|
|
}
|
|
}
|
|
|
|
bool isOk = tcu::fuzzyCompare(log, "Result", "Image comparison result", referenceFrame, renderedFrame, 0.05f, tcu::COMPARE_LOG_RESULT);
|
|
m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
|
|
isOk ? "Pass" : "Fail");
|
|
return STOP;
|
|
}
|
|
|
|
FragDepthTests::FragDepthTests (Context& context)
|
|
: TestCaseGroup(context, "fragdepth", "gl_FragDepth tests")
|
|
{
|
|
}
|
|
|
|
FragDepthTests::~FragDepthTests (void)
|
|
{
|
|
}
|
|
|
|
static float evalConstDepth (const Vec2& coord) { DE_UNREF(coord); return 0.5f; }
|
|
static float evalDynamicDepth (const Vec2& coord) { return (coord.x()+coord.y())*0.5f; }
|
|
static float evalNoWrite (const Vec2& coord) { return 1.0f - (coord.x()+coord.y())*0.5f; }
|
|
|
|
static float evalDynamicConditionalDepth (const Vec2& coord)
|
|
{
|
|
float d = (coord.x()+coord.y())*0.5f;
|
|
if (coord.y() < 0.5f)
|
|
return d;
|
|
else
|
|
return 1.0f - d;
|
|
}
|
|
|
|
void FragDepthTests::init (void)
|
|
{
|
|
static const struct
|
|
{
|
|
const char* name;
|
|
const char* desc;
|
|
EvalFragDepthFunc evalFunc;
|
|
const char* fragSrc;
|
|
} cases[] =
|
|
{
|
|
{
|
|
"no_write", "No gl_FragDepth write", evalNoWrite,
|
|
"#version 300 es\n"
|
|
"uniform highp vec4 u_color;\n"
|
|
"layout(location = 0) out mediump vec4 o_color;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" o_color = u_color;\n"
|
|
"}\n"
|
|
},
|
|
{
|
|
"const", "Const depth write", evalConstDepth,
|
|
"#version 300 es\n"
|
|
"uniform highp vec4 u_color;\n"
|
|
"layout(location = 0) out mediump vec4 o_color;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" o_color = u_color;\n"
|
|
" gl_FragDepth = 0.5;\n"
|
|
"}\n"
|
|
},
|
|
{
|
|
"uniform", "Uniform depth write", evalConstDepth,
|
|
"#version 300 es\n"
|
|
"uniform highp vec4 u_color;\n"
|
|
"uniform highp float uf_half;\n"
|
|
"layout(location = 0) out mediump vec4 o_color;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" o_color = u_color;\n"
|
|
" gl_FragDepth = uf_half;\n"
|
|
"}\n"
|
|
},
|
|
{
|
|
"dynamic", "Dynamic depth write", evalDynamicDepth,
|
|
"#version 300 es\n"
|
|
"uniform highp vec4 u_color;\n"
|
|
"in highp vec2 v_coord;\n"
|
|
"layout(location = 0) out mediump vec4 o_color;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" o_color = u_color;\n"
|
|
" gl_FragDepth = (v_coord.x+v_coord.y)*0.5;\n"
|
|
"}\n"
|
|
},
|
|
{
|
|
"fragcoord_z", "gl_FragDepth write from gl_FragCoord.z", evalNoWrite,
|
|
"#version 300 es\n"
|
|
"uniform highp vec4 u_color;\n"
|
|
"layout(location = 0) out mediump vec4 o_color;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" o_color = u_color;\n"
|
|
" gl_FragDepth = gl_FragCoord.z;\n"
|
|
"}\n"
|
|
},
|
|
{
|
|
"uniform_conditional_write", "Uniform conditional write", evalDynamicDepth,
|
|
"#version 300 es\n"
|
|
"uniform highp vec4 u_color;\n"
|
|
"uniform bool ub_true;\n"
|
|
"in highp vec2 v_coord;\n"
|
|
"layout(location = 0) out mediump vec4 o_color;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" o_color = u_color;\n"
|
|
" if (ub_true)\n"
|
|
" gl_FragDepth = (v_coord.x+v_coord.y)*0.5;\n"
|
|
"}\n"
|
|
},
|
|
{
|
|
"dynamic_conditional_write", "Uniform conditional write", evalDynamicConditionalDepth,
|
|
"#version 300 es\n"
|
|
"uniform highp vec4 u_color;\n"
|
|
"uniform bool ub_true;\n"
|
|
"in highp vec2 v_coord;\n"
|
|
"layout(location = 0) out mediump vec4 o_color;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" o_color = u_color;\n"
|
|
" mediump float d = (v_coord.x+v_coord.y)*0.5f;\n"
|
|
" if (v_coord.y < 0.5)\n"
|
|
" gl_FragDepth = d;\n"
|
|
" else\n"
|
|
" gl_FragDepth = 1.0 - d;\n"
|
|
"}\n"
|
|
},
|
|
{
|
|
"uniform_loop_write", "Uniform loop write", evalConstDepth,
|
|
"#version 300 es\n"
|
|
"uniform highp vec4 u_color;\n"
|
|
"uniform int ui_two;\n"
|
|
"uniform highp float uf_fourth;\n"
|
|
"in highp vec2 v_coord;\n"
|
|
"layout(location = 0) out mediump vec4 o_color;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" o_color = u_color;\n"
|
|
" gl_FragDepth = 0.0;\n"
|
|
" for (int i = 0; i < ui_two; i++)\n"
|
|
" gl_FragDepth += uf_fourth;\n"
|
|
"}\n"
|
|
},
|
|
{
|
|
"write_in_function", "Uniform loop write", evalDynamicDepth,
|
|
"#version 300 es\n"
|
|
"uniform highp vec4 u_color;\n"
|
|
"uniform highp float uf_half;\n"
|
|
"in highp vec2 v_coord;\n"
|
|
"layout(location = 0) out mediump vec4 o_color;\n"
|
|
"void myfunc (highp vec2 coord)\n"
|
|
"{\n"
|
|
" gl_FragDepth = (coord.x+coord.y)*0.5;\n"
|
|
"}\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" o_color = u_color;\n"
|
|
" myfunc(v_coord);\n"
|
|
"}\n"
|
|
}
|
|
};
|
|
|
|
// .write
|
|
tcu::TestCaseGroup* writeGroup = new tcu::TestCaseGroup(m_testCtx, "write", "gl_FragDepth write tests");
|
|
addChild(writeGroup);
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
|
|
writeGroup->addChild(new FragDepthWriteCase(m_context, cases[ndx].name, cases[ndx].desc, cases[ndx].fragSrc, cases[ndx].evalFunc));
|
|
|
|
// .compare
|
|
tcu::TestCaseGroup* compareGroup = new tcu::TestCaseGroup(m_testCtx, "compare", "gl_FragDepth used with depth comparison");
|
|
addChild(compareGroup);
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
|
|
compareGroup->addChild(new FragDepthCompareCase(m_context, cases[ndx].name, cases[ndx].desc, cases[ndx].fragSrc, cases[ndx].evalFunc, GL_LESS));
|
|
}
|
|
|
|
} // Functional
|
|
} // gles3
|
|
} // deqp
|