diff options
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp')
-rw-r--r-- | src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp | 208 |
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 |