Commit bbffd556 by Jamie Madill

Add a TexSubImage benchmark.

Currently we are about 2x as slow on this micro-benchmark in D3D11. Preliminary testing suggests using CopySubresourceRegion gives improved performance across the board, but testing could disprove this hypothesis. Modified from a sample from bajones. BUG=angle:705 Change-Id: Iedf36a4e7b9b9bbed308302fd2bf3912acacbd2c Reviewed-on: https://chromium-review.googlesource.com/216272Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 9e16d40d
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include <cassert> #include <cassert>
#include <sstream> #include <sstream>
#include "shader_utils.h"
namespace namespace
{ {
...@@ -128,16 +130,7 @@ std::string BufferSubDataParams::name() const ...@@ -128,16 +130,7 @@ std::string BufferSubDataParams::name() const
{ {
std::stringstream strstr; std::stringstream strstr;
strstr << "BufferSubData - "; strstr << "BufferSubData - " << BenchmarkParams::name() << " - ";
switch (requestedRenderer)
{
case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: strstr << "D3D11"; break;
case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: strstr << "D3D9"; break;
default: strstr << "UNKNOWN RENDERER (" << requestedRenderer << ")"; break;
}
strstr << " - ";
if (vertexNormalized) if (vertexNormalized)
{ {
......
...@@ -6,11 +6,6 @@ ...@@ -6,11 +6,6 @@
#include "SimpleBenchmark.h" #include "SimpleBenchmark.h"
const int BUFFER_SIZE = 1024 * 1024;
const int UPDATE_SIZE = 300;
#include "shader_utils.h"
struct BufferSubDataParams : public BenchmarkParams struct BufferSubDataParams : public BenchmarkParams
{ {
EGLint requestedRenderer; EGLint requestedRenderer;
......
...@@ -69,7 +69,17 @@ class SimpleBenchmark ...@@ -69,7 +69,17 @@ class SimpleBenchmark
// Base class // Base class
struct BenchmarkParams struct BenchmarkParams
{ {
virtual std::string name() const = 0; EGLint requestedRenderer;
virtual std::string name() const
{
switch (requestedRenderer)
{
case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: return "D3D11";
case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: return "D3D9";
default: return "Unknown Renderer";
}
}
}; };
template <typename BenchmarkT, typename ParamsT> template <typename BenchmarkT, typename ParamsT>
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "SimpleBenchmark.h" #include "SimpleBenchmark.h"
#include "BufferSubData.h" #include "BufferSubData.h"
#include "TexSubImage.h"
EGLint platforms[] = EGLint platforms[] =
{ {
...@@ -23,7 +24,7 @@ unsigned int updatesEveryNFrames[] = { 1, 4 }; ...@@ -23,7 +24,7 @@ unsigned int updatesEveryNFrames[] = { 1, 4 };
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
std::vector<BufferSubDataParams> benchmarks; std::vector<BufferSubDataParams> subDataParams;
for (size_t platIt = 0; platIt < ArraySize(platforms); platIt++) for (size_t platIt = 0; platIt < ArraySize(platforms); platIt++)
{ {
...@@ -69,7 +70,7 @@ int main(int argc, char **argv) ...@@ -69,7 +70,7 @@ int main(int argc, char **argv)
} }
} }
benchmarks.push_back(params); subDataParams.push_back(params);
} }
} }
} }
...@@ -80,5 +81,23 @@ int main(int argc, char **argv) ...@@ -80,5 +81,23 @@ int main(int argc, char **argv)
} }
// Enumerates permutations // Enumerates permutations
RunBenchmarks<BufferSubDataBenchmark>(benchmarks); RunBenchmarks<BufferSubDataBenchmark>(subDataParams);
std::vector<TexSubImageParams> subImageParams;
for (size_t platIt = 0; platIt < ArraySize(platforms); platIt++)
{
TexSubImageParams params;
params.requestedRenderer = platforms[platIt];
params.imageWidth = 1024;
params.imageHeight = 1024;
params.subImageHeight = 64;
params.subImageWidth = 64;
params.iterations = 10;
subImageParams.push_back(params);
}
RunBenchmarks<TexSubImageBenchmark>(subImageParams);
} }
//
// Copyright (c) 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.
//
#include "TexSubImage.h"
#include <sstream>
#include <cassert>
#include "shader_utils.h"
std::string TexSubImageParams::name() const
{
std::stringstream strstr;
strstr << "TexSubImage - " << BenchmarkParams::name()
<< " - " << imageWidth << "x" << imageHeight
<< " - " << subImageWidth << "x" << subImageHeight << " updates";
return strstr.str();
}
TexSubImageBenchmark::TexSubImageBenchmark(const TexSubImageParams &params)
: SimpleBenchmark(params.name(), 512, 512, 2, params.requestedRenderer),
mParams(params),
mProgram(0),
mPositionLoc(-1),
mTexCoordLoc(-1),
mSamplerLoc(-1),
mTexture(0),
mVertexBuffer(0),
mIndexBuffer(0),
mPixels(NULL)
{
assert(mParams.iterations > 0);
mDrawIterations = mParams.iterations;
}
GLuint TexSubImageBenchmark::createTexture()
{
// Use tightly packed data
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Generate a texture object
GLuint texture;
glGenTextures(1, &texture);
// Bind the texture object
glBindTexture(GL_TEXTURE_2D, texture);
glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, mParams.imageWidth, mParams.imageHeight);
// Set the filtering mode
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
return texture;
}
bool TexSubImageBenchmark::initializeBenchmark()
{
const std::string vs = SHADER_SOURCE
(
attribute vec4 a_position;
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
void main()
{
gl_Position = a_position;
v_texCoord = a_texCoord;
}
);
const std::string fs = SHADER_SOURCE
(
precision mediump float;
varying vec2 v_texCoord;
uniform sampler2D s_texture;
void main()
{
gl_FragColor = texture2D(s_texture, v_texCoord);
}
);
mProgram = CompileProgram(vs, fs);
if (!mProgram)
{
return false;
}
// Get the attribute locations
mPositionLoc = glGetAttribLocation(mProgram, "a_position");
mTexCoordLoc = glGetAttribLocation(mProgram, "a_texCoord");
// Get the sampler location
mSamplerLoc = glGetUniformLocation(mProgram, "s_texture");
// Build the vertex buffer
GLfloat vertices[] =
{
-0.5f, 0.5f, 0.0f, // Position 0
0.0f, 0.0f, // TexCoord 0
-0.5f, -0.5f, 0.0f, // Position 1
0.0f, 1.0f, // TexCoord 1
0.5f, -0.5f, 0.0f, // Position 2
1.0f, 1.0f, // TexCoord 2
0.5f, 0.5f, 0.0f, // Position 3
1.0f, 0.0f // TexCoord 3
};
glGenBuffers(1, &mVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
glGenBuffers(1, &mIndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// Load the texture
mTexture = createTexture();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
mPixels = new GLubyte[mParams.subImageWidth * mParams.subImageHeight * 4];
// Fill the pixels structure with random data:
for (int y = 0; y < mParams.subImageHeight; ++y)
{
for (int x = 0; x < mParams.subImageWidth; ++x)
{
int offset = (x + (y * mParams.subImageWidth)) * 4;
mPixels[offset + 0] = rand() % 255; // Red
mPixels[offset + 1] = rand() % 255; // Green
mPixels[offset + 2] = rand() % 255; // Blue
mPixels[offset + 3] = 255; // Alpha
}
}
return true;
}
void TexSubImageBenchmark::destroyBenchmark()
{
glDeleteProgram(mProgram);
glDeleteBuffers(1, &mVertexBuffer);
glDeleteBuffers(1, &mIndexBuffer);
glDeleteTextures(1, &mTexture);
delete[] mPixels;
}
void TexSubImageBenchmark::beginDrawBenchmark()
{
// Set the viewport
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
// Clear the color buffer
glClear(GL_COLOR_BUFFER_BIT);
// Use the program object
glUseProgram(mProgram);
// Bind the buffers
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
// Load the vertex position
glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0);
// Load the texture coordinate
glVertexAttribPointer(mTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(mPositionLoc);
glEnableVertexAttribArray(mTexCoordLoc);
// Bind the texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mTexture);
// Set the texture sampler to texture unit to 0
glUniform1i(mSamplerLoc, 0);
}
void TexSubImageBenchmark::drawBenchmark()
{
glTexSubImage2D(GL_TEXTURE_2D, 0,
rand() % (mParams.imageWidth - mParams.subImageWidth),
rand() % (mParams.imageHeight - mParams.subImageHeight),
mParams.subImageWidth, mParams.subImageHeight,
GL_RGBA, GL_UNSIGNED_BYTE, mPixels);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
}
//
// Copyright (c) 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.
//
#include "SimpleBenchmark.h"
struct TexSubImageParams : public BenchmarkParams
{
int imageWidth;
int imageHeight;
int subImageWidth;
int subImageHeight;
unsigned int iterations;
virtual std::string name() const;
};
class TexSubImageBenchmark : public SimpleBenchmark
{
public:
TexSubImageBenchmark(const TexSubImageParams &params);
virtual bool initializeBenchmark();
virtual void destroyBenchmark();
virtual void beginDrawBenchmark();
virtual void drawBenchmark();
private:
GLuint createTexture();
TexSubImageParams mParams;
// Handle to a program object
GLuint mProgram;
// Attribute locations
GLint mPositionLoc;
GLint mTexCoordLoc;
// Sampler location
GLint mSamplerLoc;
// Texture handle
GLuint mTexture;
// Buffer handle
GLuint mVertexBuffer;
GLuint mIndexBuffer;
GLubyte *mPixels;
};
...@@ -214,6 +214,8 @@ ...@@ -214,6 +214,8 @@
'perf_tests/SimpleBenchmark.cpp', 'perf_tests/SimpleBenchmark.cpp',
'perf_tests/SimpleBenchmark.h', 'perf_tests/SimpleBenchmark.h',
'perf_tests/SimpleBenchmarks.cpp', 'perf_tests/SimpleBenchmarks.cpp',
'perf_tests/TexSubImage.cpp',
'perf_tests/TexSubImage.h',
], ],
}, },
], ],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment