diff options
author | Jamie Madill <jmadill@chromium.org> | 2014-09-10 10:12:49 -0400 |
---|---|---|
committer | Jamie Madill <jmadill@chromium.org> | 2014-09-10 14:13:45 +0000 |
commit | bbffd5562e33a6cf6f6f1bb5be6cfa30df8f36ec (patch) | |
tree | cc3b582305961f8b61c7c683306853ed7c363aa2 | |
parent | 9e16d40de399d1a99958b4a22f72b325a7d3403b (diff) | |
download | angle-bbffd5562e33a6cf6f6f1bb5be6cfa30df8f36ec.tar.gz |
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/216272
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
-rw-r--r-- | tests/perf_tests/BufferSubData.cpp | 13 | ||||
-rw-r--r-- | tests/perf_tests/BufferSubData.h | 5 | ||||
-rw-r--r-- | tests/perf_tests/SimpleBenchmark.h | 12 | ||||
-rw-r--r-- | tests/perf_tests/SimpleBenchmarks.cpp | 25 | ||||
-rw-r--r-- | tests/perf_tests/TexSubImage.cpp | 194 | ||||
-rw-r--r-- | tests/perf_tests/TexSubImage.h | 53 | ||||
-rw-r--r-- | tests/tests.gyp | 2 |
7 files changed, 285 insertions, 19 deletions
diff --git a/tests/perf_tests/BufferSubData.cpp b/tests/perf_tests/BufferSubData.cpp index 183f4ea2..01c9a677 100644 --- a/tests/perf_tests/BufferSubData.cpp +++ b/tests/perf_tests/BufferSubData.cpp @@ -9,6 +9,8 @@ #include <cassert> #include <sstream> +#include "shader_utils.h" + namespace { @@ -128,16 +130,7 @@ std::string BufferSubDataParams::name() const { std::stringstream strstr; - strstr << "BufferSubData - "; - - 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 << " - "; + strstr << "BufferSubData - " << BenchmarkParams::name() << " - "; if (vertexNormalized) { diff --git a/tests/perf_tests/BufferSubData.h b/tests/perf_tests/BufferSubData.h index 30e78537..6a55fac1 100644 --- a/tests/perf_tests/BufferSubData.h +++ b/tests/perf_tests/BufferSubData.h @@ -6,11 +6,6 @@ #include "SimpleBenchmark.h" -const int BUFFER_SIZE = 1024 * 1024; -const int UPDATE_SIZE = 300; - -#include "shader_utils.h" - struct BufferSubDataParams : public BenchmarkParams { EGLint requestedRenderer; diff --git a/tests/perf_tests/SimpleBenchmark.h b/tests/perf_tests/SimpleBenchmark.h index 280aa986..b20b18a1 100644 --- a/tests/perf_tests/SimpleBenchmark.h +++ b/tests/perf_tests/SimpleBenchmark.h @@ -69,7 +69,17 @@ class SimpleBenchmark // Base class 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> diff --git a/tests/perf_tests/SimpleBenchmarks.cpp b/tests/perf_tests/SimpleBenchmarks.cpp index 7fd42f5e..e5986745 100644 --- a/tests/perf_tests/SimpleBenchmarks.cpp +++ b/tests/perf_tests/SimpleBenchmarks.cpp @@ -6,6 +6,7 @@ #include "SimpleBenchmark.h" #include "BufferSubData.h" +#include "TexSubImage.h" EGLint platforms[] = { @@ -23,7 +24,7 @@ unsigned int updatesEveryNFrames[] = { 1, 4 }; int main(int argc, char **argv) { - std::vector<BufferSubDataParams> benchmarks; + std::vector<BufferSubDataParams> subDataParams; for (size_t platIt = 0; platIt < ArraySize(platforms); platIt++) { @@ -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) } // 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); } diff --git a/tests/perf_tests/TexSubImage.cpp b/tests/perf_tests/TexSubImage.cpp new file mode 100644 index 00000000..0751f1f1 --- /dev/null +++ b/tests/perf_tests/TexSubImage.cpp @@ -0,0 +1,194 @@ +// +// 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 ¶ms) + : 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); +} diff --git a/tests/perf_tests/TexSubImage.h b/tests/perf_tests/TexSubImage.h new file mode 100644 index 00000000..259a81e9 --- /dev/null +++ b/tests/perf_tests/TexSubImage.h @@ -0,0 +1,53 @@ +// +// 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 ¶ms); + + 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; +}; diff --git a/tests/tests.gyp b/tests/tests.gyp index 1af7f214..5985c34b 100644 --- a/tests/tests.gyp +++ b/tests/tests.gyp @@ -214,6 +214,8 @@ 'perf_tests/SimpleBenchmark.cpp', 'perf_tests/SimpleBenchmark.h', 'perf_tests/SimpleBenchmarks.cpp', + 'perf_tests/TexSubImage.cpp', + 'perf_tests/TexSubImage.h', ], }, ], |