Commit d89792f4 by Jamie Madill Committed by Commit Bot

Buffer11: Keep system memory storage for large UBOs.

The system memory storage is needed to back UBOs larger than the max constant buffer size in D3D11 Windows 7. Because readback from UBOs can be tricky, the system memory storage keeps the canonical copy of the data in this case. We can also extend this to add a workaround to fix the outstanding failure cases of UBOs on Intel. BUG=chromium:660670 Change-Id: Ia3119d3064d10c4262def4c5a967972b4de2d10f Reviewed-on: https://chromium-review.googlesource.com/405367Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 1df16022
......@@ -311,9 +311,20 @@ gl::Error Buffer11::setSubData(GLenum target, const void *data, size_t size, siz
// Use system memory storage for dynamic buffers.
// Try using a constant storage for constant buffers
BufferStorage *writeBuffer = nullptr;
if (target == GL_UNIFORM_BUFFER && offset == 0 && size >= mSize)
if (target == GL_UNIFORM_BUFFER)
{
ANGLE_TRY_RESULT(getBufferStorage(BUFFER_USAGE_UNIFORM), writeBuffer);
// 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.
// TODO(jmadill): Use Context caps.
if (offset == 0 && size >= mSize &&
size <= static_cast<UINT>(mRenderer->getNativeCaps().maxUniformBlockSize))
{
ANGLE_TRY_RESULT(getBufferStorage(BUFFER_USAGE_UNIFORM), writeBuffer);
}
else
{
ANGLE_TRY_RESULT(getSystemMemoryStorage(), writeBuffer);
}
}
else if (supportsDirectBinding())
{
......@@ -522,11 +533,18 @@ gl::Error Buffer11::checkForDeallocation(BufferUsage usage)
return gl::NoError();
}
// Keep system memory when we are using it for the canonical version of data.
bool Buffer11::canDeallocateSystemMemory() const
{
return (!mBufferStorages[BUFFER_USAGE_UNIFORM] ||
mSize <= mRenderer->getNativeCaps().maxUniformBlockSize);
}
gl::Error Buffer11::markBufferUsage(BufferUsage usage)
{
mIdleness[usage] = 0;
if (usage != BUFFER_USAGE_SYSTEM_MEMORY)
if (usage != BUFFER_USAGE_SYSTEM_MEMORY && canDeallocateSystemMemory())
{
ANGLE_TRY(checkForDeallocation(BUFFER_USAGE_SYSTEM_MEMORY));
}
......
......@@ -28,15 +28,16 @@ class Renderer11;
struct SourceIndexData;
struct TranslatedAttribute;
// The order of this enum governs priority of 'getLatestBufferStorage'.
enum BufferUsage
{
BUFFER_USAGE_SYSTEM_MEMORY,
BUFFER_USAGE_STAGING,
BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK,
BUFFER_USAGE_INDEX,
BUFFER_USAGE_PIXEL_UNPACK,
BUFFER_USAGE_PIXEL_PACK,
BUFFER_USAGE_UNIFORM,
BUFFER_USAGE_SYSTEM_MEMORY,
BUFFER_USAGE_EMULATED_INDEXED_VERTEX,
BUFFER_USAGE_COUNT,
......@@ -119,6 +120,9 @@ class Buffer11 : public BufferD3D
// Free the storage if we decide it isn't being used very often.
gl::Error checkForDeallocation(BufferUsage usage);
// For some cases of uniform buffer storage, we can't deallocate system memory storage.
bool canDeallocateSystemMemory() const;
Renderer11 *mRenderer;
size_t mSize;
......
......@@ -25,7 +25,7 @@ class UniformBufferTest : public ANGLETest
setConfigAlphaBits(8);
}
virtual void SetUp()
void SetUp() override
{
ANGLETest::SetUp();
......@@ -63,7 +63,7 @@ class UniformBufferTest : public ANGLETest
ASSERT_GL_NO_ERROR();
}
virtual void TearDown()
void TearDown() override
{
glDeleteBuffers(1, &mUniformBuffer);
glDeleteProgram(mProgram);
......@@ -565,9 +565,10 @@ TEST_P(UniformBufferTest, VeryLarge)
float floatData[4] = {0.5f, 0.75f, 0.25f, 1.0f};
GLsizei bigSize = 4096 * 64;
std::vector<GLubyte> zero(bigSize, 0);
glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
glBufferData(GL_UNIFORM_BUFFER, bigSize, nullptr, GL_STATIC_DRAW);
glBufferData(GL_UNIFORM_BUFFER, bigSize, zero.data(), GL_STATIC_DRAW);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(float) * 4, floatData);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer);
......
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