diff --git a/src/libANGLE/renderer/vulkan/BufferVk.cpp b/src/libANGLE/renderer/vulkan/BufferVk.cpp index d09b58470ed..4748976cbde 100644 --- a/src/libANGLE/renderer/vulkan/BufferVk.cpp +++ b/src/libANGLE/renderer/vulkan/BufferVk.cpp @@ -673,6 +673,21 @@ angle::Result BufferVk::handleDeviceLocalBufferMap(ContextVk *contextVk, return angle::Result::Continue; } +angle::Result BufferVk::mapHostVisibleBuffer(ContextVk *contextVk, + VkDeviceSize offset, + GLbitfield access, + uint8_t **mapPtr) +{ + ANGLE_TRY(mBuffer.mapWithOffset(contextVk, mapPtr, static_cast(offset))); + + // Invalidate non-coherent for READ case. + if (!mBuffer.isCoherent() && (access & GL_MAP_READ_BIT) != 0) + { + ANGLE_TRY(mBuffer.invalidate(contextVk->getRenderer())); + } + return angle::Result::Continue; +} + angle::Result BufferVk::map(const gl::Context *context, GLenum access, void **mapPtr) { ASSERT(mBuffer.valid()); @@ -773,7 +788,7 @@ angle::Result BufferVk::mapRangeImpl(ContextVk *contextVk, { if (hostVisible) { - return mBuffer.mapWithOffset(contextVk, mapPtrBytes, static_cast(offset)); + return mapHostVisibleBuffer(contextVk, offset, access, mapPtrBytes); } return handleDeviceLocalBufferMap(contextVk, offset, length, mapPtrBytes); } @@ -795,7 +810,7 @@ angle::Result BufferVk::mapRangeImpl(ContextVk *contextVk, } if (hostVisible) { - return mBuffer.mapWithOffset(contextVk, mapPtrBytes, static_cast(offset)); + return mapHostVisibleBuffer(contextVk, offset, access, mapPtrBytes); } return handleDeviceLocalBufferMap(contextVk, offset, length, mapPtrBytes); } @@ -809,7 +824,7 @@ angle::Result BufferVk::mapRangeImpl(ContextVk *contextVk, // Write case, buffer not in use. if (isExternalBuffer() || !isCurrentlyInUse(contextVk->getRenderer())) { - return mBuffer.mapWithOffset(contextVk, mapPtrBytes, static_cast(offset)); + return mapHostVisibleBuffer(contextVk, offset, access, mapPtrBytes); } // Write case, buffer in use. @@ -828,7 +843,7 @@ angle::Result BufferVk::mapRangeImpl(ContextVk *contextVk, { ANGLE_TRY(acquireBufferHelper(contextVk, static_cast(mState.getSize()), BufferUsageType::Dynamic)); - return mBuffer.mapWithOffset(contextVk, mapPtrBytes, static_cast(offset)); + return mapHostVisibleBuffer(contextVk, offset, access, mapPtrBytes); } bool smallMapRange = (length < static_cast(mState.getSize()) / 2); @@ -849,7 +864,7 @@ angle::Result BufferVk::mapRangeImpl(ContextVk *contextVk, // Write case (worst case, buffer in use for write) ANGLE_TRY(mBuffer.waitForIdle(contextVk, "GPU stall due to mapping buffer in use by the GPU", RenderPassClosureReason::BufferInUseWhenSynchronizedMap)); - return mBuffer.mapWithOffset(contextVk, mapPtrBytes, static_cast(offset)); + return mapHostVisibleBuffer(contextVk, offset, access, mapPtrBytes); } angle::Result BufferVk::unmap(const gl::Context *context, GLboolean *result) diff --git a/src/libANGLE/renderer/vulkan/BufferVk.h b/src/libANGLE/renderer/vulkan/BufferVk.h index df7194d9600..2cc41d2ec9a 100644 --- a/src/libANGLE/renderer/vulkan/BufferVk.h +++ b/src/libANGLE/renderer/vulkan/BufferVk.h @@ -263,6 +263,10 @@ class BufferVk : public BufferImpl VkDeviceSize offset, VkDeviceSize size, uint8_t **mapPtr); + angle::Result mapHostVisibleBuffer(ContextVk *contextVk, + VkDeviceSize offset, + GLbitfield access, + uint8_t **mapPtr); angle::Result setDataImpl(ContextVk *contextVk, size_t bufferSize, const BufferDataSource &dataSource,