diff options
author | Jamie Madill <jmadill@chromium.org> | 2014-09-09 13:21:33 -0400 |
---|---|---|
committer | Jamie Madill <jmadill@chromium.org> | 2014-09-10 13:46:10 +0000 |
commit | 82cceb2de7958c7706768f21052a2e3409511fb8 (patch) | |
tree | e750daf7c9158c39ec03789308e17c49461dd638 | |
parent | c9610c51e9c02ba67c735ff449a70164cda12a60 (diff) | |
download | angle-82cceb2de7958c7706768f21052a2e3409511fb8.tar.gz |
Only use direct buffers for static data in D3D11.
For highly dynamic data, which gets updated every frame, or almost
every frame, we're better off using our existing dynamic buffer
path. We could further optimize the dynamic buffer path by only
uploading changed data every frame.
BUG=angle:705
Change-Id: Icbb357b889be789b30f73067f75b13664c806929
Reviewed-on: https://chromium-review.googlesource.com/217280
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp | 8 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d11/Buffer11.h | 2 | ||||
-rw-r--r-- | tests/perf_tests/BufferSubData.cpp | 29 | ||||
-rw-r--r-- | tests/perf_tests/BufferSubData.h | 1 | ||||
-rw-r--r-- | tests/perf_tests/SimpleBenchmark.h | 2 | ||||
-rw-r--r-- | tests/perf_tests/SimpleBenchmarks.cpp | 39 |
6 files changed, 64 insertions, 17 deletions
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp index ea6660e2..c612ddd0 100644 --- a/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp +++ b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp @@ -597,6 +597,14 @@ Buffer11::PackStorage11 *Buffer11::getPackStorage() return static_cast<PackStorage11*>(packStorage); } +bool Buffer11::supportsDirectBinding() const +{ + // Do not support direct buffers for dynamic data. The streaming buffer + // offers better performance for data which changes every frame. + // Check for absence of static buffer interfaces to detect dynamic data. + return (mStaticVertexBuffer && mStaticIndexBuffer); +} + Buffer11::BufferStorage11::BufferStorage11(Renderer11 *renderer, BufferUsage usage) : mRenderer(renderer), mUsage(usage), diff --git a/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h index 5740566c..5f24fb4e 100644 --- a/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h +++ b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h @@ -59,7 +59,7 @@ class Buffer11 : public BufferD3D // BufferD3D implementation virtual size_t getSize() const { return mSize; } - virtual bool supportsDirectBinding() const { return true; } + virtual bool supportsDirectBinding() const; virtual Renderer* getRenderer(); // BufferImpl implementation diff --git a/tests/perf_tests/BufferSubData.cpp b/tests/perf_tests/BufferSubData.cpp index 8ecf07df..183f4ea2 100644 --- a/tests/perf_tests/BufferSubData.cpp +++ b/tests/perf_tests/BufferSubData.cpp @@ -158,7 +158,7 @@ std::string BufferSubDataParams::name() const strstr << vertexComponentCount; - strstr << " - " << updateSize << "b updates - "; + strstr << " - " << updateSize << "b updates (per " << updatesEveryNFrames << ") - "; strstr << (bufferSize >> 10) << "k buffer - "; strstr << iterations << " updates"; @@ -167,6 +167,10 @@ std::string BufferSubDataParams::name() const BufferSubDataBenchmark::BufferSubDataBenchmark(const BufferSubDataParams ¶ms) : SimpleBenchmark(params.name(), 1280, 720, 2, params.requestedRenderer), + mProgram(0), + mBuffer(0), + mUpdateData(NULL), + mNumTris(0), mParams(params) { mDrawIterations = mParams.iterations; @@ -208,15 +212,22 @@ bool BufferSubDataBenchmark::initializeBenchmark() glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + + std::vector<uint8_t> zeroData(mParams.bufferSize); + memset(zeroData.data(), 0, zeroData.size()); + glGenBuffers(1, &mBuffer); glBindBuffer(GL_ARRAY_BUFFER, mBuffer); - glBufferData(GL_ARRAY_BUFFER, mParams.bufferSize, 0, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, mParams.bufferSize, zeroData.data(), GL_DYNAMIC_DRAW); glVertexAttribPointer(0, mParams.vertexComponentCount, mParams.vertexType, mParams.vertexNormalized, 0, 0); glEnableVertexAttribArray(0); - mUpdateData = new uint8_t[mParams.updateSize]; + if (mParams.updateSize > 0) + { + mUpdateData = new uint8_t[mParams.updateSize]; + } std::vector<uint8_t> data; GLsizei triDataSize = GetVertexData(mParams.vertexType, @@ -230,6 +241,12 @@ bool BufferSubDataBenchmark::initializeBenchmark() offset += triDataSize; } + if (mParams.updateSize == 0) + { + mNumTris = 1; + glBufferSubData(GL_ARRAY_BUFFER, 0, data.size(), data.data()); + } + // Set the viewport glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight()); @@ -271,7 +288,11 @@ void BufferSubDataBenchmark::drawBenchmark() { for (unsigned int it = 0; it < mParams.iterations; it++) { - glBufferSubData(GL_ARRAY_BUFFER, 0, mParams.updateSize, mUpdateData); + if (mParams.updateSize > 0 && ((mNumFrames % mParams.updatesEveryNFrames) == 0)) + { + glBufferSubData(GL_ARRAY_BUFFER, 0, mParams.updateSize, mUpdateData); + } + glDrawArrays(GL_TRIANGLES, 0, 3 * mNumTris); } } diff --git a/tests/perf_tests/BufferSubData.h b/tests/perf_tests/BufferSubData.h index f138bcc6..30e78537 100644 --- a/tests/perf_tests/BufferSubData.h +++ b/tests/perf_tests/BufferSubData.h @@ -20,6 +20,7 @@ struct BufferSubDataParams : public BenchmarkParams GLsizeiptr updateSize; GLsizeiptr bufferSize; unsigned int iterations; + unsigned int updatesEveryNFrames; virtual std::string name() const; }; diff --git a/tests/perf_tests/SimpleBenchmark.h b/tests/perf_tests/SimpleBenchmark.h index e1283665..280aa986 100644 --- a/tests/perf_tests/SimpleBenchmark.h +++ b/tests/perf_tests/SimpleBenchmark.h @@ -47,6 +47,7 @@ class SimpleBenchmark protected: unsigned int mDrawIterations; double mRunTimeSeconds; + int mNumFrames; private: DISALLOW_COPY_AND_ASSIGN(SimpleBenchmark); @@ -57,7 +58,6 @@ class SimpleBenchmark void step(float dt, double totalTime); void draw(); - int mNumFrames; std::string mName; bool mRunning; diff --git a/tests/perf_tests/SimpleBenchmarks.cpp b/tests/perf_tests/SimpleBenchmarks.cpp index dc4734bb..7fd42f5e 100644 --- a/tests/perf_tests/SimpleBenchmarks.cpp +++ b/tests/perf_tests/SimpleBenchmarks.cpp @@ -14,11 +14,12 @@ EGLint platforms[] = }; GLenum vertexTypes[] = { GL_FLOAT }; -GLint componentCounts[] = { 2, 3, 4 }; +GLint componentCounts[] = { 4 }; GLboolean vertexNorms[] = { GL_FALSE }; -GLsizeiptr updateSizes[] = { 300 }; +GLsizeiptr updateSizes[] = { 0, 300 }; GLsizeiptr bufferSizes[] = { 1024 * 1024 }; unsigned int iterationCounts[] = { 10 }; +unsigned int updatesEveryNFrames[] = { 1, 4 }; int main(int argc, char **argv) { @@ -44,16 +45,32 @@ int main(int argc, char **argv) { for (size_t itIt = 0; itIt < ArraySize(iterationCounts); itIt++) { - BufferSubDataParams params; - params.requestedRenderer = platforms[platIt]; - params.vertexType = vertexTypes[typeIt]; - params.vertexComponentCount = componentCounts[compIt]; - params.vertexNormalized = vertexNorms[normIt]; - params.updateSize = updateSizes[updateIt]; - params.bufferSize = bufferSizes[bufszIt]; - params.iterations = iterationCounts[itIt]; + for (size_t nfrIt = 0; nfrIt < ArraySize(updatesEveryNFrames); nfrIt++) + { + BufferSubDataParams params; + params.requestedRenderer = platforms[platIt]; + params.vertexType = vertexTypes[typeIt]; + params.vertexComponentCount = componentCounts[compIt]; + params.vertexNormalized = vertexNorms[normIt]; + params.updateSize = updateSizes[updateIt]; + params.bufferSize = bufferSizes[bufszIt]; + params.iterations = iterationCounts[itIt]; + params.updatesEveryNFrames = updatesEveryNFrames[nfrIt]; - benchmarks.push_back(params); + if (updateSizes[updateIt] == 0) + { + if (nfrIt > 0) + { + continue; + } + else + { + params.updatesEveryNFrames = 1; + } + } + + benchmarks.push_back(params); + } } } } |