blob: 93840cac2ba89c261cee10ef7fe7d9701ed47e08 [file] [log] [blame]
//
// Copyright 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// PointSpritesBenchmark:
// Performance test for ANGLE point sprites.
//
//
#include "ANGLEPerfTest.h"
#include <iostream>
#include <sstream>
#include "util/random_utils.h"
#include "util/shader_utils.h"
using namespace angle;
namespace
{
constexpr unsigned int kIterationsPerStep = 100;
struct PointSpritesParams final : public RenderTestParams
{
PointSpritesParams()
{
iterationsPerStep = kIterationsPerStep;
// Common default params
majorVersion = 2;
minorVersion = 0;
windowWidth = 1280;
windowHeight = 720;
count = 10;
size = 3.0f;
numVaryings = 3;
}
std::string story() const override;
unsigned int count;
float size;
unsigned int numVaryings;
};
std::ostream &operator<<(std::ostream &os, const PointSpritesParams &params)
{
os << params.backendAndStory().substr(1);
return os;
}
class PointSpritesBenchmark : public ANGLERenderTest,
public ::testing::WithParamInterface<PointSpritesParams>
{
public:
PointSpritesBenchmark();
void initializeBenchmark() override;
void destroyBenchmark() override;
void drawBenchmark() override;
private:
GLuint mProgram;
GLuint mBuffer;
RNG mRNG;
};
std::string PointSpritesParams::story() const
{
std::stringstream strstr;
strstr << RenderTestParams::story() << "_" << count << "_" << size << "px"
<< "_" << numVaryings << "vars";
return strstr.str();
}
PointSpritesBenchmark::PointSpritesBenchmark()
: ANGLERenderTest("PointSprites", GetParam()), mRNG(1)
{}
void PointSpritesBenchmark::initializeBenchmark()
{
const auto &params = GetParam();
std::stringstream vstrstr;
// Verify "numVaryings" is within MAX_VARYINGS limit
GLint maxVaryings;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
if (params.numVaryings > static_cast<unsigned int>(maxVaryings))
{
FAIL() << "Varying count (" << params.numVaryings << ")"
<< " exceeds maximum varyings: " << maxVaryings << std::endl;
}
vstrstr << "attribute vec2 vPosition;\n"
"uniform float uPointSize;\n";
for (unsigned int varCount = 0; varCount < params.numVaryings; varCount++)
{
vstrstr << "varying vec4 v" << varCount << ";\n";
}
vstrstr << "void main()\n"
"{\n";
for (unsigned int varCount = 0; varCount < params.numVaryings; varCount++)
{
vstrstr << " v" << varCount << " = vec4(1.0);\n";
}
vstrstr << " gl_Position = vec4(vPosition, 0, 1.0);\n"
" gl_PointSize = uPointSize;\n"
"}";
std::stringstream fstrstr;
fstrstr << "precision mediump float;\n";
for (unsigned int varCount = 0; varCount < params.numVaryings; varCount++)
{
fstrstr << "varying vec4 v" << varCount << ";\n";
}
fstrstr << "void main()\n"
"{\n"
" vec4 colorOut = vec4(1.0, 0.0, 0.0, 1.0);\n";
for (unsigned int varCount = 0; varCount < params.numVaryings; varCount++)
{
fstrstr << " colorOut.r += v" << varCount << ".r;\n";
}
fstrstr << " gl_FragColor = colorOut;\n"
"}\n";
mProgram = CompileProgram(vstrstr.str().c_str(), fstrstr.str().c_str());
ASSERT_NE(0u, mProgram);
// Use the program object
glUseProgram(mProgram);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
std::vector<float> vertexPositions(params.count * 2);
for (size_t pointIndex = 0; pointIndex < vertexPositions.size(); ++pointIndex)
{
vertexPositions[pointIndex] = mRNG.randomNegativeOneToOne();
}
glGenBuffers(1, &mBuffer);
glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
glBufferData(GL_ARRAY_BUFFER, vertexPositions.size() * sizeof(float), &vertexPositions[0],
GL_STATIC_DRAW);
GLint positionLocation = glGetAttribLocation(mProgram, "vPosition");
ASSERT_NE(-1, positionLocation);
glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(positionLocation);
// Set the viewport
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
GLint pointSizeLocation = glGetUniformLocation(mProgram, "uPointSize");
ASSERT_NE(-1, pointSizeLocation);
glUniform1f(pointSizeLocation, params.size);
ASSERT_GL_NO_ERROR();
}
void PointSpritesBenchmark::destroyBenchmark()
{
glDeleteProgram(mProgram);
glDeleteBuffers(1, &mBuffer);
}
void PointSpritesBenchmark::drawBenchmark()
{
glClear(GL_COLOR_BUFFER_BIT);
const auto &params = GetParam();
for (unsigned int it = 0; it < params.iterationsPerStep; it++)
{
// TODO(jmadill): Indexed point rendering. ANGLE is bad at this.
glDrawArrays(GL_POINTS, 0, params.count);
}
ASSERT_GL_NO_ERROR();
}
PointSpritesParams D3D11Params()
{
PointSpritesParams params;
params.eglParameters = egl_platform::D3D11();
return params;
}
PointSpritesParams D3D9Params()
{
PointSpritesParams params;
params.eglParameters = egl_platform::D3D9();
return params;
}
PointSpritesParams OpenGLOrGLESParams()
{
PointSpritesParams params;
params.eglParameters = egl_platform::OPENGL_OR_GLES();
return params;
}
PointSpritesParams VulkanParams()
{
PointSpritesParams params;
params.eglParameters = egl_platform::VULKAN();
return params;
}
} // namespace
TEST_P(PointSpritesBenchmark, Run)
{
run();
}
ANGLE_INSTANTIATE_TEST(PointSpritesBenchmark,
D3D11Params(),
D3D9Params(),
OpenGLOrGLESParams(),
VulkanParams());