Commit 36f34243 by Jamie Madill Committed by Commit Bot

Buffer11: Cache latest buffer storage.

This saves needing to scan the list of buffers every time we query the latest buffer storage. Should slightly improve speed. BUG=angleproject:1155 Change-Id: I6be8457aca1ee5aa871090241e6f67ae16b094a5 Reviewed-on: https://chromium-review.googlesource.com/761242Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 8d6af086
...@@ -295,6 +295,7 @@ Buffer11::Buffer11(const gl::BufferState &state, Renderer11 *renderer) ...@@ -295,6 +295,7 @@ Buffer11::Buffer11(const gl::BufferState &state, Renderer11 *renderer)
mSize(0), mSize(0),
mMappedStorage(nullptr), mMappedStorage(nullptr),
mBufferStorages({}), mBufferStorages({}),
mLatestBufferStorage(nullptr),
mDeallocThresholds({}), mDeallocThresholds({}),
mIdleness({}), mIdleness({}),
mConstantBufferStorageAdditionalSize(0), mConstantBufferStorageAdditionalSize(0),
...@@ -398,7 +399,7 @@ gl::Error Buffer11::setSubData(const gl::Context *context, ...@@ -398,7 +399,7 @@ gl::Error Buffer11::setSubData(const gl::Context *context,
} }
ANGLE_TRY(writeBuffer->setData(static_cast<const uint8_t *>(data), offset, size)); ANGLE_TRY(writeBuffer->setData(static_cast<const uint8_t *>(data), offset, size));
writeBuffer->setDataRevision(writeBuffer->getDataRevision() + 1); onStorageUpdate(writeBuffer);
// Notify any vertex arrays that we have dirty data. // Notify any vertex arrays that we have dirty data.
// TODO(jmadill): Use a more fine grained notification for data updates. // TODO(jmadill): Use a more fine grained notification for data updates.
...@@ -465,7 +466,7 @@ gl::Error Buffer11::copySubData(const gl::Context *context, ...@@ -465,7 +466,7 @@ gl::Error Buffer11::copySubData(const gl::Context *context,
CopyResult copyResult = CopyResult::NOT_RECREATED; CopyResult copyResult = CopyResult::NOT_RECREATED;
ANGLE_TRY_RESULT(copyDest->copyFromStorage(context, copySource, sourceOffset, size, destOffset), ANGLE_TRY_RESULT(copyDest->copyFromStorage(context, copySource, sourceOffset, size, destOffset),
copyResult); copyResult);
copyDest->setDataRevision(copyDest->getDataRevision() + 1); onStorageUpdate(copyDest);
mSize = std::max<size_t>(mSize, destOffset + size); mSize = std::max<size_t>(mSize, destOffset + size);
invalidateStaticData(context); invalidateStaticData(context);
...@@ -513,7 +514,7 @@ gl::Error Buffer11::mapRange(const gl::Context *context, ...@@ -513,7 +514,7 @@ gl::Error Buffer11::mapRange(const gl::Context *context,
if ((access & GL_MAP_WRITE_BIT) > 0) if ((access & GL_MAP_WRITE_BIT) > 0)
{ {
// Update the data revision immediately, since the data might be changed at any time // Update the data revision immediately, since the data might be changed at any time
mMappedStorage->setDataRevision(mMappedStorage->getDataRevision() + 1); onStorageUpdate(mMappedStorage);
invalidateStaticData(context); invalidateStaticData(context);
} }
...@@ -545,7 +546,7 @@ gl::Error Buffer11::markTransformFeedbackUsage(const gl::Context *context) ...@@ -545,7 +546,7 @@ gl::Error Buffer11::markTransformFeedbackUsage(const gl::Context *context)
if (transformFeedbackStorage) if (transformFeedbackStorage)
{ {
transformFeedbackStorage->setDataRevision(transformFeedbackStorage->getDataRevision() + 1); onStorageUpdate(transformFeedbackStorage);
} }
invalidateStaticData(context); invalidateStaticData(context);
...@@ -694,12 +695,9 @@ gl::Error Buffer11::packPixels(const gl::Context *context, ...@@ -694,12 +695,9 @@ gl::Error Buffer11::packPixels(const gl::Context *context,
PackStorage *packStorage = nullptr; PackStorage *packStorage = nullptr;
ANGLE_TRY_RESULT(getPackStorage(context), packStorage); ANGLE_TRY_RESULT(getPackStorage(context), packStorage);
BufferStorage *latestStorage = nullptr;
ANGLE_TRY_RESULT(getLatestBufferStorage(context), latestStorage);
ASSERT(packStorage); ASSERT(packStorage);
ANGLE_TRY(packStorage->packPixels(context, readAttachment, params)); ANGLE_TRY(packStorage->packPixels(context, readAttachment, params));
packStorage->setDataRevision(latestStorage ? latestStorage->getDataRevision() + 1 : 1); onStorageUpdate(packStorage);
return gl::NoError(); return gl::NoError();
} }
...@@ -850,7 +848,7 @@ gl::Error Buffer11::updateBufferStorage(const gl::Context *context, ...@@ -850,7 +848,7 @@ gl::Error Buffer11::updateBufferStorage(const gl::Context *context,
ANGLE_TRY_RESULT(stagingBuffer->copyFromStorage(context, latestBuffer, 0, ANGLE_TRY_RESULT(stagingBuffer->copyFromStorage(context, latestBuffer, 0,
latestBuffer->getSize(), 0), latestBuffer->getSize(), 0),
copyResult); copyResult);
stagingBuffer->setDataRevision(latestBuffer->getDataRevision()); onCopyStorage(stagingBuffer, latestBuffer);
latestBuffer = stagingBuffer; latestBuffer = stagingBuffer;
} }
...@@ -864,7 +862,7 @@ gl::Error Buffer11::updateBufferStorage(const gl::Context *context, ...@@ -864,7 +862,7 @@ gl::Error Buffer11::updateBufferStorage(const gl::Context *context,
{ {
updateSerial(); updateSerial();
} }
storage->setDataRevision(latestBuffer->getDataRevision()); onCopyStorage(storage, latestBuffer);
} }
return gl::NoError(); return gl::NoError();
...@@ -873,26 +871,13 @@ gl::Error Buffer11::updateBufferStorage(const gl::Context *context, ...@@ -873,26 +871,13 @@ gl::Error Buffer11::updateBufferStorage(const gl::Context *context,
gl::ErrorOrResult<Buffer11::BufferStorage *> Buffer11::getLatestBufferStorage( gl::ErrorOrResult<Buffer11::BufferStorage *> Buffer11::getLatestBufferStorage(
const gl::Context *context) const const gl::Context *context) const
{ {
// Even though we iterate over all the direct buffers, it is expected that only
// 1 or 2 will be present.
BufferStorage *latestStorage = nullptr;
DataRevision latestRevision = 0;
for (auto &storage : mBufferStorages)
{
if (storage && (!latestStorage || storage->getDataRevision() > latestRevision))
{
latestStorage = storage;
latestRevision = storage->getDataRevision();
}
}
// resize buffer // resize buffer
if (latestStorage && latestStorage->getSize() < mSize) if (mLatestBufferStorage && mLatestBufferStorage->getSize() < mSize)
{ {
ANGLE_TRY(latestStorage->resize(context, mSize, true)); ANGLE_TRY(mLatestBufferStorage->resize(context, mSize, true));
} }
return latestStorage; return mLatestBufferStorage;
} }
gl::ErrorOrResult<Buffer11::NativeStorage *> Buffer11::getStagingStorage(const gl::Context *context) gl::ErrorOrResult<Buffer11::NativeStorage *> Buffer11::getStagingStorage(const gl::Context *context)
...@@ -942,6 +927,22 @@ OnBufferDataDirtyChannel *Buffer11::getDirectBroadcastChannel() ...@@ -942,6 +927,22 @@ OnBufferDataDirtyChannel *Buffer11::getDirectBroadcastChannel()
return &mDirectBroadcastChannel; return &mDirectBroadcastChannel;
} }
void Buffer11::onCopyStorage(BufferStorage *dest, BufferStorage *source)
{
ASSERT(source);
dest->setDataRevision(source->getDataRevision());
if (!mLatestBufferStorage || dest->getUsage() < mLatestBufferStorage->getUsage())
{
mLatestBufferStorage = dest;
}
}
void Buffer11::onStorageUpdate(BufferStorage *updatedStorage)
{
updatedStorage->setDataRevision(updatedStorage->getDataRevision() + 1);
mLatestBufferStorage = updatedStorage;
}
// Buffer11::BufferStorage implementation // Buffer11::BufferStorage implementation
Buffer11::BufferStorage::BufferStorage(Renderer11 *renderer, BufferUsage usage) Buffer11::BufferStorage::BufferStorage(Renderer11 *renderer, BufferUsage usage)
......
...@@ -152,12 +152,21 @@ class Buffer11 : public BufferD3D ...@@ -152,12 +152,21 @@ class Buffer11 : public BufferD3D
// For some cases of uniform buffer storage, we can't deallocate system memory storage. // For some cases of uniform buffer storage, we can't deallocate system memory storage.
bool canDeallocateSystemMemory() const; bool canDeallocateSystemMemory() const;
// Updates data revisions and latest storage.
void onCopyStorage(BufferStorage *dest, BufferStorage *source);
void onStorageUpdate(BufferStorage *updatedStorage);
Renderer11 *mRenderer; Renderer11 *mRenderer;
size_t mSize; size_t mSize;
BufferStorage *mMappedStorage; BufferStorage *mMappedStorage;
// Buffer storages are sorted by usage. It's important that the latest buffer storage picks
// the lowest usage in the case where two storages are tied on data revision - this ensures
// we never do anything dangerous like map a uniform buffer over a staging or system memory
// copy.
std::array<BufferStorage *, BUFFER_USAGE_COUNT> mBufferStorages; std::array<BufferStorage *, BUFFER_USAGE_COUNT> mBufferStorages;
BufferStorage *mLatestBufferStorage;
// These two arrays are used to track when to free unused storage. // These two arrays are used to track when to free unused storage.
std::array<unsigned int, BUFFER_USAGE_COUNT> mDeallocThresholds; std::array<unsigned int, BUFFER_USAGE_COUNT> mDeallocThresholds;
......
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