summaryrefslogtreecommitdiff
path: root/modules/gles3
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gles3')
-rw-r--r--modules/gles3/functional/es3fBlendTests.cpp2
-rw-r--r--modules/gles3/functional/es3fFboCompletenessTests.cpp12
-rw-r--r--modules/gles3/functional/es3fFboInvalidateTests.cpp4
-rw-r--r--modules/gles3/functional/es3fFlushFinishTests.cpp6
-rw-r--r--modules/gles3/functional/es3fScissorTests.cpp400
-rw-r--r--modules/gles3/functional/es3fShaderPrecisionTests.cpp6
-rw-r--r--modules/gles3/functional/es3fShaderTextureFunctionTests.cpp14
-rw-r--r--modules/gles3/performance/CMakeLists.txt2
-rw-r--r--modules/gles3/performance/es3pBufferDataUploadTests.cpp187
-rw-r--r--modules/gles3/performance/es3pDepthTests.cpp1911
-rw-r--r--modules/gles3/performance/es3pDepthTests.hpp53
-rw-r--r--modules/gles3/performance/es3pPerformanceTests.cpp2
-rw-r--r--modules/gles3/performance/es3pShaderOperatorTests.cpp6
13 files changed, 2111 insertions, 494 deletions
diff --git a/modules/gles3/functional/es3fBlendTests.cpp b/modules/gles3/functional/es3fBlendTests.cpp
index f91573ae6..c17ff9b2d 100644
--- a/modules/gles3/functional/es3fBlendTests.cpp
+++ b/modules/gles3/functional/es3fBlendTests.cpp
@@ -319,7 +319,7 @@ BlendCase::IterateResult BlendCase::iterate (void)
// \note In sRGB cases, convert to linear space for comparison.
UVec4 compareThreshold = (m_useSrgbFbo ? tcu::PixelFormat(8, 8, 8, 8) : m_context.getRenderTarget().getPixelFormat()).getColorThreshold().toIVec().asUint()
- * UVec4(5) / UVec4(2) + UVec4(m_useSrgbFbo ? 4 : 2); // \note Non-scientific ad hoc formula. Need big threshold when few color bits; blending brings extra inaccuracy.
+ * UVec4(5) / UVec4(2) + UVec4(m_useSrgbFbo ? 5 : 2); // \note Non-scientific ad hoc formula. Need big threshold when few color bits; blending brings extra inaccuracy.
bool comparePass = tcu::intThresholdCompare(m_testCtx.getLog(), "CompareResult", "Image Comparison Result",
(m_useSrgbFbo ? sRGBATextureLevelToLinear(*m_refColorBuffer) : *m_refColorBuffer).getAccess(),
diff --git a/modules/gles3/functional/es3fFboCompletenessTests.cpp b/modules/gles3/functional/es3fFboCompletenessTests.cpp
index e3239d210..c594e4cd1 100644
--- a/modules/gles3/functional/es3fFboCompletenessTests.cpp
+++ b/modules/gles3/functional/es3fFboCompletenessTests.cpp
@@ -120,6 +120,13 @@ static const FormatKey s_extColorBufferFloatFormats[] =
GL_RGBA32F, GL_RGBA16F, GL_R11F_G11F_B10F, GL_RG32F, GL_RG16F, GL_R32F, GL_R16F,
};
+// GL_OES_texture_stencil8
+static const FormatKey s_extOESTextureStencil8[] =
+{
+ GL_STENCIL_INDEX8,
+};
+
+
static const FormatExtEntry s_es3ExtFormats[] =
{
{ "GL_EXT_color_buffer_float",
@@ -127,6 +134,11 @@ static const FormatExtEntry s_es3ExtFormats[] =
// support and makes them color-renderable.
REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID,
GLS_ARRAY_RANGE(s_extColorBufferFloatFormats) },
+ { "GL_OES_texture_stencil8",
+ // Note: es3 RBO tests actually cover the first two requirements
+ // - kept here for completeness
+ REQUIRED_RENDERABLE | STENCIL_RENDERABLE | TEXTURE_VALID,
+ GLS_ARRAY_RANGE(s_extOESTextureStencil8) }
};
class ES3Checker : public Checker
diff --git a/modules/gles3/functional/es3fFboInvalidateTests.cpp b/modules/gles3/functional/es3fFboInvalidateTests.cpp
index 4a02c29b8..7fc9f2652 100644
--- a/modules/gles3/functional/es3fFboInvalidateTests.cpp
+++ b/modules/gles3/functional/es3fFboInvalidateTests.cpp
@@ -1211,7 +1211,9 @@ protected:
const tcu::TextureFormatInfo colorFmtInfo = tcu::getTextureFormatInfo(colorFmt);
const tcu::Vec4& cBias = colorFmtInfo.valueMin;
const tcu::Vec4 cScale = colorFmtInfo.valueMax-colorFmtInfo.valueMin;
- const bool isDiscarded = (m_invalidateTarget == GL_FRAMEBUFFER && m_boundTarget == GL_DRAW_FRAMEBUFFER) || (m_invalidateTarget == m_boundTarget);
+ const bool isDiscarded = (m_boundTarget == GL_FRAMEBUFFER) ||
+ (m_invalidateTarget == GL_FRAMEBUFFER && m_boundTarget == GL_DRAW_FRAMEBUFFER) ||
+ (m_invalidateTarget == m_boundTarget);
const bool isColorDiscarded = isDiscarded && hasAttachment(m_invalidateAttachments, GL_COLOR_ATTACHMENT0);
const bool isDepthDiscarded = isDiscarded && (hasAttachment(m_invalidateAttachments, GL_DEPTH_ATTACHMENT) || hasAttachment(m_invalidateAttachments, GL_DEPTH_STENCIL_ATTACHMENT));
const bool isStencilDiscarded = isDiscarded && (hasAttachment(m_invalidateAttachments, GL_STENCIL_ATTACHMENT) || hasAttachment(m_invalidateAttachments, GL_DEPTH_STENCIL_ATTACHMENT));
diff --git a/modules/gles3/functional/es3fFlushFinishTests.cpp b/modules/gles3/functional/es3fFlushFinishTests.cpp
index 16ea85478..19da1c19b 100644
--- a/modules/gles3/functional/es3fFlushFinishTests.cpp
+++ b/modules/gles3/functional/es3fFlushFinishTests.cpp
@@ -54,7 +54,7 @@ using std::vector;
using std::string;
using tcu::TestLog;
using tcu::Vec2;
-using deqp::gls::theilSenEstimator;
+using deqp::gls::theilSenLinearRegression;
using deqp::gls::LineParameters;
namespace
@@ -427,8 +427,8 @@ void FlushFinishCase::analyzeResults (const std::vector<Sample>& samples, const
{
const vector<Vec2> waitTimes = getPointsFromSamples(samples, &Sample::waitTime);
const vector<Vec2> readTimes = getPointsFromSamples(samples, &Sample::readPixelsTime);
- const LineParameters waitLine = theilSenEstimator(waitTimes);
- const LineParameters readLine = theilSenEstimator(readTimes);
+ const LineParameters waitLine = theilSenLinearRegression(waitTimes);
+ const LineParameters readLine = theilSenLinearRegression(readTimes);
const float normWaitCoef = waitLine.coefficient * float(calibrationParams.maxDrawCalls) / float(MAX_SAMPLE_DURATION_US);
const float normReadCoef = readLine.coefficient * float(calibrationParams.maxDrawCalls) / float(MAX_SAMPLE_DURATION_US);
bool allOk = true;
diff --git a/modules/gles3/functional/es3fScissorTests.cpp b/modules/gles3/functional/es3fScissorTests.cpp
index 3ef5bc666..a3b16f278 100644
--- a/modules/gles3/functional/es3fScissorTests.cpp
+++ b/modules/gles3/functional/es3fScissorTests.cpp
@@ -45,320 +45,6 @@ namespace gles3
{
namespace Functional
{
-namespace
-{
-
-using tcu::ConstPixelBufferAccess;
-
-class FramebufferCase : public tcu::TestCase
-{
-public:
- FramebufferCase (glu::RenderContext& context, tcu::TestContext& testContext, const char* name, const char* description);
- virtual ~FramebufferCase (void) {}
-
- virtual IterateResult iterate (void);
-
-protected:
- // Must do its own 'readPixels', wrapper does not need to care about formats this way
- virtual ConstPixelBufferAccess render (sglr::Context& context, std::vector<deUint8>& pixelBuffer) = DE_NULL;
-
- glu::RenderContext& m_renderContext;
-};
-
-FramebufferCase::FramebufferCase (glu::RenderContext& context, tcu::TestContext& testContext, const char* name, const char* description)
- : tcu::TestCase (testContext, name, description)
- , m_renderContext (context)
-{
-}
-
-FramebufferCase::IterateResult FramebufferCase::iterate (void)
-{
- const tcu::Vec4 clearColor (0.0f, 0.0f, 0.0f, 1.0f);
- const tcu::RenderTarget& renderTarget = m_renderContext.getRenderTarget();
- const char* failReason = DE_NULL;
-
- const int width = 64;
- const int height = 64;
-
- tcu::TestLog& log = m_testCtx.getLog();
- glu::RenderContext& renderCtx = m_renderContext;
-
- tcu::ConstPixelBufferAccess glesAccess;
- tcu::ConstPixelBufferAccess refAccess;
-
- std::vector<deUint8> glesFrame;
- std::vector<deUint8> refFrame;
- deUint32 glesError;
-
- {
- // Render using GLES
- sglr::GLContext context(renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(0, 0, width, height));
-
- context.clearColor(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w());
- context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
-
- glesAccess = render(context, glesFrame); // Call actual render func
- glesError = context.getError();
- }
-
- // Render reference image
- {
- sglr::ReferenceContextBuffers buffers (tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), renderTarget.getDepthBits(), renderTarget.getStencilBits(), width, height);
- sglr::ReferenceContext context (sglr::ReferenceContextLimits(renderCtx), buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer());
-
- context.clearColor(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w());
- context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
-
- refAccess = render(context, refFrame);
- DE_ASSERT(context.getError() == GL_NO_ERROR);
- }
-
- if (glesError != GL_NO_ERROR)
- {
- log << tcu::TestLog::Message << "Unexpected error: got " << glu::getErrorStr(glesError) << tcu::TestLog::EndMessage;
- m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected error");
- }
- else
- {
- // Compare images
- const tcu::Vec4 threshold (0.02f, 0.02f, 0.02f, 0.02f);
- const bool imagesOk = tcu::floatThresholdCompare(log, "ComparisonResult", "Image comparison result", refAccess, glesAccess, threshold, tcu::COMPARE_LOG_RESULT);
-
- if (!imagesOk && !failReason)
- failReason = "Image comparison failed";
-
- // Store test result
- m_testCtx.setTestResult(imagesOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
- imagesOk ? "Pass" : failReason);
- }
-
- return STOP;
-}
-
-class FramebufferClearCase : public FramebufferCase
-{
-public:
- enum ClearType
- {
- COLOR_FIXED = 0,
- COLOR_FLOAT,
- COLOR_INT,
- COLOR_UINT,
- DEPTH,
- STENCIL,
- DEPTH_STENCIL,
-
- CLEAR_TYPE_LAST
- };
-
- FramebufferClearCase (glu::RenderContext& context, tcu::TestContext& testContext, ClearType clearType, const char* name, const char* description);
- virtual ~FramebufferClearCase (void) {}
-
- tcu::ConstPixelBufferAccess render (sglr::Context& context, std::vector<deUint8>& pixelBuffer);
-
-private:
- const ClearType m_clearType;
-};
-
-FramebufferClearCase::FramebufferClearCase (glu::RenderContext& context, tcu::TestContext& testContext, ClearType clearType, const char* name, const char* description)
- : FramebufferCase (context, testContext, name, description)
- , m_clearType (clearType)
-{
-}
-
-ConstPixelBufferAccess FramebufferClearCase::render (sglr::Context& context, std::vector<deUint8>& pixelBuffer)
-{
- using gls::Functional::ScissorTestShader;
-
- ScissorTestShader shader;
- const deUint32 shaderID = context.createProgram(&shader);
-
- const int width = 64;
- const int height = 64;
-
- const tcu::Vec4 clearColor (1.0f, 1.0f, 0.5f, 1.0f);
- const tcu::IVec4 clearInt (127, -127, 0, 127);
- const tcu::UVec4 clearUint (255, 255, 0, 255);
-
- const tcu::Vec4 baseColor (0.0f, 0.0f, 0.0f, 1.0f);
- const tcu::IVec4 baseIntColor (0, 0, 0, 0);
- const tcu::UVec4 baseUintColor (0, 0, 0, 0);
-
- const int clearStencil = 123;
- const float clearDepth = 1.0f;
-
- deUint32 framebuf, colorbuf, dsbuf;
-
- deUint32 colorBufferFormat = GL_RGBA8;
- deUint32 readFormat = GL_RGBA;
- deUint32 readType = GL_UNSIGNED_BYTE;
- tcu::TextureFormat textureFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
-
- context.genFramebuffers(1, &framebuf);
- context.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuf);
-
- switch (m_clearType)
- {
- case COLOR_FLOAT:
- colorBufferFormat = GL_RGBA16F;
- textureFormat = tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::HALF_FLOAT);
- DE_ASSERT(!"Floating point clear not implemented");// \todo [2014-1-23 otto] pixel read format & type, nothing guaranteed, need extension...
- break;
-
- case COLOR_INT:
- colorBufferFormat = GL_RGBA8I;
- readFormat = GL_RGBA_INTEGER;
- readType = GL_INT;
- textureFormat = tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT32);
- pixelBuffer.resize(width*height*4*4);
- break;
-
- case COLOR_UINT:
- colorBufferFormat = GL_RGBA8UI;
- readFormat = GL_RGBA_INTEGER;
- readType = GL_UNSIGNED_INT;
- textureFormat = tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32);
- pixelBuffer.resize(width*height*4*4);
- break;
-
- default:
- pixelBuffer.resize(width*height*1*4);
- break;
- }
-
- // Color
- context.genRenderbuffers(1, &colorbuf);
- context.bindRenderbuffer(GL_RENDERBUFFER, colorbuf);
- context.renderbufferStorage(GL_RENDERBUFFER, colorBufferFormat, width, height);
- context.framebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);
-
- // Depth/stencil
- context.genRenderbuffers(1, &dsbuf);
- context.bindRenderbuffer(GL_RENDERBUFFER, dsbuf);
- context.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
- context.framebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, dsbuf);
-
- context.clearBufferfi(GL_DEPTH_STENCIL, 0, 1.0f-clearDepth, ~clearStencil);
- switch (m_clearType)
- {
- case COLOR_INT: context.clearBufferiv(GL_COLOR, 0, baseIntColor.getPtr()); break;
- case COLOR_UINT: context.clearBufferuiv(GL_COLOR, 0, baseUintColor.getPtr()); break;
- default: context.clearBufferfv(GL_COLOR, 0, baseColor.getPtr());
- }
-
- context.enable(GL_SCISSOR_TEST);
- context.scissor(8, 8, 48, 48);
-
- switch (m_clearType)
- {
- case COLOR_FIXED: context.clearBufferfv(GL_COLOR, 0, clearColor.getPtr()); break;
- case COLOR_FLOAT: context.clearBufferfv(GL_COLOR, 0, clearColor.getPtr()); break;
- case COLOR_INT: context.clearBufferiv(GL_COLOR, 0, clearInt.getPtr()); break;
- case COLOR_UINT: context.clearBufferuiv(GL_COLOR, 0, clearUint.getPtr()); break;
- case DEPTH: context.clearBufferfv(GL_DEPTH, 0, &clearDepth); break;
- case STENCIL: context.clearBufferiv(GL_STENCIL, 0, &clearStencil); break;
- case DEPTH_STENCIL: context.clearBufferfi(GL_DEPTH_STENCIL, 0, clearDepth, clearStencil); break;
-
- default: DE_ASSERT(false); break;
- }
-
- context.disable(GL_SCISSOR_TEST);
-
- const bool useDepth = (m_clearType==DEPTH || m_clearType==DEPTH_STENCIL);
- const bool useStencil = (m_clearType==STENCIL || m_clearType==DEPTH_STENCIL);
-
- if (useDepth)
- context.enable(GL_DEPTH_TEST);
-
- if (useStencil)
- {
- context.enable(GL_STENCIL_TEST);
- context.stencilFunc(GL_EQUAL, clearStencil, ~0u);
- }
-
- if (useDepth || useStencil)
- {
- shader.setColor(context, shaderID, clearColor);
- sglr::drawQuad(context, shaderID, tcu::Vec3(-1.0f, -1.0f, 0.2f), tcu::Vec3(1.0f, 1.0f, 0.2f));
- }
-
- context.bindFramebuffer(GL_READ_FRAMEBUFFER, framebuf);
- context.readPixels(0, 0, width, height, readFormat, readType, &pixelBuffer[0]);
-
- context.deleteFramebuffers(1, &framebuf);
- context.deleteRenderbuffers(1, &colorbuf);
- context.deleteRenderbuffers(1, &dsbuf);
-
- return tcu::PixelBufferAccess(textureFormat, width, height, 1, &pixelBuffer[0]);
-}
-
-class FramebufferBlitCase : public gls::Functional::ScissorCase
-{
-public:
- FramebufferBlitCase (glu::RenderContext& context, tcu::TestContext& testContext, const tcu::Vec4& scissorArea, const char* name, const char* description);
- virtual ~FramebufferBlitCase (void) {}
-
- virtual void init (void);
-
-protected:
- virtual void render (sglr::Context& context, const tcu::IVec4& viewport);
-};
-
-FramebufferBlitCase::FramebufferBlitCase (glu::RenderContext& context, tcu::TestContext& testContext, const tcu::Vec4& scissorArea, const char* name, const char* description):
- ScissorCase(context, testContext, scissorArea, name, description)
-{
-}
-
-void FramebufferBlitCase::init (void)
-{
- if (m_renderContext.getRenderTarget().getNumSamples())
- throw tcu::NotSupportedError("Cannot blit to multisampled render buffer", "", __FILE__, __LINE__);
-}
-
-void FramebufferBlitCase::render (sglr::Context& context, const tcu::IVec4& viewport)
-{
- deUint32 framebuf;
- deUint32 colorbuf;
-
- const int fboWidth = 64;
- const int fboHeight = 64;
- const tcu::Vec4 clearColor (1.0f, 1.0f, 0.5f, 1.0f);
- const int width = viewport.z();
- const int height = viewport.w();
- const tcu::IVec4 scissorArea (int(m_scissorArea.x()*width) + viewport.x(),
- int(m_scissorArea.y()*height) + viewport.y(),
- int(m_scissorArea.z()*width),
- int(m_scissorArea.w()*height));
- const deInt32 defaultFramebuffer = m_renderContext.getDefaultFramebuffer();
-
- context.genFramebuffers(1, &framebuf);
- context.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuf);
-
- context.genRenderbuffers(1, &colorbuf);
- context.bindRenderbuffer(GL_RENDERBUFFER, colorbuf);
- context.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, fboWidth, fboHeight);
- context.framebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);
-
- context.clearBufferfv(GL_COLOR, 0, clearColor.getPtr());
-
- context.enable(GL_SCISSOR_TEST);
- context.scissor(scissorArea.x(), scissorArea.y(), scissorArea.z(), scissorArea.w());
-
- // blit to default framebuffer
- context.bindFramebuffer(GL_READ_FRAMEBUFFER, framebuf);
- context.bindFramebuffer(GL_DRAW_FRAMEBUFFER, defaultFramebuffer);
-
- context.blitFramebuffer(0, 0, fboWidth, fboHeight, viewport.x(), viewport.y(), viewport.x() + width, viewport.y() + height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
-
- context.bindFramebuffer(GL_READ_FRAMEBUFFER, defaultFramebuffer);
-
- context.disable(GL_SCISSOR_TEST);
-
- context.deleteFramebuffers(1, &framebuf);
- context.deleteRenderbuffers(1, &colorbuf);
-}
-
-} // Anonymous
ScissorTests::ScissorTests (Context& context):
TestCaseGroup (context, "scissor", "Scissor Tests")
@@ -372,63 +58,63 @@ ScissorTests::~ScissorTests (void)
void ScissorTests::init (void)
{
using tcu::Vec4;
- typedef gls::Functional::ScissorCase SC;
+ using namespace gls::Functional::ScissorTestInternal;
- glu::RenderContext& rc = m_context.getRenderContext();
tcu::TestContext& tc = m_context.getTestContext();
+ glu::RenderContext& rc = m_context.getRenderContext();
- static const struct
+ const struct
{
- const char* name;
- const char* description;
- const tcu::Vec4 scissor;
- const tcu::Vec4 render;
- const SC::PrimitiveType type;
- const int primitives;
+ const char* name;
+ const char* desc;
+ const tcu::Vec4 scissor;
+ const tcu::Vec4 render;
+ const PrimitiveType type;
+ const int primitives;
} cases[] =
{
- { "contained_quads", "Triangles fully inside scissor area (single call)", Vec4(0.1f, 0.1f, 0.8f, 0.8f), Vec4(0.2f, 0.2f, 0.6f, 0.6f), SC::TRIANGLE, 30 },
- { "partial_quads", "Triangles partially inside scissor area (single call)", Vec4(0.3f, 0.3f, 0.4f, 0.4f), Vec4(0.2f, 0.2f, 0.6f, 0.6f), SC::TRIANGLE, 30 },
- { "contained_tri", "Triangle fully inside scissor area", Vec4(0.1f, 0.1f, 0.8f, 0.8f), Vec4(0.2f, 0.2f, 0.6f, 0.6f), SC::TRIANGLE, 1 },
- { "enclosing_tri", "Triangle fully covering scissor area", Vec4(0.4f, 0.4f, 0.2f, 0.2f), Vec4(0.2f, 0.2f, 0.6f, 0.6f), SC::TRIANGLE, 1 },
- { "partial_tri", "Triangle partially inside scissor area", Vec4(0.4f, 0.4f, 0.6f, 0.6f), Vec4(0.0f, 0.0f, 1.0f, 1.0f), SC::TRIANGLE, 1 },
- { "outside_render_tri", "Triangle with scissor area outside render target", Vec4(1.4f, 1.4f, 0.6f, 0.6f), Vec4(0.0f, 0.0f, 0.6f, 0.6f), SC::TRIANGLE, 1 },
- { "partial_lines", "Linse partially inside scissor area", Vec4(0.4f, 0.4f, 0.6f, 0.6f), Vec4(0.0f, 0.0f, 1.0f, 1.0f), SC::LINE, 30 },
- { "contained_line", "Line fully inside scissor area", Vec4(0.1f, 0.1f, 0.8f, 0.8f), Vec4(0.2f, 0.2f, 0.6f, 0.6f), SC::LINE, 1 },
- { "partial_line", "Line partially inside scissor area", Vec4(0.4f, 0.4f, 0.6f, 0.6f), Vec4(0.0f, 0.0f, 1.0f, 1.0f), SC::LINE, 1 },
- { "outside_render_line", "Line with scissor area outside render target", Vec4(1.4f, 1.4f, 0.6f, 0.6f), Vec4(0.0f, 0.0f, 0.6f, 0.6f), SC::LINE, 1 },
- { "contained_point", "Point fully inside scissor area", Vec4(0.1f, 0.1f, 0.8f, 0.8f), Vec4(0.5f, 0.5f, 0.0f, 0.0f), SC::POINT, 1 },
- { "partial_points", "Points partially inside scissor area", Vec4(0.4f, 0.4f, 0.6f, 0.6f), Vec4(0.0f, 0.0f, 1.0f, 1.0f), SC::POINT, 30 },
- { "outside_point", "Point fully outside scissor area", Vec4(0.4f, 0.4f, 0.6f, 0.6f), Vec4(0.0f, 0.0f, 0.0f, 0.0f), SC::POINT, 1 },
- { "outside_render_point", "Point with scissor area outside render target", Vec4(1.4f, 1.4f, 0.6f, 0.6f), Vec4(0.5f, 0.5f, 0.0f, 0.0f), SC::POINT, 1 }
+ { "contained_quads", "Triangles fully inside scissor area (single call)", Vec4(0.1f, 0.1f, 0.8f, 0.8f), Vec4(0.2f, 0.2f, 0.6f, 0.6f), TRIANGLE, 30 },
+ { "partial_quads", "Triangles partially inside scissor area (single call)", Vec4(0.3f, 0.3f, 0.4f, 0.4f), Vec4(0.2f, 0.2f, 0.6f, 0.6f), TRIANGLE, 30 },
+ { "contained_tri", "Triangle fully inside scissor area", Vec4(0.1f, 0.1f, 0.8f, 0.8f), Vec4(0.2f, 0.2f, 0.6f, 0.6f), TRIANGLE, 1 },
+ { "enclosing_tri", "Triangle fully covering scissor area", Vec4(0.4f, 0.4f, 0.2f, 0.2f), Vec4(0.2f, 0.2f, 0.6f, 0.6f), TRIANGLE, 1 },
+ { "partial_tri", "Triangle partially inside scissor area", Vec4(0.4f, 0.4f, 0.6f, 0.6f), Vec4(0.0f, 0.0f, 1.0f, 1.0f), TRIANGLE, 1 },
+ { "outside_render_tri", "Triangle with scissor area outside render target", Vec4(1.4f, 1.4f, 0.6f, 0.6f), Vec4(0.0f, 0.0f, 0.6f, 0.6f), TRIANGLE, 1 },
+ { "partial_lines", "Linse partially inside scissor area", Vec4(0.4f, 0.4f, 0.6f, 0.6f), Vec4(0.0f, 0.0f, 1.0f, 1.0f), LINE, 30 },
+ { "contained_line", "Line fully inside scissor area", Vec4(0.1f, 0.1f, 0.8f, 0.8f), Vec4(0.2f, 0.2f, 0.6f, 0.6f), LINE, 1 },
+ { "partial_line", "Line partially inside scissor area", Vec4(0.4f, 0.4f, 0.6f, 0.6f), Vec4(0.0f, 0.0f, 1.0f, 1.0f), LINE, 1 },
+ { "outside_render_line", "Line with scissor area outside render target", Vec4(1.4f, 1.4f, 0.6f, 0.6f), Vec4(0.0f, 0.0f, 0.6f, 0.6f), LINE, 1 },
+ { "contained_point", "Point fully inside scissor area", Vec4(0.1f, 0.1f, 0.8f, 0.8f), Vec4(0.5f, 0.5f, 0.0f, 0.0f), POINT, 1 },
+ { "partial_points", "Points partially inside scissor area", Vec4(0.4f, 0.4f, 0.6f, 0.6f), Vec4(0.0f, 0.0f, 1.0f, 1.0f), POINT, 30 },
+ { "outside_point", "Point fully outside scissor area", Vec4(0.4f, 0.4f, 0.6f, 0.6f), Vec4(0.0f, 0.0f, 0.0f, 0.0f), POINT, 1 },
+ { "outside_render_point", "Point with scissor area outside render target", Vec4(1.4f, 1.4f, 0.6f, 0.6f), Vec4(0.5f, 0.5f, 0.0f, 0.0f), POINT, 1 }
};
for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
{
- addChild(SC::createPrimitiveTest(rc,
- tc,
- cases[caseNdx].scissor,
- cases[caseNdx].render,
- cases[caseNdx].type,
- cases[caseNdx].primitives,
- cases[caseNdx].name,
- cases[caseNdx].description));
+ addChild(createPrimitiveTest(tc,
+ rc,
+ cases[caseNdx].name,
+ cases[caseNdx].desc,
+ cases[caseNdx].scissor,
+ cases[caseNdx].render,
+ cases[caseNdx].type,
+ cases[caseNdx].primitives));
}
- addChild(SC::createClearTest(rc, tc, Vec4(0.1f, 0.1f, 0.8f, 0.8f), GL_DEPTH_BUFFER_BIT, "clear_depth", "Depth buffer clear"));
- addChild(SC::createClearTest(rc, tc, Vec4(0.1f, 0.1f, 0.8f, 0.8f), GL_STENCIL_BUFFER_BIT, "clear_stencil", "Stencil buffer clear"));
- addChild(SC::createClearTest(rc, tc, Vec4(0.1f, 0.1f, 0.8f, 0.8f), GL_COLOR_BUFFER_BIT, "clear_color", "Color buffer clear"));
+ addChild(createClearTest(tc, rc, "clear_depth", "Depth buffer clear", Vec4(0.1f, 0.1f, 0.8f, 0.8f), GL_DEPTH_BUFFER_BIT));
+ addChild(createClearTest(tc, rc, "clear_stencil", "Stencil buffer clear", Vec4(0.1f, 0.1f, 0.8f, 0.8f), GL_STENCIL_BUFFER_BIT));
+ addChild(createClearTest(tc, rc, "clear_color", "Color buffer clear", Vec4(0.1f, 0.1f, 0.8f, 0.8f), GL_COLOR_BUFFER_BIT));
- addChild(new FramebufferClearCase(rc, tc, FramebufferClearCase::COLOR_FIXED, "clear_fixed_buffer", "Fixed point color clear"));
- addChild(new FramebufferClearCase(rc, tc, FramebufferClearCase::COLOR_INT, "clear_int_buffer", "Integer color clear"));
- addChild(new FramebufferClearCase(rc, tc, FramebufferClearCase::COLOR_UINT, "clear_uint_buffer", "Unsigned integer buffer clear"));
- addChild(new FramebufferClearCase(rc, tc, FramebufferClearCase::DEPTH, "clear_depth_buffer", "Depth buffer clear"));
- addChild(new FramebufferClearCase(rc, tc, FramebufferClearCase::STENCIL, "clear_stencil_buffer", "Stencil buffer clear"));
- addChild(new FramebufferClearCase(rc, tc, FramebufferClearCase::DEPTH_STENCIL, "clear_depth_stencil_buffer", "Fixed point color buffer clear"));
+ addChild(createFramebufferClearTest(tc, rc, "clear_fixed_buffer", "Fixed point color clear", CLEAR_COLOR_FIXED));
+ addChild(createFramebufferClearTest(tc, rc, "clear_int_buffer", "Integer color clear", CLEAR_COLOR_INT));
+ addChild(createFramebufferClearTest(tc, rc, "clear_uint_buffer", "Unsigned integer buffer clear", CLEAR_COLOR_UINT));
+ addChild(createFramebufferClearTest(tc, rc, "clear_depth_buffer", "Depth buffer clear", CLEAR_DEPTH));
+ addChild(createFramebufferClearTest(tc, rc, "clear_stencil_buffer", "Stencil buffer clear", CLEAR_STENCIL));
+ addChild(createFramebufferClearTest(tc, rc, "clear_depth_stencil_buffer", "Fixed point color buffer clear", CLEAR_DEPTH_STENCIL));
- addChild(new FramebufferBlitCase(rc, tc, Vec4(0.1f, 0.1f, 0.8f, 0.8f), "framebuffer_blit_center", "Blit to default framebuffer, scissor away edges"));
- addChild(new FramebufferBlitCase(rc, tc, Vec4(0.6f, 0.6f, 0.5f, 0.5f), "framebuffer_blit_corner", "Blit to default framebuffer, scissor all but a corner"));
- addChild(new FramebufferBlitCase(rc, tc, Vec4(1.6f, 0.6f, 0.5f, 0.5f), "framebuffer_blit_none", "Blit to default framebuffer, scissor area outside screen"));
+ addChild(createFramebufferBlitTest(tc, rc, "framebuffer_blit_center", "Blit to default framebuffer, scissor away edges", Vec4(0.1f, 0.1f, 0.8f, 0.8f)));
+ addChild(createFramebufferBlitTest(tc, rc, "framebuffer_blit_corner", "Blit to default framebuffer, scissor all but a corner", Vec4(0.6f, 0.6f, 0.5f, 0.5f)));
+ addChild(createFramebufferBlitTest(tc, rc, "framebuffer_blit_none", "Blit to default framebuffer, scissor area outside screen", Vec4(1.6f, 0.6f, 0.5f, 0.5f)));
}
} // Functional
diff --git a/modules/gles3/functional/es3fShaderPrecisionTests.cpp b/modules/gles3/functional/es3fShaderPrecisionTests.cpp
index 0b405fef9..c05b7636d 100644
--- a/modules/gles3/functional/es3fShaderPrecisionTests.cpp
+++ b/modules/gles3/functional/es3fShaderPrecisionTests.cpp
@@ -288,8 +288,8 @@ bool ShaderFloatPrecisionCase::compare (float in0, float in1, double reference,
// Comparison is done using 64-bit reference value to accurately evaluate rounding mode error.
// If 32-bit reference value is used, 2 bits of rounding error must be allowed.
- // For mediump and lowp types the comparison currently allows 2 bits of rounding error:
- // one bit from conversion and another from actual operation.
+ // For mediump and lowp types the comparison currently allows 3 bits of rounding error:
+ // two bits from conversions and one from actual operation.
// \todo [2013-09-30 pyry] Make this more strict: determine if rounding can actually happen.
@@ -301,7 +301,7 @@ bool ShaderFloatPrecisionCase::compare (float in0, float in1, double reference,
const int resExp = tcu::Float32(result).exponent();
const int numLostBits = de::max(de::max(in0Exp-resExp, in1Exp-resExp), 0); // Lost due to mantissa shift.
- const int roundingUlpError = m_precision == glu::PRECISION_HIGHP ? 1 : 2;
+ const int roundingUlpError = m_precision == glu::PRECISION_HIGHP ? 1 : 3;
const int maskBits = numLostBits + numPrecBits;
m_testCtx.getLog() << TestLog::Message << "Assuming " << mantissaBits << " mantissa bits, " << numLostBits << " bits lost in operation, and " << roundingUlpError << " ULP rounding error."
diff --git a/modules/gles3/functional/es3fShaderTextureFunctionTests.cpp b/modules/gles3/functional/es3fShaderTextureFunctionTests.cpp
index 7c9d4361f..a72950b11 100644
--- a/modules/gles3/functional/es3fShaderTextureFunctionTests.cpp
+++ b/modules/gles3/functional/es3fShaderTextureFunctionTests.cpp
@@ -690,7 +690,19 @@ void ShaderTextureFunctionCase::initTexture (void)
Vec4 colorB = cBias + cScale*f.swizzle(swzB[0], swzB[1], swzB[2], swzB[3]);
m_textureCube->getRefTexture().allocLevel((tcu::CubeFace)face, level);
- tcu::fillWithGrid(m_textureCube->getRefTexture().getLevelFace(level, (tcu::CubeFace)face), de::max(1, baseCellSize>>level), colorA, colorB);
+
+ {
+ const tcu::PixelBufferAccess access = m_textureCube->getRefTexture().getLevelFace(level, (tcu::CubeFace)face);
+ const int lastPix = access.getWidth()-1;
+
+ tcu::fillWithGrid(access, de::max(1, baseCellSize>>level), colorA, colorB);
+
+ // Ensure all corners have identical colors in order to avoid dealing with ambiguous corner texel filtering
+ access.setPixel(colorA, 0, 0);
+ access.setPixel(colorA, 0, lastPix);
+ access.setPixel(colorA, lastPix, 0);
+ access.setPixel(colorA, lastPix, lastPix);
+ }
}
}
m_textureCube->upload();
diff --git a/modules/gles3/performance/CMakeLists.txt b/modules/gles3/performance/CMakeLists.txt
index 896954eda..8840b3feb 100644
--- a/modules/gles3/performance/CMakeLists.txt
+++ b/modules/gles3/performance/CMakeLists.txt
@@ -31,6 +31,8 @@ set(DEQP_GLES3_PERFORMANCE_SRCS
es3pBufferDataUploadTests.hpp
es3pShaderOperatorTests.cpp
es3pShaderOperatorTests.hpp
+ es3pDepthTests.hpp
+ es3pDepthTests.cpp
)
add_library(deqp-gles3-performance STATIC ${DEQP_GLES3_PERFORMANCE_SRCS})
diff --git a/modules/gles3/performance/es3pBufferDataUploadTests.cpp b/modules/gles3/performance/es3pBufferDataUploadTests.cpp
index c9758c4f4..45bd25fb2 100644
--- a/modules/gles3/performance/es3pBufferDataUploadTests.cpp
+++ b/modules/gles3/performance/es3pBufferDataUploadTests.cpp
@@ -22,6 +22,7 @@
*//*--------------------------------------------------------------------*/
#include "es3pBufferDataUploadTests.hpp"
+#include "glsCalibration.hpp"
#include "tcuTestLog.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuSurface.hpp"
@@ -54,6 +55,9 @@ namespace Performance
namespace
{
+using gls::theilSenSiegelLinearRegression;
+using gls::LineParametersWithConfidence;
+
static const char* const s_dummyVertexShader = "#version 300 es\n"
"in highp vec4 a_position;\n"
"void main (void)\n"
@@ -497,16 +501,6 @@ struct SampleTypeTraits<RenderUploadRenderReadDuration>
enum { LOG_UNRELATED_UPLOAD_SIZE = 1 };
};
-struct TheilSenLineFit
-{
- float coefficient;
- float coefficient60ConfidenceUpper;
- float coefficient60ConfidenceLower;
- float offset;
- float offset60ConfidenceUpper;
- float offset60ConfidenceLower;
-};
-
struct UploadSampleAnalyzeResult
{
float transferRateMedian;
@@ -689,63 +683,6 @@ static float linearSample (const std::vector<T>& values, float position)
return tcu::mix((float)values[lowerNdx], (float)values[higherNdx], interpolationFactor);
}
-static TheilSenLineFit theilSenLinearRegression (const std::vector<tcu::Vec2>& dataPoints)
-{
- DE_ASSERT(!dataPoints.empty());
-
- // \note Based on gls::theilSenEstimator()
- // Siegel's variation
-
- const float epsilon = 1e-6f;
- int numDataPoints = (int)dataPoints.size();
- std::vector<float> medianSlopes;
- std::vector<float> pointwiseOffsets;
- TheilSenLineFit result;
-
- // Compute the median slope via each element
- for (int i = 0; i < numDataPoints; i++)
- {
- const tcu::Vec2& ptA = dataPoints[i];
- std::vector<float> slopes;
-
- for (int j = 0; j < numDataPoints; j++)
- {
- const tcu::Vec2& ptB = dataPoints[j];
-
- if (de::abs(ptA.x() - ptB.x()) > epsilon)
- slopes.push_back((ptA.y() - ptB.y()) / (ptA.x() - ptB.x()));
- }
-
- std::sort(slopes.begin(), slopes.end());
- medianSlopes.push_back(linearSample(slopes, 0.5f));
- }
-
- DE_ASSERT(!medianSlopes.empty());
-
- // Find the median of the pairwise coefficients.
- std::sort(medianSlopes.begin(), medianSlopes.end());
- result.coefficient = linearSample(medianSlopes, 0.5f);
-
- // Compute the offsets corresponding to the median coefficient, for all data points.
- for (int i = 0; i < numDataPoints; i++)
- pointwiseOffsets.push_back(dataPoints[i].y() - result.coefficient*dataPoints[i].x());
-
- // Find the median of the offsets.
- std::sort(pointwiseOffsets.begin(), pointwiseOffsets.end());
- result.offset = linearSample(pointwiseOffsets, 0.5f);
-
- // calculate 60% confidence intervals
- {
- result.coefficient60ConfidenceLower = linearSample(medianSlopes, 0.2f);
- result.coefficient60ConfidenceUpper = linearSample(medianSlopes, 0.8f);
-
- result.offset60ConfidenceLower = linearSample(pointwiseOffsets, 0.2f);
- result.offset60ConfidenceUpper = linearSample(pointwiseOffsets, 0.8f);
- }
-
- return result;
-}
-
template <typename T>
SingleOperationStatistics calculateSingleOperationStatistics (const std::vector<T>& samples, deUint64 T::SampleType::*target)
{
@@ -767,7 +704,7 @@ SingleOperationStatistics calculateSingleOperationStatistics (const std::vector<
}
template <typename StatisticsType, typename SampleType>
-void calculateBasicStatistics (StatisticsType& stats, const TheilSenLineFit& fit, const std::vector<SampleType>& samples, int SampleType::*predictor)
+void calculateBasicStatistics (StatisticsType& stats, const LineParametersWithConfidence& fit, const std::vector<SampleType>& samples, int SampleType::*predictor)
{
std::vector<deUint64> values(samples.size());
@@ -842,18 +779,18 @@ void calculateBasicStatistics (StatisticsType& stats, const TheilSenLineFit& fit
}
template <typename StatisticsType, typename SampleType>
-void calculateBasicTransferStatistics (StatisticsType& stats, const TheilSenLineFit& fit, const std::vector<SampleType>& samples)
+void calculateBasicTransferStatistics (StatisticsType& stats, const LineParametersWithConfidence& fit, const std::vector<SampleType>& samples)
{
calculateBasicStatistics(stats, fit, samples, &SampleType::writtenSize);
}
template <typename StatisticsType, typename SampleType>
-void calculateBasicRenderStatistics (StatisticsType& stats, const TheilSenLineFit& fit, const std::vector<SampleType>& samples)
+void calculateBasicRenderStatistics (StatisticsType& stats, const LineParametersWithConfidence& fit, const std::vector<SampleType>& samples)
{
calculateBasicStatistics(stats, fit, samples, &SampleType::renderDataSize);
}
-static SingleCallStatistics calculateSampleStatistics (const TheilSenLineFit& fit, const std::vector<UploadSampleResult<SingleOperationDuration> >& samples)
+static SingleCallStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<UploadSampleResult<SingleOperationDuration> >& samples)
{
SingleCallStatistics stats;
@@ -862,7 +799,7 @@ static SingleCallStatistics calculateSampleStatistics (const TheilSenLineFit& fi
return stats;
}
-static MapCallStatistics calculateSampleStatistics (const TheilSenLineFit& fit, const std::vector<UploadSampleResult<MapBufferRangeDuration> >& samples)
+static MapCallStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<UploadSampleResult<MapBufferRangeDuration> >& samples)
{
MapCallStatistics stats;
@@ -876,7 +813,7 @@ static MapCallStatistics calculateSampleStatistics (const TheilSenLineFit& fit,
return stats;
}
-static MapFlushCallStatistics calculateSampleStatistics (const TheilSenLineFit& fit, const std::vector<UploadSampleResult<MapBufferRangeFlushDuration> >& samples)
+static MapFlushCallStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<UploadSampleResult<MapBufferRangeFlushDuration> >& samples)
{
MapFlushCallStatistics stats;
@@ -891,7 +828,7 @@ static MapFlushCallStatistics calculateSampleStatistics (const TheilSenLineFit&
return stats;
}
-static MapCallStatistics calculateSampleStatistics (const TheilSenLineFit& fit, const std::vector<UploadSampleResult<MapBufferRangeDurationNoAlloc> >& samples)
+static MapCallStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<UploadSampleResult<MapBufferRangeDurationNoAlloc> >& samples)
{
MapCallStatistics stats;
@@ -904,7 +841,7 @@ static MapCallStatistics calculateSampleStatistics (const TheilSenLineFit& fit,
return stats;
}
-static MapFlushCallStatistics calculateSampleStatistics (const TheilSenLineFit& fit, const std::vector<UploadSampleResult<MapBufferRangeFlushDurationNoAlloc> >& samples)
+static MapFlushCallStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<UploadSampleResult<MapBufferRangeFlushDurationNoAlloc> >& samples)
{
MapFlushCallStatistics stats;
@@ -918,7 +855,7 @@ static MapFlushCallStatistics calculateSampleStatistics (const TheilSenLineFit&
return stats;
}
-static RenderReadStatistics calculateSampleStatistics (const TheilSenLineFit& fit, const std::vector<RenderSampleResult<RenderReadDuration> >& samples)
+static RenderReadStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<RenderSampleResult<RenderReadDuration> >& samples)
{
RenderReadStatistics stats;
@@ -931,7 +868,7 @@ static RenderReadStatistics calculateSampleStatistics (const TheilSenLineFit& fi
return stats;
}
-static RenderReadStatistics calculateSampleStatistics (const TheilSenLineFit& fit, const std::vector<RenderSampleResult<UnrelatedUploadRenderReadDuration> >& samples)
+static RenderReadStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<RenderSampleResult<UnrelatedUploadRenderReadDuration> >& samples)
{
RenderReadStatistics stats;
@@ -944,7 +881,7 @@ static RenderReadStatistics calculateSampleStatistics (const TheilSenLineFit& fi
return stats;
}
-static UploadRenderReadStatistics calculateSampleStatistics (const TheilSenLineFit& fit, const std::vector<RenderSampleResult<UploadRenderReadDuration> >& samples)
+static UploadRenderReadStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<RenderSampleResult<UploadRenderReadDuration> >& samples)
{
UploadRenderReadStatistics stats;
@@ -958,7 +895,7 @@ static UploadRenderReadStatistics calculateSampleStatistics (const TheilSenLineF
return stats;
}
-static UploadRenderReadStatistics calculateSampleStatistics (const TheilSenLineFit& fit, const std::vector<RenderSampleResult<UploadRenderReadDurationWithUnrelatedUploadSize> >& samples)
+static UploadRenderReadStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<RenderSampleResult<UploadRenderReadDurationWithUnrelatedUploadSize> >& samples)
{
UploadRenderReadStatistics stats;
@@ -972,7 +909,7 @@ static UploadRenderReadStatistics calculateSampleStatistics (const TheilSenLineF
return stats;
}
-static RenderUploadRenderReadStatistics calculateSampleStatistics (const TheilSenLineFit& fit, const std::vector<RenderSampleResult<RenderUploadRenderReadDuration> >& samples)
+static RenderUploadRenderReadStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<RenderSampleResult<RenderUploadRenderReadDuration> >& samples)
{
RenderUploadRenderReadStatistics stats;
@@ -988,7 +925,7 @@ static RenderUploadRenderReadStatistics calculateSampleStatistics (const TheilSe
}
template <typename DurationType>
-static TheilSenLineFit fitLineToSamples (const std::vector<UploadSampleResult<DurationType> >& samples, int beginNdx, int endNdx, int step, deUint64 DurationType::*target = &DurationType::fitResponseDuration)
+static LineParametersWithConfidence fitLineToSamples (const std::vector<UploadSampleResult<DurationType> >& samples, int beginNdx, int endNdx, int step, deUint64 DurationType::*target = &DurationType::fitResponseDuration)
{
std::vector<tcu::Vec2> samplePoints;
@@ -1002,11 +939,11 @@ static TheilSenLineFit fitLineToSamples (const std::vector<UploadSampleResult<Du
samplePoints.push_back(point);
}
- return theilSenLinearRegression(samplePoints);
+ return theilSenSiegelLinearRegression(samplePoints, 0.6f);
}
template <typename DurationType>
-static TheilSenLineFit fitLineToSamples (const std::vector<RenderSampleResult<DurationType> >& samples, int beginNdx, int endNdx, int step, deUint64 DurationType::*target = &DurationType::fitResponseDuration)
+static LineParametersWithConfidence fitLineToSamples (const std::vector<RenderSampleResult<DurationType> >& samples, int beginNdx, int endNdx, int step, deUint64 DurationType::*target = &DurationType::fitResponseDuration)
{
std::vector<tcu::Vec2> samplePoints;
@@ -1020,17 +957,17 @@ static TheilSenLineFit fitLineToSamples (const std::vector<RenderSampleResult<Du
samplePoints.push_back(point);
}
- return theilSenLinearRegression(samplePoints);
+ return theilSenSiegelLinearRegression(samplePoints, 0.6f);
}
template <typename T>
-static TheilSenLineFit fitLineToSamples (const std::vector<T>& samples, int beginNdx, int endNdx, deUint64 T::SampleType::*target = &T::SampleType::fitResponseDuration)
+static LineParametersWithConfidence fitLineToSamples (const std::vector<T>& samples, int beginNdx, int endNdx, deUint64 T::SampleType::*target = &T::SampleType::fitResponseDuration)
{
return fitLineToSamples(samples, beginNdx, endNdx, 1, target);
}
template <typename T>
-static TheilSenLineFit fitLineToSamples (const std::vector<T>& samples, deUint64 T::SampleType::*target = &T::SampleType::fitResponseDuration)
+static LineParametersWithConfidence fitLineToSamples (const std::vector<T>& samples, deUint64 T::SampleType::*target = &T::SampleType::fitResponseDuration)
{
return fitLineToSamples(samples, 0, (int)samples.size(), target);
}
@@ -1083,8 +1020,8 @@ static float calculateSampleFitLinearity (const std::vector<T>& samples, int T::
const float epsilon = 1.e-6f;
const int midPoint = (int)samples.size() / 2;
- const TheilSenLineFit startApproximation = fitLineToSamples(samples, 0, midPoint, &T::SampleType::fitResponseDuration);
- const TheilSenLineFit endApproximation = fitLineToSamples(samples, midPoint, (int)samples.size(), &T::SampleType::fitResponseDuration);
+ const LineParametersWithConfidence startApproximation = fitLineToSamples(samples, 0, midPoint, &T::SampleType::fitResponseDuration);
+ const LineParametersWithConfidence endApproximation = fitLineToSamples(samples, midPoint, (int)samples.size(), &T::SampleType::fitResponseDuration);
const float aabbMinX = (float)(samples.front().*predictor);
const float aabbMinY = de::min(startApproximation.offset + startApproximation.coefficient*aabbMinX, endApproximation.offset + endApproximation.coefficient*aabbMinX);
@@ -1119,8 +1056,8 @@ static float calculateSampleTemporalStability (const std::vector<T>& samples, in
// the lines and the AABB.
const float epsilon = 1.e-6f;
- const TheilSenLineFit evenApproximation = fitLineToSamples(samples, 0, (int)samples.size(), 2, &T::SampleType::fitResponseDuration);
- const TheilSenLineFit oddApproximation = fitLineToSamples(samples, 1, (int)samples.size(), 2, &T::SampleType::fitResponseDuration);
+ const LineParametersWithConfidence evenApproximation = fitLineToSamples(samples, 0, (int)samples.size(), 2, &T::SampleType::fitResponseDuration);
+ const LineParametersWithConfidence oddApproximation = fitLineToSamples(samples, 1, (int)samples.size(), 2, &T::SampleType::fitResponseDuration);
const float aabbMinX = (float)(samples.front().*predictor);
const float aabbMinY = de::min(evenApproximation.offset + evenApproximation.coefficient*aabbMinX, oddApproximation.offset + oddApproximation.coefficient*aabbMinX);
@@ -1259,7 +1196,7 @@ static typename EnableIfNot<void, SampleTypeTraits<SampleType>::HAS_ALLOC_STATS>
template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_MAP_STATS>::Type logMapContribution (tcu::TestLog& log, const std::vector<UploadSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
- const TheilSenLineFit contributionFitting = fitLineToSamples(samples, &SampleType::mapDuration);
+ const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::mapDuration);
log << tcu::TestLog::Float("MapConstantCost", "Map: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
<< tcu::TestLog::Float("MapLinearCost", "Map: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
<< tcu::TestLog::Float("MapMedianCost", "Map: Median cost", "us", QP_KEY_TAG_TIME, stats.map.medianTime);
@@ -1268,7 +1205,7 @@ static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_MAP_STATS>::Typ
template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_UNMAP_STATS>::Type logUnmapContribution (tcu::TestLog& log, const std::vector<UploadSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
- const TheilSenLineFit contributionFitting = fitLineToSamples(samples, &SampleType::unmapDuration);
+ const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::unmapDuration);
log << tcu::TestLog::Float("UnmapConstantCost", "Unmap: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
<< tcu::TestLog::Float("UnmapLinearCost", "Unmap: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
<< tcu::TestLog::Float("UnmapMedianCost", "Unmap: Median cost", "us", QP_KEY_TAG_TIME, stats.unmap.medianTime);
@@ -1277,7 +1214,7 @@ static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_UNMAP_STATS>::T
template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_WRITE_STATS>::Type logWriteContribution (tcu::TestLog& log, const std::vector<UploadSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
- const TheilSenLineFit contributionFitting = fitLineToSamples(samples, &SampleType::writeDuration);
+ const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::writeDuration);
log << tcu::TestLog::Float("WriteConstantCost", "Write: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
<< tcu::TestLog::Float("WriteLinearCost", "Write: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
<< tcu::TestLog::Float("WriteMedianCost", "Write: Median cost", "us", QP_KEY_TAG_TIME, stats.write.medianTime);
@@ -1286,7 +1223,7 @@ static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_WRITE_STATS>::T
template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_FLUSH_STATS>::Type logFlushContribution (tcu::TestLog& log, const std::vector<UploadSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
- const TheilSenLineFit contributionFitting = fitLineToSamples(samples, &SampleType::flushDuration);
+ const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::flushDuration);
log << tcu::TestLog::Float("FlushConstantCost", "Flush: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
<< tcu::TestLog::Float("FlushLinearCost", "Flush: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
<< tcu::TestLog::Float("FlushMedianCost", "Flush: Median cost", "us", QP_KEY_TAG_TIME, stats.flush.medianTime);
@@ -1295,7 +1232,7 @@ static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_FLUSH_STATS>::T
template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_ALLOC_STATS>::Type logAllocContribution (tcu::TestLog& log, const std::vector<UploadSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
- const TheilSenLineFit contributionFitting = fitLineToSamples(samples, &SampleType::allocDuration);
+ const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::allocDuration);
log << tcu::TestLog::Float("AllocConstantCost", "Alloc: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
<< tcu::TestLog::Float("AllocLinearCost", "Alloc: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
<< tcu::TestLog::Float("AllocMedianCost", "Alloc: Median cost", "us", QP_KEY_TAG_TIME, stats.alloc.medianTime);
@@ -1304,7 +1241,7 @@ static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_ALLOC_STATS>::T
template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_RENDER_STATS>::Type logRenderContribution (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
- const TheilSenLineFit contributionFitting = fitLineToSamples(samples, &SampleType::renderDuration);
+ const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::renderDuration);
log << tcu::TestLog::Float("DrawCallConstantCost", "DrawCall: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
<< tcu::TestLog::Float("DrawCallLinearCost", "DrawCall: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
<< tcu::TestLog::Float("DrawCallMedianCost", "DrawCall: Median cost", "us", QP_KEY_TAG_TIME, stats.render.medianTime);
@@ -1313,7 +1250,7 @@ static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_RENDER_STATS>::
template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_READ_STATS>::Type logReadContribution (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
- const TheilSenLineFit contributionFitting = fitLineToSamples(samples, &SampleType::readDuration);
+ const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::readDuration);
log << tcu::TestLog::Float("ReadConstantCost", "Read: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
<< tcu::TestLog::Float("ReadLinearCost", "Read: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
<< tcu::TestLog::Float("ReadMedianCost", "Read: Median cost", "us", QP_KEY_TAG_TIME, stats.read.medianTime);
@@ -1322,7 +1259,7 @@ static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_READ_STATS>::Ty
template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_UPLOAD_STATS>::Type logUploadContribution (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
- const TheilSenLineFit contributionFitting = fitLineToSamples(samples, &SampleType::uploadDuration);
+ const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::uploadDuration);
log << tcu::TestLog::Float("UploadConstantCost", "Upload: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
<< tcu::TestLog::Float("UploadLinearCost", "Upload: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
<< tcu::TestLog::Float("UploadMedianCost", "Upload: Median cost", "us", QP_KEY_TAG_TIME, stats.upload.medianTime);
@@ -1331,7 +1268,7 @@ static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_UPLOAD_STATS>::
template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_TOTAL_STATS>::Type logTotalContribution (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
- const TheilSenLineFit contributionFitting = fitLineToSamples(samples, &SampleType::totalDuration);
+ const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::totalDuration);
log << tcu::TestLog::Float("TotalConstantCost", "Total: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
<< tcu::TestLog::Float("TotalLinearCost", "Total: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
<< tcu::TestLog::Float("TotalMedianCost", "Total: Median cost", "us", QP_KEY_TAG_TIME, stats.total.medianTime);
@@ -1340,7 +1277,7 @@ static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_TOTAL_STATS>::T
template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_FIRST_RENDER_STATS>::Type logFirstRenderContribution (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
- const TheilSenLineFit contributionFitting = fitLineToSamples(samples, &SampleType::firstRenderDuration);
+ const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::firstRenderDuration);
log << tcu::TestLog::Float("FirstDrawCallConstantCost", "First DrawCall: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
<< tcu::TestLog::Float("FirstDrawCallLinearCost", "First DrawCall: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
<< tcu::TestLog::Float("FirstDrawCallMedianCost", "First DrawCall: Median cost", "us", QP_KEY_TAG_TIME, stats.firstRender.medianTime);
@@ -1349,7 +1286,7 @@ static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_FIRST_RENDER_ST
template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_SECOND_RENDER_STATS>::Type logSecondRenderContribution (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
- const TheilSenLineFit contributionFitting = fitLineToSamples(samples, &SampleType::secondRenderDuration);
+ const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::secondRenderDuration);
log << tcu::TestLog::Float("SecondDrawCallConstantCost", "Second DrawCall: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
<< tcu::TestLog::Float("SecondDrawCallLinearCost", "Second DrawCall: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
<< tcu::TestLog::Float("SecondDrawCallMedianCost", "Second DrawCall: Median cost", "us", QP_KEY_TAG_TIME, stats.secondRender.medianTime);
@@ -1443,7 +1380,7 @@ static typename EnableIfNot<void, SampleTypeTraits<SampleType>::HAS_SECOND_RENDE
DE_UNREF(stats);
}
-void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, const std::vector<UploadSampleResult<SingleOperationDuration> >& samples)
+void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<UploadSampleResult<SingleOperationDuration> >& samples)
{
log << tcu::TestLog::SampleList("Samples", "Samples")
<< tcu::TestLog::SampleInfo
@@ -1467,7 +1404,7 @@ void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, c
log << tcu::TestLog::EndSampleList;
}
-void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, const std::vector<UploadSampleResult<MapBufferRangeDuration> >& samples)
+void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<UploadSampleResult<MapBufferRangeDuration> >& samples)
{
log << tcu::TestLog::SampleList("Samples", "Samples")
<< tcu::TestLog::SampleInfo
@@ -1499,7 +1436,7 @@ void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, c
log << tcu::TestLog::EndSampleList;
}
-void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, const std::vector<UploadSampleResult<MapBufferRangeDurationNoAlloc> >& samples)
+void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<UploadSampleResult<MapBufferRangeDurationNoAlloc> >& samples)
{
log << tcu::TestLog::SampleList("Samples", "Samples")
<< tcu::TestLog::SampleInfo
@@ -1529,7 +1466,7 @@ void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, c
log << tcu::TestLog::EndSampleList;
}
-void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, const std::vector<UploadSampleResult<MapBufferRangeFlushDuration> >& samples)
+void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<UploadSampleResult<MapBufferRangeFlushDuration> >& samples)
{
log << tcu::TestLog::SampleList("Samples", "Samples")
<< tcu::TestLog::SampleInfo
@@ -1563,7 +1500,7 @@ void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, c
log << tcu::TestLog::EndSampleList;
}
-void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, const std::vector<UploadSampleResult<MapBufferRangeFlushDurationNoAlloc> >& samples)
+void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<UploadSampleResult<MapBufferRangeFlushDurationNoAlloc> >& samples)
{
log << tcu::TestLog::SampleList("Samples", "Samples")
<< tcu::TestLog::SampleInfo
@@ -1595,7 +1532,7 @@ void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, c
log << tcu::TestLog::EndSampleList;
}
-void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, const std::vector<RenderSampleResult<RenderReadDuration> >& samples)
+void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<RenderSampleResult<RenderReadDuration> >& samples)
{
log << tcu::TestLog::SampleList("Samples", "Samples")
<< tcu::TestLog::SampleInfo
@@ -1623,7 +1560,7 @@ void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, c
log << tcu::TestLog::EndSampleList;
}
-void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, const std::vector<RenderSampleResult<UnrelatedUploadRenderReadDuration> >& samples)
+void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<RenderSampleResult<UnrelatedUploadRenderReadDuration> >& samples)
{
log << tcu::TestLog::SampleList("Samples", "Samples")
<< tcu::TestLog::SampleInfo
@@ -1653,7 +1590,7 @@ void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, c
log << tcu::TestLog::EndSampleList;
}
-void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, const std::vector<RenderSampleResult<UploadRenderReadDuration> >& samples)
+void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<RenderSampleResult<UploadRenderReadDuration> >& samples)
{
log << tcu::TestLog::SampleList("Samples", "Samples")
<< tcu::TestLog::SampleInfo
@@ -1687,7 +1624,7 @@ void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, c
log << tcu::TestLog::EndSampleList;
}
-void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, const std::vector<RenderSampleResult<UploadRenderReadDurationWithUnrelatedUploadSize> >& samples)
+void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<RenderSampleResult<UploadRenderReadDurationWithUnrelatedUploadSize> >& samples)
{
log << tcu::TestLog::SampleList("Samples", "Samples")
<< tcu::TestLog::SampleInfo
@@ -1723,7 +1660,7 @@ void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, c
log << tcu::TestLog::EndSampleList;
}
-void logSampleList (tcu::TestLog& log, const TheilSenLineFit& theilSenFitting, const std::vector<RenderSampleResult<RenderUploadRenderReadDuration> >& samples)
+void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<RenderSampleResult<RenderUploadRenderReadDuration> >& samples)
{
log << tcu::TestLog::SampleList("Samples", "Samples")
<< tcu::TestLog::SampleInfo
@@ -1763,7 +1700,7 @@ template <typename SampleType>
static UploadSampleAnalyzeResult analyzeSampleResults (tcu::TestLog& log, const std::vector<UploadSampleResult<SampleType> >& samples, bool logBucketPerformance)
{
// Assume data is linear with some outliers, fit a line
- const TheilSenLineFit theilSenFitting = fitLineToSamples(samples);
+ const LineParametersWithConfidence theilSenFitting = fitLineToSamples(samples);
const typename SampleTypeTraits<SampleType>::StatsType resultStats = calculateSampleStatistics(theilSenFitting, samples);
float approximatedTransferRate;
float approximatedTransferRateNoConstant;
@@ -1845,11 +1782,11 @@ static UploadSampleAnalyzeResult analyzeSampleResults (tcu::TestLog& log, const
log << tcu::TestLog::Float("ResultLinearity", "Sample linearity", "%", QP_KEY_TAG_QUALITY, sampleLinearity * 100.0f)
<< tcu::TestLog::Float("SampleTemporalStability", "Sample temporal stability", "%", QP_KEY_TAG_QUALITY, sampleTemporalStability * 100.0f)
<< tcu::TestLog::Float("ApproximatedConstantCost", "Approximated contant cost", "us", QP_KEY_TAG_TIME, theilSenFitting.offset)
- << tcu::TestLog::Float("ApproximatedConstantCostConfidence60Lower", "Approximated contant cost 60% confidence lower limit", "us", QP_KEY_TAG_TIME, theilSenFitting.offset60ConfidenceLower)
- << tcu::TestLog::Float("ApproximatedConstantCostConfidence60Upper", "Approximated contant cost 60% confidence upper limit", "us", QP_KEY_TAG_TIME, theilSenFitting.offset60ConfidenceUpper)
+ << tcu::TestLog::Float("ApproximatedConstantCostConfidence60Lower", "Approximated contant cost 60% confidence lower limit", "us", QP_KEY_TAG_TIME, theilSenFitting.offsetConfidenceLower)
+ << tcu::TestLog::Float("ApproximatedConstantCostConfidence60Upper", "Approximated contant cost 60% confidence upper limit", "us", QP_KEY_TAG_TIME, theilSenFitting.offsetConfidenceUpper)
<< tcu::TestLog::Float("ApproximatedLinearCost", "Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, theilSenFitting.coefficient * 1024.0f * 1024.0f)
- << tcu::TestLog::Float("ApproximatedLinearCostConfidence60Lower", "Approximated linear cost 60% confidence lower limit", "us / MB", QP_KEY_TAG_TIME, theilSenFitting.coefficient60ConfidenceLower * 1024.0f * 1024.0f)
- << tcu::TestLog::Float("ApproximatedLinearCostConfidence60Upper", "Approximated linear cost 60% confidence upper limit", "us / MB", QP_KEY_TAG_TIME, theilSenFitting.coefficient60ConfidenceUpper * 1024.0f * 1024.0f)
+ << tcu::TestLog::Float("ApproximatedLinearCostConfidence60Lower", "Approximated linear cost 60% confidence lower limit", "us / MB", QP_KEY_TAG_TIME, theilSenFitting.coefficientConfidenceLower * 1024.0f * 1024.0f)
+ << tcu::TestLog::Float("ApproximatedLinearCostConfidence60Upper", "Approximated linear cost 60% confidence upper limit", "us / MB", QP_KEY_TAG_TIME, theilSenFitting.coefficientConfidenceUpper * 1024.0f * 1024.0f)
<< tcu::TestLog::Float("ApproximatedTransferRate", "Approximated transfer rate", "MB / s", QP_KEY_TAG_PERFORMANCE, approximatedTransferRate / 1024.0f / 1024.0f)
<< tcu::TestLog::Float("ApproximatedTransferRateNoConstant", "Approximated transfer rate without constant cost", "MB / s", QP_KEY_TAG_PERFORMANCE, approximatedTransferRateNoConstant / 1024.0f / 1024.0f)
<< tcu::TestLog::Float("SampleMedianTime", "Median sample time", "us", QP_KEY_TAG_TIME, resultStats.result.medianTime)
@@ -1872,7 +1809,7 @@ template <typename SampleType>
static RenderSampleAnalyzeResult analyzeSampleResults (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples)
{
// Assume data is linear with some outliers, fit a line
- const TheilSenLineFit theilSenFitting = fitLineToSamples(samples);
+ const LineParametersWithConfidence theilSenFitting = fitLineToSamples(samples);
const typename SampleTypeTraits<SampleType>::StatsType resultStats = calculateSampleStatistics(theilSenFitting, samples);
float approximatedProcessingRate;
float approximatedProcessingRateNoConstant;
@@ -1912,11 +1849,11 @@ static RenderSampleAnalyzeResult analyzeSampleResults (tcu::TestLog& log, const
log << tcu::TestLog::Float("ResultLinearity", "Sample linearity", "%", QP_KEY_TAG_QUALITY, sampleLinearity * 100.0f)
<< tcu::TestLog::Float("SampleTemporalStability", "Sample temporal stability", "%", QP_KEY_TAG_QUALITY, sampleTemporalStability * 100.0f)
<< tcu::TestLog::Float("ApproximatedConstantCost", "Approximated contant cost", "us", QP_KEY_TAG_TIME, theilSenFitting.offset)
- << tcu::TestLog::Float("ApproximatedConstantCostConfidence60Lower", "Approximated contant cost 60% confidence lower limit", "us", QP_KEY_TAG_TIME, theilSenFitting.offset60ConfidenceLower)
- << tcu::TestLog::Float("ApproximatedConstantCostConfidence60Upper", "Approximated contant cost 60% confidence upper limit", "us", QP_KEY_TAG_TIME, theilSenFitting.offset60ConfidenceUpper)
+ << tcu::TestLog::Float("ApproximatedConstantCostConfidence60Lower", "Approximated contant cost 60% confidence lower limit", "us", QP_KEY_TAG_TIME, theilSenFitting.offsetConfidenceLower)
+ << tcu::TestLog::Float("ApproximatedConstantCostConfidence60Upper", "Approximated contant cost 60% confidence upper limit", "us", QP_KEY_TAG_TIME, theilSenFitting.offsetConfidenceUpper)
<< tcu::TestLog::Float("ApproximatedLinearCost", "Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, theilSenFitting.coefficient * 1024.0f * 1024.0f)
- << tcu::TestLog::Float("ApproximatedLinearCostConfidence60Lower", "Approximated linear cost 60% confidence lower limit", "us / MB", QP_KEY_TAG_TIME, theilSenFitting.coefficient60ConfidenceLower * 1024.0f * 1024.0f)
- << tcu::TestLog::Float("ApproximatedLinearCostConfidence60Upper", "Approximated linear cost 60% confidence upper limit", "us / MB", QP_KEY_TAG_TIME, theilSenFitting.coefficient60ConfidenceUpper * 1024.0f * 1024.0f)
+ << tcu::TestLog::Float("ApproximatedLinearCostConfidence60Lower", "Approximated linear cost 60% confidence lower limit", "us / MB", QP_KEY_TAG_TIME, theilSenFitting.coefficientConfidenceLower * 1024.0f * 1024.0f)
+ << tcu::TestLog::Float("ApproximatedLinearCostConfidence60Upper", "Approximated linear cost 60% confidence upper limit", "us / MB", QP_KEY_TAG_TIME, theilSenFitting.coefficientConfidenceUpper * 1024.0f * 1024.0f)
<< tcu::TestLog::Float("ApproximatedProcessRate", "Approximated processing rate", "MB / s", QP_KEY_TAG_PERFORMANCE, approximatedProcessingRate / 1024.0f / 1024.0f)
<< tcu::TestLog::Float("ApproximatedProcessRateNoConstant", "Approximated processing rate without constant cost", "MB / s", QP_KEY_TAG_PERFORMANCE, approximatedProcessingRateNoConstant / 1024.0f / 1024.0f)
<< tcu::TestLog::Float("SampleMedianTime", "Median sample time", "us", QP_KEY_TAG_TIME, resultStats.result.medianTime)
@@ -6233,9 +6170,9 @@ bool UploadWaitDrawCase::checkSampleTemporalStability (deUint64 (UploadWaitDrawC
{
// Try to find correlation with sample order and sample times
- const int numDataPoints = (int)m_iterationOrder.size();
- std::vector<tcu::Vec2> dataPoints (m_iterationOrder.size());
- TheilSenLineFit lineFit;
+ const int numDataPoints = (int)m_iterationOrder.size();
+ std::vector<tcu::Vec2> dataPoints (m_iterationOrder.size());
+ LineParametersWithConfidence lineFit;
for (int ndx = 0; ndx < (int)m_iterationOrder.size(); ++ndx)
{
@@ -6243,7 +6180,7 @@ bool UploadWaitDrawCase::checkSampleTemporalStability (deUint64 (UploadWaitDrawC
dataPoints[m_iterationOrder[ndx]].y() = (float)(m_results[m_iterationOrder[ndx]].*target);
}
- lineFit = theilSenLinearRegression(dataPoints);
+ lineFit = theilSenSiegelLinearRegression(dataPoints, 0.6f);
// Difference of more than 25% of the offset along the whole sample range
if (de::abs(lineFit.coefficient) * numDataPoints > de::abs(lineFit.offset) * 0.25f)
diff --git a/modules/gles3/performance/es3pDepthTests.cpp b/modules/gles3/performance/es3pDepthTests.cpp
new file mode 100644
index 000000000..2638a1eba
--- /dev/null
+++ b/modules/gles3/performance/es3pDepthTests.cpp
@@ -0,0 +1,1911 @@
+/*-------------------------------------------------------------------------
+ * 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 Depth buffer performance tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "es3pDepthTests.hpp"
+
+#include "glsCalibration.hpp"
+
+#include "gluShaderProgram.hpp"
+#include "gluObjectWrapper.hpp"
+#include "gluPixelTransfer.hpp"
+
+#include "glwFunctions.hpp"
+#include "glwEnums.hpp"
+
+#include "tcuTestLog.hpp"
+#include "tcuStringTemplate.hpp"
+#include "tcuCPUWarmup.hpp"
+#include "tcuCommandLine.hpp"
+
+#include "deClock.h"
+#include "deString.h"
+#include "deMath.h"
+#include "deStringUtil.hpp"
+#include "deRandom.hpp"
+#include "deUniquePtr.hpp"
+
+#include <vector>
+#include <algorithm>
+
+namespace deqp
+{
+namespace gles3
+{
+namespace Performance
+{
+namespace
+{
+using namespace glw;
+using de::MovePtr;
+using tcu::TestContext;
+using tcu::TestLog;
+using tcu::Vec4;
+using tcu::Vec3;
+using tcu::Vec2;
+using glu::RenderContext;
+using glu::ProgramSources;
+using glu::ShaderSource;
+using std::vector;
+using std::string;
+using std::map;
+
+struct Sample
+{
+ deInt64 nullTime;
+ deInt64 baseTime;
+ deInt64 testTime;
+ int order;
+ int workload;
+};
+
+struct SampleParams
+{
+ int step;
+ int measurement;
+
+ SampleParams(int step_, int measurement_) : step(step_), measurement(measurement_) {}
+};
+
+typedef vector<float> Geometry;
+
+struct ObjectData
+{
+ ProgramSources shader;
+ Geometry geometry;
+
+ ObjectData (const ProgramSources& shader_, const Geometry& geometry_) : shader(shader_), geometry(geometry_) {}
+};
+
+class RenderData
+{
+public:
+ RenderData (const ObjectData& object, const glu::RenderContext& renderCtx, TestLog& log);
+ ~RenderData (void) {};
+
+ const glu::ShaderProgram m_program;
+ const glu::VertexArray m_vao;
+ const glu::Buffer m_vbo;
+
+ const int m_numVertices;
+};
+
+RenderData::RenderData (const ObjectData& object, const glu::RenderContext& renderCtx, TestLog& log)
+ : m_program (renderCtx, object.shader)
+ , m_vao (renderCtx.getFunctions())
+ , m_vbo (renderCtx.getFunctions())
+ , m_numVertices (int(object.geometry.size())/4)
+{
+ const glw::Functions& gl = renderCtx.getFunctions();
+
+ if (!m_program.isOk())
+ log << m_program;
+
+ gl.bindBuffer(GL_ARRAY_BUFFER, *m_vbo);
+ gl.bufferData(GL_ARRAY_BUFFER, object.geometry.size() * sizeof(float), &object.geometry[0], GL_STATIC_DRAW);
+ gl.bindAttribLocation(m_program.getProgram(), 0, "a_position");
+
+ gl.bindVertexArray(*m_vao);
+ gl.vertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
+ gl.enableVertexAttribArray(0);
+ gl.bindVertexArray(0);
+}
+
+namespace Utils
+{
+ vector<float> getFullscreenQuad (float depth)
+ {
+ const float data[] =
+ {
+ +1.0f, +1.0f, depth, 0.0f, // .w is gl_VertexId%3 since Nexus 4&5 can't handle that on their own
+ +1.0f, -1.0f, depth, 1.0f,
+ -1.0f, -1.0f, depth, 2.0f,
+ -1.0f, -1.0f, depth, 0.0f,
+ -1.0f, +1.0f, depth, 1.0f,
+ +1.0f, +1.0f, depth, 2.0f,
+ };
+
+ return vector<float>(DE_ARRAY_BEGIN(data), DE_ARRAY_END(data));
+ }
+
+ vector<float> getFullscreenQuadWithGradient (float depth0, float depth1)
+ {
+ const float data[] =
+ {
+ +1.0f, +1.0f, depth0, 0.0f,
+ +1.0f, -1.0f, depth0, 1.0f,
+ -1.0f, -1.0f, depth1, 2.0f,
+ -1.0f, -1.0f, depth1, 0.0f,
+ -1.0f, +1.0f, depth1, 1.0f,
+ +1.0f, +1.0f, depth0, 2.0f,
+ };
+
+ return vector<float>(DE_ARRAY_BEGIN(data), DE_ARRAY_END(data));
+ }
+
+ vector<float> getPartScreenQuad (float coverage, float depth)
+ {
+ const float xMax = -1.0f + 2.0f*coverage;
+ const float data[] =
+ {
+ xMax, +1.0f, depth, 0.0f,
+ xMax, -1.0f, depth, 1.0f,
+ -1.0f, -1.0f, depth, 2.0f,
+ -1.0f, -1.0f, depth, 0.0f,
+ -1.0f, +1.0f, depth, 1.0f,
+ xMax, +1.0f, depth, 2.0f,
+ };
+
+ return vector<float>(DE_ARRAY_BEGIN(data), DE_ARRAY_END(data));
+ }
+
+ // Axis aligned grid. Depth of vertices is baseDepth +/- depthNoise
+ vector<float> getFullScreenGrid (int resolution, deUint32 seed, float baseDepth, float depthNoise, float xyNoise)
+ {
+ const int gridsize = resolution+1;
+ vector<Vec3> vertices (gridsize*gridsize);
+ vector<float> retval;
+ de::Random rng (seed);
+
+ for (int y = 0; y < gridsize; y++)
+ for (int x = 0; x < gridsize; x++)
+ {
+ const bool isEdge = x == 0 || y == 0 || x == resolution || y == resolution;
+ const float x_ = float(x)/float(resolution)*2.0f - 1.0f + (isEdge ? 0.0f : rng.getFloat(-xyNoise, +xyNoise));
+ const float y_ = float(y)/float(resolution)*2.0f - 1.0f + (isEdge ? 0.0f : rng.getFloat(-xyNoise, +xyNoise));
+ const float z_ = baseDepth + rng.getFloat(-depthNoise, +depthNoise);
+
+ vertices[y*gridsize + x] = Vec3(x_, y_, z_);
+ }
+
+ retval.reserve(resolution*resolution*6);
+
+ for (int y = 0; y < resolution; y++)
+ for (int x = 0; x < resolution; x++)
+ {
+ const Vec3& p0 = vertices[(y+0)*gridsize + (x+0)];
+ const Vec3& p1 = vertices[(y+0)*gridsize + (x+1)];
+ const Vec3& p2 = vertices[(y+1)*gridsize + (x+0)];
+ const Vec3& p3 = vertices[(y+1)*gridsize + (x+1)];
+
+ const float temp[6*4] =
+ {
+ p0.x(), p0.y(), p0.z(), 0.0f,
+ p2.x(), p2.y(), p2.z(), 1.0f,
+ p1.x(), p1.y(), p1.z(), 2.0f,
+
+ p3.x(), p3.y(), p3.z(), 0.0f,
+ p1.x(), p1.y(), p1.z(), 1.0f,
+ p2.x(), p2.y(), p2.z(), 2.0f,
+ };
+
+ retval.insert(retval.end(), DE_ARRAY_BEGIN(temp), DE_ARRAY_END(temp));
+ }
+
+ return retval;
+ }
+
+ // Outputs barycentric coordinates as v_bcoords. Otherwise a passthrough shader
+ string getBaseVertexShader (void)
+ {
+ return "#version 300 es\n"
+ "in highp vec4 a_position;\n"
+ "out mediump vec3 v_bcoords;\n"
+ "void main()\n"
+ "{\n"
+ " v_bcoords = vec3(0, 0, 0);\n"
+ " v_bcoords[int(a_position.w)] = 1.0;\n"
+ " gl_Position = vec4(a_position.xyz, 1.0);\n"
+ "}\n";
+ }
+
+ // Adds noise to coordinates based on InstanceID Outputs barycentric coordinates as v_bcoords
+ string getInstanceNoiseVertexShader (void)
+ {
+ return "#version 300 es\n"
+ "in highp vec4 a_position;\n"
+ "out mediump vec3 v_bcoords;\n"
+ "void main()\n"
+ "{\n"
+ " v_bcoords = vec3(0, 0, 0);\n"
+ " v_bcoords[int(a_position.w)] = 1.0;\n"
+ " vec3 noise = vec3(sin(float(gl_InstanceID)*1.05), sin(float(gl_InstanceID)*1.23), sin(float(gl_InstanceID)*1.71));\n"
+ " gl_Position = vec4(a_position.xyz + noise * 0.005, 1.0);\n"
+ "}\n";
+ }
+
+ // Renders green triangles with edges highlighted. Exact shade depends on depth.
+ string getDepthAsGreenFragmentShader (void)
+ {
+ return "#version 300 es\n"
+ "in mediump vec3 v_bcoords;\n"
+ "out mediump vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " mediump float d = gl_FragCoord.z;\n"
+ " if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
+ " fragColor = vec4(d,1,d,1);\n"
+ " else\n"
+ " fragColor = vec4(0,d,0,1);\n"
+ "}\n";
+ }
+
+ // Renders green triangles with edges highlighted. Exact shade depends on depth.
+ string getDepthAsRedFragmentShader (void)
+ {
+ return "#version 300 es\n"
+ "in mediump vec3 v_bcoords;\n"
+ "out mediump vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " mediump float d = gl_FragCoord.z;\n"
+ " if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
+ " fragColor = vec4(1,d,d,1);\n"
+ " else\n"
+ " fragColor = vec4(d,0,0,1);\n"
+ "}\n";
+ }
+
+ // Basic time waster. Renders red triangles with edges highlighted. Exact shade depends on depth.
+ string getArithmeticWorkloadFragmentShader (void)
+ {
+
+ return "#version 300 es\n"
+ "in mediump vec3 v_bcoords;\n"
+ "out mediump vec4 fragColor;\n"
+ "uniform mediump int u_iterations;\n"
+ "void main()\n"
+ "{\n"
+ " mediump float d = gl_FragCoord.z;\n"
+ " for (int i = 0; i<u_iterations; i++)\n"
+ // cos(a)^2 + sin(a)^2 == 1. since d is in range [0,1] this will lose a few ULP's of precision per iteration but should not significantly change the value of d without extreme iteration counts
+ " d = d*sin(d)*sin(d) + d*cos(d)*cos(d);\n"
+ " if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
+ " fragColor = vec4(1,d,d,1);\n"
+ " else\n"
+ " fragColor = vec4(d,0,0,1);\n"
+ "}\n";
+ }
+
+ // Arithmetic workload shader but contains discard
+ string getArithmeticWorkloadDiscardFragmentShader (void)
+ {
+ return "#version 300 es\n"
+ "in mediump vec3 v_bcoords;\n"
+ "out mediump vec4 fragColor;\n"
+ "uniform mediump int u_iterations;\n"
+ "void main()\n"
+ "{\n"
+ " mediump float d = gl_FragCoord.z;\n"
+ " for (int i = 0; i<u_iterations; i++)\n"
+ " d = d*sin(d)*sin(d) + d*cos(d)*cos(d);\n"
+ " if (d < 0.5) discard;\n"
+ " if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
+ " fragColor = vec4(1,d,d,1);\n"
+ " else\n"
+ " fragColor = vec4(d,0,0,1);\n"
+ "}\n";
+ }
+
+ // Texture fetch based time waster. Renders red triangles with edges highlighted. Exact shade depends on depth.
+ string getTextureWorkloadFragmentShader (void)
+ {
+ return "#version 300 es\n"
+ "in mediump vec3 v_bcoords;\n"
+ "out mediump vec4 fragColor;\n"
+ "uniform mediump int u_iterations;\n"
+ "uniform sampler2D u_texture;\n"
+ "void main()\n"
+ "{\n"
+ " mediump float d = gl_FragCoord.z;\n"
+ " for (int i = 0; i<u_iterations; i++)\n"
+ " d *= texture(u_texture, (gl_FragCoord.xy+vec2(i))/512.0).r;\n" // Texture is expected to be fully white
+ " if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
+ " fragColor = vec4(1,1,1,1);\n"
+ " else\n"
+ " fragColor = vec4(d,0,0,1);\n"
+ "}\n";
+ }
+
+ // Discard fragments in a grid pattern
+ string getGridDiscardFragmentShader (int gridsize)
+ {
+ const string fragSrc = "#version 300 es\n"
+ "in mediump vec3 v_bcoords;\n"
+ "out mediump vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " mediump float d = gl_FragCoord.z;\n"
+ " if ((int(gl_FragCoord.x)/${GRIDRENDER_SIZE} + int(gl_FragCoord.y)/${GRIDRENDER_SIZE})%2 == 0)\n"
+ " discard;\n"
+ " if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
+ " fragColor = vec4(d,1,d,1);\n"
+ " else\n"
+ " fragColor = vec4(0,d,0,1);\n"
+ "}\n";
+ map<string, string> params;
+
+ params["GRIDRENDER_SIZE"] = de::toString(gridsize);
+
+ return tcu::StringTemplate(fragSrc).specialize(params);
+ }
+
+ // A static increment to frag depth
+ string getStaticFragDepthFragmentShader (void)
+ {
+ return "#version 300 es\n"
+ "in mediump vec3 v_bcoords;\n"
+ "out mediump vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " mediump float d = gl_FragCoord.z;\n"
+ " gl_FragDepth = gl_FragCoord.z + 0.1;\n"
+ " if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
+ " fragColor = vec4(d,1,d,1);\n"
+ " else\n"
+ " fragColor = vec4(0,d,0,1);\n"
+ "}\n";
+ }
+
+ // A trivial dynamic change to frag depth
+ string getDynamicFragDepthFragmentShader (void)
+ {
+ return "#version 300 es\n"
+ "in mediump vec3 v_bcoords;\n"
+ "out mediump vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " mediump float d = gl_FragCoord.z;\n"
+ " gl_FragDepth = gl_FragCoord.z + (v_bcoords.x + v_bcoords.y + v_bcoords.z)*0.05;\n" // Sum of v_bcoords components is allways 1
+ " if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
+ " fragColor = vec4(d,1,d,1);\n"
+ " else\n"
+ " fragColor = vec4(0,d,0,1);\n"
+ "}\n";
+ }
+
+ // A static increment to frag depth
+ string getStaticFragDepthArithmeticWorkloadFragmentShader (void)
+ {
+ return "#version 300 es\n"
+ "in mediump vec3 v_bcoords;\n"
+ "out mediump vec4 fragColor;\n"
+ "uniform mediump int u_iterations;\n"
+ "void main()\n"
+ "{\n"
+ " mediump float d = gl_FragCoord.z;\n"
+ " gl_FragDepth = gl_FragCoord.z + 0.1;\n"
+ " for (int i = 0; i<u_iterations; i++)\n"
+ " d = d*sin(d)*sin(d) + d*cos(d)*cos(d);\n"
+ " if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
+ " fragColor = vec4(1,d,d,1);\n"
+ " else\n"
+ " fragColor = vec4(d,0,0,1);\n"
+ "}\n";
+ }
+
+ // A trivial dynamic change to frag depth
+ string getDynamicFragDepthArithmeticWorkloadFragmentShader (void)
+ {
+ return "#version 300 es\n"
+ "in mediump vec3 v_bcoords;\n"
+ "out mediump vec4 fragColor;\n"
+ "uniform mediump int u_iterations;\n"
+ "void main()\n"
+ "{\n"
+ " mediump float d = gl_FragCoord.z;\n"
+ " gl_FragDepth = gl_FragCoord.z + (v_bcoords.x + v_bcoords.y + v_bcoords.z)*0.05;\n" // Sum of v_bcoords components is allways 1
+ " for (int i = 0; i<u_iterations; i++)\n"
+ " d = d*sin(d)*sin(d) + d*cos(d)*cos(d);\n"
+ " if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
+ " fragColor = vec4(1,d,d,1);\n"
+ " else\n"
+ " fragColor = vec4(d,0,0,1);\n"
+ "}\n";
+ }
+
+ glu::ProgramSources getBaseShader (void)
+ {
+ return glu::makeVtxFragSources(getBaseVertexShader(), getDepthAsGreenFragmentShader());
+ }
+
+ glu::ProgramSources getArithmeticWorkloadShader (void)
+ {
+ return glu::makeVtxFragSources(getBaseVertexShader(), getArithmeticWorkloadFragmentShader());
+ }
+
+ glu::ProgramSources getArithmeticWorkloadDiscardShader (void)
+ {
+ return glu::makeVtxFragSources(getBaseVertexShader(), getArithmeticWorkloadDiscardFragmentShader());
+ }
+
+ glu::ProgramSources getTextureWorkloadShader (void)
+ {
+ return glu::makeVtxFragSources(getBaseVertexShader(), getTextureWorkloadFragmentShader());
+ }
+
+ glu::ProgramSources getGridDiscardShader (int gridsize)
+ {
+ return glu::makeVtxFragSources(getBaseVertexShader(), getGridDiscardFragmentShader(gridsize));
+ }
+
+ inline ObjectData quadWith (const glu::ProgramSources& shader, float depth)
+ {
+ return ObjectData(shader, getFullscreenQuad(depth));
+ }
+
+ inline ObjectData quadWith (const string& fragShader, float depth)
+ {
+ return ObjectData(glu::makeVtxFragSources(getBaseVertexShader(), fragShader), getFullscreenQuad(depth));
+ }
+
+ inline ObjectData variableQuad (float depth)
+ {
+ return ObjectData(glu::makeVtxFragSources(getInstanceNoiseVertexShader(), getDepthAsRedFragmentShader()), getFullscreenQuad(depth));
+ }
+
+ inline ObjectData fastQuad (float depth)
+ {
+ return ObjectData(getBaseShader(), getFullscreenQuad(depth));
+ }
+
+ inline ObjectData slowQuad (float depth)
+ {
+ return ObjectData(getArithmeticWorkloadShader(), getFullscreenQuad(depth));
+ }
+
+ inline ObjectData fastQuadWithGradient (float depth0, float depth1)
+ {
+ return ObjectData(getBaseShader(), getFullscreenQuadWithGradient(depth0, depth1));
+ }
+} // Utils
+
+// Shared base
+class BaseCase : public tcu::TestCase
+{
+public:
+ enum {RENDER_SIZE = 512};
+
+ BaseCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc);
+ virtual ~BaseCase (void) {}
+
+ virtual IterateResult iterate (void);
+
+protected:
+ void logSamples (const vector<Sample>& samples, const string& name, const string& desc);
+ void logGeometry (const tcu::ConstPixelBufferAccess& sample, const glu::ShaderProgram& occluderProg, const glu::ShaderProgram& occludedProg);
+ virtual void logAnalysis (const vector<Sample>& samples) = 0;
+ virtual void logDescription (void) = 0;
+
+ virtual ObjectData genOccluderGeometry (void) const = 0;
+ virtual ObjectData genOccludedGeometry (void) const = 0;
+
+ virtual int calibrate (void) const = 0;
+ virtual Sample renderSample (const RenderData& occluder, const RenderData& occluded, int workload) const = 0;
+
+ void render (const RenderData& data) const;
+ void render (const RenderData& data, int instances) const;
+
+ const RenderContext& m_renderCtx;
+ tcu::ResultCollector m_results;
+
+ enum {ITERATION_STEPS = 10, ITERATION_SAMPLES = 16};
+};
+
+BaseCase::BaseCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
+ : TestCase (testCtx, tcu::NODETYPE_PERFORMANCE, name, desc)
+ , m_renderCtx (renderCtx)
+{
+}
+
+BaseCase::IterateResult BaseCase::iterate (void)
+{
+ typedef de::MovePtr<RenderData> RenderDataP;
+
+ const glw::Functions& gl = m_renderCtx.getFunctions();
+ TestLog& log = m_testCtx.getLog();
+
+ const glu::Framebuffer framebuffer (gl);
+ const glu::Renderbuffer renderbuffer (gl);
+ const glu::Renderbuffer depthbuffer (gl);
+
+ vector<Sample> results;
+ vector<int> params;
+ RenderDataP occluderData;
+ RenderDataP occludedData;
+ tcu::TextureLevel resultTex (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), RENDER_SIZE, RENDER_SIZE);
+ int maxWorkload = 0;
+ de::Random rng (deInt32Hash(deStringHash(getName())) ^ m_testCtx.getCommandLine().getBaseSeed());
+
+ logDescription();
+
+ gl.bindRenderbuffer(GL_RENDERBUFFER, *renderbuffer);
+ gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, RENDER_SIZE, RENDER_SIZE);
+ gl.bindRenderbuffer(GL_RENDERBUFFER, *depthbuffer);
+ gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, RENDER_SIZE, RENDER_SIZE);
+
+ gl.bindFramebuffer(GL_FRAMEBUFFER, *framebuffer);
+ gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *renderbuffer);
+ gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *depthbuffer);
+ gl.viewport(0, 0, RENDER_SIZE, RENDER_SIZE);
+ gl.clearColor(0.125f, 0.25f, 0.5f, 1.0f);
+
+ maxWorkload = calibrate();
+
+ // Setup data
+ occluderData = RenderDataP(new RenderData (genOccluderGeometry(), m_renderCtx, log));
+ occludedData = RenderDataP(new RenderData (genOccludedGeometry(), m_renderCtx, log));
+
+ TCU_CHECK(occluderData->m_program.isOk());
+ TCU_CHECK(occludedData->m_program.isOk());
+
+ // Force initialization of GPU resources
+ gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ gl.enable(GL_DEPTH_TEST);
+
+ render(*occluderData);
+ render(*occludedData);
+ glu::readPixels(m_renderCtx, 0, 0, resultTex.getAccess());
+
+ logGeometry(resultTex.getAccess(), occluderData->m_program, occludedData->m_program);
+
+ params.reserve(ITERATION_STEPS*ITERATION_SAMPLES);
+
+ // Setup parameters
+ for (int step = 0; step < ITERATION_STEPS; step++)
+ {
+ const int workload = maxWorkload*step/ITERATION_STEPS;
+
+ for (int count = 0; count < ITERATION_SAMPLES; count++)
+ params.push_back(workload);
+ }
+
+ rng.shuffle(params.begin(), params.end());
+
+ // Render samples
+ for (size_t ndx = 0; ndx < params.size(); ndx++)
+ {
+ const int workload = params[ndx];
+ Sample sample = renderSample(*occluderData, *occludedData, workload);
+
+ sample.workload = workload;
+ sample.order = int(ndx);
+
+ results.push_back(sample);
+ }
+
+ logSamples(results, "Samples", "Samples");
+ logAnalysis(results);
+
+ m_results.setTestContextResult(m_testCtx);
+
+ return STOP;
+}
+
+void BaseCase::logSamples (const vector<Sample>& samples, const string& name, const string& desc)
+{
+ TestLog& log = m_testCtx.getLog();
+
+ bool testOnly = true;
+
+ for (size_t ndx = 0; ndx < samples.size(); ndx++)
+ {
+ if (samples[ndx].baseTime != 0 || samples[ndx].nullTime != 0)
+ {
+ testOnly = false;
+ break;
+ }
+ }
+
+ log << TestLog::SampleList(name, desc);
+
+ if (testOnly)
+ {
+ log << TestLog::SampleInfo
+ << TestLog::ValueInfo("Workload", "Workload", "", QP_SAMPLE_VALUE_TAG_PREDICTOR)
+ << TestLog::ValueInfo("Order", "Order of sample", "", QP_SAMPLE_VALUE_TAG_PREDICTOR)
+ << TestLog::ValueInfo("TestTime", "Test render time", "us", QP_SAMPLE_VALUE_TAG_RESPONSE)
+ << TestLog::EndSampleInfo;
+
+ for (size_t sampleNdx = 0; sampleNdx < samples.size(); sampleNdx++)
+ {
+ const Sample& sample = samples[sampleNdx];
+
+ log << TestLog::Sample << sample.workload << sample.order << sample.testTime << TestLog::EndSample;
+ }
+ }
+ else
+ {
+ log << TestLog::SampleInfo
+ << TestLog::ValueInfo("Workload", "Workload", "", QP_SAMPLE_VALUE_TAG_PREDICTOR)
+ << TestLog::ValueInfo("Order", "Order of sample", "", QP_SAMPLE_VALUE_TAG_PREDICTOR)
+ << TestLog::ValueInfo("TestTime", "Test render time", "us", QP_SAMPLE_VALUE_TAG_RESPONSE)
+ << TestLog::ValueInfo("NullTime", "Read pixels time", "us", QP_SAMPLE_VALUE_TAG_RESPONSE)
+ << TestLog::ValueInfo("BaseTime", "Base render time", "us", QP_SAMPLE_VALUE_TAG_RESPONSE)
+ << TestLog::EndSampleInfo;
+
+ for (size_t sampleNdx = 0; sampleNdx < samples.size(); sampleNdx++)
+ {
+ const Sample& sample = samples[sampleNdx];
+
+ log << TestLog::Sample << sample.workload << sample.order << sample.testTime << sample.nullTime << sample.baseTime << TestLog::EndSample;
+ }
+ }
+
+ log << TestLog::EndSampleList;
+}
+
+void BaseCase::logGeometry (const tcu::ConstPixelBufferAccess& sample, const glu::ShaderProgram& occluderProg, const glu::ShaderProgram& occludedProg)
+{
+ TestLog& log = m_testCtx.getLog();
+
+ log << TestLog::Section("Geometry", "Geometry");
+ log << TestLog::Message << "Occluding geometry is green with shade dependent on depth (rgb == 0, depth, 0)" << TestLog::EndMessage;
+ log << TestLog::Message << "Occluded geometry is red with shade dependent on depth (rgb == depth, 0, 0)" << TestLog::EndMessage;
+ log << TestLog::Message << "Primitive edges are a lighter shade of red/green" << TestLog::EndMessage;
+
+ log << TestLog::Image("Test Geometry", "Test Geometry", sample);
+ log << TestLog::EndSection;
+
+ log << TestLog::Section("Occluder", "Occluder");
+ log << occluderProg;
+ log << TestLog::EndSection;
+
+ log << TestLog::Section("Occluded", "Occluded");
+ log << occludedProg;
+ log << TestLog::EndSection;
+}
+
+void BaseCase::render (const RenderData& data) const
+{
+ const glw::Functions& gl = m_renderCtx.getFunctions();
+
+ gl.useProgram(data.m_program.getProgram());
+
+ gl.bindVertexArray(*data.m_vao);
+ gl.drawArrays(GL_TRIANGLES, 0, data.m_numVertices);
+ gl.bindVertexArray(0);
+}
+
+void BaseCase::render (const RenderData& data, int instances) const
+{
+ const glw::Functions& gl = m_renderCtx.getFunctions();
+
+ gl.useProgram(data.m_program.getProgram());
+
+ gl.bindVertexArray(*data.m_vao);
+ gl.drawArraysInstanced(GL_TRIANGLES, 0, data.m_numVertices, instances);
+ gl.bindVertexArray(0);
+}
+
+// Render occluder once, then repeatedly render occluded geometry. Sample with multiple repetition counts & establish time per call with linear regression
+class RenderCountCase : public BaseCase
+{
+public:
+ RenderCountCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc);
+ ~RenderCountCase (void) {}
+
+protected:
+ virtual void logAnalysis (const vector<Sample>& samples);
+
+private:
+ virtual int calibrate (void) const;
+ virtual Sample renderSample (const RenderData& occluder, const RenderData& occluded, int callcount) const;
+};
+
+RenderCountCase::RenderCountCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
+ : BaseCase (testCtx, renderCtx, name, desc)
+{
+}
+
+void RenderCountCase::logAnalysis (const vector<Sample>& samples)
+{
+ using namespace gls;
+
+ TestLog& log = m_testCtx.getLog();
+ int maxWorkload = 0;
+ vector<Vec2> testSamples (samples.size());
+
+ for (size_t ndx = 0; ndx < samples.size(); ndx++)
+ {
+ const Sample& sample = samples[ndx];
+
+ testSamples[ndx] = Vec2((float)sample.workload, (float)sample.testTime);
+
+ maxWorkload = de::max(maxWorkload, sample.workload);
+ }
+
+ {
+ const float confidence = 0.60f;
+ const LineParametersWithConfidence testParam = theilSenSiegelLinearRegression(testSamples, confidence);
+ const float usPerCall = testParam.coefficient;
+ const float pxPerCall = RENDER_SIZE*RENDER_SIZE;
+ const float pxPerUs = pxPerCall/usPerCall;
+ const float mpxPerS = pxPerUs;
+
+ log << TestLog::Section("Linear Regression", "Linear Regression");
+ log << TestLog::Message << "Offset & coefficient presented as [confidence interval min, estimate, confidence interval max]. Reported confidence interval for this test is " << confidence << TestLog::EndMessage;
+ log << TestLog::Message << "Render time for scene with depth test was\n\t"
+ << "[" << testParam.offsetConfidenceLower << ", " << testParam.offset << ", " << testParam.offsetConfidenceUpper << "]us +"
+ << "[" << testParam.coefficientConfidenceLower << ", " << testParam.coefficient << ", " << testParam.coefficientConfidenceUpper << "]"
+ << "us/workload" << TestLog::EndMessage;
+ log << TestLog::EndSection;
+
+ log << TestLog::Section("Result", "Result");
+
+ if (testParam.coefficientConfidenceLower < 0.0f)
+ {
+ log << TestLog::Message << "Coefficient confidence bounds include values below 0.0, the operation likely has neglible per-pixel cost" << TestLog::EndMessage;
+ m_results.addResult(QP_TEST_RESULT_PASS, "Pass");
+ }
+ else if (testParam.coefficientConfidenceLower < testParam.coefficientConfidenceUpper*0.25)
+ {
+ log << TestLog::Message << "Coefficient confidence range is extremely large, cannot give reliable result" << TestLog::EndMessage;
+ m_results.addResult(QP_TEST_RESULT_PASS, "Result confidence extremely low");
+ }
+ else
+ {
+ log << TestLog::Message << "Culled hidden pixels @ " << mpxPerS << "Mpx/s" << TestLog::EndMessage;
+ m_results.addResult(QP_TEST_RESULT_PASS, de::floatToString(mpxPerS, 2));
+ }
+
+ log << TestLog::EndSection;
+ }
+}
+
+Sample RenderCountCase::renderSample (const RenderData& occluder, const RenderData& occluded, int callcount) const
+{
+ const glw::Functions& gl = m_renderCtx.getFunctions();
+ Sample sample;
+ deUint64 now = 0;
+ deUint64 prev = 0;
+ deUint8 buffer[4];
+
+ // Stabilize
+ {
+ gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ gl.enable(GL_DEPTH_TEST);
+ gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+ }
+
+ prev = deGetMicroseconds();
+
+ gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ gl.enable(GL_DEPTH_TEST);
+
+ render(occluder);
+ render(occluded, callcount);
+
+ gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+
+ now = deGetMicroseconds();
+
+ sample.testTime = now - prev;
+ sample.baseTime = 0;
+ sample.nullTime = 0;
+ sample.workload = callcount;
+
+ return sample;
+}
+
+int RenderCountCase::calibrate (void) const
+{
+ using namespace gls;
+
+ const glw::Functions& gl = m_renderCtx.getFunctions();
+ TestLog& log = m_testCtx.getLog();
+
+ const RenderData occluderGeometry (genOccluderGeometry(), m_renderCtx, log);
+ const RenderData occludedGeometry (genOccludedGeometry(), m_renderCtx, log);
+
+ TheilSenCalibrator calibrator (CalibratorParameters(20, // Initial workload
+ 10, // Max iteration frames
+ 20.0f, // Iteration shortcut threshold ms
+ 20, // Max iterations
+ 33.0f, // Target frame time
+ 40.0f, // Frame time cap
+ 1000.0f // Target measurement duration
+ ));
+
+ while (true)
+ {
+ switch(calibrator.getState())
+ {
+ case TheilSenCalibrator::STATE_FINISHED:
+ logCalibrationInfo(m_testCtx.getLog(), calibrator);
+ return calibrator.getCallCount();
+
+ case TheilSenCalibrator::STATE_MEASURE:
+ {
+ deUint8 buffer[4];
+ deInt64 now;
+ deInt64 prev;
+
+ prev = deGetMicroseconds();
+
+ gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ gl.disable(GL_DEPTH_TEST);
+
+ render(occluderGeometry);
+ render(occludedGeometry, calibrator.getCallCount());
+
+ gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+
+ now = deGetMicroseconds();
+
+ calibrator.recordIteration(now - prev);
+ break;
+ }
+
+ case TheilSenCalibrator::STATE_RECOMPUTE_PARAMS:
+ calibrator.recomputeParameters();
+ break;
+ default:
+ DE_ASSERT(false);
+ return 1;
+ }
+ }
+}
+
+// Compares time/workload gradients of same geometry with and without depth testing
+class RelativeChangeCase : public BaseCase
+{
+public:
+ RelativeChangeCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc);
+ virtual ~RelativeChangeCase (void) {}
+
+protected:
+ Sample renderSample (const RenderData& occluder, const RenderData& occluded, int workload) const;
+
+ virtual void logAnalysis (const vector<Sample>& samples);
+
+private:
+ int calibrate (void) const;
+};
+
+RelativeChangeCase::RelativeChangeCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
+ : BaseCase (testCtx, renderCtx, name, desc)
+{
+}
+
+int RelativeChangeCase::calibrate (void) const
+{
+ using namespace gls;
+
+ const glw::Functions& gl = m_renderCtx.getFunctions();
+ TestLog& log = m_testCtx.getLog();
+
+ const RenderData geom (genOccludedGeometry(), m_renderCtx, log);
+
+ TheilSenCalibrator calibrator(CalibratorParameters( 20, // Initial workload
+ 10, // Max iteration frames
+ 20.0f, // Iteration shortcut threshold ms
+ 20, // Max iterations
+ 10.0f, // Target frame time
+ 15.0f, // Frame time cap
+ 1000.0f // Target measurement duration
+ ));
+
+ while (true)
+ {
+ switch(calibrator.getState())
+ {
+ case TheilSenCalibrator::STATE_FINISHED:
+ logCalibrationInfo(m_testCtx.getLog(), calibrator);
+ return calibrator.getCallCount();
+
+ case TheilSenCalibrator::STATE_MEASURE:
+ {
+ deUint8 buffer[4];
+ const GLuint program = geom.m_program.getProgram();
+
+ gl.useProgram(program);
+ gl.uniform1i(gl.getUniformLocation(program, "u_iterations"), calibrator.getCallCount());
+
+ const deInt64 prev = deGetMicroseconds();
+
+ gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ gl.disable(GL_DEPTH_TEST);
+
+ render(geom);
+
+ gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+
+ const deInt64 now = deGetMicroseconds();
+
+ calibrator.recordIteration(now - prev);
+ break;
+ }
+
+ case TheilSenCalibrator::STATE_RECOMPUTE_PARAMS:
+ calibrator.recomputeParameters();
+ break;
+ default:
+ DE_ASSERT(false);
+ return 1;
+ }
+ }
+}
+
+Sample RelativeChangeCase::renderSample (const RenderData& occluder, const RenderData& occluded, int workload) const
+{
+ const glw::Functions& gl = m_renderCtx.getFunctions();
+ const GLuint program = occluded.m_program.getProgram();
+ Sample sample;
+ deUint64 now = 0;
+ deUint64 prev = 0;
+ deUint8 buffer[4];
+
+ gl.useProgram(program);
+ gl.uniform1i(gl.getUniformLocation(program, "u_iterations"), workload);
+
+ // Warmup (this workload seems to reduce variation in following workloads)
+ {
+ gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ gl.disable(GL_DEPTH_TEST);
+
+ gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+ }
+
+ // Null time
+ {
+ prev = deGetMicroseconds();
+
+ gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ gl.disable(GL_DEPTH_TEST);
+
+ gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+
+ now = deGetMicroseconds();
+
+ sample.nullTime = now - prev;
+ }
+
+ // Test time
+ {
+ prev = deGetMicroseconds();
+
+ gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ gl.enable(GL_DEPTH_TEST);
+
+ render(occluder);
+ render(occluded);
+
+ gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+
+ now = deGetMicroseconds();
+
+ sample.testTime = now - prev;
+ }
+
+ // Base time
+ {
+ prev = deGetMicroseconds();
+
+ gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ gl.disable(GL_DEPTH_TEST);
+
+ render(occluder);
+ render(occluded);
+
+ gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+
+ now = deGetMicroseconds();
+
+ sample.baseTime = now - prev;
+ }
+
+ sample.workload = 0;
+
+ return sample;
+}
+
+void RelativeChangeCase::logAnalysis (const vector<Sample>& samples)
+{
+ using namespace gls;
+
+ TestLog& log = m_testCtx.getLog();
+
+ int maxWorkload = 0;
+
+ vector<Vec2> nullSamples (samples.size());
+ vector<Vec2> baseSamples (samples.size());
+ vector<Vec2> testSamples (samples.size());
+
+ for (size_t ndx = 0; ndx < samples.size(); ndx++)
+ {
+ const Sample& sample = samples[ndx];
+
+ nullSamples[ndx] = Vec2((float)sample.workload, (float)sample.nullTime);
+ baseSamples[ndx] = Vec2((float)sample.workload, (float)sample.baseTime);
+ testSamples[ndx] = Vec2((float)sample.workload, (float)sample.testTime);
+
+ maxWorkload = de::max(maxWorkload, sample.workload);
+ }
+
+ {
+ const float confidence = 0.60f;
+
+ const LineParametersWithConfidence nullParam = theilSenSiegelLinearRegression(nullSamples, confidence);
+ const LineParametersWithConfidence baseParam = theilSenSiegelLinearRegression(baseSamples, confidence);
+ const LineParametersWithConfidence testParam = theilSenSiegelLinearRegression(testSamples, confidence);
+
+ if (!de::inRange(0.0f, nullParam.coefficientConfidenceLower, nullParam.coefficientConfidenceUpper))
+ {
+ m_results.addResult(QP_TEST_RESULT_FAIL, "Constant operation sequence duration not constant");
+ log << TestLog::Message << "Constant operation sequence timing may vary as a function of workload. Result quality extremely low" << TestLog::EndMessage;
+ }
+
+ if (de::inRange(0.0f, baseParam.coefficientConfidenceLower, baseParam.coefficientConfidenceUpper))
+ {
+ m_results.addResult(QP_TEST_RESULT_FAIL, "Workload has no effect on duration");
+ log << TestLog::Message << "Workload factor has no effect on duration of sample (smart optimizer?)" << TestLog::EndMessage;
+ }
+
+ log << TestLog::Section("Linear Regression", "Linear Regression");
+ log << TestLog::Message << "Offset & coefficient presented as [confidence interval min, estimate, confidence interval max]. Reported confidence interval for this test is " << confidence << TestLog::EndMessage;
+
+ log << TestLog::Message << "Render time for empty scene was\n\t"
+ << "[" << nullParam.offsetConfidenceLower << ", " << nullParam.offset << ", " << nullParam.offsetConfidenceUpper << "]us +"
+ << "[" << nullParam.coefficientConfidenceLower << ", " << nullParam.coefficient << ", " << nullParam.coefficientConfidenceUpper << "]"
+ << "us/workload" << TestLog::EndMessage;
+
+ log << TestLog::Message << "Render time for scene without depth test was\n\t"
+ << "[" << baseParam.offsetConfidenceLower << ", " << baseParam.offset << ", " << baseParam.offsetConfidenceUpper << "]us +"
+ << "[" << baseParam.coefficientConfidenceLower << ", " << baseParam.coefficient << ", " << baseParam.coefficientConfidenceUpper << "]"
+ << "us/workload" << TestLog::EndMessage;
+
+ log << TestLog::Message << "Render time for scene with depth test was\n\t"
+ << "[" << testParam.offsetConfidenceLower << ", " << testParam.offset << ", " << testParam.offsetConfidenceUpper << "]us +"
+ << "[" << testParam.coefficientConfidenceLower << ", " << testParam.coefficient << ", " << testParam.coefficientConfidenceUpper << "]"
+ << "us/workload" << TestLog::EndMessage;
+
+ log << TestLog::EndSection;
+
+ if (de::inRange(0.0f, testParam.coefficientConfidenceLower, testParam.coefficientConfidenceUpper))
+ {
+ log << TestLog::Message << "Test duration not dependent on culled workload" << TestLog::EndMessage;
+ m_results.addResult(QP_TEST_RESULT_PASS, "0.0");
+ }
+ else if (testParam.coefficientConfidenceLower < testParam.coefficientConfidenceUpper*0.25)
+ {
+ log << TestLog::Message << "Coefficient confidence range is extremely large, cannot give reliable result" << TestLog::EndMessage;
+ m_results.addResult(QP_TEST_RESULT_PASS, "Result confidence extremely low");
+ }
+ else if (baseParam.coefficientConfidenceLower < baseParam.coefficientConfidenceUpper*0.25)
+ {
+ log << TestLog::Message << "Coefficient confidence range for base render time is extremely large, cannot give reliable result" << TestLog::EndMessage;
+ m_results.addResult(QP_TEST_RESULT_PASS, "Result confidence extremely low");
+ }
+ else
+ {
+ log << TestLog::Message << "Test duration is dependent on culled workload" << TestLog::EndMessage;
+ m_results.addResult(QP_TEST_RESULT_PASS, de::floatToString(de::abs(testParam.coefficient)/de::abs(baseParam.coefficient), 2));
+ }
+ }
+}
+
+// Speed of trivial culling
+class BaseCostCase : public RenderCountCase
+{
+public:
+ BaseCostCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
+ : RenderCountCase (testCtx, renderCtx, name, desc) {}
+
+ ~BaseCostCase (void) {}
+
+private:
+ virtual ObjectData genOccluderGeometry (void) const { return Utils::fastQuad(0.2f); }
+ virtual ObjectData genOccludedGeometry (void) const { return Utils::variableQuad(0.8f); }
+
+ virtual void logDescription (void)
+ {
+ TestLog& log = m_testCtx.getLog();
+
+ log << TestLog::Section("Description", "Test description");
+ log << TestLog::Message << "Testing hidden fragment culling speed" << TestLog::EndMessage;
+ log << TestLog::Message << "Geometry consists of two fullsceen quads. The first (occluding) is rendered once, the second (occluded) is rendered repeatedly" << TestLog::EndMessage;
+ log << TestLog::Message << "Workload indicates the number of times the occluded quad is rendered" << TestLog::EndMessage;
+ log << TestLog::Message << "The time per culled pixel is estimated from the rate of change of rendering time as a function of workload" << TestLog::EndMessage;
+ log << TestLog::EndSection;
+ }
+};
+
+// Gradient
+class GradientCostCase : public RenderCountCase
+{
+public:
+ GradientCostCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc, float gradientDistance)
+ : RenderCountCase (testCtx, renderCtx, name, desc)
+ , m_gradientDistance (gradientDistance)
+ {
+ }
+
+ ~GradientCostCase (void) {}
+
+private:
+ virtual ObjectData genOccluderGeometry (void) const { return Utils::fastQuadWithGradient(0.0f, 1.0f - m_gradientDistance); }
+ virtual ObjectData genOccludedGeometry (void) const
+ {
+ return ObjectData(glu::makeVtxFragSources(Utils::getInstanceNoiseVertexShader(), Utils::getDepthAsRedFragmentShader()), Utils::getFullscreenQuadWithGradient(m_gradientDistance, 1.0f));
+ }
+
+ virtual void logDescription (void)
+ {
+ TestLog& log = m_testCtx.getLog();
+
+ log << TestLog::Section("Description", "Test description");
+ log << TestLog::Message << "Testing hidden fragment culling speed" << TestLog::EndMessage;
+ log << TestLog::Message << "Geometry consists of two fullsceen quads. The first (occluding) is rendered once, the second (occluded) is rendered repeatedly" << TestLog::EndMessage;
+ log << TestLog::Message << "Workload indicates the number of times the occluded quad is rendered" << TestLog::EndMessage;
+ log << TestLog::Message << "The quads are tilted so that the left edge of the occluded quad has a depth of 1.0 and the right edge of the occluding quad has a depth of 0.0." << TestLog::EndMessage;
+ log << TestLog::Message << "The quads are spaced to have a depth difference of " << m_gradientDistance << " at all points." << TestLog::EndMessage;
+ log << TestLog::Message << "The time per culled pixel is estimated from the rate of change of rendering time as a function of workload" << TestLog::EndMessage;
+ log << TestLog::EndSection;
+ }
+
+ const float m_gradientDistance;
+};
+
+// Constant offset to frag depth in occluder
+class OccluderStaticFragDepthCostCase : public RenderCountCase
+{
+public:
+ OccluderStaticFragDepthCostCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
+ : RenderCountCase(testCtx, renderCtx, name, desc)
+ {
+ }
+
+ ~OccluderStaticFragDepthCostCase (void) {}
+
+private:
+ virtual ObjectData genOccluderGeometry (void) const { return Utils::quadWith(Utils::getStaticFragDepthFragmentShader(), 0.2f); }
+ virtual ObjectData genOccludedGeometry (void) const { return Utils::fastQuad(0.8f); }
+
+ virtual void logDescription (void)
+ {
+ TestLog& log = m_testCtx.getLog();
+
+ log << TestLog::Section("Description", "Test description");
+ log << TestLog::Message << "Testing hidden fragment culling speed" << TestLog::EndMessage;
+ log << TestLog::Message << "Geometry consists of two fullsceen quads. The first (occluding) is rendered once, the second (occluded) is rendered repeatedly" << TestLog::EndMessage;
+ log << TestLog::Message << "Workload indicates the number of times the occluded quad is rendered" << TestLog::EndMessage;
+ log << TestLog::Message << "The occluder quad has a static offset applied to gl_FragDepth" << TestLog::EndMessage;
+ log << TestLog::Message << "The time per culled pixel is estimated from the rate of change of rendering time as a function of workload" << TestLog::EndMessage;
+ log << TestLog::EndSection;
+ }
+};
+
+// Dynamic offset to frag depth in occluder
+class OccluderDynamicFragDepthCostCase : public RenderCountCase
+{
+public:
+ OccluderDynamicFragDepthCostCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
+ : RenderCountCase(testCtx, renderCtx, name, desc)
+ {
+ }
+
+ ~OccluderDynamicFragDepthCostCase (void) {}
+
+private:
+ virtual ObjectData genOccluderGeometry (void) const { return Utils::quadWith(Utils::getDynamicFragDepthFragmentShader(), 0.2f); }
+ virtual ObjectData genOccludedGeometry (void) const { return Utils::fastQuad(0.8f); }
+
+ virtual void logDescription (void)
+ {
+ TestLog& log = m_testCtx.getLog();
+
+ log << TestLog::Section("Description", "Test description");
+ log << TestLog::Message << "Testing hidden fragment culling speed" << TestLog::EndMessage;
+ log << TestLog::Message << "Geometry consists of two fullsceen quads. The first (occluding) is rendered once, the second (occluded) is rendered repeatedly" << TestLog::EndMessage;
+ log << TestLog::Message << "Workload indicates the number of times the occluded quad is rendered" << TestLog::EndMessage;
+ log << TestLog::Message << "The occluder quad has a dynamic offset applied to gl_FragDepth" << TestLog::EndMessage;
+ log << TestLog::Message << "The time per culled pixel is estimated from the rate of change of rendering time as a function of workload" << TestLog::EndMessage;
+ log << TestLog::EndSection;
+ }
+};
+
+// Constant offset to frag depth in occluder
+class OccludedStaticFragDepthCostCase : public RenderCountCase
+{
+public:
+ OccludedStaticFragDepthCostCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
+ : RenderCountCase(testCtx, renderCtx, name, desc)
+ {
+ }
+
+ ~OccludedStaticFragDepthCostCase (void) {}
+
+private:
+ virtual ObjectData genOccluderGeometry (void) const { return Utils::fastQuad(0.2f); }
+ virtual ObjectData genOccludedGeometry (void) const { return Utils::quadWith(Utils::getStaticFragDepthFragmentShader(), 0.2f); }
+
+ virtual void logDescription (void)
+ {
+ TestLog& log = m_testCtx.getLog();
+
+ log << TestLog::Section("Description", "Test description");
+ log << TestLog::Message << "Testing hidden fragment culling speed" << TestLog::EndMessage;
+ log << TestLog::Message << "Geometry consists of two fullsceen quads. The first (occluding) is rendered once, the second (occluded) is rendered repeatedly" << TestLog::EndMessage;
+ log << TestLog::Message << "Workload indicates the number of times the occluded quad is rendered" << TestLog::EndMessage;
+ log << TestLog::Message << "The occluded quad has a static offset applied to gl_FragDepth" << TestLog::EndMessage;
+ log << TestLog::Message << "The time per culled pixel is estimated from the rate of change of rendering time as a function of workload" << TestLog::EndMessage;
+ log << TestLog::EndSection;
+ }
+};
+
+// Dynamic offset to frag depth in occluder
+class OccludedDynamicFragDepthCostCase : public RenderCountCase
+{
+public:
+ OccludedDynamicFragDepthCostCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
+ : RenderCountCase(testCtx, renderCtx, name, desc)
+ {
+ }
+
+ ~OccludedDynamicFragDepthCostCase (void) {}
+
+private:
+ virtual ObjectData genOccluderGeometry (void) const { return Utils::fastQuad(0.2f); }
+ virtual ObjectData genOccludedGeometry (void) const { return Utils::quadWith(Utils::getDynamicFragDepthFragmentShader(), 0.2f); }
+
+ virtual void logDescription (void)
+ {
+ TestLog& log = m_testCtx.getLog();
+
+ log << TestLog::Section("Description", "Test description");
+ log << TestLog::Message << "Testing hidden fragment culling speed" << TestLog::EndMessage;
+ log << TestLog::Message << "Geometry consists of two fullsceen quads. The first (occluding) is rendered once, the second (occluded) is rendered repeatedly" << TestLog::EndMessage;
+ log << TestLog::Message << "Workload indicates the number of times the occluded quad is rendered" << TestLog::EndMessage;
+ log << TestLog::Message << "The occluded quad has a dynamic offset applied to gl_FragDepth" << TestLog::EndMessage;
+ log << TestLog::Message << "The time per culled pixel is estimated from the rate of change of rendering time as a function of workload" << TestLog::EndMessage;
+ log << TestLog::EndSection;
+ }
+};
+
+// Culling speed with slightly less trivial geometry
+class OccludingGeometryComplexityCostCase : public RenderCountCase
+{
+public:
+ OccludingGeometryComplexityCostCase (TestContext& testCtx,
+ const RenderContext& renderCtx,
+ const char* name,
+ const char* desc,
+ int resolution,
+ float xyNoise,
+ float zNoise)
+ : RenderCountCase (testCtx, renderCtx, name, desc)
+ , m_resolution (resolution)
+ , m_xyNoise (xyNoise)
+ , m_zNoise (zNoise)
+ {
+ }
+
+ ~OccludingGeometryComplexityCostCase (void) {}
+
+private:
+ virtual ObjectData genOccluderGeometry (void) const
+ {
+ return ObjectData(Utils::getBaseShader(),
+ Utils::getFullScreenGrid(m_resolution,
+ deInt32Hash(deStringHash(getName())) ^ m_testCtx.getCommandLine().getBaseSeed(),
+ 0.2f,
+ m_zNoise,
+ m_xyNoise));
+ }
+
+ virtual ObjectData genOccludedGeometry (void) const { return Utils::variableQuad(0.8f); }
+
+ virtual void logDescription (void)
+ {
+ TestLog& log = m_testCtx.getLog();
+
+ log << TestLog::Section("Description", "Test description");
+ log << TestLog::Message << "Testing hidden fragment culling speed" << TestLog::EndMessage;
+ log << TestLog::Message << "Geometry consists of an occluding grid and an occluded fullsceen quad. The occluding geometry is rendered once, the occluded one is rendered repeatedly" << TestLog::EndMessage;
+ log << TestLog::Message << "Workload indicates the number of times the occluded quad is rendered" << TestLog::EndMessage;
+ log << TestLog::Message << "The time per culled pixel is estimated from the rate of change of rendering time as a function of workload" << TestLog::EndMessage;
+ log << TestLog::EndSection;
+ }
+
+ const int m_resolution;
+ const float m_xyNoise;
+ const float m_zNoise;
+};
+
+
+// Cases with varying workloads in the fragment shader
+class FragmentWorkloadCullCase : public RelativeChangeCase
+{
+public:
+ FragmentWorkloadCullCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc);
+ virtual ~FragmentWorkloadCullCase (void) {}
+
+private:
+ virtual ObjectData genOccluderGeometry (void) const { return Utils::fastQuad(0.2f); }
+
+ virtual void logDescription (void);
+};
+
+FragmentWorkloadCullCase::FragmentWorkloadCullCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
+ : RelativeChangeCase (testCtx, renderCtx, name, desc)
+{
+}
+
+void FragmentWorkloadCullCase::logDescription (void)
+{
+ TestLog& log = m_testCtx.getLog();
+
+ log << TestLog::Section("Description", "Test description");
+ log << TestLog::Message << "Testing effects of culled fragment workload on render time" << TestLog::EndMessage;
+ log << TestLog::Message << "Geometry consists of two fullsceen quads. The first (occluding) quad uses a trivial shader,"
+ "the second (occluded) contains significant fragment shader work" << TestLog::EndMessage;
+ log << TestLog::Message << "Workload indicates the number of iterations of dummy work done in the occluded quad's fragment shader" << TestLog::EndMessage;
+ log << TestLog::Message << "The ratio of rendering times of this scene with/without depth testing are compared" << TestLog::EndMessage;
+ log << TestLog::Message << "Successfull early Z-testing should result in no correlation between workload and render time" << TestLog::EndMessage;
+ log << TestLog::EndSection;
+}
+
+// Additional workload consists of texture lookups
+class FragmentTextureWorkloadCullCase : public FragmentWorkloadCullCase
+{
+public:
+ FragmentTextureWorkloadCullCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc);
+ virtual ~FragmentTextureWorkloadCullCase (void) {}
+
+ virtual void init (void);
+ virtual void deinit (void);
+
+private:
+ typedef MovePtr<glu::Texture> TexPtr;
+
+ virtual ObjectData genOccludedGeometry (void) const
+ {
+ return ObjectData(Utils::getTextureWorkloadShader(), Utils::getFullscreenQuad(0.8f));
+ }
+
+ TexPtr m_texture;
+};
+
+FragmentTextureWorkloadCullCase::FragmentTextureWorkloadCullCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
+ : FragmentWorkloadCullCase (testCtx, renderCtx, name, desc)
+{
+}
+
+void FragmentTextureWorkloadCullCase::init (void)
+{
+ const glw::Functions& gl = m_renderCtx.getFunctions();
+ const int size = 128;
+ const vector<deUint8> data (size*size*4, 255);
+
+ m_texture = MovePtr<glu::Texture>(new glu::Texture(gl));
+
+ gl.bindTexture(GL_TEXTURE_2D, m_texture);
+ gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
+ gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+}
+
+void FragmentTextureWorkloadCullCase::deinit (void)
+{
+ m_texture.clear();
+}
+
+// Additional workload consists of arithmetic
+class FragmentArithmeticWorkloadCullCase : public FragmentWorkloadCullCase
+{
+public:
+ FragmentArithmeticWorkloadCullCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
+ : FragmentWorkloadCullCase (testCtx, renderCtx, name, desc)
+ {
+ }
+ virtual ~FragmentArithmeticWorkloadCullCase (void) {}
+
+private:
+ virtual ObjectData genOccludedGeometry (void) const
+ {
+ return ObjectData(Utils::getArithmeticWorkloadShader(), Utils::getFullscreenQuad(0.8f));
+ }
+};
+
+// Contains dynamicly unused discard after a series of calculations
+class FragmentDiscardArithmeticWorkloadCullCase : public FragmentWorkloadCullCase
+{
+public:
+ FragmentDiscardArithmeticWorkloadCullCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
+ : FragmentWorkloadCullCase (testCtx, renderCtx, name, desc)
+ {
+ }
+
+ virtual ~FragmentDiscardArithmeticWorkloadCullCase (void) {}
+
+private:
+ virtual ObjectData genOccludedGeometry (void) const
+ {
+ return ObjectData(Utils::getArithmeticWorkloadDiscardShader(), Utils::getFullscreenQuad(0.8f));
+ }
+
+ virtual void logDescription (void)
+ {
+ TestLog& log = m_testCtx.getLog();
+
+ log << TestLog::Section("Description", "Test description");
+ log << TestLog::Message << "Testing effects of culled fragment workload on render time" << TestLog::EndMessage;
+ log << TestLog::Message << "Geometry consists of two fullsceen quads. The first (occluding) quad uses a trivial shader,"
+ "the second (occluded) contains significant fragment shader work and a discard that is never triggers but has a dynamic condition" << TestLog::EndMessage;
+ log << TestLog::Message << "Workload indicates the number of iterations of dummy work done in the occluded quad's fragment shader" << TestLog::EndMessage;
+ log << TestLog::Message << "The ratio of rendering times of this scene with/without depth testing are compared" << TestLog::EndMessage;
+ log << TestLog::Message << "Successfull early Z-testing should result in no correlation between workload and render time" << TestLog::EndMessage;
+ log << TestLog::EndSection;
+ }
+};
+
+// Discards fragments from the occluder in a grid pattern
+class PartialOccluderDiscardCullCase : public RelativeChangeCase
+{
+public:
+ PartialOccluderDiscardCullCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc, int gridsize)
+ : RelativeChangeCase (testCtx, renderCtx, name, desc)
+ , m_gridsize (gridsize)
+ {
+ }
+ virtual ~PartialOccluderDiscardCullCase (void) {}
+
+private:
+ virtual ObjectData genOccluderGeometry (void) const { return Utils::quadWith(Utils::getGridDiscardShader(m_gridsize), 0.2f); }
+ virtual ObjectData genOccludedGeometry (void) const { return Utils::slowQuad(0.8f); }
+
+ virtual void logDescription (void)
+ {
+ TestLog& log = m_testCtx.getLog();
+
+ log << TestLog::Section("Description", "Test description");
+ log << TestLog::Message << "Testing effects of partially discarded occluder on rendering time" << TestLog::EndMessage;
+ log << TestLog::Message << "Geometry consists of two fullsceen quads. The first (occluding) quad discards half the "
+ "fragments in a grid pattern, the second (partially occluded) contains significant fragment shader work" << TestLog::EndMessage;
+ log << TestLog::Message << "Workload indicates the number of iterations of dummy work done in the occluded quad's fragment shader" << TestLog::EndMessage;
+ log << TestLog::Message << "The ratio of rendering times of this scene with/without depth testing are compared" << TestLog::EndMessage;
+ log << TestLog::Message << "Successfull early Z-testing should result in depth testing halving the render time" << TestLog::EndMessage;
+ log << TestLog::EndSection;
+ }
+
+ const int m_gridsize;
+};
+
+// Trivial occluder covering part of screen
+class PartialOccluderCullCase : public RelativeChangeCase
+{
+public:
+ PartialOccluderCullCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc, float coverage)
+ : RelativeChangeCase (testCtx, renderCtx, name, desc)
+ , m_coverage (coverage)
+ {
+ }
+ ~PartialOccluderCullCase (void) {}
+
+private:
+ virtual ObjectData genOccluderGeometry (void) const { return ObjectData(Utils::getBaseShader(), Utils::getPartScreenQuad(m_coverage, 0.2f)); }
+ virtual ObjectData genOccludedGeometry (void) const {return Utils::slowQuad(0.8f); }
+
+ virtual void logDescription (void)
+ {
+ TestLog& log = m_testCtx.getLog();
+
+ log << TestLog::Section("Description", "Test description");
+ log << TestLog::Message << "Testing effects of partial occluder on rendering time" << TestLog::EndMessage;
+ log << TestLog::Message << "Geometry consists of two quads. The first (occluding) quad covers " << m_coverage*100.0f
+ << "% of the screen, while the second (partially occluded, fullscreen) contains significant fragment shader work" << TestLog::EndMessage;
+ log << TestLog::Message << "Workload indicates the number of iterations of dummy work done in the occluded quad's fragment shader" << TestLog::EndMessage;
+ log << TestLog::Message << "The ratio of rendering times of this scene with/without depth testing are compared" << TestLog::EndMessage;
+ log << TestLog::Message << "Successfull early Z-testing should result in render time increasing proportionally with unoccluded area" << TestLog::EndMessage;
+ log << TestLog::EndSection;
+ }
+
+ const float m_coverage;
+};
+
+// Constant offset to frag depth in occluder
+class StaticOccluderFragDepthCullCase : public RelativeChangeCase
+{
+public:
+ StaticOccluderFragDepthCullCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
+ : RelativeChangeCase(testCtx, renderCtx, name, desc)
+ {
+ }
+
+ ~StaticOccluderFragDepthCullCase (void) {}
+
+private:
+ virtual ObjectData genOccluderGeometry (void) const { return Utils::quadWith(Utils::getStaticFragDepthFragmentShader(), 0.2f); }
+ virtual ObjectData genOccludedGeometry (void) const { return Utils::slowQuad(0.8f); }
+
+ virtual void logDescription (void)
+ {
+ TestLog& log = m_testCtx.getLog();
+
+ log << TestLog::Section("Description", "Test description");
+ log << TestLog::Message << "Testing effects of non-default frag depth on culling efficiency" << TestLog::EndMessage;
+ log << TestLog::Message << "Geometry consists of two fullscreen quads. The first (occluding) quad is trivial, while the second (occluded) contains significant fragment shader work" << TestLog::EndMessage;
+ log << TestLog::Message << "Workload indicates the number of iterations of dummy work done in the occluded quad's fragment shader" << TestLog::EndMessage;
+ log << TestLog::Message << "The occluder quad has a static offset applied to gl_FragDepth" << TestLog::EndMessage;
+ log << TestLog::Message << "The ratio of rendering times of this scene with/without depth testing are compared" << TestLog::EndMessage;
+ log << TestLog::Message << "Successfull early Z-testing should result in no correlation between workload and render time" << TestLog::EndMessage;
+ log << TestLog::EndSection;
+ }
+};
+
+// Dynamic offset to frag depth in occluder
+class DynamicOccluderFragDepthCullCase : public RelativeChangeCase
+{
+public:
+ DynamicOccluderFragDepthCullCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
+ : RelativeChangeCase(testCtx, renderCtx, name, desc)
+ {
+ }
+
+ ~DynamicOccluderFragDepthCullCase (void) {}
+
+private:
+ virtual ObjectData genOccluderGeometry (void) const { return Utils::quadWith(Utils::getDynamicFragDepthFragmentShader(), 0.2f); }
+ virtual ObjectData genOccludedGeometry (void) const { return Utils::slowQuad(0.8f); }
+
+ virtual void logDescription (void)
+ {
+ TestLog& log = m_testCtx.getLog();
+
+ log << TestLog::Section("Description", "Test description");
+ log << TestLog::Message << "Testing effects of non-default frag depth on culling efficiency" << TestLog::EndMessage;
+ log << TestLog::Message << "Geometry consists of two fullscreen quads. The first (occluding) quad is trivial, while the second (occluded) contains significant fragment shader work" << TestLog::EndMessage;
+ log << TestLog::Message << "Workload indicates the number of iterations of dummy work done in the occluded quad's fragment shader" << TestLog::EndMessage;
+ log << TestLog::Message << "The occluder quad has a dynamic offset applied to gl_FragDepth" << TestLog::EndMessage;
+ log << TestLog::Message << "The ratio of rendering times of this scene with/without depth testing are compared" << TestLog::EndMessage;
+ log << TestLog::Message << "Successfull early Z-testing should result in no correlation between workload and render time" << TestLog::EndMessage;
+ log << TestLog::EndSection;
+ }
+};
+
+// Constant offset to frag depth in occluded
+class StaticOccludedFragDepthCullCase : public RelativeChangeCase
+{
+public:
+ StaticOccludedFragDepthCullCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
+ : RelativeChangeCase(testCtx, renderCtx, name, desc)
+ {
+ }
+
+ ~StaticOccludedFragDepthCullCase (void) {}
+
+private:
+ virtual ObjectData genOccluderGeometry (void) const { return Utils::fastQuad(0.2f); }
+ virtual ObjectData genOccludedGeometry (void) const { return Utils::quadWith(Utils::getStaticFragDepthArithmeticWorkloadFragmentShader(), 0.2f); }
+
+ virtual void logDescription (void)
+ {
+ TestLog& log = m_testCtx.getLog();
+
+ log << TestLog::Section("Description", "Test description");
+ log << TestLog::Message << "Testing effects of non-default frag depth on rendering time" << TestLog::EndMessage;
+ log << TestLog::Message << "Geometry consists of two fullscreen quads. The first (occluding) quad is trivial, while the second (occluded) contains significant fragment shader work" << TestLog::EndMessage;
+ log << TestLog::Message << "Workload indicates the number of iterations of dummy work done in the occluded quad's fragment shader" << TestLog::EndMessage;
+ log << TestLog::Message << "The occluded quad has a static offset applied to gl_FragDepth" << TestLog::EndMessage;
+ log << TestLog::Message << "The ratio of rendering times of this scene with/without depth testing are compared" << TestLog::EndMessage;
+ log << TestLog::Message << "Successfull early Z-testing should result in no correlation between workload and render time" << TestLog::EndMessage;
+ log << TestLog::EndSection;
+ }
+};
+
+// Dynamic offset to frag depth in occluded
+class DynamicOccludedFragDepthCullCase : public RelativeChangeCase
+{
+public:
+ DynamicOccludedFragDepthCullCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
+ : RelativeChangeCase(testCtx, renderCtx, name, desc)
+ {
+ }
+
+ ~DynamicOccludedFragDepthCullCase (void) {}
+
+private:
+ virtual ObjectData genOccluderGeometry (void) const { return Utils::fastQuad(0.2f); }
+ virtual ObjectData genOccludedGeometry (void) const { return Utils::quadWith(Utils::getDynamicFragDepthArithmeticWorkloadFragmentShader(), 0.2f); }
+
+ virtual void logDescription (void)
+ {
+ TestLog& log = m_testCtx.getLog();
+
+ log << TestLog::Section("Description", "Test description");
+ log << TestLog::Message << "Testing effects of non-default frag depth on rendering time" << TestLog::EndMessage;
+ log << TestLog::Message << "Geometry consists of two fullscreen quads. The first (occluding) quad is trivial, while the second (occluded) contains significant fragment shader work" << TestLog::EndMessage;
+ log << TestLog::Message << "Workload indicates the number of iterations of dummy work done in the occluded quad's fragment shader" << TestLog::EndMessage;
+ log << TestLog::Message << "The occluded quad has a dynamic offset applied to gl_FragDepth" << TestLog::EndMessage;
+ log << TestLog::Message << "The ratio of rendering times of this scene with/without depth testing are compared" << TestLog::EndMessage;
+ log << TestLog::Message << "Successfull early Z-testing should result in no correlation between workload and render time" << TestLog::EndMessage;
+ log << TestLog::EndSection;
+ }
+};
+
+// Dynamic offset to frag depth in occluded
+class ReversedDepthOrderCullCase : public RelativeChangeCase
+{
+public:
+ ReversedDepthOrderCullCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
+ : RelativeChangeCase(testCtx, renderCtx, name, desc)
+ {
+ }
+
+ ~ReversedDepthOrderCullCase (void) {}
+
+private:
+ virtual ObjectData genOccluderGeometry (void) const { return Utils::fastQuad(0.2f); }
+ virtual ObjectData genOccludedGeometry (void) const { return Utils::slowQuad(0.8f); }
+
+ virtual void logDescription (void)
+ {
+ TestLog& log = m_testCtx.getLog();
+
+ log << TestLog::Section("Description", "Test description");
+ log << TestLog::Message << "Testing effects of of back first rendering order on culling efficiency" << TestLog::EndMessage;
+ log << TestLog::Message << "Geometry consists of two fullscreen quads. The second (occluding) quad is trivial, while the first (occluded) contains significant fragment shader work" << TestLog::EndMessage;
+ log << TestLog::Message << "Workload indicates the number of iterations of dummy work done in the occluded quad's fragment shader" << TestLog::EndMessage;
+ log << TestLog::Message << "The ratio of rendering times of this scene with/without depth testing are compared" << TestLog::EndMessage;
+ log << TestLog::Message << "Successfull early Z-testing should result in no correlation between workload and render time" << TestLog::EndMessage;
+ log << TestLog::EndSection;
+ }
+
+ // Rendering order of occluder & occluded is reversed, otherwise identical to parent version
+ Sample renderSample (const RenderData& occluder, const RenderData& occluded, int workload) const
+ {
+ const glw::Functions& gl = m_renderCtx.getFunctions();
+ const GLuint program = occluded.m_program.getProgram();
+ Sample sample;
+ deUint64 now = 0;
+ deUint64 prev = 0;
+ deUint8 buffer[4];
+
+ gl.useProgram(program);
+ gl.uniform1i(gl.getUniformLocation(program, "u_iterations"), workload);
+
+ // Warmup (this workload seems to reduce variation in following workloads)
+ {
+ gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ gl.disable(GL_DEPTH_TEST);
+
+ gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+ }
+
+ // Null time
+ {
+ prev = deGetMicroseconds();
+
+ gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ gl.disable(GL_DEPTH_TEST);
+
+ gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+
+ now = deGetMicroseconds();
+
+ sample.nullTime = now - prev;
+ }
+
+ // Test time
+ {
+ prev = deGetMicroseconds();
+
+ gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ gl.enable(GL_DEPTH_TEST);
+
+ render(occluded);
+ render(occluder);
+
+ gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+
+ now = deGetMicroseconds();
+
+ sample.testTime = now - prev;
+ }
+
+ // Base time
+ {
+ prev = deGetMicroseconds();
+
+ gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ gl.disable(GL_DEPTH_TEST);
+
+ render(occluded);
+ render(occluder);
+
+ gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+
+ now = deGetMicroseconds();
+
+ sample.baseTime = now - prev;
+ }
+
+ sample.workload = 0;
+
+ return sample;
+ }
+};
+
+} // Anonymous
+
+DepthTests::DepthTests (Context& context)
+ : TestCaseGroup (context, "depth", "Depth culling performance")
+{
+}
+
+void DepthTests::init (void)
+{
+ TestContext& testCtx = m_context.getTestContext();
+ const RenderContext& renderCtx = m_context.getRenderContext();
+
+ {
+ tcu::TestCaseGroup* const cullEfficiencyGroup = new tcu::TestCaseGroup(m_testCtx, "cull_efficiency", "Fragment cull efficiency");
+
+ addChild(cullEfficiencyGroup);
+
+ {
+ tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "workload", "Workload");
+
+ cullEfficiencyGroup->addChild(group);
+
+ group->addChild(new FragmentTextureWorkloadCullCase( testCtx, renderCtx, "workload_texture", "Fragment shader with texture lookup workload"));
+ group->addChild(new FragmentArithmeticWorkloadCullCase( testCtx, renderCtx, "workload_arithmetic", "Fragment shader with arithmetic workload"));
+ group->addChild(new FragmentDiscardArithmeticWorkloadCullCase( testCtx, renderCtx, "workload_arithmetic_discard", "Fragment shader that may discard with arithmetic workload"));
+ }
+
+ {
+ tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "occluder_discard", "Discard");
+
+ cullEfficiencyGroup->addChild(group);
+
+ group->addChild(new PartialOccluderDiscardCullCase(testCtx, renderCtx, "grid_256", "Parts of occluder geometry discarded", 256));
+ group->addChild(new PartialOccluderDiscardCullCase(testCtx, renderCtx, "grid_128", "Parts of occluder geometry discarded", 128));
+ group->addChild(new PartialOccluderDiscardCullCase(testCtx, renderCtx, "grid_64", "Parts of occluder geometry discarded", 64));
+ group->addChild(new PartialOccluderDiscardCullCase(testCtx, renderCtx, "grid_32", "Parts of occluder geometry discarded", 32));
+ group->addChild(new PartialOccluderDiscardCullCase(testCtx, renderCtx, "grid_16", "Parts of occluder geometry discarded", 16));
+ group->addChild(new PartialOccluderDiscardCullCase(testCtx, renderCtx, "grid_8", "Parts of occluder geometry discarded", 8));
+ group->addChild(new PartialOccluderDiscardCullCase(testCtx, renderCtx, "grid_4", "Parts of occluder geometry discarded", 4));
+ group->addChild(new PartialOccluderDiscardCullCase(testCtx, renderCtx, "grid_2", "Parts of occluder geometry discarded", 2));
+ group->addChild(new PartialOccluderDiscardCullCase(testCtx, renderCtx, "grid_1", "Parts of occluder geometry discarded", 1));
+ }
+
+ {
+ tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "partial_coverage", "Partial Coverage");
+
+ cullEfficiencyGroup->addChild(group);
+
+ group->addChild(new PartialOccluderCullCase(testCtx, renderCtx, "100", "Occluder covering only part of occluded geometry", 1.00f));
+ group->addChild(new PartialOccluderCullCase(testCtx, renderCtx, "099", "Occluder covering only part of occluded geometry", 0.99f));
+ group->addChild(new PartialOccluderCullCase(testCtx, renderCtx, "095", "Occluder covering only part of occluded geometry", 0.95f));
+ group->addChild(new PartialOccluderCullCase(testCtx, renderCtx, "090", "Occluder covering only part of occluded geometry", 0.90f));
+ group->addChild(new PartialOccluderCullCase(testCtx, renderCtx, "080", "Occluder covering only part of occluded geometry", 0.80f));
+ group->addChild(new PartialOccluderCullCase(testCtx, renderCtx, "070", "Occluder covering only part of occluded geometry", 0.70f));
+ group->addChild(new PartialOccluderCullCase(testCtx, renderCtx, "050", "Occluder covering only part of occluded geometry", 0.50f));
+ group->addChild(new PartialOccluderCullCase(testCtx, renderCtx, "025", "Occluder covering only part of occluded geometry", 0.25f));
+ group->addChild(new PartialOccluderCullCase(testCtx, renderCtx, "010", "Occluder covering only part of occluded geometry", 0.10f));
+ }
+
+ {
+ tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "frag_depth", "Partial Coverage");
+
+ cullEfficiencyGroup->addChild(group);
+
+ group->addChild(new StaticOccluderFragDepthCullCase( testCtx, renderCtx, "occluder_static", ""));
+ group->addChild(new DynamicOccluderFragDepthCullCase(testCtx, renderCtx, "occluder_dynamic", ""));
+ group->addChild(new StaticOccludedFragDepthCullCase( testCtx, renderCtx, "occluded_static", ""));
+ group->addChild(new DynamicOccludedFragDepthCullCase(testCtx, renderCtx, "occluded_dynamic", ""));
+ }
+
+ {
+ tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "order", "Rendering order");
+
+ cullEfficiencyGroup->addChild(group);
+
+ group->addChild(new ReversedDepthOrderCullCase(testCtx, renderCtx, "reversed", "Back to front rendering order"));
+ }
+ }
+
+ {
+ tcu::TestCaseGroup* const testCostGroup = new tcu::TestCaseGroup(m_testCtx, "culled_pixel_cost", "Fragment cull efficiency");
+
+ addChild(testCostGroup);
+
+ {
+ tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "gradient", "Gradients with small depth differences");
+
+ testCostGroup->addChild(group);
+
+ group->addChild(new BaseCostCase(testCtx, renderCtx, "flat", ""));
+ group->addChild(new GradientCostCase(testCtx, renderCtx, "gradient_050", "", 0.50f));
+ group->addChild(new GradientCostCase(testCtx, renderCtx, "gradient_010", "", 0.10f));
+ group->addChild(new GradientCostCase(testCtx, renderCtx, "gradient_005", "", 0.05f));
+ group->addChild(new GradientCostCase(testCtx, renderCtx, "gradient_002", "", 0.02f));
+ group->addChild(new GradientCostCase(testCtx, renderCtx, "gradient_001", "", 0.01f));
+ }
+
+ {
+ tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "occluder_geometry", "Occluders with varying geometry complexity");
+
+ testCostGroup->addChild(group);
+
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_uniform_grid_5", "", 5, 0.0f, 0.0f));
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_uniform_grid_15", "", 15, 0.0f, 0.0f));
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_uniform_grid_25", "", 25, 0.0f, 0.0f));
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_uniform_grid_50", "", 50, 0.0f, 0.0f));
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_uniform_grid_100", "", 100, 0.0f, 0.0f));
+
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_noisy_grid_5", "", 5, 1.0f/5.0f, 0.0f));
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_noisy_grid_15", "", 15, 1.0f/15.0f, 0.0f));
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_noisy_grid_25", "", 25, 1.0f/25.0f, 0.0f));
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_noisy_grid_50", "", 50, 1.0f/50.0f, 0.0f));
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_noisy_grid_100", "", 100, 1.0f/100.0f, 0.0f));
+
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_uniform_grid_5", "", 5, 0.0f, 0.2f));
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_uniform_grid_15", "", 15, 0.0f, 0.2f));
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_uniform_grid_25", "", 25, 0.0f, 0.2f));
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_uniform_grid_50", "", 50, 0.0f, 0.2f));
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_uniform_grid_100", "", 100, 0.0f, 0.2f));
+
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_noisy_grid_5", "", 5, 1.0f/5.0f, 0.2f));
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_noisy_grid_15", "", 15, 1.0f/15.0f, 0.2f));
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_noisy_grid_25", "", 25, 1.0f/25.0f, 0.2f));
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_noisy_grid_50", "", 50, 1.0f/50.0f, 0.2f));
+ group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_noisy_grid_100", "", 100, 1.0f/100.0f, 0.2f));
+ }
+
+ {
+ tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "frag_depth", "Modifying gl_FragDepth");
+
+ testCostGroup->addChild(group);
+
+ group->addChild(new OccluderStaticFragDepthCostCase( testCtx, renderCtx, "occluder_static", ""));
+ group->addChild(new OccluderDynamicFragDepthCostCase(testCtx, renderCtx, "occluder_dynamic", ""));
+ group->addChild(new OccludedStaticFragDepthCostCase( testCtx, renderCtx, "occluded_static", ""));
+ group->addChild(new OccludedDynamicFragDepthCostCase(testCtx, renderCtx, "occluded_dynamic", ""));
+ }
+ }
+}
+
+} // Performance
+} // gles3
+} // deqp
diff --git a/modules/gles3/performance/es3pDepthTests.hpp b/modules/gles3/performance/es3pDepthTests.hpp
new file mode 100644
index 000000000..5b861b5bd
--- /dev/null
+++ b/modules/gles3/performance/es3pDepthTests.hpp
@@ -0,0 +1,53 @@
+#ifndef _ES3PDEPTHTESTS_HPP
+#define _ES3PDEPTHTESTS_HPP
+/*-------------------------------------------------------------------------
+ * 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 Depth buffer performance tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tes3TestCase.hpp"
+
+namespace deqp
+{
+namespace gles3
+{
+namespace Performance
+{
+
+class DepthTests : public TestCaseGroup
+{
+public:
+ DepthTests (Context& context);
+ ~DepthTests (void) {}
+
+ virtual void init (void);
+
+private:
+ DepthTests (const DepthTests& other);
+ DepthTests& operator= (const DepthTests& other);
+};
+
+} // Performance
+} // gles3
+} // deqp
+
+#endif // _ES3PDEPTHTESTS_HPP
diff --git a/modules/gles3/performance/es3pPerformanceTests.cpp b/modules/gles3/performance/es3pPerformanceTests.cpp
index f7377cc75..7c05a035d 100644
--- a/modules/gles3/performance/es3pPerformanceTests.cpp
+++ b/modules/gles3/performance/es3pPerformanceTests.cpp
@@ -35,6 +35,7 @@
#include "es3pStateChangeCallTests.hpp"
#include "es3pStateChangeTests.hpp"
#include "es3pBufferDataUploadTests.hpp"
+#include "es3pDepthTests.hpp"
namespace deqp
{
@@ -131,6 +132,7 @@ void PerformanceTests::init (void)
addChild(new ShaderCompilerTests (m_context));
addChild(new APITests (m_context));
addChild(new BufferTestGroup (m_context));
+ addChild(new DepthTests (m_context));
}
} // Performance
diff --git a/modules/gles3/performance/es3pShaderOperatorTests.cpp b/modules/gles3/performance/es3pShaderOperatorTests.cpp
index f4254b141..ac502bed6 100644
--- a/modules/gles3/performance/es3pShaderOperatorTests.cpp
+++ b/modules/gles3/performance/es3pShaderOperatorTests.cpp
@@ -545,13 +545,13 @@ static SegmentedEstimator computeSegmentedEstimator (const vector<Vec2>& data)
}
{
- const gls::LineParameters leftLine = gls::theilSenEstimator(leftData);
- const gls::LineParameters rightLine = gls::theilSenEstimator(rightData);
+ const gls::LineParameters leftLine = gls::theilSenLinearRegression(leftData);
+ const gls::LineParameters rightLine = gls::theilSenLinearRegression(rightData);
if (numDistinctX(leftData) < 2 || leftLine.coefficient > rightLine.coefficient*0.5f)
{
// Left data doesn't seem credible; assume the data is just a single line.
- const gls::LineParameters entireLine = gls::theilSenEstimator(data);
+ const gls::LineParameters entireLine = gls::theilSenLinearRegression(data);
return SegmentedEstimator(gls::LineParameters(entireLine.offset, 0.0f), entireLine, -std::numeric_limits<float>::infinity());
}
else