summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp')
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp208
1 files changed, 67 insertions, 141 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp
index ffca99c3ac..7769ab2b75 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp
@@ -12,42 +12,33 @@
#include "common/utilities.h"
#include "libANGLE/renderer/d3d/IndexBuffer.h"
#include "libANGLE/renderer/d3d/VertexBuffer.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
namespace rx
{
unsigned int BufferD3D::mNextSerial = 1;
-BufferD3D::BufferD3D(BufferFactoryD3D *factory)
- : BufferImpl(),
+BufferD3D::BufferD3D(const gl::BufferState &state, BufferFactoryD3D *factory)
+ : BufferImpl(state),
mFactory(factory),
- mStaticVertexBuffer(nullptr),
mStaticIndexBuffer(nullptr),
- mStaticBufferCache(nullptr),
mStaticBufferCacheTotalSize(0),
mStaticVertexBufferOutOfDate(false),
mUnmodifiedDataUse(0),
- mUsage(D3D_BUFFER_USAGE_STATIC)
+ mUsage(D3DBufferUsage::STATIC)
{
updateSerial();
}
BufferD3D::~BufferD3D()
{
- SafeDelete(mStaticVertexBuffer);
SafeDelete(mStaticIndexBuffer);
-
- emptyStaticBufferCache();
}
void BufferD3D::emptyStaticBufferCache()
{
- if (mStaticBufferCache != nullptr)
- {
- SafeDeleteContainer(*mStaticBufferCache);
- SafeDelete(mStaticBufferCache);
- }
-
+ mStaticVertexBuffers.clear();
mStaticBufferCacheTotalSize = 0;
}
@@ -56,35 +47,37 @@ void BufferD3D::updateSerial()
mSerial = mNextSerial++;
}
-void BufferD3D::updateD3DBufferUsage(GLenum usage)
+void BufferD3D::updateD3DBufferUsage(const gl::Context *context, gl::BufferUsage usage)
{
switch (usage)
{
- case GL_STATIC_DRAW:
- case GL_STATIC_READ:
- case GL_STATIC_COPY:
- mUsage = D3D_BUFFER_USAGE_STATIC;
- initializeStaticData();
+ case gl::BufferUsage::StaticCopy:
+ case gl::BufferUsage::StaticDraw:
+ case gl::BufferUsage::StaticRead:
+ mUsage = D3DBufferUsage::STATIC;
+ initializeStaticData(context);
break;
- case GL_STREAM_DRAW:
- case GL_STREAM_READ:
- case GL_STREAM_COPY:
- case GL_DYNAMIC_READ:
- case GL_DYNAMIC_COPY:
- case GL_DYNAMIC_DRAW:
- mUsage = D3D_BUFFER_USAGE_DYNAMIC;
+ case gl::BufferUsage::DynamicCopy:
+ case gl::BufferUsage::DynamicDraw:
+ case gl::BufferUsage::DynamicRead:
+ case gl::BufferUsage::StreamCopy:
+ case gl::BufferUsage::StreamDraw:
+ case gl::BufferUsage::StreamRead:
+ mUsage = D3DBufferUsage::DYNAMIC;
break;
default:
UNREACHABLE();
}
}
-void BufferD3D::initializeStaticData()
+void BufferD3D::initializeStaticData(const gl::Context *context)
{
- if (!mStaticVertexBuffer)
+ if (mStaticVertexBuffers.empty())
{
- mStaticVertexBuffer = new StaticVertexBufferInterface(mFactory);
+ StaticVertexBufferInterface *newStaticBuffer = new StaticVertexBufferInterface(mFactory);
+ mStaticVertexBuffers.push_back(
+ std::unique_ptr<StaticVertexBufferInterface>(newStaticBuffer));
}
if (!mStaticIndexBuffer)
{
@@ -97,168 +90,101 @@ StaticIndexBufferInterface *BufferD3D::getStaticIndexBuffer()
return mStaticIndexBuffer;
}
-StaticVertexBufferInterface *BufferD3D::getStaticVertexBuffer(
- const gl::VertexAttribute &attribute,
- D3DStaticBufferCreationType creationType)
+StaticVertexBufferInterface *BufferD3D::getStaticVertexBuffer(const gl::VertexAttribute &attribute,
+ const gl::VertexBinding &binding)
{
- if (!mStaticVertexBuffer)
+ if (mStaticVertexBuffers.empty())
{
// Early out if there aren't any static buffers at all
- ASSERT(mStaticBufferCache == nullptr);
return nullptr;
}
- if (mStaticBufferCache == nullptr && !mStaticVertexBuffer->isCommitted())
+ // Early out, the attribute can be added to mStaticVertexBuffer.
+ if (mStaticVertexBuffers.size() == 1 && mStaticVertexBuffers[0]->empty())
{
- // Early out, the attribute can be added to mStaticVertexBuffer or is already in there
- return mStaticVertexBuffer;
+ return mStaticVertexBuffers[0].get();
}
- // At this point, see if any of the existing static buffers contains the attribute data
+ // Cache size limiting: track the total allocated buffer sizes.
+ size_t currentTotalSize = 0;
- // If the default static vertex buffer contains the attribute, then return it
- if (mStaticVertexBuffer->lookupAttribute(attribute, nullptr))
- {
- return mStaticVertexBuffer;
- }
-
- if (mStaticBufferCache != nullptr)
+ // At this point, see if any of the existing static buffers contains the attribute data
+ // If there is a cached static buffer that already contains the attribute, then return it
+ for (const auto &staticBuffer : mStaticVertexBuffers)
{
- // If there is a cached static buffer that already contains the attribute, then return it
- for (StaticVertexBufferInterface *staticBuffer : *mStaticBufferCache)
+ if (staticBuffer->matchesAttribute(attribute, binding))
{
- if (staticBuffer->lookupAttribute(attribute, nullptr))
- {
- return staticBuffer;
- }
+ return staticBuffer.get();
}
- }
- if (!mStaticVertexBuffer->isCommitted())
- {
- // None of the existing static buffers contain the attribute data and we are able to add
- // the data to mStaticVertexBuffer, so we should just do so
- return mStaticVertexBuffer;
+ currentTotalSize += staticBuffer->getBufferSize();
}
- // At this point, we must create a new static buffer for the attribute data
- if (creationType != D3D_BUFFER_CREATE_IF_NECESSARY)
- {
- return nullptr;
- }
+ // Cache size limiting: Clean-up threshold is four times the base buffer size, with a minimum.
+ ASSERT(getSize() < std::numeric_limits<size_t>::max() / 4u);
+ size_t sizeThreshold = std::max(getSize() * 4u, static_cast<size_t>(0x1000u));
- ASSERT(mStaticVertexBuffer);
- ASSERT(mStaticVertexBuffer->isCommitted());
- unsigned int staticVertexBufferSize = mStaticVertexBuffer->getBufferSize();
- if (IsUnsignedAdditionSafe(staticVertexBufferSize, mStaticBufferCacheTotalSize))
+ // If we're past the threshold, clear the buffer cache. Note that this will release buffers
+ // that are currenly bound, and in an edge case can even translate the same attribute twice
+ // in the same draw call. It will not delete currently bound buffers, however, because they
+ // are ref counted.
+ if (currentTotalSize > sizeThreshold)
{
- // Ensure that the total size of the static buffer cache remains less than 4x the
- // size of the original buffer
- unsigned int maxStaticCacheSize =
- IsUnsignedMultiplicationSafe(static_cast<unsigned int>(getSize()), 4u)
- ? 4u * static_cast<unsigned int>(getSize())
- : std::numeric_limits<unsigned int>::max();
-
- // We can't reuse the default static vertex buffer, so we add it to the cache
- if (staticVertexBufferSize + mStaticBufferCacheTotalSize <= maxStaticCacheSize)
- {
- if (mStaticBufferCache == nullptr)
- {
- mStaticBufferCache = new std::vector<StaticVertexBufferInterface *>();
- }
-
- mStaticBufferCacheTotalSize += staticVertexBufferSize;
- (*mStaticBufferCache).push_back(mStaticVertexBuffer);
- mStaticVertexBuffer = nullptr;
-
- // Then reinitialize the static buffers to create a new static vertex buffer
- initializeStaticData();
-
- // Return the default static vertex buffer
- return mStaticVertexBuffer;
- }
+ emptyStaticBufferCache();
}
- // At this point:
- // - mStaticVertexBuffer is committed and can't be altered
- // - mStaticBufferCache is full (or nearly overflowing)
- // The inputted attribute should be put in some static buffer at some point, but it can't
- // go in one right now, since mStaticBufferCache is full and we can't delete mStaticVertexBuffer
- // in case another attribute is relying upon it for the current draw.
- // We therefore mark mStaticVertexBuffer for deletion at the next possible time.
- mStaticVertexBufferOutOfDate = true;
- return nullptr;
+ // At this point, we must create a new static buffer for the attribute data.
+ StaticVertexBufferInterface *newStaticBuffer = new StaticVertexBufferInterface(mFactory);
+ newStaticBuffer->setAttribute(attribute, binding);
+ mStaticVertexBuffers.push_back(std::unique_ptr<StaticVertexBufferInterface>(newStaticBuffer));
+ return newStaticBuffer;
}
-void BufferD3D::reinitOutOfDateStaticData()
+void BufferD3D::invalidateStaticData(const gl::Context *context)
{
- if (mStaticVertexBufferOutOfDate)
- {
- // During the last draw the caller tried to use some attribute with static data, but neither
- // the static buffer cache nor mStaticVertexBuffer contained that data.
- // Therefore, invalidate mStaticVertexBuffer so that if the caller tries to use that
- // attribute in the next draw, it'll successfully get put into mStaticVertexBuffer.
- invalidateStaticData(D3D_BUFFER_INVALIDATE_DEFAULT_BUFFER_ONLY);
- mStaticVertexBufferOutOfDate = false;
- }
-}
+ emptyStaticBufferCache();
-void BufferD3D::invalidateStaticData(D3DBufferInvalidationType invalidationType)
-{
- if (invalidationType == D3D_BUFFER_INVALIDATE_WHOLE_CACHE && mStaticBufferCache != nullptr)
+ if (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0)
{
- emptyStaticBufferCache();
+ SafeDelete(mStaticIndexBuffer);
}
- if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0))
+ // If the buffer was created with a static usage then we recreate the static
+ // buffers so that they are populated the next time we use this buffer.
+ if (mUsage == D3DBufferUsage::STATIC)
{
- SafeDelete(mStaticVertexBuffer);
- SafeDelete(mStaticIndexBuffer);
-
- // If the buffer was created with a static usage then we recreate the static
- // buffers so that they are populated the next time we use this buffer.
- if (mUsage == D3D_BUFFER_USAGE_STATIC)
- {
- initializeStaticData();
- }
+ initializeStaticData(context);
}
mUnmodifiedDataUse = 0;
}
// Creates static buffers if sufficient used data has been left unmodified
-void BufferD3D::promoteStaticUsage(int dataSize)
+void BufferD3D::promoteStaticUsage(const gl::Context *context, int dataSize)
{
- if (!mStaticVertexBuffer && !mStaticIndexBuffer)
+ if (mUsage == D3DBufferUsage::DYNAMIC)
{
- // There isn't any scenario that involves promoting static usage and the static buffer cache
- // being non-empty
- ASSERT(mStaticBufferCache == nullptr);
-
mUnmodifiedDataUse += dataSize;
if (mUnmodifiedDataUse > 3 * getSize())
{
- initializeStaticData();
+ updateD3DBufferUsage(context, gl::BufferUsage::StaticDraw);
}
}
}
-gl::Error BufferD3D::getIndexRange(GLenum type,
+gl::Error BufferD3D::getIndexRange(const gl::Context *context,
+ GLenum type,
size_t offset,
size_t count,
bool primitiveRestartEnabled,
gl::IndexRange *outRange)
{
const uint8_t *data = nullptr;
- gl::Error error = getData(&data);
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(getData(context, &data));
*outRange = gl::ComputeIndexRange(type, data + offset, count, primitiveRestartEnabled);
- return gl::Error(GL_NO_ERROR);
+ return gl::NoError();
}
-}
+} // namespace rx