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/181911
Tested-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
diff --git a/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp b/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp
index 839905b..e6798ee 100644
--- a/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp
+++ b/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp
@@ -42,9 +42,9 @@
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 @@
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);
@@ -234,42 +234,45 @@
}
}
-ID3D11Buffer *BufferStorage11::getBuffer(bool isConstantBufferUsage)
+ID3D11Buffer *BufferStorage11::getBuffer(BufferUsage usage)
{
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];
-
- if (directBuffer->isConstantBufferUsage() == isConstantBufferUsage)
- {
- 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))
- {
- updateSerial();
- }
- }
- return directBuffer->getD3DBuffer();
- }
+ directBuffer = directBufferIt->second;
}
- // buffer is not allocated, create it
- DirectBufferStorage11 *directBuffer = new DirectBufferStorage11(mRenderer, isConstantBufferUsage);
- directBuffer->updateFromStagingBuffer(mStagingBuffer, mSize, 0);
+ if (directBuffer)
+ {
+ 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))
+ {
+ updateSerial();
+ }
+ }
+ }
+ else
+ {
+ // buffer is not allocated, create it
+ directBuffer = new DirectBufferStorage11(mRenderer, usage);
+ directBuffer->updateFromStagingBuffer(mStagingBuffer, mSize, 0);
- mDirectBuffers.push_back(directBuffer);
- updateSerial();
+ mDirectBuffers.insert(std::make_pair(usage, directBuffer));
+ updateSerial();
+ }
return directBuffer->getD3DBuffer();
}
ID3D11ShaderResourceView *BufferStorage11::getSRV(DXGI_FORMAT srvFormat)
{
- ID3D11Buffer *buffer = getBuffer(false);
+ ID3D11Buffer *buffer = getBuffer(BUFFER_USAGE_PIXEL);
auto bufferSRVIt = mBufferResourceViews.find(srvFormat);
@@ -303,9 +306,9 @@
return bufferSRV;
}
-DirectBufferStorage11::DirectBufferStorage11(Renderer11 *renderer, bool isConstantBufferUsage)
+DirectBufferStorage11::DirectBufferStorage11(Renderer11 *renderer, BufferUsage usage)
: mRenderer(renderer),
- mIsConstantBufferUsage(isConstantBufferUsage),
+ mUsage(usage),
mDirectBuffer(NULL),
mBufferSize(0),
mDirty(false)
@@ -317,9 +320,9 @@
SafeRelease(mDirectBuffer);
}
-bool DirectBufferStorage11::isConstantBufferUsage() const
+BufferUsage DirectBufferStorage11::getUsage() const
{
- return mIsConstantBufferUsage;
+ return mUsage;
}
// Returns true if it recreates the direct buffer
@@ -338,7 +341,7 @@
if (createBuffer)
{
D3D11_BUFFER_DESC bufferDesc;
- fillBufferDesc(&bufferDesc, requiredBufferSize);
+ fillBufferDesc(&bufferDesc, mRenderer, mUsage, requiredBufferSize);
ID3D11Buffer *newBuffer;
HRESULT result = device->CreateBuffer(&bufferDesc, NULL, &newBuffer);
@@ -371,20 +374,33 @@
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->MiscFlags = 0;
bufferDesc->StructureByteStride = 0;
- if (!mIsConstantBufferUsage)
+ switch (usage)
{
+ case BUFFER_USAGE_VERTEX:
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;
- }
- else
- {
+ break;
+
+ 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->BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bufferDesc->CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
@@ -392,7 +408,11 @@
// 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
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();
}
}
diff --git a/src/libGLESv2/renderer/d3d11/BufferStorage11.h b/src/libGLESv2/renderer/d3d11/BufferStorage11.h
index 689e413..be6a00c 100644
--- a/src/libGLESv2/renderer/d3d11/BufferStorage11.h
+++ b/src/libGLESv2/renderer/d3d11/BufferStorage11.h
@@ -13,9 +13,18 @@
namespace rx
{
+class Renderer;
class Renderer11;
class DirectBufferStorage11;
+enum BufferUsage
+{
+ BUFFER_USAGE_VERTEX,
+ BUFFER_USAGE_INDEX,
+ BUFFER_USAGE_PIXEL,
+ BUFFER_USAGE_UNIFORM,
+};
+
class BufferStorage11 : public BufferStorage
{
public:
@@ -32,7 +41,7 @@
virtual unsigned int getSize() const;
virtual bool supportsDirectBinding() const;
- ID3D11Buffer *getBuffer(bool isConstantBufferUsage);
+ ID3D11Buffer *getBuffer(BufferUsage usage);
ID3D11ShaderResourceView *getSRV(DXGI_FORMAT srvFormat);
private:
@@ -41,7 +50,7 @@
ID3D11Buffer *mStagingBuffer;
unsigned int mStagingBufferSize;
- std::vector<DirectBufferStorage11*> mDirectBuffers;
+ std::map<BufferUsage, DirectBufferStorage11*> mDirectBuffers;
typedef std::pair<ID3D11Buffer *, ID3D11ShaderResourceView *> BufferSRVPair;
std::map<DXGI_FORMAT, BufferSRVPair> mBufferResourceViews;
@@ -65,10 +74,10 @@
class DirectBufferStorage11
{
public:
- DirectBufferStorage11(Renderer11 *renderer, bool isConstantBufferUsage);
+ DirectBufferStorage11(Renderer11 *renderer, BufferUsage usage);
~DirectBufferStorage11();
- bool isConstantBufferUsage() const;
+ BufferUsage getUsage() const;
bool updateFromStagingBuffer(ID3D11Buffer *stagingBuffer, size_t size, size_t offset);
ID3D11Buffer *getD3DBuffer() { return mDirectBuffer; }
@@ -77,12 +86,12 @@
private:
Renderer11 *mRenderer;
- const bool mIsConstantBufferUsage;
+ const BufferUsage mUsage;
ID3D11Buffer *mDirectBuffer;
size_t mBufferSize;
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);
};
}
diff --git a/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp b/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp
index 5e9ac56..75f74d6 100644
--- a/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp
+++ b/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp
@@ -117,7 +117,7 @@
ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = attributes[i].divisor;
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();
vertexStrides[i] = attributes[i].stride;
vertexOffsets[i] = attributes[i].offset;
diff --git a/src/libGLESv2/renderer/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
index 28a7ae6..72fbe0e 100644
--- a/src/libGLESv2/renderer/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
@@ -658,7 +658,7 @@
if (uniformBuffer)
{
BufferStorage11 *bufferStorage = BufferStorage11::makeBufferStorage11(uniformBuffer->getStorage());
- ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(true);
+ ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
if (!constantBuffer)
{
@@ -680,7 +680,7 @@
if (uniformBuffer)
{
BufferStorage11 *bufferStorage = BufferStorage11::makeBufferStorage11(uniformBuffer->getStorage());
- ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(true);
+ ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
if (!constantBuffer)
{
@@ -1114,7 +1114,7 @@
BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(indexInfo->storage);
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;
mAppliedStorageIBSerial = storage->getSerial();