Commit 041d678b by Jamie Madill Committed by Commit Bot

Clean up Buffer11.

This cleans up some messy stuff from the emulated index buffers, which were caching variables that didn't need to be cached. Also add in missing error checks. This touches a lot of code. BUG=angleproject:1327 BUG=angleproject:1310 Change-Id: Icd722d57d9449388fbabc62c7ea37f0526a568ff Reviewed-on: https://chromium-review.googlesource.com/334731Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 7d52be02
...@@ -53,7 +53,13 @@ class ErrorOrResult ...@@ -53,7 +53,13 @@ class ErrorOrResult
{ {
public: public:
ErrorOrResult(const gl::Error &error) : mError(error) {} ErrorOrResult(const gl::Error &error) : mError(error) {}
ErrorOrResult(T &&result) : mError(GL_NO_ERROR), mResult(std::move(result)) {} ErrorOrResult(gl::Error &&error) : mError(std::move(error)) {}
template <typename ArgT>
ErrorOrResult(ArgT &&result)
: mError(GL_NO_ERROR), mResult(std::forward<T>(result))
{
}
bool isError() const { return mError.isError(); } bool isError() const { return mError.isError(); }
const gl::Error &getError() const { return mError; } const gl::Error &getError() const { return mError; }
......
...@@ -37,7 +37,7 @@ class BufferD3D : public BufferImpl ...@@ -37,7 +37,7 @@ class BufferD3D : public BufferImpl
virtual size_t getSize() const = 0; virtual size_t getSize() const = 0;
virtual bool supportsDirectBinding() const = 0; virtual bool supportsDirectBinding() const = 0;
virtual void markTransformFeedbackUsage() = 0; virtual gl::Error markTransformFeedbackUsage() = 0;
virtual gl::Error getData(const uint8_t **outData) = 0; virtual gl::Error getData(const uint8_t **outData) = 0;
StaticVertexBufferInterface *getStaticVertexBuffer(const gl::VertexAttribute &attribute); StaticVertexBufferInterface *getStaticVertexBuffer(const gl::VertexAttribute &attribute);
......
...@@ -272,7 +272,11 @@ gl::Error RendererD3D::genericDrawArrays(const gl::Data &data, ...@@ -272,7 +272,11 @@ gl::Error RendererD3D::genericDrawArrays(const gl::Data &data,
if (data.state->isTransformFeedbackActiveUnpaused()) if (data.state->isTransformFeedbackActiveUnpaused())
{ {
markTransformFeedbackUsage(data); error = markTransformFeedbackUsage(data);
if (error.isError())
{
return error;
}
} }
} }
...@@ -509,7 +513,7 @@ bool RendererD3D::skipDraw(const gl::Data &data, GLenum drawMode) ...@@ -509,7 +513,7 @@ bool RendererD3D::skipDraw(const gl::Data &data, GLenum drawMode)
return false; return false;
} }
void RendererD3D::markTransformFeedbackUsage(const gl::Data &data) gl::Error RendererD3D::markTransformFeedbackUsage(const gl::Data &data)
{ {
const gl::TransformFeedback *transformFeedback = data.state->getCurrentTransformFeedback(); const gl::TransformFeedback *transformFeedback = data.state->getCurrentTransformFeedback();
for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++) for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
...@@ -518,9 +522,15 @@ void RendererD3D::markTransformFeedbackUsage(const gl::Data &data) ...@@ -518,9 +522,15 @@ void RendererD3D::markTransformFeedbackUsage(const gl::Data &data)
if (binding.get() != nullptr) if (binding.get() != nullptr)
{ {
BufferD3D *bufferD3D = GetImplAs<BufferD3D>(binding.get()); BufferD3D *bufferD3D = GetImplAs<BufferD3D>(binding.get());
bufferD3D->markTransformFeedbackUsage(); auto error = bufferD3D->markTransformFeedbackUsage();
if (error.isError())
{
return error;
}
} }
} }
return gl::Error(GL_NO_ERROR);
} }
size_t RendererD3D::getBoundFramebufferTextures(const gl::Data &data, FramebufferTextureArray *outTextureArray) size_t RendererD3D::getBoundFramebufferTextures(const gl::Data &data, FramebufferTextureArray *outTextureArray)
......
...@@ -180,7 +180,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D ...@@ -180,7 +180,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
GLenum mode, GLenum mode,
GLenum type, GLenum type,
TranslatedIndexData *indexInfo) = 0; TranslatedIndexData *indexInfo) = 0;
virtual void applyTransformFeedbackBuffers(const gl::State& state) = 0; virtual gl::Error applyTransformFeedbackBuffers(const gl::State &state) = 0;
virtual unsigned int getReservedVertexUniformVectors() const = 0; virtual unsigned int getReservedVertexUniformVectors() const = 0;
virtual unsigned int getReservedFragmentUniformVectors() const = 0; virtual unsigned int getReservedFragmentUniformVectors() const = 0;
...@@ -326,7 +326,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D ...@@ -326,7 +326,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
gl::Error applyTextures(const gl::Data &data); gl::Error applyTextures(const gl::Data &data);
bool skipDraw(const gl::Data &data, GLenum drawMode); bool skipDraw(const gl::Data &data, GLenum drawMode);
void markTransformFeedbackUsage(const gl::Data &data); gl::Error markTransformFeedbackUsage(const gl::Data &data);
size_t getBoundFramebufferTextures(const gl::Data &data, FramebufferTextureArray *outTextureArray); size_t getBoundFramebufferTextures(const gl::Data &data, FramebufferTextureArray *outTextureArray);
gl::Texture *getIncompleteTexture(GLenum type); gl::Texture *getIncompleteTexture(GLenum type);
......
...@@ -111,7 +111,7 @@ gl::ErrorOrResult<unsigned int> VertexBufferInterface::getSpaceRequired( ...@@ -111,7 +111,7 @@ gl::ErrorOrResult<unsigned int> VertexBufferInterface::getSpaceRequired(
"Vertex buffer overflow in VertexBufferInterface::getSpaceRequired."); "Vertex buffer overflow in VertexBufferInterface::getSpaceRequired.");
} }
return std::move(alignedSpaceRequired); return alignedSpaceRequired;
} }
gl::Error VertexBufferInterface::discard() gl::Error VertexBufferInterface::discard()
......
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
namespace rx
{
namespace namespace
{ {
...@@ -27,10 +30,15 @@ GLuint ReadIndexValueFromIndices(const uint8_t *data, size_t index) ...@@ -27,10 +30,15 @@ GLuint ReadIndexValueFromIndices(const uint8_t *data, size_t index)
return reinterpret_cast<const T *>(data)[index]; return reinterpret_cast<const T *>(data)[index];
} }
typedef GLuint (*ReadIndexValueFunction)(const uint8_t *data, size_t index); typedef GLuint (*ReadIndexValueFunction)(const uint8_t *data, size_t index);
}
namespace rx enum class CopyResult
{ {
RECREATED,
NOT_RECREATED,
};
} // anonymous namespace
PackPixelsParams::PackPixelsParams() PackPixelsParams::PackPixelsParams()
: format(GL_NONE), type(GL_NONE), outputPitch(0), packBuffer(nullptr), offset(0) : format(GL_NONE), type(GL_NONE), outputPitch(0), packBuffer(nullptr), offset(0)
{ {
...@@ -83,7 +91,7 @@ D3D11_MAP GetD3DMapTypeFromBits(GLbitfield access) ...@@ -83,7 +91,7 @@ D3D11_MAP GetD3DMapTypeFromBits(GLbitfield access)
return D3D11_MAP_READ; return D3D11_MAP_READ;
} }
} }
} } // namespace gl_d3d11
// Each instance of Buffer11::BufferStorage is specialized for a class of D3D binding points // Each instance of Buffer11::BufferStorage is specialized for a class of D3D binding points
// - vertex/transform feedback buffers // - vertex/transform feedback buffers
...@@ -102,13 +110,16 @@ class Buffer11::BufferStorage : angle::NonCopyable ...@@ -102,13 +110,16 @@ class Buffer11::BufferStorage : angle::NonCopyable
virtual bool isMappable() const = 0; virtual bool isMappable() const = 0;
virtual bool copyFromStorage(BufferStorage *source, virtual gl::ErrorOrResult<CopyResult> copyFromStorage(BufferStorage *source,
size_t sourceOffset, size_t sourceOffset,
size_t size, size_t size,
size_t destOffset) = 0; size_t destOffset) = 0;
virtual gl::Error resize(size_t size, bool preserveData) = 0; virtual gl::Error resize(size_t size, bool preserveData) = 0;
virtual uint8_t *map(size_t offset, size_t length, GLbitfield access) = 0; virtual gl::Error map(size_t offset,
size_t length,
GLbitfield access,
uint8_t **mapPointerOut) = 0;
virtual void unmap() = 0; virtual void unmap() = 0;
gl::Error setData(const uint8_t *data, size_t offset, size_t size); gl::Error setData(const uint8_t *data, size_t offset, size_t size);
...@@ -133,13 +144,16 @@ class Buffer11::NativeStorage : public Buffer11::BufferStorage ...@@ -133,13 +144,16 @@ class Buffer11::NativeStorage : public Buffer11::BufferStorage
bool isMappable() const override { return mUsage == BUFFER_USAGE_STAGING; } bool isMappable() const override { return mUsage == BUFFER_USAGE_STAGING; }
ID3D11Buffer *getNativeStorage() const { return mNativeStorage; } ID3D11Buffer *getNativeStorage() const { return mNativeStorage; }
bool copyFromStorage(BufferStorage *source, gl::ErrorOrResult<CopyResult> copyFromStorage(BufferStorage *source,
size_t sourceOffset, size_t sourceOffset,
size_t size, size_t size,
size_t destOffset) override; size_t destOffset) override;
gl::Error resize(size_t size, bool preserveData) override; gl::Error resize(size_t size, bool preserveData) override;
uint8_t *map(size_t offset, size_t length, GLbitfield access) override; gl::Error map(size_t offset,
size_t length,
GLbitfield access,
uint8_t **mapPointerOut) override;
void unmap() override; void unmap() override;
private: private:
...@@ -162,26 +176,26 @@ class Buffer11::EmulatedIndexedStorage : public Buffer11::BufferStorage ...@@ -162,26 +176,26 @@ class Buffer11::EmulatedIndexedStorage : public Buffer11::BufferStorage
bool isMappable() const override { return true; } bool isMappable() const override { return true; }
ID3D11Buffer *getNativeStorage(); gl::ErrorOrResult<ID3D11Buffer *> getNativeStorage(SourceIndexData *indexInfo,
const TranslatedAttribute &attribute);
bool copyFromStorage(BufferStorage *source, gl::ErrorOrResult<CopyResult> copyFromStorage(BufferStorage *source,
size_t sourceOffset, size_t sourceOffset,
size_t size, size_t size,
size_t destOffset) override; size_t destOffset) override;
gl::Error resize(size_t size, bool preserveData) override; gl::Error resize(size_t size, bool preserveData) override;
uint8_t *map(size_t offset, size_t length, GLbitfield access) override; gl::Error map(size_t offset,
size_t length,
GLbitfield access,
uint8_t **mapPointerOut) override;
void unmap() override; void unmap() override;
bool update(SourceIndexData *indexInfo, const TranslatedAttribute *attribute);
private: private:
ID3D11Buffer *mNativeStorage; // contains expanded data for use by D3D ID3D11Buffer *mNativeStorage; // contains expanded data for use by D3D
MemoryBuffer mMemoryBuffer; // original data (not expanded) MemoryBuffer mMemoryBuffer; // original data (not expanded)
MemoryBuffer mIndicesMemoryBuffer; // indices data MemoryBuffer mIndicesMemoryBuffer; // indices data
SourceIndexData mIndexInfo; // indices information
size_t mAttributeStride; // per element stride in bytes
size_t mAttributeOffset; // starting offset
}; };
// Pack storage represents internal storage for pack buffers. We implement pack buffers // Pack storage represents internal storage for pack buffers. We implement pack buffers
...@@ -193,13 +207,16 @@ class Buffer11::PackStorage : public Buffer11::BufferStorage ...@@ -193,13 +207,16 @@ class Buffer11::PackStorage : public Buffer11::BufferStorage
~PackStorage() override; ~PackStorage() override;
bool isMappable() const override { return true; } bool isMappable() const override { return true; }
bool copyFromStorage(BufferStorage *source, gl::ErrorOrResult<CopyResult> copyFromStorage(BufferStorage *source,
size_t sourceOffset, size_t sourceOffset,
size_t size, size_t size,
size_t destOffset) override; size_t destOffset) override;
gl::Error resize(size_t size, bool preserveData) override; gl::Error resize(size_t size, bool preserveData) override;
uint8_t *map(size_t offset, size_t length, GLbitfield access) override; gl::Error map(size_t offset,
size_t length,
GLbitfield access,
uint8_t **mapPointerOut) override;
void unmap() override; void unmap() override;
gl::Error packPixels(const gl::FramebufferAttachment &readAttachment, gl::Error packPixels(const gl::FramebufferAttachment &readAttachment,
...@@ -225,13 +242,16 @@ class Buffer11::SystemMemoryStorage : public Buffer11::BufferStorage ...@@ -225,13 +242,16 @@ class Buffer11::SystemMemoryStorage : public Buffer11::BufferStorage
~SystemMemoryStorage() override {} ~SystemMemoryStorage() override {}
bool isMappable() const override { return true; } bool isMappable() const override { return true; }
bool copyFromStorage(BufferStorage *source, gl::ErrorOrResult<CopyResult> copyFromStorage(BufferStorage *source,
size_t sourceOffset, size_t sourceOffset,
size_t size, size_t size,
size_t destOffset) override; size_t destOffset) override;
gl::Error resize(size_t size, bool preserveData) override; gl::Error resize(size_t size, bool preserveData) override;
uint8_t *map(size_t offset, size_t length, GLbitfield access) override; gl::Error map(size_t offset,
size_t length,
GLbitfield access,
uint8_t **mapPointerOut) override;
void unmap() override; void unmap() override;
MemoryBuffer *getSystemCopy() { return &mSystemCopy; } MemoryBuffer *getSystemCopy() { return &mSystemCopy; }
...@@ -282,15 +302,15 @@ gl::Error Buffer11::setData(const void *data, size_t size, GLenum usage) ...@@ -282,15 +302,15 @@ gl::Error Buffer11::setData(const void *data, size_t size, GLenum usage)
gl::Error Buffer11::getData(const uint8_t **outData) gl::Error Buffer11::getData(const uint8_t **outData)
{ {
SystemMemoryStorage *systemMemoryStorage = nullptr; auto systemOrError = getSystemMemoryStorage();
gl::Error error = getSystemMemoryStorage(&systemMemoryStorage); if (systemOrError.isError())
if (error.isError())
{ {
*outData = nullptr; *outData = nullptr;
return error; return systemOrError.getError();
} }
SystemMemoryStorage *systemMemoryStorage = systemOrError.getResult();
mReadUsageCount = 0; mReadUsageCount = 0;
ASSERT(systemMemoryStorage->getSize() >= mSize); ASSERT(systemMemoryStorage->getSize() >= mSize);
...@@ -299,18 +319,16 @@ gl::Error Buffer11::getData(const uint8_t **outData) ...@@ -299,18 +319,16 @@ gl::Error Buffer11::getData(const uint8_t **outData)
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error Buffer11::getSystemMemoryStorage(SystemMemoryStorage **storageOut) gl::ErrorOrResult<Buffer11::SystemMemoryStorage *> Buffer11::getSystemMemoryStorage()
{ {
BufferStorage *memStorageUntyped = getBufferStorage(BUFFER_USAGE_SYSTEM_MEMORY); auto systemOrError = getBufferStorage(BUFFER_USAGE_SYSTEM_MEMORY);
if (systemOrError.isError())
if (memStorageUntyped == nullptr)
{ {
// TODO(jmadill): convert all to errors return systemOrError.getError();
return gl::Error(GL_OUT_OF_MEMORY);
} }
*storageOut = GetAs<SystemMemoryStorage>(memStorageUntyped); auto resultT = GetAs<SystemMemoryStorage>(systemOrError.getResult());
return gl::Error(GL_NO_ERROR); return resultT;
} }
gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset) gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset)
...@@ -324,23 +342,23 @@ gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset) ...@@ -324,23 +342,23 @@ gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset)
BufferStorage *writeBuffer = nullptr; BufferStorage *writeBuffer = nullptr;
if (supportsDirectBinding()) if (supportsDirectBinding())
{ {
writeBuffer = getStagingStorage(); auto stagingOrError = getStagingStorage();
if (stagingOrError.isError())
if (!writeBuffer)
{ {
return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal buffer."); return stagingOrError.getError();
} }
writeBuffer = stagingOrError.getResult();
} }
else else
{ {
SystemMemoryStorage *systemMemoryStorage = nullptr; auto systemOrError = getSystemMemoryStorage();
gl::Error error = getSystemMemoryStorage(&systemMemoryStorage); if (systemOrError.isError())
if (error.isError())
{ {
return error; return systemOrError.getError();
} }
writeBuffer = systemMemoryStorage; writeBuffer = systemOrError.getResult();
} }
ASSERT(writeBuffer); ASSERT(writeBuffer);
...@@ -375,13 +393,29 @@ gl::Error Buffer11::copySubData(BufferImpl *source, ...@@ -375,13 +393,29 @@ gl::Error Buffer11::copySubData(BufferImpl *source,
Buffer11 *sourceBuffer = GetAs<Buffer11>(source); Buffer11 *sourceBuffer = GetAs<Buffer11>(source);
ASSERT(sourceBuffer != nullptr); ASSERT(sourceBuffer != nullptr);
BufferStorage *copyDest = getLatestBufferStorage(); auto latestOrError = getLatestBufferStorage();
if (latestOrError.isError())
{
return latestOrError.getError();
}
BufferStorage *copyDest = latestOrError.getResult();
if (!copyDest) if (!copyDest)
{ {
copyDest = getStagingStorage(); auto stagingOrError = getStagingStorage();
if (stagingOrError.isError())
{
return stagingOrError.getError();
}
copyDest = stagingOrError.getResult();
} }
BufferStorage *copySource = sourceBuffer->getLatestBufferStorage(); auto sourceLatestOrError = sourceBuffer->getLatestBufferStorage();
if (sourceLatestOrError.isError())
{
return sourceLatestOrError.getError();
}
BufferStorage *copySource = sourceLatestOrError.getResult();
if (!copySource || !copyDest) if (!copySource || !copyDest)
{ {
...@@ -392,11 +426,21 @@ gl::Error Buffer11::copySubData(BufferImpl *source, ...@@ -392,11 +426,21 @@ gl::Error Buffer11::copySubData(BufferImpl *source,
// pack buffer partner, because other native buffers can't be mapped // pack buffer partner, because other native buffers can't be mapped
if (copyDest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copySource->isMappable()) if (copyDest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copySource->isMappable())
{ {
copySource = sourceBuffer->getStagingStorage(); auto sourceStagingOrError = sourceBuffer->getStagingStorage();
if (sourceStagingOrError.isError())
{
return sourceStagingOrError.getError();
}
copySource = sourceStagingOrError.getResult();
} }
else if (copySource->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copyDest->isMappable()) else if (copySource->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copyDest->isMappable())
{ {
copyDest = getStagingStorage(); auto stagingOrError = getStagingStorage();
if (stagingOrError.isError())
{
return stagingOrError.getError();
}
copyDest = stagingOrError.getResult();
} }
// D3D11 does not allow overlapped copies until 11.1, and only if the // D3D11 does not allow overlapped copies until 11.1, and only if the
...@@ -406,15 +450,29 @@ gl::Error Buffer11::copySubData(BufferImpl *source, ...@@ -406,15 +450,29 @@ gl::Error Buffer11::copySubData(BufferImpl *source,
{ {
if (copySource->getUsage() == BUFFER_USAGE_STAGING) if (copySource->getUsage() == BUFFER_USAGE_STAGING)
{ {
copySource = getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); auto vertexOrError = getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
if (vertexOrError.isError())
{
return vertexOrError.getError();
}
copySource = vertexOrError.getResult();
} }
else else
{ {
copySource = getStagingStorage(); auto stagingOrError = getStagingStorage();
if (stagingOrError.isError())
{
return stagingOrError.getError();
}
copySource = stagingOrError.getResult();
} }
} }
copyDest->copyFromStorage(copySource, sourceOffset, size, destOffset); auto resultOrError = copyDest->copyFromStorage(copySource, sourceOffset, size, destOffset);
if (resultOrError.isError())
{
return resultOrError.getError();
}
copyDest->setDataRevision(copyDest->getDataRevision() + 1); copyDest->setDataRevision(copyDest->getDataRevision() + 1);
mSize = std::max<size_t>(mSize, destOffset + size); mSize = std::max<size_t>(mSize, destOffset + size);
...@@ -435,7 +493,12 @@ gl::Error Buffer11::mapRange(size_t offset, size_t length, GLbitfield access, GL ...@@ -435,7 +493,12 @@ gl::Error Buffer11::mapRange(size_t offset, size_t length, GLbitfield access, GL
{ {
ASSERT(!mMappedStorage); ASSERT(!mMappedStorage);
BufferStorage *latestStorage = getLatestBufferStorage(); auto latestOrError = getLatestBufferStorage();
if (latestOrError.isError())
{
return latestOrError.getError();
}
BufferStorage *latestStorage = latestOrError.getResult();
if (latestStorage && (latestStorage->getUsage() == BUFFER_USAGE_PIXEL_PACK || if (latestStorage && (latestStorage->getUsage() == BUFFER_USAGE_PIXEL_PACK ||
latestStorage->getUsage() == BUFFER_USAGE_STAGING)) latestStorage->getUsage() == BUFFER_USAGE_STAGING))
{ {
...@@ -446,7 +509,12 @@ gl::Error Buffer11::mapRange(size_t offset, size_t length, GLbitfield access, GL ...@@ -446,7 +509,12 @@ gl::Error Buffer11::mapRange(size_t offset, size_t length, GLbitfield access, GL
{ {
// Fall back to using the staging buffer if the latest storage does // Fall back to using the staging buffer if the latest storage does
// not exist or is not CPU-accessible. // not exist or is not CPU-accessible.
mMappedStorage = getStagingStorage(); auto stagingOrError = getStagingStorage();
if (stagingOrError.isError())
{
return stagingOrError.getError();
}
mMappedStorage = stagingOrError.getResult();
} }
if (!mMappedStorage) if (!mMappedStorage)
...@@ -461,11 +529,13 @@ gl::Error Buffer11::mapRange(size_t offset, size_t length, GLbitfield access, GL ...@@ -461,11 +529,13 @@ gl::Error Buffer11::mapRange(size_t offset, size_t length, GLbitfield access, GL
invalidateStaticData(); invalidateStaticData();
} }
uint8_t *mappedBuffer = mMappedStorage->map(offset, length, access); uint8_t *mappedBuffer = nullptr;
if (!mappedBuffer) auto error = mMappedStorage->map(offset, length, access, &mappedBuffer);
if (error.isError())
{ {
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer."); return error;
} }
ASSERT(mappedBuffer);
*mapPtr = static_cast<GLvoid *>(mappedBuffer); *mapPtr = static_cast<GLvoid *>(mappedBuffer);
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
...@@ -483,20 +553,25 @@ gl::Error Buffer11::unmap(GLboolean *result) ...@@ -483,20 +553,25 @@ gl::Error Buffer11::unmap(GLboolean *result)
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
void Buffer11::markTransformFeedbackUsage() gl::Error Buffer11::markTransformFeedbackUsage()
{ {
BufferStorage *transformFeedbackStorage = auto tfOrError = getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); if (tfOrError.isError())
{
return tfOrError.getError();
}
BufferStorage *transformFeedbackStorage = tfOrError.getResult();
if (transformFeedbackStorage) if (transformFeedbackStorage)
{ {
transformFeedbackStorage->setDataRevision(transformFeedbackStorage->getDataRevision() + 1); transformFeedbackStorage->setDataRevision(transformFeedbackStorage->getDataRevision() + 1);
} }
invalidateStaticData(); invalidateStaticData();
return gl::Error(GL_NO_ERROR);
} }
void Buffer11::markBufferUsage() gl::Error Buffer11::markBufferUsage()
{ {
mReadUsageCount++; mReadUsageCount++;
...@@ -506,87 +581,106 @@ void Buffer11::markBufferUsage() ...@@ -506,87 +581,106 @@ void Buffer11::markBufferUsage()
BufferStorage *&sysMemUsage = mBufferStorages[BUFFER_USAGE_SYSTEM_MEMORY]; BufferStorage *&sysMemUsage = mBufferStorages[BUFFER_USAGE_SYSTEM_MEMORY];
if (mReadUsageCount > usageLimit && sysMemUsage != nullptr) if (mReadUsageCount > usageLimit && sysMemUsage != nullptr)
{ {
if (getLatestBufferStorage() != sysMemUsage) auto latestOrError = getLatestBufferStorage();
if (latestOrError.isError())
{
return latestOrError.getError();
}
if (latestOrError.getResult() != sysMemUsage)
{ {
SafeDelete(sysMemUsage); SafeDelete(sysMemUsage);
} }
} }
return gl::Error(GL_NO_ERROR);
} }
ID3D11Buffer *Buffer11::getBuffer(BufferUsage usage) gl::ErrorOrResult<ID3D11Buffer *> Buffer11::getBuffer(BufferUsage usage)
{ {
markBufferUsage(); gl::Error error = markBufferUsage();
if (error.isError())
BufferStorage *bufferStorage = getBufferStorage(usage);
if (!bufferStorage)
{ {
// Storage out-of-memory return error;
return nullptr;
} }
return GetAs<NativeStorage>(bufferStorage)->getNativeStorage(); auto bufferOrError = getBufferStorage(usage);
if (bufferOrError.isError())
{
return bufferOrError.getError();
}
return GetAs<NativeStorage>(bufferOrError.getResult())->getNativeStorage();
} }
ID3D11Buffer *Buffer11::getEmulatedIndexedBuffer(SourceIndexData *indexInfo, gl::ErrorOrResult<ID3D11Buffer *> Buffer11::getEmulatedIndexedBuffer(
const TranslatedAttribute *attribute) SourceIndexData *indexInfo,
const TranslatedAttribute &attribute)
{ {
markBufferUsage(); gl::Error error = markBufferUsage();
if (error.isError())
{
return error;
}
assert(indexInfo != nullptr); ASSERT(indexInfo);
assert(attribute != nullptr);
BufferStorage *bufferStorage = getBufferStorage(BUFFER_USAGE_EMULATED_INDEXED_VERTEX); auto emulatedOrError = getBufferStorage(BUFFER_USAGE_EMULATED_INDEXED_VERTEX);
if (!bufferStorage) if (emulatedOrError.isError())
{ {
// Storage out-of-memory return emulatedOrError.getError();
return nullptr;
} }
EmulatedIndexedStorage *emulatedStorage = GetAs<EmulatedIndexedStorage>(bufferStorage); EmulatedIndexedStorage *emulatedStorage =
if (!emulatedStorage->update(indexInfo, attribute)) GetAs<EmulatedIndexedStorage>(emulatedOrError.getResult());
auto errorOrResult = emulatedStorage->getNativeStorage(indexInfo, attribute);
if (errorOrResult.isError())
{ {
// Storage out-of-memory return errorOrResult.getError();
return nullptr;
} }
return emulatedStorage->getNativeStorage(); return errorOrResult.getResult();
} }
ID3D11Buffer *Buffer11::getConstantBufferRange(GLintptr offset, GLsizeiptr size) gl::ErrorOrResult<ID3D11Buffer *> Buffer11::getConstantBufferRange(GLintptr offset, GLsizeiptr size)
{ {
markBufferUsage(); gl::Error error = markBufferUsage();
if (error.isError())
{
return error;
}
BufferStorage *bufferStorage; BufferStorage *bufferStorage;
if (offset == 0) if (offset == 0)
{ {
bufferStorage = getBufferStorage(BUFFER_USAGE_UNIFORM); auto uniformOrError = getBufferStorage(BUFFER_USAGE_UNIFORM);
if (uniformOrError.isError())
{
return uniformOrError.getError();
}
bufferStorage = uniformOrError.getResult();
} }
else else
{ {
bufferStorage = getConstantBufferRangeStorage(offset, size); auto constantOrError = getConstantBufferRangeStorage(offset, size);
} if (constantOrError.isError())
{
if (!bufferStorage) return constantOrError.getError();
{ }
// Storage out-of-memory bufferStorage = constantOrError.getResult();
return nullptr;
} }
return GetAs<NativeStorage>(bufferStorage)->getNativeStorage(); return GetAs<NativeStorage>(bufferStorage)->getNativeStorage();
} }
ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat) gl::ErrorOrResult<ID3D11ShaderResourceView *> Buffer11::getSRV(DXGI_FORMAT srvFormat)
{ {
BufferStorage *storage = getBufferStorage(BUFFER_USAGE_PIXEL_UNPACK); auto unpackOrError = getBufferStorage(BUFFER_USAGE_PIXEL_UNPACK);
if (unpackOrError.isError())
if (!storage)
{ {
// Storage out-of-memory return unpackOrError.getError();
return nullptr;
} }
BufferStorage *storage = unpackOrError.getResult();
ID3D11Buffer *buffer = GetAs<NativeStorage>(storage)->getNativeStorage(); ID3D11Buffer *buffer = GetAs<NativeStorage>(storage)->getNativeStorage();
auto bufferSRVIt = mBufferResourceViews.find(srvFormat); auto bufferSRVIt = mBufferResourceViews.find(srvFormat);
...@@ -628,18 +722,27 @@ ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat) ...@@ -628,18 +722,27 @@ ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat)
gl::Error Buffer11::packPixels(const gl::FramebufferAttachment &readAttachment, gl::Error Buffer11::packPixels(const gl::FramebufferAttachment &readAttachment,
const PackPixelsParams &params) const PackPixelsParams &params)
{ {
PackStorage *packStorage = getPackStorage(); auto packOrError = getPackStorage();
BufferStorage *latestStorage = getLatestBufferStorage(); if (packOrError.isError())
{
return packOrError.getError();
}
PackStorage *packStorage = packOrError.getResult();
if (packStorage) auto latestOrError = getLatestBufferStorage();
if (latestOrError.isError())
{ {
gl::Error error = packStorage->packPixels(readAttachment, params); return latestOrError.getError();
if (error.isError()) }
{ BufferStorage *latestStorage = latestOrError.getResult();
return error;
} ASSERT(packStorage);
packStorage->setDataRevision(latestStorage ? latestStorage->getDataRevision() + 1 : 1); gl::Error error = packStorage->packPixels(readAttachment, params);
if (error.isError())
{
return error;
} }
packStorage->setDataRevision(latestStorage ? latestStorage->getDataRevision() + 1 : 1);
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
...@@ -657,7 +760,7 @@ size_t Buffer11::getTotalCPUBufferMemoryBytes() const ...@@ -657,7 +760,7 @@ size_t Buffer11::getTotalCPUBufferMemoryBytes() const
return allocationSize; return allocationSize;
} }
Buffer11::BufferStorage *Buffer11::getBufferStorage(BufferUsage usage) gl::ErrorOrResult<Buffer11::BufferStorage *> Buffer11::getBufferStorage(BufferUsage usage)
{ {
ASSERT(0 <= usage && usage < BUFFER_USAGE_COUNT); ASSERT(0 <= usage && usage < BUFFER_USAGE_COUNT);
BufferStorage *&newStorage = mBufferStorages[usage]; BufferStorage *&newStorage = mBufferStorages[usage];
...@@ -686,19 +789,25 @@ Buffer11::BufferStorage *Buffer11::getBufferStorage(BufferUsage usage) ...@@ -686,19 +789,25 @@ Buffer11::BufferStorage *Buffer11::getBufferStorage(BufferUsage usage)
// resize buffer // resize buffer
if (newStorage->getSize() < mSize) if (newStorage->getSize() < mSize)
{ {
if (newStorage->resize(mSize, true).isError()) auto error = newStorage->resize(mSize, true);
if (error.isError())
{ {
// Out of memory error return error;
return nullptr;
} }
} }
updateBufferStorage(newStorage, 0, mSize); auto error = updateBufferStorage(newStorage, 0, mSize);
if (error.isError())
{
return error;
}
return newStorage; return newStorage;
} }
Buffer11::BufferStorage *Buffer11::getConstantBufferRangeStorage(GLintptr offset, GLsizeiptr size) gl::ErrorOrResult<Buffer11::BufferStorage *> Buffer11::getConstantBufferRangeStorage(
GLintptr offset,
GLsizeiptr size)
{ {
BufferStorage *newStorage; BufferStorage *newStorage;
...@@ -741,10 +850,10 @@ Buffer11::BufferStorage *Buffer11::getConstantBufferRangeStorage(GLintptr offset ...@@ -741,10 +850,10 @@ Buffer11::BufferStorage *Buffer11::getConstantBufferRangeStorage(GLintptr offset
mConstantBufferRangeStoragesCache.erase(iter); mConstantBufferRangeStoragesCache.erase(iter);
} }
if (newStorage->resize(size, false).isError()) auto error = newStorage->resize(size, false);
if (error.isError())
{ {
// Out of memory error return error;
return nullptr;
} }
mConstantBufferStorageAdditionalSize += sizeDelta; mConstantBufferStorageAdditionalSize += sizeDelta;
...@@ -755,14 +864,26 @@ Buffer11::BufferStorage *Buffer11::getConstantBufferRangeStorage(GLintptr offset ...@@ -755,14 +864,26 @@ Buffer11::BufferStorage *Buffer11::getConstantBufferRangeStorage(GLintptr offset
newStorage->setDataRevision(0); newStorage->setDataRevision(0);
} }
updateBufferStorage(newStorage, offset, size); auto error = updateBufferStorage(newStorage, offset, size);
if (error.isError())
{
return error;
}
return newStorage; return newStorage;
} }
void Buffer11::updateBufferStorage(BufferStorage *storage, size_t sourceOffset, size_t storageSize) gl::Error Buffer11::updateBufferStorage(BufferStorage *storage,
size_t sourceOffset,
size_t storageSize)
{ {
BufferStorage *latestBuffer = getLatestBufferStorage(); auto latestOrError = getLatestBufferStorage();
if (latestOrError.isError())
{
return latestOrError.getError();
}
BufferStorage *latestBuffer = latestOrError.getResult();
if (latestBuffer && latestBuffer->getDataRevision() > storage->getDataRevision()) if (latestBuffer && latestBuffer->getDataRevision() > storage->getDataRevision())
{ {
// Copy through a staging buffer if we're copying from or to a non-staging, mappable // Copy through a staging buffer if we're copying from or to a non-staging, mappable
...@@ -772,25 +893,41 @@ void Buffer11::updateBufferStorage(BufferStorage *storage, size_t sourceOffset, ...@@ -772,25 +893,41 @@ void Buffer11::updateBufferStorage(BufferStorage *storage, size_t sourceOffset,
storage->getUsage() != BUFFER_USAGE_STAGING && storage->getUsage() != BUFFER_USAGE_STAGING &&
(!latestBuffer->isMappable() || !storage->isMappable())) (!latestBuffer->isMappable() || !storage->isMappable()))
{ {
NativeStorage *stagingBuffer = getStagingStorage(); auto stagingOrError = getStagingStorage();
if (stagingOrError.isError())
{
return stagingOrError.getError();
}
NativeStorage *stagingBuffer = stagingOrError.getResult();
stagingBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0); auto resultOrError =
stagingBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0);
if (resultOrError.isError())
{
return resultOrError.getError();
}
stagingBuffer->setDataRevision(latestBuffer->getDataRevision()); stagingBuffer->setDataRevision(latestBuffer->getDataRevision());
latestBuffer = stagingBuffer; latestBuffer = stagingBuffer;
} }
// if copyFromStorage returns true, the D3D buffer has been recreated auto resultOrError = storage->copyFromStorage(latestBuffer, sourceOffset, storageSize, 0);
// and we should update our serial if (resultOrError.isError())
if (storage->copyFromStorage(latestBuffer, sourceOffset, storageSize, 0)) {
return resultOrError.getError();
}
// If the D3D buffer has been recreated, we should update our serial.
if (resultOrError.getResult() == CopyResult::RECREATED)
{ {
updateSerial(); updateSerial();
} }
storage->setDataRevision(latestBuffer->getDataRevision()); storage->setDataRevision(latestBuffer->getDataRevision());
} }
return gl::Error(GL_NO_ERROR);
} }
Buffer11::BufferStorage *Buffer11::getLatestBufferStorage() const gl::ErrorOrResult<Buffer11::BufferStorage *> Buffer11::getLatestBufferStorage() const
{ {
// Even though we iterate over all the direct buffers, it is expected that only // Even though we iterate over all the direct buffers, it is expected that only
// 1 or 2 will be present. // 1 or 2 will be present.
...@@ -808,40 +945,36 @@ Buffer11::BufferStorage *Buffer11::getLatestBufferStorage() const ...@@ -808,40 +945,36 @@ Buffer11::BufferStorage *Buffer11::getLatestBufferStorage() const
// resize buffer // resize buffer
if (latestStorage && latestStorage->getSize() < mSize) if (latestStorage && latestStorage->getSize() < mSize)
{ {
if (latestStorage->resize(mSize, true).isError()) auto error = latestStorage->resize(mSize, true);
if (error.isError())
{ {
// Out of memory error return error;
return nullptr;
} }
} }
return latestStorage; return latestStorage;
} }
Buffer11::NativeStorage *Buffer11::getStagingStorage() gl::ErrorOrResult<Buffer11::NativeStorage *> Buffer11::getStagingStorage()
{ {
BufferStorage *stagingStorage = getBufferStorage(BUFFER_USAGE_STAGING); auto stagingOrError = getBufferStorage(BUFFER_USAGE_STAGING);
if (stagingOrError.isError())
if (!stagingStorage)
{ {
// Out-of-memory return stagingOrError.getError();
return nullptr;
} }
return GetAs<NativeStorage>(stagingStorage); return GetAs<NativeStorage>(stagingOrError.getResult());
} }
Buffer11::PackStorage *Buffer11::getPackStorage() gl::ErrorOrResult<Buffer11::PackStorage *> Buffer11::getPackStorage()
{ {
BufferStorage *packStorage = getBufferStorage(BUFFER_USAGE_PIXEL_PACK); auto packOrError = getBufferStorage(BUFFER_USAGE_PIXEL_PACK);
if (packOrError.isError())
if (!packStorage)
{ {
// Out-of-memory return packOrError.getError();
return nullptr;
} }
return GetAs<PackStorage>(packStorage); return GetAs<PackStorage>(packOrError.getResult());
} }
bool Buffer11::supportsDirectBinding() const bool Buffer11::supportsDirectBinding() const
...@@ -861,10 +994,11 @@ gl::Error Buffer11::BufferStorage::setData(const uint8_t *data, size_t offset, s ...@@ -861,10 +994,11 @@ gl::Error Buffer11::BufferStorage::setData(const uint8_t *data, size_t offset, s
{ {
ASSERT(isMappable()); ASSERT(isMappable());
uint8_t *writePointer = map(offset, size, GL_MAP_WRITE_BIT); uint8_t *writePointer = nullptr;
if (!writePointer) gl::Error error = map(offset, size, GL_MAP_WRITE_BIT, &writePointer);
if (error.isError())
{ {
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer."); return error;
} }
memcpy(writePointer, data, size); memcpy(writePointer, data, size);
...@@ -885,10 +1019,10 @@ Buffer11::NativeStorage::~NativeStorage() ...@@ -885,10 +1019,10 @@ Buffer11::NativeStorage::~NativeStorage()
} }
// Returns true if it recreates the direct buffer // Returns true if it recreates the direct buffer
bool Buffer11::NativeStorage::copyFromStorage(BufferStorage *source, gl::ErrorOrResult<CopyResult> Buffer11::NativeStorage::copyFromStorage(BufferStorage *source,
size_t sourceOffset, size_t sourceOffset,
size_t size, size_t size,
size_t destOffset) size_t destOffset)
{ {
ID3D11DeviceContext *context = mRenderer->getDeviceContext(); ID3D11DeviceContext *context = mRenderer->getDeviceContext();
...@@ -907,7 +1041,12 @@ bool Buffer11::NativeStorage::copyFromStorage(BufferStorage *source, ...@@ -907,7 +1041,12 @@ bool Buffer11::NativeStorage::copyFromStorage(BufferStorage *source,
{ {
ASSERT(source->isMappable()); ASSERT(source->isMappable());
uint8_t *sourcePointer = source->map(sourceOffset, size, GL_MAP_READ_BIT); uint8_t *sourcePointer = nullptr;
gl::Error error = source->map(sourceOffset, size, GL_MAP_READ_BIT, &sourcePointer);
if (error.isError())
{
return error;
}
D3D11_MAPPED_SUBRESOURCE mappedResource; D3D11_MAPPED_SUBRESOURCE mappedResource;
HRESULT hr = context->Map(mNativeStorage, 0, D3D11_MAP_WRITE, 0, &mappedResource); HRESULT hr = context->Map(mNativeStorage, 0, D3D11_MAP_WRITE, 0, &mappedResource);
...@@ -915,7 +1054,9 @@ bool Buffer11::NativeStorage::copyFromStorage(BufferStorage *source, ...@@ -915,7 +1054,9 @@ bool Buffer11::NativeStorage::copyFromStorage(BufferStorage *source,
if (FAILED(hr)) if (FAILED(hr))
{ {
source->unmap(); source->unmap();
return false; return gl::Error(
GL_OUT_OF_MEMORY,
"Failed to map native storage in Buffer11::NativeStorage::copyFromStorage");
} }
uint8_t *destPointer = static_cast<uint8_t *>(mappedResource.pData) + destOffset; uint8_t *destPointer = static_cast<uint8_t *>(mappedResource.pData) + destOffset;
...@@ -943,7 +1084,7 @@ bool Buffer11::NativeStorage::copyFromStorage(BufferStorage *source, ...@@ -943,7 +1084,7 @@ bool Buffer11::NativeStorage::copyFromStorage(BufferStorage *source,
0, sourceBuffer, 0, &srcBox); 0, sourceBuffer, 0, &srcBox);
} }
return createBuffer; return createBuffer ? CopyResult::RECREATED : CopyResult::NOT_RECREATED;
} }
gl::Error Buffer11::NativeStorage::resize(size_t size, bool preserveData) gl::Error Buffer11::NativeStorage::resize(size_t size, bool preserveData)
...@@ -1049,7 +1190,10 @@ void Buffer11::NativeStorage::fillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, ...@@ -1049,7 +1190,10 @@ void Buffer11::NativeStorage::fillBufferDesc(D3D11_BUFFER_DESC *bufferDesc,
} }
} }
uint8_t *Buffer11::NativeStorage::map(size_t offset, size_t length, GLbitfield access) gl::Error Buffer11::NativeStorage::map(size_t offset,
size_t length,
GLbitfield access,
uint8_t **mapPointerOut)
{ {
ASSERT(mUsage == BUFFER_USAGE_STAGING); ASSERT(mUsage == BUFFER_USAGE_STAGING);
...@@ -1062,9 +1206,12 @@ uint8_t *Buffer11::NativeStorage::map(size_t offset, size_t length, GLbitfield a ...@@ -1062,9 +1206,12 @@ uint8_t *Buffer11::NativeStorage::map(size_t offset, size_t length, GLbitfield a
ASSERT(SUCCEEDED(result)); ASSERT(SUCCEEDED(result));
if (FAILED(result)) if (FAILED(result))
{ {
return nullptr; return gl::Error(GL_OUT_OF_MEMORY,
"Failed to map native storage in Buffer11::NativeStorage::map");
} }
return static_cast<uint8_t *>(mappedResource.pData) + offset; ASSERT(mappedResource.pData);
*mapPointerOut = static_cast<uint8_t *>(mappedResource.pData) + offset;
return gl::Error(GL_NO_ERROR);
} }
void Buffer11::NativeStorage::unmap() void Buffer11::NativeStorage::unmap()
...@@ -1084,32 +1231,74 @@ Buffer11::EmulatedIndexedStorage::~EmulatedIndexedStorage() ...@@ -1084,32 +1231,74 @@ Buffer11::EmulatedIndexedStorage::~EmulatedIndexedStorage()
SafeRelease(mNativeStorage); SafeRelease(mNativeStorage);
} }
ID3D11Buffer *Buffer11::EmulatedIndexedStorage::getNativeStorage() gl::ErrorOrResult<ID3D11Buffer *> Buffer11::EmulatedIndexedStorage::getNativeStorage(
SourceIndexData *indexInfo,
const TranslatedAttribute &attribute)
{ {
// If a change in the indices applied from the last draw call is detected, then the emulated
// indexed buffer needs to be invalidated. After invalidation, the change detected flag should
// be cleared to avoid unnecessary recreation of the buffer.
if (mNativeStorage == nullptr || indexInfo->srcIndicesChanged)
{
SafeRelease(mNativeStorage);
// Copy the source index data. This ensures that the lifetime of the indices pointer
// stays with this storage until the next time we invalidate.
size_t indicesDataSize = 0;
switch (indexInfo->srcIndexType)
{
case GL_UNSIGNED_INT:
indicesDataSize = sizeof(GLuint) * indexInfo->srcCount;
break;
case GL_UNSIGNED_SHORT:
indicesDataSize = sizeof(GLushort) * indexInfo->srcCount;
break;
case GL_UNSIGNED_BYTE:
indicesDataSize = sizeof(GLubyte) * indexInfo->srcCount;
break;
default:
indicesDataSize = sizeof(GLushort) * indexInfo->srcCount;
break;
}
if (!mIndicesMemoryBuffer.resize(indicesDataSize))
{
return gl::Error(GL_OUT_OF_MEMORY,
"Error resizing index memory buffer in "
"Buffer11::EmulatedIndexedStorage::getNativeStorage");
}
memcpy(mIndicesMemoryBuffer.data(), indexInfo->srcIndices, indicesDataSize);
indexInfo->srcIndicesChanged = false;
}
if (!mNativeStorage) if (!mNativeStorage)
{ {
// Expand the memory storage upon request and cache the results. // Expand the memory storage upon request and cache the results.
unsigned int expandedDataSize = unsigned int expandedDataSize =
static_cast<unsigned int>((mIndexInfo.srcCount * mAttributeStride) + mAttributeOffset); static_cast<unsigned int>((indexInfo->srcCount * attribute.stride) + attribute.offset);
MemoryBuffer expandedData; MemoryBuffer expandedData;
if (!expandedData.resize(expandedDataSize)) if (!expandedData.resize(expandedDataSize))
{ {
return nullptr; return gl::Error(
GL_OUT_OF_MEMORY,
"Error resizing buffer in Buffer11::EmulatedIndexedStorage::getNativeStorage");
} }
// Clear the contents of the allocated buffer // Clear the contents of the allocated buffer
ZeroMemory(expandedData.data(), expandedDataSize); ZeroMemory(expandedData.data(), expandedDataSize);
uint8_t *curr = expandedData.data(); uint8_t *curr = expandedData.data();
const uint8_t *ptr = static_cast<const uint8_t *>(mIndexInfo.srcIndices); const uint8_t *ptr = static_cast<const uint8_t *>(indexInfo->srcIndices);
// Ensure that we start in the correct place for the emulated data copy operation to // Ensure that we start in the correct place for the emulated data copy operation to
// maintain offset behaviors. // maintain offset behaviors.
curr += mAttributeOffset; curr += attribute.offset;
ReadIndexValueFunction readIndexValue = ReadIndexValueFromIndices<GLushort>; ReadIndexValueFunction readIndexValue = ReadIndexValueFromIndices<GLushort>;
switch (mIndexInfo.srcIndexType) switch (indexInfo->srcIndexType)
{ {
case GL_UNSIGNED_INT: case GL_UNSIGNED_INT:
readIndexValue = ReadIndexValueFromIndices<GLuint>; readIndexValue = ReadIndexValueFromIndices<GLuint>;
...@@ -1123,11 +1312,11 @@ ID3D11Buffer *Buffer11::EmulatedIndexedStorage::getNativeStorage() ...@@ -1123,11 +1312,11 @@ ID3D11Buffer *Buffer11::EmulatedIndexedStorage::getNativeStorage()
} }
// Iterate over the cached index data and copy entries indicated into the emulated buffer. // Iterate over the cached index data and copy entries indicated into the emulated buffer.
for (GLuint i = 0; i < mIndexInfo.srcCount; i++) for (GLuint i = 0; i < indexInfo->srcCount; i++)
{ {
GLuint idx = readIndexValue(ptr, i); GLuint idx = readIndexValue(ptr, i);
memcpy(curr, mMemoryBuffer.data() + (mAttributeStride * idx), mAttributeStride); memcpy(curr, mMemoryBuffer.data() + (attribute.stride * idx), attribute.stride);
curr += mAttributeStride; curr += attribute.stride;
} }
// Finally, initialize the emulated indexed native storage object with the newly copied data // Finally, initialize the emulated indexed native storage object with the newly copied data
...@@ -1147,8 +1336,8 @@ ID3D11Buffer *Buffer11::EmulatedIndexedStorage::getNativeStorage() ...@@ -1147,8 +1336,8 @@ ID3D11Buffer *Buffer11::EmulatedIndexedStorage::getNativeStorage()
HRESULT result = device->CreateBuffer(&bufferDesc, &subResourceData, &mNativeStorage); HRESULT result = device->CreateBuffer(&bufferDesc, &subResourceData, &mNativeStorage);
if (FAILED(result)) if (FAILED(result))
{ {
ERR("Could not create emulated index data buffer: %08lX", result); return gl::Error(GL_OUT_OF_MEMORY, "Could not create emulated index data buffer: %08lX",
return nullptr; result);
} }
d3d11::SetDebugName(mNativeStorage, "Buffer11::EmulatedIndexedStorage"); d3d11::SetDebugName(mNativeStorage, "Buffer11::EmulatedIndexedStorage");
} }
...@@ -1156,67 +1345,23 @@ ID3D11Buffer *Buffer11::EmulatedIndexedStorage::getNativeStorage() ...@@ -1156,67 +1345,23 @@ ID3D11Buffer *Buffer11::EmulatedIndexedStorage::getNativeStorage()
return mNativeStorage; return mNativeStorage;
} }
bool Buffer11::EmulatedIndexedStorage::update(SourceIndexData *indexInfo, gl::ErrorOrResult<CopyResult> Buffer11::EmulatedIndexedStorage::copyFromStorage(
const TranslatedAttribute *attribute) BufferStorage *source,
size_t sourceOffset,
size_t size,
size_t destOffset)
{ {
// If a change in the indices applied from the last draw call is detected, then the emulated ASSERT(source->isMappable());
// indexed buffer needs to be invalidated. After invalidation, the change detected flag should uint8_t *sourceData = nullptr;
// be cleared to avoid unnecessary recreation of the buffer. gl::Error error = source->map(sourceOffset, size, GL_MAP_READ_BIT, &sourceData);
if (mNativeStorage == nullptr || indexInfo->srcIndicesChanged) if (error.isError())
{ {
SafeRelease(mNativeStorage); return error;
// Copy attribute offset and stride information
mAttributeStride = attribute->stride;
mAttributeOffset = attribute->offset;
// Copy the source index data. This ensures that the lifetime of the indices pointer
// stays with this storage until the next time we invalidate.
size_t indicesDataSize = 0;
switch (indexInfo->srcIndexType)
{
case GL_UNSIGNED_INT:
indicesDataSize = sizeof(GLuint) * indexInfo->srcCount;
break;
case GL_UNSIGNED_SHORT:
indicesDataSize = sizeof(GLushort) * indexInfo->srcCount;
break;
case GL_UNSIGNED_BYTE:
indicesDataSize = sizeof(GLubyte) * indexInfo->srcCount;
break;
default:
indicesDataSize = sizeof(GLushort) * indexInfo->srcCount;
break;
}
if (!mIndicesMemoryBuffer.resize(indicesDataSize))
{
return false;
}
memcpy(mIndicesMemoryBuffer.data(), indexInfo->srcIndices, indicesDataSize);
// Copy the source index data description and update the srcIndices pointer to point
// to our cached index data.
mIndexInfo = *indexInfo;
mIndexInfo.srcIndices = mIndicesMemoryBuffer.data();
indexInfo->srcIndicesChanged = false;
} }
return true;
}
bool Buffer11::EmulatedIndexedStorage::copyFromStorage(BufferStorage *source,
size_t sourceOffset,
size_t size,
size_t destOffset)
{
ASSERT(source->isMappable());
const uint8_t *sourceData = source->map(sourceOffset, size, GL_MAP_READ_BIT);
ASSERT(destOffset + size <= mMemoryBuffer.size()); ASSERT(destOffset + size <= mMemoryBuffer.size());
memcpy(mMemoryBuffer.data() + destOffset, sourceData, size); memcpy(mMemoryBuffer.data() + destOffset, sourceData, size);
source->unmap(); source->unmap();
return true; return CopyResult::RECREATED;
} }
gl::Error Buffer11::EmulatedIndexedStorage::resize(size_t size, bool preserveData) gl::Error Buffer11::EmulatedIndexedStorage::resize(size_t size, bool preserveData)
...@@ -1233,10 +1378,14 @@ gl::Error Buffer11::EmulatedIndexedStorage::resize(size_t size, bool preserveDat ...@@ -1233,10 +1378,14 @@ gl::Error Buffer11::EmulatedIndexedStorage::resize(size_t size, bool preserveDat
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
uint8_t *Buffer11::EmulatedIndexedStorage::map(size_t offset, size_t length, GLbitfield access) gl::Error Buffer11::EmulatedIndexedStorage::map(size_t offset,
size_t length,
GLbitfield access,
uint8_t **mapPointerOut)
{ {
ASSERT(!mMemoryBuffer.empty() && offset + length <= mMemoryBuffer.size()); ASSERT(!mMemoryBuffer.empty() && offset + length <= mMemoryBuffer.size());
return mMemoryBuffer.data() + offset; *mapPointerOut = mMemoryBuffer.data() + offset;
return gl::Error(GL_NO_ERROR);
} }
void Buffer11::EmulatedIndexedStorage::unmap() void Buffer11::EmulatedIndexedStorage::unmap()
...@@ -1253,15 +1402,15 @@ Buffer11::PackStorage::~PackStorage() ...@@ -1253,15 +1402,15 @@ Buffer11::PackStorage::~PackStorage()
{ {
} }
bool Buffer11::PackStorage::copyFromStorage(BufferStorage *source, gl::ErrorOrResult<CopyResult> Buffer11::PackStorage::copyFromStorage(BufferStorage *source,
size_t sourceOffset, size_t sourceOffset,
size_t size, size_t size,
size_t destOffset) size_t destOffset)
{ {
// We copy through a staging buffer when drawing with a pack buffer, // We copy through a staging buffer when drawing with a pack buffer,
// or for other cases where we access the pack buffer // or for other cases where we access the pack buffer
UNREACHABLE(); UNREACHABLE();
return false; return CopyResult::NOT_RECREATED;
} }
gl::Error Buffer11::PackStorage::resize(size_t size, bool preserveData) gl::Error Buffer11::PackStorage::resize(size_t size, bool preserveData)
...@@ -1278,7 +1427,10 @@ gl::Error Buffer11::PackStorage::resize(size_t size, bool preserveData) ...@@ -1278,7 +1427,10 @@ gl::Error Buffer11::PackStorage::resize(size_t size, bool preserveData)
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
uint8_t *Buffer11::PackStorage::map(size_t offset, size_t length, GLbitfield access) gl::Error Buffer11::PackStorage::map(size_t offset,
size_t length,
GLbitfield access,
uint8_t **mapPointerOut)
{ {
ASSERT(offset + length <= getSize()); ASSERT(offset + length <= getSize());
// TODO: fast path // TODO: fast path
...@@ -1289,12 +1441,13 @@ uint8_t *Buffer11::PackStorage::map(size_t offset, size_t length, GLbitfield acc ...@@ -1289,12 +1441,13 @@ uint8_t *Buffer11::PackStorage::map(size_t offset, size_t length, GLbitfield acc
gl::Error error = flushQueuedPackCommand(); gl::Error error = flushQueuedPackCommand();
if (error.isError()) if (error.isError())
{ {
return nullptr; return error;
} }
mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0); mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0);
return mMemoryBuffer.data() + offset; *mapPointerOut = mMemoryBuffer.data() + offset;
return gl::Error(GL_NO_ERROR);
} }
void Buffer11::PackStorage::unmap() void Buffer11::PackStorage::unmap()
...@@ -1389,17 +1542,22 @@ Buffer11::SystemMemoryStorage::SystemMemoryStorage(Renderer11 *renderer) ...@@ -1389,17 +1542,22 @@ Buffer11::SystemMemoryStorage::SystemMemoryStorage(Renderer11 *renderer)
{ {
} }
bool Buffer11::SystemMemoryStorage::copyFromStorage(BufferStorage *source, gl::ErrorOrResult<CopyResult> Buffer11::SystemMemoryStorage::copyFromStorage(BufferStorage *source,
size_t sourceOffset, size_t sourceOffset,
size_t size, size_t size,
size_t destOffset) size_t destOffset)
{ {
ASSERT(source->isMappable()); ASSERT(source->isMappable());
const uint8_t *sourceData = source->map(sourceOffset, size, GL_MAP_READ_BIT); uint8_t *sourceData = nullptr;
gl::Error error = source->map(sourceOffset, size, GL_MAP_READ_BIT, &sourceData);
if (error.isError())
{
return error;
}
ASSERT(destOffset + size <= mSystemCopy.size()); ASSERT(destOffset + size <= mSystemCopy.size());
memcpy(mSystemCopy.data() + destOffset, sourceData, size); memcpy(mSystemCopy.data() + destOffset, sourceData, size);
source->unmap(); source->unmap();
return true; return CopyResult::RECREATED;
} }
gl::Error Buffer11::SystemMemoryStorage::resize(size_t size, bool preserveData) gl::Error Buffer11::SystemMemoryStorage::resize(size_t size, bool preserveData)
...@@ -1416,14 +1574,18 @@ gl::Error Buffer11::SystemMemoryStorage::resize(size_t size, bool preserveData) ...@@ -1416,14 +1574,18 @@ gl::Error Buffer11::SystemMemoryStorage::resize(size_t size, bool preserveData)
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
uint8_t *Buffer11::SystemMemoryStorage::map(size_t offset, size_t length, GLbitfield access) gl::Error Buffer11::SystemMemoryStorage::map(size_t offset,
size_t length,
GLbitfield access,
uint8_t **mapPointerOut)
{ {
ASSERT(!mSystemCopy.empty() && offset + length <= mSystemCopy.size()); ASSERT(!mSystemCopy.empty() && offset + length <= mSystemCopy.size());
return mSystemCopy.data() + offset; *mapPointerOut = mSystemCopy.data() + offset;
return gl::Error(GL_NO_ERROR);
} }
void Buffer11::SystemMemoryStorage::unmap() void Buffer11::SystemMemoryStorage::unmap()
{ {
// No-op // No-op
} }
} } // namespace rx
...@@ -62,11 +62,13 @@ class Buffer11 : public BufferD3D ...@@ -62,11 +62,13 @@ class Buffer11 : public BufferD3D
Buffer11(Renderer11 *renderer); Buffer11(Renderer11 *renderer);
virtual ~Buffer11(); virtual ~Buffer11();
ID3D11Buffer *getBuffer(BufferUsage usage); gl::ErrorOrResult<ID3D11Buffer *> getBuffer(BufferUsage usage);
ID3D11Buffer *getEmulatedIndexedBuffer(SourceIndexData *indexInfo, const TranslatedAttribute *attribute); gl::ErrorOrResult<ID3D11Buffer *> getEmulatedIndexedBuffer(
ID3D11Buffer *getConstantBufferRange(GLintptr offset, GLsizeiptr size); SourceIndexData *indexInfo,
ID3D11ShaderResourceView *getSRV(DXGI_FORMAT srvFormat); const TranslatedAttribute &attribute);
bool isMapped() const { return mMappedStorage != NULL; } gl::ErrorOrResult<ID3D11Buffer *> getConstantBufferRange(GLintptr offset, GLsizeiptr size);
gl::ErrorOrResult<ID3D11ShaderResourceView *> getSRV(DXGI_FORMAT srvFormat);
bool isMapped() const { return mMappedStorage != nullptr; }
gl::Error packPixels(const gl::FramebufferAttachment &readAttachment, gl::Error packPixels(const gl::FramebufferAttachment &readAttachment,
const PackPixelsParams &params); const PackPixelsParams &params);
size_t getTotalCPUBufferMemoryBytes() const; size_t getTotalCPUBufferMemoryBytes() const;
...@@ -83,7 +85,7 @@ class Buffer11 : public BufferD3D ...@@ -83,7 +85,7 @@ class Buffer11 : public BufferD3D
virtual gl::Error map(GLenum access, GLvoid **mapPtr); virtual gl::Error map(GLenum access, GLvoid **mapPtr);
virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr); virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr);
virtual gl::Error unmap(GLboolean *result); virtual gl::Error unmap(GLboolean *result);
virtual void markTransformFeedbackUsage(); virtual gl::Error markTransformFeedbackUsage();
private: private:
class BufferStorage; class BufferStorage;
...@@ -120,20 +122,19 @@ class Buffer11 : public BufferD3D ...@@ -120,20 +122,19 @@ class Buffer11 : public BufferD3D
unsigned int mReadUsageCount; unsigned int mReadUsageCount;
void markBufferUsage(); gl::Error markBufferUsage();
NativeStorage *getStagingStorage(); gl::ErrorOrResult<NativeStorage *> getStagingStorage();
PackStorage *getPackStorage(); gl::ErrorOrResult<PackStorage *> getPackStorage();
gl::Error getSystemMemoryStorage(SystemMemoryStorage **storageOut); gl::ErrorOrResult<SystemMemoryStorage *> getSystemMemoryStorage();
void updateBufferStorage(BufferStorage *storage, size_t sourceOffset, size_t storageSize); gl::Error updateBufferStorage(BufferStorage *storage, size_t sourceOffset, size_t storageSize);
BufferStorage *getBufferStorage(BufferUsage usage); gl::ErrorOrResult<BufferStorage *> getBufferStorage(BufferUsage usage);
BufferStorage *getLatestBufferStorage() const; gl::ErrorOrResult<BufferStorage *> getLatestBufferStorage() const;
BufferStorage *getConstantBufferRangeStorage(GLintptr offset, GLsizeiptr size); gl::ErrorOrResult<BufferStorage *> getConstantBufferRangeStorage(GLintptr offset,
GLsizeiptr size);
void invalidateEmulatedIndexedBuffer();
}; };
} } // namespace rx
#endif // LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_ #endif // LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_
...@@ -293,11 +293,23 @@ gl::Error InputLayoutCache::applyVertexBuffers( ...@@ -293,11 +293,23 @@ gl::Error InputLayoutCache::applyVertexBuffers(
indexInfo->srcIndexData.srcIndices = bufferData + offset; indexInfo->srcIndexData.srcIndices = bufferData + offset;
} }
buffer = bufferStorage->getEmulatedIndexedBuffer(&indexInfo->srcIndexData, &attrib); auto bufferOrError =
bufferStorage->getEmulatedIndexedBuffer(&indexInfo->srcIndexData, attrib);
if (bufferOrError.isError())
{
return bufferOrError.getError();
}
buffer = bufferOrError.getResult();
} }
else else
{ {
buffer = bufferStorage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); auto bufferOrError =
bufferStorage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
if (bufferOrError.isError())
{
return bufferOrError.getError();
}
buffer = bufferOrError.getResult();
} }
vertexStride = attrib.stride; vertexStride = attrib.stride;
......
...@@ -208,18 +208,23 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac ...@@ -208,18 +208,23 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac
DXGI_FORMAT srvFormat = sourceFormatInfo.formatSet->srvFormat; DXGI_FORMAT srvFormat = sourceFormatInfo.formatSet->srvFormat;
ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN); ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN);
Buffer11 *bufferStorage11 = GetAs<Buffer11>(sourceBuffer.getImplementation()); Buffer11 *bufferStorage11 = GetAs<Buffer11>(sourceBuffer.getImplementation());
ID3D11ShaderResourceView *bufferSRV = bufferStorage11->getSRV(srvFormat); auto srvOrError = bufferStorage11->getSRV(srvFormat);
ASSERT(bufferSRV != NULL); if (srvOrError.isError())
{
return srvOrError.getError();
}
ID3D11ShaderResourceView *bufferSRV = srvOrError.getResult();
ASSERT(bufferSRV != nullptr);
ID3D11RenderTargetView *textureRTV = GetAs<RenderTarget11>(destRenderTarget)->getRenderTargetView(); ID3D11RenderTargetView *textureRTV = GetAs<RenderTarget11>(destRenderTarget)->getRenderTargetView();
ASSERT(textureRTV != NULL); ASSERT(textureRTV != nullptr);
CopyShaderParams shaderParams; CopyShaderParams shaderParams;
setBufferToTextureCopyParams(destArea, destSize, sourceFormat, unpack, offset, &shaderParams); setBufferToTextureCopyParams(destArea, destSize, sourceFormat, unpack, offset, &shaderParams);
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
ID3D11Buffer *nullBuffer = NULL; ID3D11Buffer *nullBuffer = nullptr;
UINT zero = 0; UINT zero = 0;
// Are we doing a 2D or 3D copy? // Are we doing a 2D or 3D copy?
......
...@@ -1288,11 +1288,22 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data, ...@@ -1288,11 +1288,22 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data,
if (mRenderer11DeviceCaps.supportsConstantBufferOffsets) if (mRenderer11DeviceCaps.supportsConstantBufferOffsets)
{ {
constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM); auto bufferOrError = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
if (bufferOrError.isError())
{
return bufferOrError.getError();
}
constantBuffer = bufferOrError.getResult();
} }
else else
{ {
constantBuffer = bufferStorage->getConstantBufferRange(uniformBufferOffset, uniformBufferSize); auto bufferOrError =
bufferStorage->getConstantBufferRange(uniformBufferOffset, uniformBufferSize);
if (bufferOrError.isError())
{
return bufferOrError.getError();
}
constantBuffer = bufferOrError.getResult();
} }
if (!constantBuffer) if (!constantBuffer)
...@@ -1349,11 +1360,22 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data, ...@@ -1349,11 +1360,22 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data,
if (mRenderer11DeviceCaps.supportsConstantBufferOffsets) if (mRenderer11DeviceCaps.supportsConstantBufferOffsets)
{ {
constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM); auto bufferOrError = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
if (bufferOrError.isError())
{
return bufferOrError.getError();
}
constantBuffer = bufferOrError.getResult();
} }
else else
{ {
constantBuffer = bufferStorage->getConstantBufferRange(uniformBufferOffset, uniformBufferSize); auto bufferOrError =
bufferStorage->getConstantBufferRange(uniformBufferOffset, uniformBufferSize);
if (bufferOrError.isError())
{
return bufferOrError.getError();
}
constantBuffer = bufferOrError.getResult();
} }
if (!constantBuffer) if (!constantBuffer)
...@@ -1542,7 +1564,12 @@ gl::Error Renderer11::applyIndexBuffer(const gl::Data &data, ...@@ -1542,7 +1564,12 @@ gl::Error Renderer11::applyIndexBuffer(const gl::Data &data,
if (indexInfo->storage) if (indexInfo->storage)
{ {
Buffer11 *storage = GetAs<Buffer11>(indexInfo->storage); Buffer11 *storage = GetAs<Buffer11>(indexInfo->storage);
buffer = storage->getBuffer(BUFFER_USAGE_INDEX); auto indexOrError = storage->getBuffer(BUFFER_USAGE_INDEX);
if (indexOrError.isError())
{
return indexOrError.getError();
}
buffer = indexOrError.getResult();
} }
else else
{ {
...@@ -1564,7 +1591,7 @@ gl::Error Renderer11::applyIndexBuffer(const gl::Data &data, ...@@ -1564,7 +1591,7 @@ gl::Error Renderer11::applyIndexBuffer(const gl::Data &data,
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
void Renderer11::applyTransformFeedbackBuffers(const gl::State &state) gl::Error Renderer11::applyTransformFeedbackBuffers(const gl::State &state)
{ {
size_t numXFBBindings = 0; size_t numXFBBindings = 0;
bool requiresUpdate = false; bool requiresUpdate = false;
...@@ -1579,11 +1606,16 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State &state) ...@@ -1579,11 +1606,16 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State &state)
{ {
const OffsetBindingPointer<gl::Buffer> &binding = transformFeedback->getIndexedBuffer(i); const OffsetBindingPointer<gl::Buffer> &binding = transformFeedback->getIndexedBuffer(i);
ID3D11Buffer *d3dBuffer = NULL; ID3D11Buffer *d3dBuffer = nullptr;
if (binding.get() != nullptr) if (binding.get() != nullptr)
{ {
Buffer11 *storage = GetImplAs<Buffer11>(binding.get()); Buffer11 *storage = GetImplAs<Buffer11>(binding.get());
d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); auto bufferOrError = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
if (bufferOrError.isError())
{
return bufferOrError.getError();
}
d3dBuffer = bufferOrError.getResult();
} }
// TODO: mAppliedTFBuffers and friends should also be kept in a vector. // TODO: mAppliedTFBuffers and friends should also be kept in a vector.
...@@ -1603,7 +1635,12 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State &state) ...@@ -1603,7 +1635,12 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State &state)
if (binding.get() != nullptr) if (binding.get() != nullptr)
{ {
Buffer11 *storage = GetImplAs<Buffer11>(binding.get()); Buffer11 *storage = GetImplAs<Buffer11>(binding.get());
ID3D11Buffer *d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); auto bufferOrError = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
if (bufferOrError.isError())
{
return bufferOrError.getError();
}
ID3D11Buffer *d3dBuffer = bufferOrError.getResult();
mCurrentD3DOffsets[i] = (mAppliedTFBuffers[i] != d3dBuffer || mAppliedTFOffsets[i] != binding.getOffset()) ? mCurrentD3DOffsets[i] = (mAppliedTFBuffers[i] != d3dBuffer || mAppliedTFOffsets[i] != binding.getOffset()) ?
static_cast<UINT>(binding.getOffset()) : -1; static_cast<UINT>(binding.getOffset()) : -1;
...@@ -1611,7 +1648,7 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State &state) ...@@ -1611,7 +1648,7 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State &state)
} }
else else
{ {
mAppliedTFBuffers[i] = NULL; mAppliedTFBuffers[i] = nullptr;
mCurrentD3DOffsets[i] = 0; mCurrentD3DOffsets[i] = 0;
} }
mAppliedTFOffsets[i] = binding.getOffset(); mAppliedTFOffsets[i] = binding.getOffset();
...@@ -1622,6 +1659,8 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State &state) ...@@ -1622,6 +1659,8 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State &state)
mDeviceContext->SOSetTargets(static_cast<unsigned int>(numXFBBindings), mAppliedTFBuffers, mDeviceContext->SOSetTargets(static_cast<unsigned int>(numXFBBindings), mAppliedTFBuffers,
mCurrentD3DOffsets); mCurrentD3DOffsets);
} }
return gl::Error(GL_NO_ERROR);
} }
gl::Error Renderer11::drawArraysImpl(const gl::Data &data, gl::Error Renderer11::drawArraysImpl(const gl::Data &data,
......
...@@ -148,7 +148,7 @@ class Renderer11 : public RendererD3D ...@@ -148,7 +148,7 @@ class Renderer11 : public RendererD3D
GLenum mode, GLenum mode,
GLenum type, GLenum type,
TranslatedIndexData *indexInfo) override; TranslatedIndexData *indexInfo) override;
void applyTransformFeedbackBuffers(const gl::State &state) override; gl::Error applyTransformFeedbackBuffers(const gl::State &state) override;
// lost device // lost device
bool testDeviceLost() override; bool testDeviceLost() override;
......
...@@ -104,9 +104,10 @@ gl::Error Buffer9::unmap(GLboolean *result) ...@@ -104,9 +104,10 @@ gl::Error Buffer9::unmap(GLboolean *result)
return gl::Error(GL_INVALID_OPERATION); return gl::Error(GL_INVALID_OPERATION);
} }
void Buffer9::markTransformFeedbackUsage() gl::Error Buffer9::markTransformFeedbackUsage()
{ {
UNREACHABLE(); UNREACHABLE();
return gl::Error(GL_INVALID_OPERATION);
} }
} } // namespace rx
...@@ -35,13 +35,13 @@ class Buffer9 : public BufferD3D ...@@ -35,13 +35,13 @@ class Buffer9 : public BufferD3D
virtual gl::Error map(GLenum access, GLvoid **mapPtr); virtual gl::Error map(GLenum access, GLvoid **mapPtr);
virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr); virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr);
virtual gl::Error unmap(GLboolean *result); virtual gl::Error unmap(GLboolean *result);
virtual void markTransformFeedbackUsage(); virtual gl::Error markTransformFeedbackUsage();
private: private:
MemoryBuffer mMemory; MemoryBuffer mMemory;
size_t mSize; size_t mSize;
}; };
} } // namespace rx
#endif // LIBANGLE_RENDERER_D3D_D3D9_BUFFER9_H_ #endif // LIBANGLE_RENDERER_D3D_D3D9_BUFFER9_H_
...@@ -1218,9 +1218,10 @@ gl::Error Renderer9::applyIndexBuffer(const gl::Data &data, ...@@ -1218,9 +1218,10 @@ gl::Error Renderer9::applyIndexBuffer(const gl::Data &data,
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
void Renderer9::applyTransformFeedbackBuffers(const gl::State& state) gl::Error Renderer9::applyTransformFeedbackBuffers(const gl::State &state)
{ {
ASSERT(!state.isTransformFeedbackActiveUnpaused()); ASSERT(!state.isTransformFeedbackActiveUnpaused());
return gl::Error(GL_NO_ERROR);
} }
gl::Error Renderer9::drawArraysImpl(const gl::Data &data, gl::Error Renderer9::drawArraysImpl(const gl::Data &data,
......
...@@ -134,7 +134,7 @@ class Renderer9 : public RendererD3D ...@@ -134,7 +134,7 @@ class Renderer9 : public RendererD3D
GLenum type, GLenum type,
TranslatedIndexData *indexInfo) override; TranslatedIndexData *indexInfo) override;
void applyTransformFeedbackBuffers(const gl::State &state) override; gl::Error applyTransformFeedbackBuffers(const gl::State &state) override;
gl::Error clear(const ClearParameters &clearParams, gl::Error clear(const ClearParameters &clearParams,
const gl::FramebufferAttachment *colorBuffer, const gl::FramebufferAttachment *colorBuffer,
......
...@@ -107,9 +107,10 @@ class D3D11EmulatedIndexedBufferTest : public ANGLETest ...@@ -107,9 +107,10 @@ class D3D11EmulatedIndexedBufferTest : public ANGLETest
void emulateAndCompare(rx::SourceIndexData *srcData) void emulateAndCompare(rx::SourceIndexData *srcData)
{ {
ID3D11Buffer* emulatedBuffer = mSourceBuffer->getEmulatedIndexedBuffer(srcData, &mTranslatedAttribute); auto bufferOrError = mSourceBuffer->getEmulatedIndexedBuffer(srcData, mTranslatedAttribute);
ASSERT_FALSE(bufferOrError.isError());
ID3D11Buffer *emulatedBuffer = bufferOrError.getResult();
ASSERT_TRUE(emulatedBuffer != nullptr); ASSERT_TRUE(emulatedBuffer != nullptr);
compareContents(emulatedBuffer); compareContents(emulatedBuffer);
} }
......
...@@ -99,7 +99,7 @@ class MockBufferD3D : public rx::BufferD3D ...@@ -99,7 +99,7 @@ class MockBufferD3D : public rx::BufferD3D
MOCK_METHOD1(unmap, gl::Error(GLboolean *)); MOCK_METHOD1(unmap, gl::Error(GLboolean *));
// BufferD3D // BufferD3D
MOCK_METHOD0(markTransformFeedbackUsage, void()); MOCK_METHOD0(markTransformFeedbackUsage, gl::Error());
// inlined for speed // inlined for speed
bool supportsDirectBinding() const override { return false; } bool supportsDirectBinding() const override { return false; }
......
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