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()
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
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 @@ void BufferStorage11::markBufferUsage()
}
}
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];
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
// and we should update our serial
if (directBuffer->updateFromStagingBuffer(mStagingBuffer, mSize, 0))
{
updateSerial();
}
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
DirectBufferStorage11 *directBuffer = new DirectBufferStorage11(mRenderer, isConstantBufferUsage);
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 @@ ID3D11ShaderResourceView *BufferStorage11::getSRV(DXGI_FORMAT srvFormat)
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 @@ DirectBufferStorage11::~DirectBufferStorage11()
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 @@ bool DirectBufferStorage11::updateFromStagingBuffer(ID3D11Buffer *stagingBuffer,
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 @@ bool DirectBufferStorage11::updateFromStagingBuffer(ID3D11Buffer *stagingBuffer,
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 @@ void DirectBufferStorage11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, unsign
// 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();
}
}
......
......@@ -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 @@ class BufferStorage11 : public BufferStorage
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 @@ class BufferStorage11 : public BufferStorage
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 BufferStorage11 : public BufferStorage
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 @@ class DirectBufferStorage11
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);
};
}
......
......@@ -117,7 +117,7 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M
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;
......
......@@ -658,7 +658,7 @@ bool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], con
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 @@ bool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], con
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 @@ GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementAr
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();
......
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