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.
304 lines
9.9 KiB
304 lines
9.9 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 Occlusion query stress tests
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "es3sOcclusionQueryTests.hpp"
|
|
|
|
#include "deRandom.hpp"
|
|
#include "deStringUtil.hpp"
|
|
#include "deString.h"
|
|
#include "tcuTestLog.hpp"
|
|
#include "tcuVector.hpp"
|
|
#include "tcuSurface.hpp"
|
|
#include "gluShaderProgram.hpp"
|
|
#include "deClock.h"
|
|
|
|
#include "glw.h"
|
|
|
|
#include <vector>
|
|
|
|
using std::vector;
|
|
using tcu::TestLog;
|
|
|
|
namespace deqp
|
|
{
|
|
namespace gles3
|
|
{
|
|
namespace Stress
|
|
{
|
|
|
|
static const tcu::Vec4 OCCLUDER_COLOR = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
|
|
static const tcu::Vec4 TARGET_COLOR = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
|
|
static const int NUM_CASE_ITERATIONS = 3;
|
|
static const int NUM_GENERATED_VERTICES = 100;
|
|
static const int WATCHDOG_INTERVAL = 50; // Touch watchdog every N iterations.
|
|
|
|
class OcclusionQueryStressCase : public TestCase
|
|
{
|
|
public:
|
|
OcclusionQueryStressCase (Context& ctx, const char* name, const char* desc, int m_numOccluderDraws, int m_numOccludersPerDraw, int m_numTargetDraws, int m_numTargetsPerDraw, int m_numQueries, deUint32 m_queryMode);
|
|
~OcclusionQueryStressCase (void);
|
|
|
|
void init (void);
|
|
void deinit (void);
|
|
IterateResult iterate (void);
|
|
|
|
private:
|
|
OcclusionQueryStressCase (const OcclusionQueryStressCase&);
|
|
OcclusionQueryStressCase& operator= (const OcclusionQueryStressCase&);
|
|
|
|
int m_numOccluderDraws;
|
|
int m_numOccludersPerDraw;
|
|
int m_numTargetDraws;
|
|
int m_numTargetsPerDraw;
|
|
int m_numQueries;
|
|
deUint32 m_queryMode;
|
|
|
|
glu::RenderContext& m_renderCtx;
|
|
glu::ShaderProgram* m_program;
|
|
int m_iterNdx;
|
|
de::Random m_rnd;
|
|
|
|
};
|
|
|
|
OcclusionQueryStressCase::OcclusionQueryStressCase (Context& ctx, const char* name, const char* desc, int numOccluderDraws, int numOccludersPerDraw, int numTargetDraws, int numTargetsPerDraw, int numQueries, deUint32 queryMode)
|
|
: TestCase (ctx, name, desc)
|
|
, m_numOccluderDraws (numOccluderDraws)
|
|
, m_numOccludersPerDraw (numOccludersPerDraw)
|
|
, m_numTargetDraws (numTargetDraws)
|
|
, m_numTargetsPerDraw (numTargetsPerDraw)
|
|
, m_numQueries (numQueries)
|
|
, m_queryMode (queryMode)
|
|
, m_renderCtx (ctx.getRenderContext())
|
|
, m_program (DE_NULL)
|
|
, m_iterNdx (0)
|
|
, m_rnd (deStringHash(name))
|
|
{
|
|
}
|
|
|
|
OcclusionQueryStressCase::~OcclusionQueryStressCase (void)
|
|
{
|
|
OcclusionQueryStressCase::deinit();
|
|
}
|
|
|
|
void OcclusionQueryStressCase::init (void)
|
|
{
|
|
const char* vertShaderSource =
|
|
"#version 300 es\n"
|
|
"layout(location = 0) in mediump vec4 a_position;\n"
|
|
"\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" gl_Position = a_position;\n"
|
|
"}\n";
|
|
|
|
const char* fragShaderSource =
|
|
"#version 300 es\n"
|
|
"layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
|
|
"uniform mediump vec4 u_color;\n"
|
|
"\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" mediump float depth_gradient = gl_FragCoord.z;\n"
|
|
" mediump float bias = 0.1;\n"
|
|
" dEQP_FragColor = vec4(u_color.xyz * (depth_gradient + bias), 1.0);\n"
|
|
"}\n";
|
|
|
|
DE_ASSERT(!m_program);
|
|
m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertShaderSource, fragShaderSource));
|
|
|
|
if (!m_program->isOk())
|
|
{
|
|
m_testCtx.getLog() << *m_program;
|
|
TCU_FAIL("Failed to compile shader program");
|
|
}
|
|
|
|
m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); // Initialize test result to pass.
|
|
GLU_CHECK_MSG ("Case initialization finished");
|
|
}
|
|
|
|
void OcclusionQueryStressCase::deinit (void)
|
|
{
|
|
delete m_program;
|
|
m_program = DE_NULL;
|
|
}
|
|
|
|
|
|
OcclusionQueryStressCase::IterateResult OcclusionQueryStressCase::iterate (void)
|
|
{
|
|
tcu::TestLog& log = m_testCtx.getLog();
|
|
deUint32 colorUnif = glGetUniformLocation(m_program->getProgram(), "u_color");
|
|
|
|
std::vector<float> vertices;
|
|
std::vector<float> occluderVertices;
|
|
std::vector<float> targetVertices;
|
|
std::vector<deUint32> queryIds (m_numQueries, 0);
|
|
std::vector<deUint32> queryResultReady (m_numQueries, 0);
|
|
std::vector<deUint32> queryResult (m_numQueries, 0);
|
|
|
|
std::string sectionName ("Case iteration " + de::toString(m_iterNdx+1) + "/" + de::toString(NUM_CASE_ITERATIONS));
|
|
tcu::ScopedLogSection section (log, sectionName.c_str(), sectionName.c_str());
|
|
|
|
log << tcu::TestLog::Message << "Parameters:\n"
|
|
<< "- Number of occlusion queries: " << m_numQueries << ".\n"
|
|
<< "- Number of occluder draws per query: " << m_numOccluderDraws << ", primitives per draw: " << m_numOccludersPerDraw << ".\n"
|
|
<< "- Number of target draws per query: " << m_numTargetDraws << ", primitives per draw: " << m_numTargetsPerDraw << ".\n"
|
|
<< tcu::TestLog::EndMessage;
|
|
|
|
int numOccluderIndicesPerDraw = 3*m_numOccludersPerDraw;
|
|
int numTargetIndicesPerDraw = 3*m_numTargetsPerDraw;
|
|
|
|
// Generate vertex data
|
|
|
|
vertices.resize(4*NUM_GENERATED_VERTICES);
|
|
|
|
for (int i = 0; i < NUM_GENERATED_VERTICES; i++)
|
|
{
|
|
vertices[4*i ] = m_rnd.getFloat(-1.0f, 1.0f);
|
|
vertices[4*i + 1] = m_rnd.getFloat(-1.0f, 1.0f);
|
|
vertices[4*i + 2] = m_rnd.getFloat(0.0f, 1.0f);
|
|
vertices[4*i + 3] = 1.0f;
|
|
}
|
|
|
|
// Generate primitives
|
|
|
|
occluderVertices.resize(4*numOccluderIndicesPerDraw * m_numOccluderDraws);
|
|
|
|
for (int i = 0; i < numOccluderIndicesPerDraw * m_numOccluderDraws; i++)
|
|
{
|
|
int vtxNdx = m_rnd.getInt(0, NUM_GENERATED_VERTICES-1);
|
|
occluderVertices[4*i ] = vertices[4*vtxNdx];
|
|
occluderVertices[4*i + 1] = vertices[4*vtxNdx + 1];
|
|
occluderVertices[4*i + 2] = vertices[4*vtxNdx + 2];
|
|
occluderVertices[4*i + 3] = vertices[4*vtxNdx + 3];
|
|
}
|
|
|
|
targetVertices.resize(4*numTargetIndicesPerDraw * m_numTargetDraws);
|
|
|
|
for (int i = 0; i < numTargetIndicesPerDraw * m_numTargetDraws; i++)
|
|
{
|
|
int vtxNdx = m_rnd.getInt(0, NUM_GENERATED_VERTICES-1);
|
|
targetVertices[4*i ] = vertices[4*vtxNdx];
|
|
targetVertices[4*i + 1] = vertices[4*vtxNdx + 1];
|
|
targetVertices[4*i + 2] = vertices[4*vtxNdx + 2];
|
|
targetVertices[4*i + 3] = vertices[4*vtxNdx + 3];
|
|
}
|
|
|
|
TCU_CHECK(m_program);
|
|
|
|
glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
|
|
glClearDepthf (1.0f);
|
|
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
glEnable (GL_DEPTH_TEST);
|
|
glUseProgram (m_program->getProgram());
|
|
glEnableVertexAttribArray (0);
|
|
|
|
deUint64 time = deGetMicroseconds();
|
|
|
|
for (int queryIter = 0; queryIter < m_numQueries; queryIter++)
|
|
{
|
|
// Draw occluders
|
|
|
|
glUniform4f (colorUnif, OCCLUDER_COLOR.x(), OCCLUDER_COLOR.y(), OCCLUDER_COLOR.z(), OCCLUDER_COLOR.w());
|
|
|
|
for (int drawIter = 0; drawIter < m_numOccluderDraws; drawIter++)
|
|
{
|
|
glVertexAttribPointer (0, 4, GL_FLOAT, GL_FALSE, 0, &occluderVertices[drawIter * numOccluderIndicesPerDraw]);
|
|
glDrawArrays (GL_TRIANGLES, 0, numOccluderIndicesPerDraw);
|
|
}
|
|
|
|
// Begin occlusion query
|
|
|
|
glGenQueries (1, &queryIds[queryIter]);
|
|
glBeginQuery (m_queryMode, queryIds[queryIter]);
|
|
|
|
// Draw targets
|
|
|
|
glUniform4f (colorUnif, TARGET_COLOR.x(), TARGET_COLOR.y(), TARGET_COLOR.z(), TARGET_COLOR.w());
|
|
|
|
for (int drawIter = 0; drawIter < m_numTargetDraws; drawIter++)
|
|
{
|
|
glVertexAttribPointer (0, 4, GL_FLOAT, GL_FALSE, 0, &targetVertices[drawIter * numTargetIndicesPerDraw]);
|
|
glDrawArrays (GL_TRIANGLES, 0, numTargetIndicesPerDraw);
|
|
}
|
|
|
|
// End occlusion query
|
|
|
|
glEndQuery (m_queryMode);
|
|
|
|
if ((queryIter % WATCHDOG_INTERVAL) == 0 && m_testCtx.getWatchDog())
|
|
qpWatchDog_touch(m_testCtx.getWatchDog());
|
|
}
|
|
|
|
glFinish();
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
deUint64 dTime = deGetMicroseconds() - time;
|
|
log << tcu::TestLog::Message << "Total duration: " << dTime/1000 << " ms" << tcu::TestLog::EndMessage;
|
|
|
|
// Get results
|
|
|
|
for (int queryIter = 0; queryIter < m_numQueries; queryIter++)
|
|
{
|
|
glGetQueryObjectuiv(queryIds[queryIter], GL_QUERY_RESULT_AVAILABLE, &queryResultReady[queryIter]);
|
|
|
|
if (queryResultReady[queryIter] == GL_TRUE)
|
|
{
|
|
glGetQueryObjectuiv(queryIds[queryIter], GL_QUERY_RESULT, &queryResult[queryIter]);
|
|
}
|
|
else
|
|
TCU_FAIL("Occlusion query failed to return a result after glFinish()");
|
|
|
|
if ((queryIter % WATCHDOG_INTERVAL) == 0 && m_testCtx.getWatchDog())
|
|
qpWatchDog_touch(m_testCtx.getWatchDog());
|
|
}
|
|
|
|
glDeleteQueries (m_numQueries, &queryIds[0]);
|
|
GLU_CHECK_MSG ("Occlusion queries finished");
|
|
|
|
log << tcu::TestLog::Message << "Case passed!" << tcu::TestLog::EndMessage;
|
|
|
|
return (++m_iterNdx < NUM_CASE_ITERATIONS) ? CONTINUE : STOP;
|
|
}
|
|
|
|
|
|
OcclusionQueryTests::OcclusionQueryTests (Context& testCtx)
|
|
: TestCaseGroup(testCtx, "occlusion_query", "Occlusion query stress tests")
|
|
{
|
|
}
|
|
|
|
OcclusionQueryTests::~OcclusionQueryTests(void)
|
|
{
|
|
}
|
|
|
|
void OcclusionQueryTests::init (void)
|
|
{
|
|
addChild(new OcclusionQueryStressCase(m_context, "10_queries_2500_triangles_per_query", "10_queries_2500_triangles_per_query", 49, 50, 1, 50, 10, GL_ANY_SAMPLES_PASSED));
|
|
addChild(new OcclusionQueryStressCase(m_context, "100_queries_2500_triangles_per_query", "100_queries_2500_triangles_per_query", 49, 50, 1, 50, 100, GL_ANY_SAMPLES_PASSED));
|
|
addChild(new OcclusionQueryStressCase(m_context, "1000_queries_500_triangles_per_query", "1000_queries_500_triangles_per_query", 49, 10, 1, 10, 1000, GL_ANY_SAMPLES_PASSED));
|
|
addChild(new OcclusionQueryStressCase(m_context, "10000_queries_20_triangles_per_query", "10000_queries_20_triangles_per_query", 1, 19, 1, 1, 10000, GL_ANY_SAMPLES_PASSED));
|
|
}
|
|
|
|
} // Stress
|
|
} // gles3
|
|
} // deqp
|