Commit be0facc6 by Austin Kinross Committed by Geoff Lang

Reduce calls to ID3D11DeviceContext::Map() in VertexBuffer11.cpp

This change moves VertexBuffer11::storeVertexAttributes()'s call to Map() outside a for-loop, eliminating unnecessary calls to Map(). Since Map() is a relatively expensive operation (even when using NO_OVERWRITE) this change gives a noticeable performance boost in some scenarios. Change-Id: I320111b32f2bb9eed92efbd240206e12aaa9964e Reviewed-on: https://chromium-review.googlesource.com/240181Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarAustin Kinross <aukinros@microsoft.com>
parent 691e58cd
...@@ -47,6 +47,9 @@ class VertexBuffer ...@@ -47,6 +47,9 @@ class VertexBuffer
unsigned int getSerial() const; unsigned int getSerial() const;
// This may be overridden (e.g. by VertexBuffer11) if necessary.
virtual void hintUnmapResource() { };
protected: protected:
void updateSerial(); void updateSerial();
......
...@@ -85,6 +85,35 @@ VertexDataManager::~VertexDataManager() ...@@ -85,6 +85,35 @@ VertexDataManager::~VertexDataManager()
} }
} }
void VertexDataManager::hintUnmapAllResources(const gl::State &state)
{
mStreamingBuffer->getVertexBuffer()->hintUnmapResource();
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
const gl::VertexAttribute &attrib = state.getVertexAttribState(i);
if (attrib.enabled)
{
gl::Buffer *buffer = attrib.buffer.get();
BufferD3D *storage = buffer ? BufferD3D::makeBufferD3D(buffer->getImplementation()) : NULL;
StaticVertexBufferInterface *staticBuffer = storage ? storage->getStaticVertexBuffer() : NULL;
if (staticBuffer)
{
staticBuffer->getVertexBuffer()->hintUnmapResource();
}
}
}
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
if (mCurrentValueBuffer[i] != NULL)
{
mCurrentValueBuffer[i]->getVertexBuffer()->hintUnmapResource();
}
}
}
gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint start, GLsizei count, gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint start, GLsizei count,
TranslatedAttribute *translated, GLsizei instances) TranslatedAttribute *translated, GLsizei instances)
{ {
...@@ -132,6 +161,7 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint sta ...@@ -132,6 +161,7 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint sta
if (error.isError()) if (error.isError())
{ {
hintUnmapAllResources(state);
return error; return error;
} }
} }
...@@ -147,12 +177,16 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint sta ...@@ -147,12 +177,16 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint sta
mCurrentValueBuffer[i]); mCurrentValueBuffer[i]);
if (error.isError()) if (error.isError())
{ {
hintUnmapAllResources(state);
return error; return error;
} }
} }
} }
} }
// Hint to unmap all the resources
hintUnmapAllResources(state);
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{ {
const gl::VertexAttribute &curAttrib = state.getVertexAttribState(i); const gl::VertexAttribute &curAttrib = state.getVertexAttribState(i);
......
...@@ -80,6 +80,8 @@ class VertexDataManager ...@@ -80,6 +80,8 @@ class VertexDataManager
size_t *cachedOffset, size_t *cachedOffset,
StreamingVertexBufferInterface *buffer); StreamingVertexBufferInterface *buffer);
void hintUnmapAllResources(const gl::State &state);
RendererD3D *const mRenderer; RendererD3D *const mRenderer;
StreamingVertexBufferInterface *mStreamingBuffer; StreamingVertexBufferInterface *mStreamingBuffer;
......
...@@ -21,10 +21,12 @@ VertexBuffer11::VertexBuffer11(Renderer11 *const renderer) : mRenderer(renderer) ...@@ -21,10 +21,12 @@ VertexBuffer11::VertexBuffer11(Renderer11 *const renderer) : mRenderer(renderer)
mBuffer = NULL; mBuffer = NULL;
mBufferSize = 0; mBufferSize = 0;
mDynamicUsage = false; mDynamicUsage = false;
mMappedResourceData = NULL;
} }
VertexBuffer11::~VertexBuffer11() VertexBuffer11::~VertexBuffer11()
{ {
ASSERT(mMappedResourceData == NULL);
SafeRelease(mBuffer); SafeRelease(mBuffer);
} }
...@@ -65,6 +67,37 @@ VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer) ...@@ -65,6 +67,37 @@ VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer)
return static_cast<VertexBuffer11*>(vetexBuffer); return static_cast<VertexBuffer11*>(vetexBuffer);
} }
gl::Error VertexBuffer11::mapResource()
{
if (mMappedResourceData == NULL)
{
ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
D3D11_MAPPED_SUBRESOURCE mappedResource;
HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
if (FAILED(result))
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer, HRESULT: 0x%08x.", result);
}
mMappedResourceData = reinterpret_cast<uint8_t*>(mappedResource.pData);
}
return gl::Error(GL_NO_ERROR);
}
void VertexBuffer11::hintUnmapResource()
{
if (mMappedResourceData != NULL)
{
ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
dxContext->Unmap(mBuffer, 0);
mMappedResourceData = NULL;
}
}
gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue, gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
GLint start, GLsizei count, GLsizei instances, unsigned int offset) GLint start, GLsizei count, GLsizei instances, unsigned int offset)
{ {
...@@ -75,16 +108,15 @@ gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attri ...@@ -75,16 +108,15 @@ gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attri
gl::Buffer *buffer = attrib.buffer.get(); gl::Buffer *buffer = attrib.buffer.get();
int inputStride = ComputeVertexAttributeStride(attrib); int inputStride = ComputeVertexAttributeStride(attrib);
ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
D3D11_MAPPED_SUBRESOURCE mappedResource; // This will map the resource if it isn't already mapped.
HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); gl::Error error = mapResource();
if (FAILED(result)) if (error.isError())
{ {
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer, HRESULT: 0x%08x.", result); return error;
} }
uint8_t *output = reinterpret_cast<uint8_t*>(mappedResource.pData) + offset; uint8_t *output = mMappedResourceData + offset;
const uint8_t *input = NULL; const uint8_t *input = NULL;
if (attrib.enabled) if (attrib.enabled)
...@@ -119,8 +151,6 @@ gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attri ...@@ -119,8 +151,6 @@ gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attri
ASSERT(vertexFormatInfo.copyFunction != NULL); ASSERT(vertexFormatInfo.copyFunction != NULL);
vertexFormatInfo.copyFunction(input, inputStride, count, output); vertexFormatInfo.copyFunction(input, inputStride, count, output);
dxContext->Unmap(mBuffer, 0);
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#ifndef LIBANGLE_RENDERER_D3D_D3D11_VERTEXBUFFER11_H_ #ifndef LIBANGLE_RENDERER_D3D_D3D11_VERTEXBUFFER11_H_
#define LIBANGLE_RENDERER_D3D_D3D11_VERTEXBUFFER11_H_ #define LIBANGLE_RENDERER_D3D_D3D11_VERTEXBUFFER11_H_
#include <stdint.h>
#include "libANGLE/renderer/d3d/VertexBuffer.h" #include "libANGLE/renderer/d3d/VertexBuffer.h"
namespace rx namespace rx
...@@ -35,16 +37,22 @@ class VertexBuffer11 : public VertexBuffer ...@@ -35,16 +37,22 @@ class VertexBuffer11 : public VertexBuffer
virtual gl::Error setBufferSize(unsigned int size); virtual gl::Error setBufferSize(unsigned int size);
virtual gl::Error discard(); virtual gl::Error discard();
virtual void hintUnmapResource();
ID3D11Buffer *getBuffer() const; ID3D11Buffer *getBuffer() const;
private: private:
DISALLOW_COPY_AND_ASSIGN(VertexBuffer11); DISALLOW_COPY_AND_ASSIGN(VertexBuffer11);
gl::Error mapResource();
Renderer11 *const mRenderer; Renderer11 *const mRenderer;
ID3D11Buffer *mBuffer; ID3D11Buffer *mBuffer;
unsigned int mBufferSize; unsigned int mBufferSize;
bool mDynamicUsage; bool mDynamicUsage;
uint8_t *mMappedResourceData;
}; };
} }
......
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