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.
1053 lines
35 KiB
1053 lines
35 KiB
/*-------------------------------------------------------------------------
|
|
* drawElements Quality Program OpenGL ES 3.1 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 Stencil texturing tests.
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "es31fStencilTexturingTests.hpp"
|
|
|
|
#include "gluStrUtil.hpp"
|
|
#include "gluObjectWrapper.hpp"
|
|
#include "gluRenderContext.hpp"
|
|
#include "gluShaderProgram.hpp"
|
|
#include "gluDrawUtil.hpp"
|
|
#include "gluPixelTransfer.hpp"
|
|
#include "gluTextureUtil.hpp"
|
|
#include "gluContextInfo.hpp"
|
|
|
|
#include "glsTextureTestUtil.hpp"
|
|
|
|
#include "tcuVector.hpp"
|
|
#include "tcuTexture.hpp"
|
|
#include "tcuTextureUtil.hpp"
|
|
#include "tcuTestLog.hpp"
|
|
#include "tcuTexLookupVerifier.hpp"
|
|
|
|
#include "glwFunctions.hpp"
|
|
#include "glwEnums.hpp"
|
|
|
|
#include "deStringUtil.hpp"
|
|
|
|
namespace deqp
|
|
{
|
|
namespace gles31
|
|
{
|
|
namespace Functional
|
|
{
|
|
|
|
using std::vector;
|
|
using std::string;
|
|
using tcu::IVec4;
|
|
using tcu::Vec2;
|
|
using tcu::Vec4;
|
|
using tcu::TestLog;
|
|
using tcu::TextureLevel;
|
|
using tcu::TextureFormat;
|
|
|
|
namespace
|
|
{
|
|
|
|
static void genTestRects (vector<IVec4>& rects, int width, int height)
|
|
{
|
|
int curWidth = width;
|
|
int curHeight = height;
|
|
int ndx = 0;
|
|
|
|
for (;;)
|
|
{
|
|
rects.push_back(IVec4(width-curWidth, height-curHeight, curWidth, curHeight));
|
|
|
|
DE_ASSERT(curWidth >= 1 && curHeight >= 1);
|
|
if (curWidth == 1 && curHeight == 1)
|
|
break;
|
|
else if (curHeight > 1 && ((ndx%2) == 0 || curWidth == 1))
|
|
curHeight -= 1;
|
|
else
|
|
curWidth -= 1;
|
|
|
|
ndx += 1;
|
|
}
|
|
}
|
|
|
|
static void rectsToTriangles (const vector<IVec4>& rects, int width, int height, vector<Vec2>& positions, vector<deUint16>& indices)
|
|
{
|
|
const float w = float(width);
|
|
const float h = float(height);
|
|
|
|
positions.resize(rects.size()*4);
|
|
indices.resize(rects.size()*6);
|
|
|
|
for (int rectNdx = 0; rectNdx < (int)rects.size(); rectNdx++)
|
|
{
|
|
const int rx = rects[rectNdx].x();
|
|
const int ry = rects[rectNdx].y();
|
|
const int rw = rects[rectNdx].z();
|
|
const int rh = rects[rectNdx].w();
|
|
|
|
const float x0 = float(rx*2)/w - 1.0f;
|
|
const float x1 = float((rx+rw)*2)/w - 1.0f;
|
|
const float y0 = float(ry*2)/h - 1.0f;
|
|
const float y1 = float((ry+rh)*2)/h - 1.0f;
|
|
|
|
positions[rectNdx*4 + 0] = Vec2(x0, y0);
|
|
positions[rectNdx*4 + 1] = Vec2(x1, y0);
|
|
positions[rectNdx*4 + 2] = Vec2(x0, y1);
|
|
positions[rectNdx*4 + 3] = Vec2(x1, y1);
|
|
|
|
indices[rectNdx*6 + 0] = (deUint16)(rectNdx*4 + 0);
|
|
indices[rectNdx*6 + 1] = (deUint16)(rectNdx*4 + 1);
|
|
indices[rectNdx*6 + 2] = (deUint16)(rectNdx*4 + 2);
|
|
indices[rectNdx*6 + 3] = (deUint16)(rectNdx*4 + 2);
|
|
indices[rectNdx*6 + 4] = (deUint16)(rectNdx*4 + 1);
|
|
indices[rectNdx*6 + 5] = (deUint16)(rectNdx*4 + 3);
|
|
}
|
|
}
|
|
|
|
static void drawTestPattern (const glu::RenderContext& renderCtx, int width, int height)
|
|
{
|
|
const glu::ShaderProgram program(renderCtx, glu::ProgramSources()
|
|
<< glu::VertexSource(
|
|
"#version 300 es\n"
|
|
"in highp vec4 a_position;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" gl_Position = a_position;\n"
|
|
"}\n")
|
|
<< glu::FragmentSource(
|
|
"#version 300 es\n"
|
|
"void main (void) {}\n"));
|
|
|
|
const glw::Functions& gl = renderCtx.getFunctions();
|
|
vector<IVec4> rects;
|
|
vector<Vec2> positions;
|
|
vector<deUint16> indices;
|
|
|
|
if (!program.isOk())
|
|
throw tcu::TestError("Compile failed");
|
|
|
|
gl.useProgram (program.getProgram());
|
|
gl.viewport (0, 0, width, height);
|
|
gl.clear (GL_STENCIL_BUFFER_BIT);
|
|
gl.enable (GL_STENCIL_TEST);
|
|
gl.stencilOp (GL_KEEP, GL_KEEP, GL_INCR_WRAP);
|
|
gl.stencilFunc (GL_ALWAYS, 0, ~0u);
|
|
GLU_EXPECT_NO_ERROR(gl.getError(), "State setup failed");
|
|
|
|
genTestRects (rects, width, height);
|
|
rectsToTriangles(rects, width, height, positions, indices);
|
|
|
|
{
|
|
const glu::VertexArrayBinding posBinding = glu::va::Float("a_position", 2, (int)positions.size(), 0, positions[0].getPtr());
|
|
glu::draw(renderCtx, program.getProgram(), 1, &posBinding, glu::pr::Triangles((int)indices.size(), &indices[0]));
|
|
}
|
|
|
|
gl.disable(GL_STENCIL_TEST);
|
|
}
|
|
|
|
static void renderTestPatternReference (const tcu::PixelBufferAccess& dst)
|
|
{
|
|
const int stencilBits = tcu::getTextureFormatBitDepth(tcu::getEffectiveDepthStencilAccess(dst, tcu::Sampler::MODE_STENCIL).getFormat()).x();
|
|
const deUint32 stencilMask = (1u<<stencilBits)-1u;
|
|
vector<IVec4> rects;
|
|
|
|
DE_ASSERT(dst.getFormat().order == TextureFormat::S || dst.getFormat().order == TextureFormat::DS);
|
|
|
|
// clear depth and stencil
|
|
if (dst.getFormat().order == TextureFormat::DS)
|
|
tcu::clearDepth(dst, 0.0f);
|
|
tcu::clearStencil(dst, 0u);
|
|
|
|
genTestRects(rects, dst.getWidth(), dst.getHeight());
|
|
|
|
for (vector<IVec4>::const_iterator rectIter = rects.begin(); rectIter != rects.end(); ++rectIter)
|
|
{
|
|
const int x0 = rectIter->x();
|
|
const int y0 = rectIter->y();
|
|
const int x1 = x0+rectIter->z();
|
|
const int y1 = y0+rectIter->w();
|
|
|
|
for (int y = y0; y < y1; y++)
|
|
{
|
|
for (int x = x0; x < x1; x++)
|
|
{
|
|
const int oldVal = dst.getPixStencil(x, y);
|
|
const int newVal = (oldVal+1)&stencilMask;
|
|
|
|
dst.setPixStencil(newVal, x, y);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void blitStencilToColor2D (const glu::RenderContext& renderCtx, deUint32 srcTex, int width, int height)
|
|
{
|
|
const glu::ShaderProgram program(renderCtx, glu::ProgramSources()
|
|
<< glu::VertexSource(
|
|
"#version 300 es\n"
|
|
"in highp vec4 a_position;\n"
|
|
"in highp vec2 a_texCoord;\n"
|
|
"out highp vec2 v_texCoord;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" gl_Position = a_position;\n"
|
|
" v_texCoord = a_texCoord;\n"
|
|
"}\n")
|
|
<< glu::FragmentSource(
|
|
"#version 300 es\n"
|
|
"uniform highp usampler2D u_sampler;\n"
|
|
"in highp vec2 v_texCoord;\n"
|
|
"layout(location = 0) out highp uint o_stencil;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" o_stencil = texture(u_sampler, v_texCoord).x;\n"
|
|
"}\n"));
|
|
|
|
const float positions[] =
|
|
{
|
|
-1.0f, -1.0f,
|
|
+1.0f, -1.0f,
|
|
-1.0f, +1.0f,
|
|
+1.0f, +1.0f
|
|
};
|
|
const float texCoord[] =
|
|
{
|
|
0.0f, 0.0f,
|
|
1.0f, 0.0f,
|
|
0.0f, 1.0f,
|
|
1.0f, 1.0f
|
|
};
|
|
const glu::VertexArrayBinding vertexArrays[] =
|
|
{
|
|
glu::va::Float("a_position", 2, 4, 0, &positions[0]),
|
|
glu::va::Float("a_texCoord", 2, 4, 0, &texCoord[0])
|
|
};
|
|
const deUint8 indices[] = { 0, 1, 2, 2, 1, 3 };
|
|
|
|
const glw::Functions& gl = renderCtx.getFunctions();
|
|
|
|
if (!program.isOk())
|
|
throw tcu::TestError("Compile failed");
|
|
|
|
gl.activeTexture(GL_TEXTURE0);
|
|
gl.bindTexture(GL_TEXTURE_2D, srcTex);
|
|
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
|
|
GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state setup failed");
|
|
|
|
gl.useProgram(program.getProgram());
|
|
gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_sampler"), 0);
|
|
GLU_EXPECT_NO_ERROR(gl.getError(), "Program setup failed");
|
|
|
|
gl.viewport(0, 0, width, height);
|
|
glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
|
|
glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
|
|
}
|
|
|
|
static void blitStencilToColor2DArray (const glu::RenderContext& renderCtx, deUint32 srcTex, int width, int height, int level)
|
|
{
|
|
const glu::ShaderProgram program(renderCtx, glu::ProgramSources()
|
|
<< glu::VertexSource(
|
|
"#version 300 es\n"
|
|
"in highp vec4 a_position;\n"
|
|
"in highp vec3 a_texCoord;\n"
|
|
"out highp vec3 v_texCoord;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" gl_Position = a_position;\n"
|
|
" v_texCoord = a_texCoord;\n"
|
|
"}\n")
|
|
<< glu::FragmentSource(
|
|
"#version 300 es\n"
|
|
"uniform highp usampler2DArray u_sampler;\n"
|
|
"in highp vec3 v_texCoord;\n"
|
|
"layout(location = 0) out highp uint o_stencil;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" o_stencil = texture(u_sampler, v_texCoord).x;\n"
|
|
"}\n"));
|
|
|
|
const float positions[] =
|
|
{
|
|
-1.0f, -1.0f,
|
|
+1.0f, -1.0f,
|
|
-1.0f, +1.0f,
|
|
+1.0f, +1.0f
|
|
};
|
|
const float texCoord[] =
|
|
{
|
|
0.0f, 0.0f, float(level),
|
|
1.0f, 0.0f, float(level),
|
|
0.0f, 1.0f, float(level),
|
|
1.0f, 1.0f, float(level)
|
|
};
|
|
const glu::VertexArrayBinding vertexArrays[] =
|
|
{
|
|
glu::va::Float("a_position", 2, 4, 0, &positions[0]),
|
|
glu::va::Float("a_texCoord", 3, 4, 0, &texCoord[0])
|
|
};
|
|
const deUint8 indices[] = { 0, 1, 2, 2, 1, 3 };
|
|
|
|
const glw::Functions& gl = renderCtx.getFunctions();
|
|
|
|
if (!program.isOk())
|
|
throw tcu::TestError("Compile failed");
|
|
|
|
gl.activeTexture(GL_TEXTURE0);
|
|
gl.bindTexture(GL_TEXTURE_2D_ARRAY, srcTex);
|
|
gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
|
|
GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state setup failed");
|
|
|
|
gl.useProgram(program.getProgram());
|
|
gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_sampler"), 0);
|
|
GLU_EXPECT_NO_ERROR(gl.getError(), "Program setup failed");
|
|
|
|
gl.viewport(0, 0, width, height);
|
|
glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
|
|
glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
|
|
}
|
|
|
|
static void blitStencilToColorCube (const glu::RenderContext& renderCtx, deUint32 srcTex, const float* texCoord, int width, int height)
|
|
{
|
|
const glu::ShaderProgram program(renderCtx, glu::ProgramSources()
|
|
<< glu::VertexSource(
|
|
"#version 300 es\n"
|
|
"in highp vec4 a_position;\n"
|
|
"in highp vec3 a_texCoord;\n"
|
|
"out highp vec3 v_texCoord;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" gl_Position = a_position;\n"
|
|
" v_texCoord = a_texCoord;\n"
|
|
"}\n")
|
|
<< glu::FragmentSource(
|
|
"#version 300 es\n"
|
|
"uniform highp usamplerCube u_sampler;\n"
|
|
"in highp vec3 v_texCoord;\n"
|
|
"layout(location = 0) out highp vec4 o_color;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" o_color.x = float(texture(u_sampler, v_texCoord).x) / 255.0;\n"
|
|
" o_color.yzw = vec3(0.0, 0.0, 1.0);\n"
|
|
"}\n"));
|
|
|
|
const float positions[] =
|
|
{
|
|
-1.0f, -1.0f,
|
|
-1.0f, +1.0f,
|
|
+1.0f, -1.0f,
|
|
+1.0f, +1.0f
|
|
};
|
|
const glu::VertexArrayBinding vertexArrays[] =
|
|
{
|
|
glu::va::Float("a_position", 2, 4, 0, &positions[0]),
|
|
glu::va::Float("a_texCoord", 3, 4, 0, texCoord)
|
|
};
|
|
const deUint8 indices[] = { 0, 1, 2, 2, 1, 3 };
|
|
|
|
const glw::Functions& gl = renderCtx.getFunctions();
|
|
|
|
if (!program.isOk())
|
|
throw tcu::TestError("Compile failed");
|
|
|
|
gl.activeTexture(GL_TEXTURE0);
|
|
gl.bindTexture(GL_TEXTURE_CUBE_MAP, srcTex);
|
|
gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
|
|
GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state setup failed");
|
|
|
|
gl.useProgram(program.getProgram());
|
|
gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_sampler"), 0);
|
|
GLU_EXPECT_NO_ERROR(gl.getError(), "Program setup failed");
|
|
|
|
gl.viewport(0, 0, width, height);
|
|
glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
|
|
glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
|
|
}
|
|
|
|
static inline tcu::ConstPixelBufferAccess stencilToRedAccess (const tcu::ConstPixelBufferAccess& access)
|
|
{
|
|
DE_ASSERT(access.getFormat() == TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8));
|
|
return tcu::ConstPixelBufferAccess(TextureFormat(TextureFormat::R, TextureFormat::UNSIGNED_INT8), access.getSize(), access.getPitch(), access.getDataPtr());
|
|
}
|
|
|
|
static bool compareStencilToRed (tcu::TestLog& log, const tcu::ConstPixelBufferAccess& stencilRef, const tcu::ConstPixelBufferAccess& result)
|
|
{
|
|
const int maxPrints = 10;
|
|
int numFailed = 0;
|
|
|
|
DE_ASSERT(stencilRef.getFormat().order == TextureFormat::S);
|
|
DE_ASSERT(stencilRef.getWidth() == result.getWidth() && stencilRef.getHeight() == result.getHeight());
|
|
|
|
for (int y = 0; y < stencilRef.getHeight(); y++)
|
|
{
|
|
for (int x = 0; x < stencilRef.getWidth(); x++)
|
|
{
|
|
const int ref = stencilRef.getPixStencil(x, y);
|
|
const int res = result.getPixelInt(x, y).x();
|
|
|
|
if (ref != res)
|
|
{
|
|
if (numFailed < maxPrints)
|
|
log << TestLog::Message << "ERROR: Expected " << ref << ", got " << res << " at (" << x << ", " << y << ")" << TestLog::EndMessage;
|
|
else if (numFailed == maxPrints)
|
|
log << TestLog::Message << "..." << TestLog::EndMessage;
|
|
|
|
numFailed += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
log << TestLog::Message << "Found " << numFailed << " faulty pixels, comparison " << (numFailed == 0 ? "passed." : "FAILED!") << TestLog::EndMessage;
|
|
|
|
log << TestLog::ImageSet("ComparisonResult", "Image comparison result")
|
|
<< TestLog::Image("Result", "Result stencil buffer", result);
|
|
|
|
if (numFailed > 0)
|
|
log << TestLog::Image("Reference", "Reference stencil buffer", stencilToRedAccess(stencilRef));
|
|
|
|
log << TestLog::EndImageSet;
|
|
|
|
return numFailed == 0;
|
|
}
|
|
|
|
static bool compareRedChannel (tcu::TestLog& log, const tcu::ConstPixelBufferAccess& result, int reference)
|
|
{
|
|
const int maxPrints = 10;
|
|
int numFailed = 0;
|
|
|
|
for (int y = 0; y < result.getHeight(); y++)
|
|
{
|
|
for (int x = 0; x < result.getWidth(); x++)
|
|
{
|
|
const int res = result.getPixelInt(x, y).x();
|
|
|
|
if (reference != res)
|
|
{
|
|
if (numFailed < maxPrints)
|
|
log << TestLog::Message << "ERROR: Expected " << reference << ", got " << res << " at (" << x << ", " << y << ")" << TestLog::EndMessage;
|
|
else if (numFailed == maxPrints)
|
|
log << TestLog::Message << "..." << TestLog::EndMessage;
|
|
|
|
numFailed += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
log << TestLog::Message << "Found " << numFailed << " faulty pixels, comparison " << (numFailed == 0 ? "passed." : "FAILED!") << TestLog::EndMessage;
|
|
|
|
log << TestLog::ImageSet("ComparisonResult", "Image comparison result")
|
|
<< TestLog::Image("Result", "Result stencil buffer", result);
|
|
|
|
log << TestLog::EndImageSet;
|
|
|
|
return numFailed == 0;
|
|
}
|
|
|
|
static void stencilToUnorm8 (const tcu::TextureCube& src, tcu::TextureCube& dst)
|
|
{
|
|
for (int levelNdx = 0; levelNdx < src.getNumLevels(); levelNdx++)
|
|
{
|
|
for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
|
|
{
|
|
const tcu::CubeFace face = tcu::CubeFace(faceNdx);
|
|
|
|
if (!src.isLevelEmpty(face, levelNdx))
|
|
{
|
|
dst.allocLevel(face, levelNdx);
|
|
|
|
const tcu::ConstPixelBufferAccess srcLevel = src.getLevelFace(levelNdx, face);
|
|
const tcu::PixelBufferAccess dstLevel = dst.getLevelFace(levelNdx, face);
|
|
|
|
for (int y = 0; y < src.getSize(); y++)
|
|
for (int x = 0; x < src.getSize(); x++)
|
|
dstLevel.setPixel(Vec4(float(srcLevel.getPixStencil(x, y)) / 255.f, 0.f, 0.f, 1.f), x, y);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void checkDepthStencilFormatSupport (Context& context, deUint32 format)
|
|
{
|
|
if (format == GL_STENCIL_INDEX8)
|
|
{
|
|
const char* reqExt = "GL_OES_texture_stencil8";
|
|
glu::ContextType contextType = context.getRenderContext().getType();
|
|
if (!glu::contextSupports(contextType, glu::ApiType::es(3, 2)) &&
|
|
!glu::contextSupports(contextType, glu::ApiType::core(4, 5)) &&
|
|
!context.getContextInfo().isExtensionSupported(reqExt))
|
|
throw tcu::NotSupportedError(glu::getTextureFormatStr(format).toString() + " requires " + reqExt);
|
|
}
|
|
else
|
|
{
|
|
DE_ASSERT(format == GL_DEPTH32F_STENCIL8 || format == GL_DEPTH24_STENCIL8);
|
|
}
|
|
}
|
|
|
|
static void checkFramebufferStatus (const glw::Functions& gl)
|
|
{
|
|
const deUint32 status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
|
|
|
|
if (status == GL_FRAMEBUFFER_UNSUPPORTED)
|
|
throw tcu::NotSupportedError("Unsupported framebuffer configuration");
|
|
else if (status != GL_FRAMEBUFFER_COMPLETE)
|
|
throw tcu::TestError("Incomplete framebuffer: " + glu::getFramebufferStatusStr(status).toString());
|
|
}
|
|
|
|
class UploadTex2DCase : public TestCase
|
|
{
|
|
public:
|
|
UploadTex2DCase (Context& context, const char* name, deUint32 format)
|
|
: TestCase (context, name, glu::getTextureFormatName(format))
|
|
, m_format (format)
|
|
{
|
|
}
|
|
|
|
IterateResult iterate (void)
|
|
{
|
|
const glu::RenderContext& renderCtx = m_context.getRenderContext();
|
|
const glw::Functions& gl = renderCtx.getFunctions();
|
|
const int width = 129;
|
|
const int height = 113;
|
|
glu::Framebuffer fbo (renderCtx);
|
|
glu::Renderbuffer colorBuf (renderCtx);
|
|
glu::Texture depthStencilTex (renderCtx);
|
|
TextureLevel uploadLevel (glu::mapGLInternalFormat(m_format), width, height);
|
|
TextureLevel readLevel (TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
|
|
TextureLevel stencilOnlyLevel (TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
|
|
|
|
checkDepthStencilFormatSupport(m_context, m_format);
|
|
|
|
renderTestPatternReference(uploadLevel);
|
|
renderTestPatternReference(stencilOnlyLevel);
|
|
|
|
gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
|
|
gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);
|
|
glu::texSubImage2D(renderCtx, GL_TEXTURE_2D, 0, 0, 0, uploadLevel);
|
|
GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
|
|
|
|
gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
|
|
gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
|
|
|
|
gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
|
|
gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
|
|
checkFramebufferStatus(gl);
|
|
|
|
blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
|
|
glu::readPixels(renderCtx, 0, 0, readLevel);
|
|
|
|
{
|
|
const bool compareOk = compareStencilToRed(m_testCtx.getLog(), stencilOnlyLevel, readLevel);
|
|
m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
|
|
compareOk ? "Pass" : "Image comparison failed");
|
|
}
|
|
|
|
return STOP;
|
|
}
|
|
|
|
private:
|
|
const deUint32 m_format;
|
|
};
|
|
|
|
class UploadTex2DArrayCase : public TestCase
|
|
{
|
|
public:
|
|
UploadTex2DArrayCase (Context& context, const char* name, deUint32 format)
|
|
: TestCase (context, name, glu::getTextureFormatName(format))
|
|
, m_format (format)
|
|
{
|
|
}
|
|
|
|
IterateResult iterate (void)
|
|
{
|
|
const glu::RenderContext& renderCtx = m_context.getRenderContext();
|
|
const glw::Functions& gl = renderCtx.getFunctions();
|
|
const int width = 41;
|
|
const int height = 13;
|
|
const int levels = 7;
|
|
const int ptrnLevel = 3;
|
|
glu::Framebuffer fbo (renderCtx);
|
|
glu::Renderbuffer colorBuf (renderCtx);
|
|
glu::Texture depthStencilTex (renderCtx);
|
|
TextureLevel uploadLevel (glu::mapGLInternalFormat(m_format), width, height, levels);
|
|
|
|
checkDepthStencilFormatSupport(m_context, m_format);
|
|
|
|
for (int levelNdx = 0; levelNdx < levels; levelNdx++)
|
|
{
|
|
const tcu::PixelBufferAccess levelAccess = tcu::getSubregion(uploadLevel.getAccess(), 0, 0, levelNdx, width, height, 1);
|
|
|
|
if (levelNdx == ptrnLevel)
|
|
renderTestPatternReference(levelAccess);
|
|
else
|
|
tcu::clearStencil(levelAccess, levelNdx);
|
|
}
|
|
|
|
gl.bindTexture(GL_TEXTURE_2D_ARRAY, *depthStencilTex);
|
|
gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, m_format, width, height, levels);
|
|
glu::texSubImage3D(renderCtx, GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, uploadLevel);
|
|
GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
|
|
|
|
gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
|
|
gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
|
|
|
|
gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
|
|
gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
|
|
checkFramebufferStatus(gl);
|
|
|
|
{
|
|
TextureLevel readLevel (TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
|
|
bool allLevelsOk = true;
|
|
|
|
for (int levelNdx = 0; levelNdx < levels; levelNdx++)
|
|
{
|
|
tcu::ScopedLogSection section(m_testCtx.getLog(), "Level" + de::toString(levelNdx), "Level " + de::toString(levelNdx));
|
|
bool levelOk;
|
|
|
|
blitStencilToColor2DArray(renderCtx, *depthStencilTex, width, height, levelNdx);
|
|
glu::readPixels(renderCtx, 0, 0, readLevel);
|
|
|
|
if (levelNdx == ptrnLevel)
|
|
{
|
|
TextureLevel reference(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
|
|
renderTestPatternReference(reference);
|
|
|
|
levelOk = compareStencilToRed(m_testCtx.getLog(), reference, readLevel);
|
|
}
|
|
else
|
|
levelOk = compareRedChannel(m_testCtx.getLog(), readLevel, levelNdx);
|
|
|
|
if (!levelOk)
|
|
{
|
|
allLevelsOk = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
m_testCtx.setTestResult(allLevelsOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
|
|
allLevelsOk ? "Pass" : "Image comparison failed");
|
|
}
|
|
|
|
return STOP;
|
|
}
|
|
|
|
private:
|
|
const deUint32 m_format;
|
|
};
|
|
|
|
class UploadTexCubeCase : public TestCase
|
|
{
|
|
public:
|
|
UploadTexCubeCase (Context& context, const char* name, deUint32 format)
|
|
: TestCase (context, name, glu::getTextureFormatName(format))
|
|
, m_format (format)
|
|
{
|
|
}
|
|
|
|
IterateResult iterate (void)
|
|
{
|
|
const glu::RenderContext& renderCtx = m_context.getRenderContext();
|
|
const glw::Functions& gl = renderCtx.getFunctions();
|
|
const int size = 64;
|
|
const int renderWidth = 128;
|
|
const int renderHeight = 128;
|
|
vector<float> texCoord;
|
|
glu::Framebuffer fbo (renderCtx);
|
|
glu::Renderbuffer colorBuf (renderCtx);
|
|
glu::Texture depthStencilTex (renderCtx);
|
|
tcu::TextureCube texData (glu::mapGLInternalFormat(m_format), size);
|
|
tcu::TextureLevel result (TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), renderWidth, renderHeight);
|
|
|
|
checkDepthStencilFormatSupport(m_context, m_format);
|
|
|
|
for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
|
|
{
|
|
const tcu::CubeFace face = tcu::CubeFace(faceNdx);
|
|
const int stencilVal = 42*faceNdx;
|
|
|
|
texData.allocLevel(face, 0);
|
|
tcu::clearStencil(texData.getLevelFace(0, face), stencilVal);
|
|
}
|
|
|
|
glu::TextureTestUtil::computeQuadTexCoordCube(texCoord, tcu::CUBEFACE_NEGATIVE_X, Vec2(-1.5f, -1.3f), Vec2(1.3f, 1.4f));
|
|
|
|
gl.bindTexture(GL_TEXTURE_CUBE_MAP, *depthStencilTex);
|
|
gl.texStorage2D(GL_TEXTURE_CUBE_MAP, 1, m_format, size, size);
|
|
|
|
for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
|
|
glu::texSubImage2D(renderCtx, glu::getGLCubeFace(tcu::CubeFace(faceNdx)), 0, 0, 0, texData.getLevelFace(0, tcu::CubeFace(faceNdx)));
|
|
|
|
GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
|
|
|
|
gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
|
|
gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, renderWidth, renderHeight);
|
|
|
|
gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
|
|
gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
|
|
checkFramebufferStatus(gl);
|
|
|
|
blitStencilToColorCube(renderCtx, *depthStencilTex, &texCoord[0], renderWidth, renderHeight);
|
|
glu::readPixels(renderCtx, 0, 0, result);
|
|
|
|
{
|
|
using namespace glu::TextureTestUtil;
|
|
|
|
tcu::TextureCube redTex (TextureFormat(TextureFormat::R, TextureFormat::UNORM_INT8), size);
|
|
const ReferenceParams sampleParams (TEXTURETYPE_CUBE, tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE,
|
|
tcu::Sampler::CLAMP_TO_EDGE,
|
|
tcu::Sampler::CLAMP_TO_EDGE,
|
|
tcu::Sampler::NEAREST,
|
|
tcu::Sampler::NEAREST));
|
|
tcu::LookupPrecision lookupPrec;
|
|
tcu::LodPrecision lodPrec;
|
|
bool compareOk;
|
|
|
|
lookupPrec.colorMask = tcu::BVec4(true, true, true, true);
|
|
lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(IVec4(8, 8, 8, 8));
|
|
lookupPrec.coordBits = tcu::IVec3(22, 22, 22);
|
|
lookupPrec.uvwBits = tcu::IVec3(5, 5, 0);
|
|
lodPrec.lodBits = 7;
|
|
lodPrec.derivateBits = 16;
|
|
|
|
stencilToUnorm8(texData, redTex);
|
|
|
|
compareOk = verifyTextureResult(m_testCtx, result, redTex, &texCoord[0], sampleParams, lookupPrec, lodPrec, tcu::PixelFormat(8, 8, 8, 8));
|
|
|
|
m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
|
|
compareOk ? "Pass" : "Image comparison failed");
|
|
}
|
|
|
|
return STOP;
|
|
}
|
|
|
|
private:
|
|
const deUint32 m_format;
|
|
};
|
|
|
|
class RenderTex2DCase : public TestCase
|
|
{
|
|
public:
|
|
RenderTex2DCase (Context& context, const char* name, deUint32 format)
|
|
: TestCase (context, name, glu::getTextureFormatName(format))
|
|
, m_format (format)
|
|
{
|
|
}
|
|
|
|
IterateResult iterate (void)
|
|
{
|
|
const glu::RenderContext& renderCtx = m_context.getRenderContext();
|
|
const glw::Functions& gl = renderCtx.getFunctions();
|
|
const int width = 117;
|
|
const int height = 193;
|
|
glu::Framebuffer fbo (renderCtx);
|
|
glu::Renderbuffer colorBuf (renderCtx);
|
|
glu::Texture depthStencilTex (renderCtx);
|
|
TextureLevel result (TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
|
|
TextureLevel reference (TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
|
|
|
|
checkDepthStencilFormatSupport(m_context, m_format);
|
|
|
|
gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
|
|
gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
|
|
|
|
gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
|
|
gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);
|
|
|
|
gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
|
|
gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
|
|
gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, *depthStencilTex, 0);
|
|
checkFramebufferStatus(gl);
|
|
|
|
drawTestPattern(renderCtx, width, height);
|
|
|
|
gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
|
|
checkFramebufferStatus(gl);
|
|
|
|
blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
|
|
glu::readPixels(renderCtx, 0, 0, result.getAccess());
|
|
|
|
renderTestPatternReference(reference);
|
|
|
|
{
|
|
const bool compareOk = compareStencilToRed(m_testCtx.getLog(), reference, result);
|
|
m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
|
|
compareOk ? "Pass" : "Image comparison failed");
|
|
}
|
|
|
|
return STOP;
|
|
}
|
|
|
|
private:
|
|
const deUint32 m_format;
|
|
};
|
|
|
|
class ClearTex2DCase : public TestCase
|
|
{
|
|
public:
|
|
ClearTex2DCase (Context& context, const char* name, deUint32 format)
|
|
: TestCase (context, name, glu::getTextureFormatName(format))
|
|
, m_format (format)
|
|
{
|
|
}
|
|
|
|
IterateResult iterate (void)
|
|
{
|
|
const glu::RenderContext& renderCtx = m_context.getRenderContext();
|
|
const glw::Functions& gl = renderCtx.getFunctions();
|
|
const int width = 125;
|
|
const int height = 117;
|
|
const int cellSize = 8;
|
|
glu::Framebuffer fbo (renderCtx);
|
|
glu::Renderbuffer colorBuf (renderCtx);
|
|
glu::Texture depthStencilTex (renderCtx);
|
|
TextureLevel result (TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
|
|
TextureLevel reference (TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
|
|
|
|
checkDepthStencilFormatSupport(m_context, m_format);
|
|
|
|
gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
|
|
gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
|
|
|
|
gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
|
|
gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);
|
|
|
|
gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
|
|
gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
|
|
gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, *depthStencilTex, 0);
|
|
checkFramebufferStatus(gl);
|
|
|
|
gl.enable(GL_SCISSOR_TEST);
|
|
|
|
for (int y = 0; y < height; y += cellSize)
|
|
{
|
|
for (int x = 0; x < width; x += cellSize)
|
|
{
|
|
const int clearW = de::min(cellSize, width-x);
|
|
const int clearH = de::min(cellSize, height-y);
|
|
const int stencil = int((deInt32Hash(x) ^ deInt32Hash(y)) & 0xff);
|
|
|
|
gl.clearStencil(stencil);
|
|
gl.scissor(x, y, clearW, clearH);
|
|
gl.clear(GL_STENCIL_BUFFER_BIT);
|
|
|
|
tcu::clearStencil(tcu::getSubregion(reference.getAccess(), x, y, clearW, clearH), stencil);
|
|
}
|
|
}
|
|
|
|
gl.disable(GL_SCISSOR_TEST);
|
|
|
|
gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
|
|
checkFramebufferStatus(gl);
|
|
|
|
blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
|
|
glu::readPixels(renderCtx, 0, 0, result.getAccess());
|
|
|
|
{
|
|
const bool compareOk = compareStencilToRed(m_testCtx.getLog(), reference, result);
|
|
m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
|
|
compareOk ? "Pass" : "Image comparison failed");
|
|
}
|
|
|
|
return STOP;
|
|
}
|
|
|
|
private:
|
|
const deUint32 m_format;
|
|
};
|
|
|
|
class CompareModeCase : public TestCase
|
|
{
|
|
public:
|
|
CompareModeCase (Context& context, const char* name, deUint32 format)
|
|
: TestCase (context, name, glu::getTextureFormatName(format))
|
|
, m_format (format)
|
|
{
|
|
}
|
|
|
|
IterateResult iterate (void)
|
|
{
|
|
const glu::RenderContext& renderCtx = m_context.getRenderContext();
|
|
const glw::Functions& gl = renderCtx.getFunctions();
|
|
const int width = 64;
|
|
const int height = 64;
|
|
glu::Framebuffer fbo (renderCtx);
|
|
glu::Renderbuffer colorBuf (renderCtx);
|
|
glu::Texture depthStencilTex (renderCtx);
|
|
TextureLevel uploadLevel (glu::mapGLInternalFormat(m_format), width, height);
|
|
TextureLevel readLevel (TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
|
|
TextureLevel stencilOnlyLevel (TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
|
|
|
|
checkDepthStencilFormatSupport(m_context, m_format);
|
|
|
|
m_testCtx.getLog() << TestLog::Message << "NOTE: Texture compare mode has no effect when reading stencil values." << TestLog::EndMessage;
|
|
|
|
renderTestPatternReference(uploadLevel);
|
|
renderTestPatternReference(stencilOnlyLevel);
|
|
|
|
gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
|
|
gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);
|
|
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
|
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
|
|
glu::texSubImage2D(renderCtx, GL_TEXTURE_2D, 0, 0, 0, uploadLevel);
|
|
GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
|
|
|
|
gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
|
|
gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
|
|
|
|
gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
|
|
gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
|
|
checkFramebufferStatus(gl);
|
|
|
|
blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
|
|
glu::readPixels(renderCtx, 0, 0, readLevel);
|
|
|
|
{
|
|
const bool compareOk = compareStencilToRed(m_testCtx.getLog(), stencilOnlyLevel, readLevel);
|
|
m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
|
|
compareOk ? "Pass" : "Image comparison failed");
|
|
}
|
|
|
|
return STOP;
|
|
}
|
|
|
|
private:
|
|
const deUint32 m_format;
|
|
};
|
|
|
|
class BaseLevelCase : public TestCase
|
|
{
|
|
public:
|
|
BaseLevelCase (Context& context, const char* name, deUint32 format)
|
|
: TestCase (context, name, glu::getTextureFormatName(format))
|
|
, m_format (format)
|
|
{
|
|
}
|
|
|
|
IterateResult iterate (void)
|
|
{
|
|
const glu::RenderContext& renderCtx = m_context.getRenderContext();
|
|
const glw::Functions& gl = renderCtx.getFunctions();
|
|
const int width = 128;
|
|
const int height = 128;
|
|
const int levelNdx = 2;
|
|
const int levelWidth = width>>levelNdx;
|
|
const int levelHeight = height>>levelNdx;
|
|
glu::Framebuffer fbo (renderCtx);
|
|
glu::Renderbuffer colorBuf (renderCtx);
|
|
glu::Texture depthStencilTex (renderCtx);
|
|
TextureLevel uploadLevel (glu::mapGLInternalFormat(m_format), levelWidth, levelHeight);
|
|
TextureLevel readLevel (TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), levelWidth, levelHeight);
|
|
TextureLevel stencilOnlyLevel (TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), levelWidth, levelHeight);
|
|
|
|
checkDepthStencilFormatSupport(m_context, m_format);
|
|
|
|
m_testCtx.getLog() << TestLog::Message << "GL_TEXTURE_BASE_LEVEL = " << levelNdx << TestLog::EndMessage;
|
|
|
|
renderTestPatternReference(uploadLevel);
|
|
renderTestPatternReference(stencilOnlyLevel);
|
|
|
|
gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
|
|
gl.texStorage2D(GL_TEXTURE_2D, deLog2Floor32(de::max(width, height))+1, m_format, width, height);
|
|
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, levelNdx);
|
|
glu::texSubImage2D(renderCtx, GL_TEXTURE_2D, levelNdx, 0, 0, uploadLevel);
|
|
GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
|
|
|
|
gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
|
|
gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, levelWidth, levelHeight);
|
|
|
|
gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
|
|
gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
|
|
checkFramebufferStatus(gl);
|
|
|
|
blitStencilToColor2D(renderCtx, *depthStencilTex, levelWidth, levelHeight);
|
|
glu::readPixels(renderCtx, 0, 0, readLevel);
|
|
|
|
{
|
|
const bool compareOk = compareStencilToRed(m_testCtx.getLog(), stencilOnlyLevel, readLevel);
|
|
m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
|
|
compareOk ? "Pass" : "Image comparison failed");
|
|
}
|
|
|
|
return STOP;
|
|
}
|
|
|
|
private:
|
|
const deUint32 m_format;
|
|
};
|
|
|
|
} // anonymous
|
|
|
|
StencilTexturingTests::StencilTexturingTests (Context& context)
|
|
: TestCaseGroup(context, "stencil_texturing", "Stencil texturing tests")
|
|
{
|
|
}
|
|
|
|
StencilTexturingTests::~StencilTexturingTests (void)
|
|
{
|
|
}
|
|
|
|
void StencilTexturingTests::init (void)
|
|
{
|
|
// .format
|
|
{
|
|
tcu::TestCaseGroup* const formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "Formats");
|
|
addChild(formatGroup);
|
|
|
|
formatGroup->addChild(new UploadTex2DCase (m_context, "depth32f_stencil8_2d", GL_DEPTH32F_STENCIL8));
|
|
formatGroup->addChild(new UploadTex2DArrayCase (m_context, "depth32f_stencil8_2d_array", GL_DEPTH32F_STENCIL8));
|
|
formatGroup->addChild(new UploadTexCubeCase (m_context, "depth32f_stencil8_cube", GL_DEPTH32F_STENCIL8));
|
|
formatGroup->addChild(new UploadTex2DCase (m_context, "depth24_stencil8_2d", GL_DEPTH24_STENCIL8));
|
|
formatGroup->addChild(new UploadTex2DArrayCase (m_context, "depth24_stencil8_2d_array", GL_DEPTH24_STENCIL8));
|
|
formatGroup->addChild(new UploadTexCubeCase (m_context, "depth24_stencil8_cube", GL_DEPTH24_STENCIL8));
|
|
|
|
// OES_texture_stencil8
|
|
formatGroup->addChild(new UploadTex2DCase (m_context, "stencil_index8_2d", GL_STENCIL_INDEX8));
|
|
formatGroup->addChild(new UploadTex2DArrayCase (m_context, "stencil_index8_2d_array", GL_STENCIL_INDEX8));
|
|
formatGroup->addChild(new UploadTexCubeCase (m_context, "stencil_index8_cube", GL_STENCIL_INDEX8));
|
|
}
|
|
|
|
// .render
|
|
{
|
|
tcu::TestCaseGroup* const readRenderGroup = new tcu::TestCaseGroup(m_testCtx, "render", "Read rendered stencil values");
|
|
addChild(readRenderGroup);
|
|
|
|
readRenderGroup->addChild(new ClearTex2DCase (m_context, "depth32f_stencil8_clear", GL_DEPTH32F_STENCIL8));
|
|
readRenderGroup->addChild(new RenderTex2DCase (m_context, "depth32f_stencil8_draw", GL_DEPTH32F_STENCIL8));
|
|
readRenderGroup->addChild(new ClearTex2DCase (m_context, "depth24_stencil8_clear", GL_DEPTH24_STENCIL8));
|
|
readRenderGroup->addChild(new RenderTex2DCase (m_context, "depth24_stencil8_draw", GL_DEPTH24_STENCIL8));
|
|
}
|
|
|
|
// .misc
|
|
{
|
|
tcu::TestCaseGroup* const miscGroup = new tcu::TestCaseGroup(m_testCtx, "misc", "Misc cases");
|
|
addChild(miscGroup);
|
|
|
|
miscGroup->addChild(new CompareModeCase (m_context, "compare_mode_effect", GL_DEPTH24_STENCIL8));
|
|
miscGroup->addChild(new BaseLevelCase (m_context, "base_level", GL_DEPTH24_STENCIL8));
|
|
}
|
|
}
|
|
|
|
} // Functional
|
|
} // gles31
|
|
} // deqp
|