Commit 9c53f1e9 by Geoff Lang

Add more D3D11 buffer usages.

Works around performance regressions when index and vertex buffer bind flags are used on the same buffer. Change-Id: I28bc0d3147c6bd70cec507f20e41d97ec4cc45a5 Reviewed-on: https://chromium-review.googlesource.com/181911Tested-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org>
parent 28576da5
...@@ -42,9 +42,9 @@ BufferStorage11::~BufferStorage11() ...@@ -42,9 +42,9 @@ BufferStorage11::~BufferStorage11()
mResolvedData = NULL; mResolvedData = NULL;
} }
for (size_t bufferIndex = 0; bufferIndex < mDirectBuffers.size(); bufferIndex++) for (auto it = mDirectBuffers.begin(); it != mDirectBuffers.end(); it++)
{ {
SafeDelete(mDirectBuffers[bufferIndex]); SafeDelete(it->second);
} }
} }
...@@ -170,9 +170,9 @@ void BufferStorage11::setData(const void* data, unsigned int size, unsigned int ...@@ -170,9 +170,9 @@ void BufferStorage11::setData(const void* data, unsigned int size, unsigned int
context->Unmap(mStagingBuffer, 0); context->Unmap(mStagingBuffer, 0);
} }
for (size_t bufferIndex = 0; bufferIndex < mDirectBuffers.size(); bufferIndex++) for (auto it = mDirectBuffers.begin(); it != mDirectBuffers.end(); it++)
{ {
mDirectBuffers[bufferIndex]->markDirty(); it->second->markDirty();
} }
mSize = std::max(mSize, requiredStagingBufferSize); mSize = std::max(mSize, requiredStagingBufferSize);
...@@ -234,42 +234,45 @@ void BufferStorage11::markBufferUsage() ...@@ -234,42 +234,45 @@ void BufferStorage11::markBufferUsage()
} }
} }
ID3D11Buffer *BufferStorage11::getBuffer(bool isConstantBufferUsage) ID3D11Buffer *BufferStorage11::getBuffer(BufferUsage usage)
{ {
markBufferUsage(); markBufferUsage();
for (size_t bufferIndex = 0; bufferIndex < mDirectBuffers.size(); bufferIndex++) DirectBufferStorage11 *directBuffer = NULL;
auto directBufferIt = mDirectBuffers.find(usage);
if (directBufferIt != mDirectBuffers.end())
{ {
DirectBufferStorage11 *directBuffer = mDirectBuffers[bufferIndex]; directBuffer = directBufferIt->second;
}
if (directBuffer->isConstantBufferUsage() == isConstantBufferUsage) if (directBuffer)
{
if (directBuffer->isDirty())
{ {
if (directBuffer->isDirty()) // if updateFromStagingBuffer returns true, the D3D buffer has been recreated
// and we should update our serial
if (directBuffer->updateFromStagingBuffer(mStagingBuffer, mSize, 0))
{ {
// if updateFromStagingBuffer returns true, the D3D buffer has been recreated updateSerial();
// and we should update our serial
if (directBuffer->updateFromStagingBuffer(mStagingBuffer, mSize, 0))
{
updateSerial();
}
} }
return directBuffer->getD3DBuffer();
} }
} }
else
{
// buffer is not allocated, create it
directBuffer = new DirectBufferStorage11(mRenderer, usage);
directBuffer->updateFromStagingBuffer(mStagingBuffer, mSize, 0);
// buffer is not allocated, create it mDirectBuffers.insert(std::make_pair(usage, directBuffer));
DirectBufferStorage11 *directBuffer = new DirectBufferStorage11(mRenderer, isConstantBufferUsage); updateSerial();
directBuffer->updateFromStagingBuffer(mStagingBuffer, mSize, 0); }
mDirectBuffers.push_back(directBuffer);
updateSerial();
return directBuffer->getD3DBuffer(); return directBuffer->getD3DBuffer();
} }
ID3D11ShaderResourceView *BufferStorage11::getSRV(DXGI_FORMAT srvFormat) ID3D11ShaderResourceView *BufferStorage11::getSRV(DXGI_FORMAT srvFormat)
{ {
ID3D11Buffer *buffer = getBuffer(false); ID3D11Buffer *buffer = getBuffer(BUFFER_USAGE_PIXEL);
auto bufferSRVIt = mBufferResourceViews.find(srvFormat); auto bufferSRVIt = mBufferResourceViews.find(srvFormat);
...@@ -303,9 +306,9 @@ ID3D11ShaderResourceView *BufferStorage11::getSRV(DXGI_FORMAT srvFormat) ...@@ -303,9 +306,9 @@ ID3D11ShaderResourceView *BufferStorage11::getSRV(DXGI_FORMAT srvFormat)
return bufferSRV; return bufferSRV;
} }
DirectBufferStorage11::DirectBufferStorage11(Renderer11 *renderer, bool isConstantBufferUsage) DirectBufferStorage11::DirectBufferStorage11(Renderer11 *renderer, BufferUsage usage)
: mRenderer(renderer), : mRenderer(renderer),
mIsConstantBufferUsage(isConstantBufferUsage), mUsage(usage),
mDirectBuffer(NULL), mDirectBuffer(NULL),
mBufferSize(0), mBufferSize(0),
mDirty(false) mDirty(false)
...@@ -317,9 +320,9 @@ DirectBufferStorage11::~DirectBufferStorage11() ...@@ -317,9 +320,9 @@ DirectBufferStorage11::~DirectBufferStorage11()
SafeRelease(mDirectBuffer); SafeRelease(mDirectBuffer);
} }
bool DirectBufferStorage11::isConstantBufferUsage() const BufferUsage DirectBufferStorage11::getUsage() const
{ {
return mIsConstantBufferUsage; return mUsage;
} }
// Returns true if it recreates the direct buffer // Returns true if it recreates the direct buffer
...@@ -338,7 +341,7 @@ bool DirectBufferStorage11::updateFromStagingBuffer(ID3D11Buffer *stagingBuffer, ...@@ -338,7 +341,7 @@ bool DirectBufferStorage11::updateFromStagingBuffer(ID3D11Buffer *stagingBuffer,
if (createBuffer) if (createBuffer)
{ {
D3D11_BUFFER_DESC bufferDesc; D3D11_BUFFER_DESC bufferDesc;
fillBufferDesc(&bufferDesc, requiredBufferSize); fillBufferDesc(&bufferDesc, mRenderer, mUsage, requiredBufferSize);
ID3D11Buffer *newBuffer; ID3D11Buffer *newBuffer;
HRESULT result = device->CreateBuffer(&bufferDesc, NULL, &newBuffer); HRESULT result = device->CreateBuffer(&bufferDesc, NULL, &newBuffer);
...@@ -371,20 +374,33 @@ bool DirectBufferStorage11::updateFromStagingBuffer(ID3D11Buffer *stagingBuffer, ...@@ -371,20 +374,33 @@ bool DirectBufferStorage11::updateFromStagingBuffer(ID3D11Buffer *stagingBuffer,
return createBuffer; return createBuffer;
} }
void DirectBufferStorage11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, unsigned int bufferSize) void DirectBufferStorage11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer, BufferUsage usage, unsigned int bufferSize)
{ {
bufferDesc->ByteWidth = bufferSize; bufferDesc->ByteWidth = bufferSize;
bufferDesc->MiscFlags = 0; bufferDesc->MiscFlags = 0;
bufferDesc->StructureByteStride = 0; bufferDesc->StructureByteStride = 0;
if (!mIsConstantBufferUsage) switch (usage)
{ {
case BUFFER_USAGE_VERTEX:
bufferDesc->Usage = D3D11_USAGE_DEFAULT; bufferDesc->Usage = D3D11_USAGE_DEFAULT;
bufferDesc->BindFlags = D3D11_BIND_INDEX_BUFFER | D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_SHADER_RESOURCE; bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDesc->CPUAccessFlags = 0; bufferDesc->CPUAccessFlags = 0;
} break;
else
{ case BUFFER_USAGE_INDEX:
bufferDesc->Usage = D3D11_USAGE_DEFAULT;
bufferDesc->BindFlags = D3D11_BIND_INDEX_BUFFER;
bufferDesc->CPUAccessFlags = 0;
break;
case BUFFER_USAGE_PIXEL:
bufferDesc->Usage = D3D11_USAGE_DEFAULT;
bufferDesc->BindFlags = D3D11_BIND_SHADER_RESOURCE;
bufferDesc->CPUAccessFlags = 0;
break;
case BUFFER_USAGE_UNIFORM:
bufferDesc->Usage = D3D11_USAGE_DYNAMIC; bufferDesc->Usage = D3D11_USAGE_DYNAMIC;
bufferDesc->BindFlags = D3D11_BIND_CONSTANT_BUFFER; bufferDesc->BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bufferDesc->CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; bufferDesc->CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
...@@ -392,7 +408,11 @@ void DirectBufferStorage11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, unsign ...@@ -392,7 +408,11 @@ void DirectBufferStorage11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, unsign
// Constant buffers must be of a limited size, and aligned to 16 byte boundaries // Constant buffers must be of a limited size, and aligned to 16 byte boundaries
// For our purposes we ignore any buffer data past the maximum constant buffer size // For our purposes we ignore any buffer data past the maximum constant buffer size
bufferDesc->ByteWidth = roundUp(bufferDesc->ByteWidth, 16u); bufferDesc->ByteWidth = roundUp(bufferDesc->ByteWidth, 16u);
bufferDesc->ByteWidth = std::min(bufferDesc->ByteWidth, mRenderer->getMaxUniformBufferSize()); bufferDesc->ByteWidth = std::min(bufferDesc->ByteWidth, renderer->getMaxUniformBufferSize());
break;
default:
UNREACHABLE();
} }
} }
......
...@@ -13,9 +13,18 @@ ...@@ -13,9 +13,18 @@
namespace rx namespace rx
{ {
class Renderer;
class Renderer11; class Renderer11;
class DirectBufferStorage11; class DirectBufferStorage11;
enum BufferUsage
{
BUFFER_USAGE_VERTEX,
BUFFER_USAGE_INDEX,
BUFFER_USAGE_PIXEL,
BUFFER_USAGE_UNIFORM,
};
class BufferStorage11 : public BufferStorage class BufferStorage11 : public BufferStorage
{ {
public: public:
...@@ -32,7 +41,7 @@ class BufferStorage11 : public BufferStorage ...@@ -32,7 +41,7 @@ class BufferStorage11 : public BufferStorage
virtual unsigned int getSize() const; virtual unsigned int getSize() const;
virtual bool supportsDirectBinding() const; virtual bool supportsDirectBinding() const;
ID3D11Buffer *getBuffer(bool isConstantBufferUsage); ID3D11Buffer *getBuffer(BufferUsage usage);
ID3D11ShaderResourceView *getSRV(DXGI_FORMAT srvFormat); ID3D11ShaderResourceView *getSRV(DXGI_FORMAT srvFormat);
private: private:
...@@ -41,7 +50,7 @@ class BufferStorage11 : public BufferStorage ...@@ -41,7 +50,7 @@ class BufferStorage11 : public BufferStorage
ID3D11Buffer *mStagingBuffer; ID3D11Buffer *mStagingBuffer;
unsigned int mStagingBufferSize; unsigned int mStagingBufferSize;
std::vector<DirectBufferStorage11*> mDirectBuffers; std::map<BufferUsage, DirectBufferStorage11*> mDirectBuffers;
typedef std::pair<ID3D11Buffer *, ID3D11ShaderResourceView *> BufferSRVPair; typedef std::pair<ID3D11Buffer *, ID3D11ShaderResourceView *> BufferSRVPair;
std::map<DXGI_FORMAT, BufferSRVPair> mBufferResourceViews; std::map<DXGI_FORMAT, BufferSRVPair> mBufferResourceViews;
...@@ -65,10 +74,10 @@ class BufferStorage11 : public BufferStorage ...@@ -65,10 +74,10 @@ class BufferStorage11 : public BufferStorage
class DirectBufferStorage11 class DirectBufferStorage11
{ {
public: public:
DirectBufferStorage11(Renderer11 *renderer, bool isConstantBufferUsage); DirectBufferStorage11(Renderer11 *renderer, BufferUsage usage);
~DirectBufferStorage11(); ~DirectBufferStorage11();
bool isConstantBufferUsage() const; BufferUsage getUsage() const;
bool updateFromStagingBuffer(ID3D11Buffer *stagingBuffer, size_t size, size_t offset); bool updateFromStagingBuffer(ID3D11Buffer *stagingBuffer, size_t size, size_t offset);
ID3D11Buffer *getD3DBuffer() { return mDirectBuffer; } ID3D11Buffer *getD3DBuffer() { return mDirectBuffer; }
...@@ -77,12 +86,12 @@ class DirectBufferStorage11 ...@@ -77,12 +86,12 @@ class DirectBufferStorage11
private: private:
Renderer11 *mRenderer; Renderer11 *mRenderer;
const bool mIsConstantBufferUsage; const BufferUsage mUsage;
ID3D11Buffer *mDirectBuffer; ID3D11Buffer *mDirectBuffer;
size_t mBufferSize; size_t mBufferSize;
bool mDirty; bool mDirty;
void fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, unsigned int bufferSize); static void fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer, BufferUsage usage, unsigned int bufferSize);
}; };
} }
......
...@@ -117,7 +117,7 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M ...@@ -117,7 +117,7 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M
ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = attributes[i].divisor; ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = attributes[i].divisor;
ilKey.elementCount++; ilKey.elementCount++;
vertexBuffers[i] = bufferStorage ? bufferStorage->getBuffer(false) : vertexBuffer->getBuffer(); vertexBuffers[i] = bufferStorage ? bufferStorage->getBuffer(BUFFER_USAGE_VERTEX) : vertexBuffer->getBuffer();
vertexBufferSerials[i] = bufferStorage ? bufferStorage->getSerial() : vertexBuffer->getSerial(); vertexBufferSerials[i] = bufferStorage ? bufferStorage->getSerial() : vertexBuffer->getSerial();
vertexStrides[i] = attributes[i].stride; vertexStrides[i] = attributes[i].stride;
vertexOffsets[i] = attributes[i].offset; vertexOffsets[i] = attributes[i].offset;
......
...@@ -658,7 +658,7 @@ bool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], con ...@@ -658,7 +658,7 @@ bool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], con
if (uniformBuffer) if (uniformBuffer)
{ {
BufferStorage11 *bufferStorage = BufferStorage11::makeBufferStorage11(uniformBuffer->getStorage()); BufferStorage11 *bufferStorage = BufferStorage11::makeBufferStorage11(uniformBuffer->getStorage());
ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(true); ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
if (!constantBuffer) if (!constantBuffer)
{ {
...@@ -680,7 +680,7 @@ bool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], con ...@@ -680,7 +680,7 @@ bool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], con
if (uniformBuffer) if (uniformBuffer)
{ {
BufferStorage11 *bufferStorage = BufferStorage11::makeBufferStorage11(uniformBuffer->getStorage()); BufferStorage11 *bufferStorage = BufferStorage11::makeBufferStorage11(uniformBuffer->getStorage());
ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(true); ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
if (!constantBuffer) if (!constantBuffer)
{ {
...@@ -1114,7 +1114,7 @@ GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementAr ...@@ -1114,7 +1114,7 @@ GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementAr
BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(indexInfo->storage); BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(indexInfo->storage);
IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer); IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer);
mDeviceContext->IASetIndexBuffer(storage->getBuffer(false), indexBuffer->getIndexFormat(), indexInfo->startOffset); mDeviceContext->IASetIndexBuffer(storage->getBuffer(BUFFER_USAGE_INDEX), indexBuffer->getIndexFormat(), indexInfo->startOffset);
mAppliedIBSerial = 0; mAppliedIBSerial = 0;
mAppliedStorageIBSerial = storage->getSerial(); mAppliedStorageIBSerial = storage->getSerial();
......
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