Buffer11: Intel workaround for constant buffers.

This workaround avoids using inter-buffer copies involving constant
buffers. Instead of copying from a staging storage to a constant
buffer (or vice-versa), the Buffer memory managment will keep the
system memory storage around permanently. This uses a bit more memory
but should fix all the problematic cases where we have the canonical
version of the buffer data inside GPU memory.

BUG=chromium:593024

Change-Id: I2ce0cfd22784aa43e819ce2df2d0da540d0a0cfe
Reviewed-on: https://chromium-review.googlesource.com/412140
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Jamie Madill 2016-11-16 11:51:01 -08:00 коммит произвёл Commit Bot
Родитель 96ed3527d0
Коммит 555009cefe
4 изменённых файлов: 19 добавлений и 23 удалений

Просмотреть файл

@ -99,6 +99,12 @@ struct WorkaroundsD3D
// a target with width or height < 16. To work around this bug, we call clear() twice on these
// platforms. Tracking bug: https://crbug.com/655534
bool callClearTwiceOnSmallTarget = false;
// On some Intel drivers, copying from staging storage to constant buffer storage does not
// seem to work. Work around this by keeping system memory storage as a canonical reference
// for buffer data.
// D3D11-only workaround. See http://crbug.com/593024.
bool useSystemMemoryForConstantBuffers = false;
};
} // namespace rx

Просмотреть файл

@ -336,10 +336,13 @@ gl::Error Buffer11::setSubData(GLenum target, const void *data, size_t size, siz
if (target == GL_UNIFORM_BUFFER)
{
// If we are a very large uniform buffer, keep system memory storage around so that we
// aren't forced to read back from a constant buffer.
// aren't forced to read back from a constant buffer. We also check the workaround for
// Intel - this requires us to use system memory so we don't end up having to copy from
// a constant buffer to a staging buffer.
// TODO(jmadill): Use Context caps.
if (offset == 0 && size >= mSize &&
size <= static_cast<UINT>(mRenderer->getNativeCaps().maxUniformBlockSize))
size <= static_cast<UINT>(mRenderer->getNativeCaps().maxUniformBlockSize) &&
!mRenderer->getWorkarounds().useSystemMemoryForConstantBuffers)
{
ANGLE_TRY_RESULT(getBufferStorage(BUFFER_USAGE_UNIFORM), writeBuffer);
}
@ -558,6 +561,12 @@ gl::Error Buffer11::checkForDeallocation(BufferUsage usage)
// Keep system memory when we are using it for the canonical version of data.
bool Buffer11::canDeallocateSystemMemory() const
{
// Must keep system memory on Intel.
if (mRenderer->getWorkarounds().useSystemMemoryForConstantBuffers)
{
return false;
}
return (!mBufferStorages[BUFFER_USAGE_UNIFORM] ||
mSize <= mRenderer->getNativeCaps().maxUniformBlockSize);
}

Просмотреть файл

@ -1872,6 +1872,8 @@ WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps,
workarounds.emulateTinyStencilTextures = false;
}
workarounds.useSystemMemoryForConstantBuffers = IsIntel(adapterDesc.VendorId);
return workarounds;
}

Просмотреть файл

@ -98,13 +98,6 @@ TEST_P(UniformBufferTest, Simple)
// The second step renders a color from a UBO with a non-zero offset.
TEST_P(UniformBufferTest, UniformBufferRange)
{
// TODO(jmadill): Figure out why this fails on Intel.
if (IsIntel() && IsD3D11())
{
std::cout << "Test skipped on Intel D3D11." << std::endl;
return;
}
int px = getWindowWidth() / 2;
int py = getWindowHeight() / 2;
@ -272,12 +265,6 @@ TEST_P(UniformBufferTest, UniformBufferManyUpdates)
// Use a large number of buffer ranges (compared to the actual size of the UBO)
TEST_P(UniformBufferTest, ManyUniformBufferRange)
{
// TODO(jmadill): Figure out why this fails on Intel.
if (IsIntel() && IsD3D11())
{
std::cout << "Test skipped on Intel D3D11." << std::endl;
return;
}
int px = getWindowWidth() / 2;
int py = getWindowHeight() / 2;
@ -556,14 +543,6 @@ TEST_P(UniformBufferTest, ActiveUniformNumberAndName)
// Test that using a very large buffer to back a small uniform block works OK.
TEST_P(UniformBufferTest, VeryLarge)
{
// TODO(jmadill): Figure out why this fails on Intel.
// See http://crbug.com/593024
if (IsIntel() && IsD3D11())
{
std::cout << "Test skipped on Intel D3D11." << std::endl;
return;
}
glClear(GL_COLOR_BUFFER_BIT);
float floatData[4] = {0.5f, 0.75f, 0.25f, 1.0f};