Commit f5aad063 by Tobin Ehlis Committed by Commit Bot

Avoid flush/invalidate of host-coherent memory

For DynamicBuffer avoid calling vkFlushMappedMemoryRanges() or vkInvalidateMappedMemoryRanges() if the underlying memory is host- coherent. These calls are not required for host-coherent memory and may negatively impact performance. When currently allocating HOST_VISIBLE memory it's possible to also get HOST_COHERENT memory even though it's not explicitly requested. Because of this, the change updates the memory allocaiton interfaces through the stack to pass back the actual allocated memory properties so that it can be checked to see if it's host-coherent. Bug: angleproject:2804 Change-Id: Ife95c4b98115b16d16c087dd72dba7d9661fdb46 Reviewed-on: https://chromium-review.googlesource.com/1234276 Commit-Queue: Tobin Ehlis <tobine@google.com> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent e2d2270a
...@@ -18,7 +18,8 @@ ...@@ -18,7 +18,8 @@
namespace rx namespace rx
{ {
BufferVk::BufferVk(const gl::BufferState &state) : BufferImpl(state) BufferVk::BufferVk(const gl::BufferState &state)
: BufferImpl(state), mAllocatedMemoryPropertyFlags(0)
{ {
} }
...@@ -74,8 +75,9 @@ gl::Error BufferVk::setData(const gl::Context *context, ...@@ -74,8 +75,9 @@ gl::Error BufferVk::setData(const gl::Context *context,
// Assume host vislble/coherent memory available. // Assume host vislble/coherent memory available.
const VkMemoryPropertyFlags memoryPropertyFlags = const VkMemoryPropertyFlags memoryPropertyFlags =
(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
ANGLE_TRY( ANGLE_TRY(vk::AllocateBufferMemory(contextVk, memoryPropertyFlags,
vk::AllocateBufferMemory(contextVk, memoryPropertyFlags, &mBuffer, &mBufferMemory)); &mAllocatedMemoryPropertyFlags, &mBuffer,
&mBufferMemory));
} }
if (data && size > 0) if (data && size > 0)
......
...@@ -70,6 +70,7 @@ class BufferVk : public BufferImpl, public vk::CommandGraphResource ...@@ -70,6 +70,7 @@ class BufferVk : public BufferImpl, public vk::CommandGraphResource
vk::Buffer mBuffer; vk::Buffer mBuffer;
vk::DeviceMemory mBufferMemory; vk::DeviceMemory mBufferMemory;
VkMemoryPropertyFlags mAllocatedMemoryPropertyFlags;
}; };
} // namespace rx } // namespace rx
......
...@@ -436,7 +436,9 @@ angle::Result ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext) ...@@ -436,7 +436,9 @@ angle::Result ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
// Assume host visible/coherent memory available. // Assume host visible/coherent memory available.
VkMemoryPropertyFlags flags = VkMemoryPropertyFlags flags =
(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
ANGLE_TRY(AllocateBufferMemory(contextVk, flags, &mEmptyUniformBlockStorage.buffer, VkMemoryPropertyFlags flagsOut = 0;
ANGLE_TRY(AllocateBufferMemory(contextVk, flags, &flagsOut,
&mEmptyUniformBlockStorage.buffer,
&mEmptyUniformBlockStorage.memory)); &mEmptyUniformBlockStorage.memory));
} }
} }
......
...@@ -82,6 +82,7 @@ VkImageCreateFlags GetImageCreateFlags(gl::TextureType textureType) ...@@ -82,6 +82,7 @@ VkImageCreateFlags GetImageCreateFlags(gl::TextureType textureType)
DynamicBuffer::DynamicBuffer(VkBufferUsageFlags usage, size_t minSize) DynamicBuffer::DynamicBuffer(VkBufferUsageFlags usage, size_t minSize)
: mUsage(usage), : mUsage(usage),
mMinSize(minSize), mMinSize(minSize),
mHostCoherent(false),
mNextAllocationOffset(0), mNextAllocationOffset(0),
mLastFlushOrInvalidateOffset(0), mLastFlushOrInvalidateOffset(0),
mSize(0), mSize(0),
...@@ -137,8 +138,11 @@ angle::Result DynamicBuffer::allocate(Context *context, ...@@ -137,8 +138,11 @@ angle::Result DynamicBuffer::allocate(Context *context,
createInfo.pQueueFamilyIndices = nullptr; createInfo.pQueueFamilyIndices = nullptr;
ANGLE_TRY(mBuffer.init(context, createInfo)); ANGLE_TRY(mBuffer.init(context, createInfo));
ANGLE_TRY( VkMemoryPropertyFlags actualMemoryPropertyFlags = 0;
AllocateBufferMemory(context, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &mBuffer, &mMemory)); ANGLE_TRY(AllocateBufferMemory(context, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
&actualMemoryPropertyFlags, &mBuffer, &mMemory));
mHostCoherent = (VK_MEMORY_PROPERTY_HOST_COHERENT_BIT ==
(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT & actualMemoryPropertyFlags));
ANGLE_TRY(mMemory.map(context, 0, mSize, 0, &mMappedMemory)); ANGLE_TRY(mMemory.map(context, 0, mSize, 0, &mMappedMemory));
mNextAllocationOffset = 0; mNextAllocationOffset = 0;
...@@ -170,7 +174,7 @@ angle::Result DynamicBuffer::allocate(Context *context, ...@@ -170,7 +174,7 @@ angle::Result DynamicBuffer::allocate(Context *context,
angle::Result DynamicBuffer::flush(Context *context) angle::Result DynamicBuffer::flush(Context *context)
{ {
if (mNextAllocationOffset > mLastFlushOrInvalidateOffset) if (!mHostCoherent && (mNextAllocationOffset > mLastFlushOrInvalidateOffset))
{ {
VkMappedMemoryRange range; VkMappedMemoryRange range;
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
...@@ -187,7 +191,7 @@ angle::Result DynamicBuffer::flush(Context *context) ...@@ -187,7 +191,7 @@ angle::Result DynamicBuffer::flush(Context *context)
angle::Result DynamicBuffer::invalidate(Context *context) angle::Result DynamicBuffer::invalidate(Context *context)
{ {
if (mNextAllocationOffset > mLastFlushOrInvalidateOffset) if (!mHostCoherent && (mNextAllocationOffset > mLastFlushOrInvalidateOffset))
{ {
VkMappedMemoryRange range; VkMappedMemoryRange range;
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
......
...@@ -75,6 +75,7 @@ class DynamicBuffer : angle::NonCopyable ...@@ -75,6 +75,7 @@ class DynamicBuffer : angle::NonCopyable
size_t mMinSize; size_t mMinSize;
Buffer mBuffer; Buffer mBuffer;
DeviceMemory mMemory; DeviceMemory mMemory;
bool mHostCoherent;
uint32_t mNextAllocationOffset; uint32_t mNextAllocationOffset;
uint32_t mLastFlushOrInvalidateOffset; uint32_t mLastFlushOrInvalidateOffset;
size_t mSize; size_t mSize;
......
...@@ -94,13 +94,15 @@ bool HasValidationLayers(const std::vector<VkLayerProperties> &layerProps) ...@@ -94,13 +94,15 @@ bool HasValidationLayers(const std::vector<VkLayerProperties> &layerProps)
angle::Result FindAndAllocateCompatibleMemory(vk::Context *context, angle::Result FindAndAllocateCompatibleMemory(vk::Context *context,
const vk::MemoryProperties &memoryProperties, const vk::MemoryProperties &memoryProperties,
VkMemoryPropertyFlags memoryPropertyFlags, VkMemoryPropertyFlags requestedMemoryPropertyFlags,
VkMemoryPropertyFlags *memoryPropertyFlagsOut,
const VkMemoryRequirements &memoryRequirements, const VkMemoryRequirements &memoryRequirements,
vk::DeviceMemory *deviceMemoryOut) vk::DeviceMemory *deviceMemoryOut)
{ {
uint32_t memoryTypeIndex = 0; uint32_t memoryTypeIndex = 0;
ANGLE_TRY(memoryProperties.findCompatibleMemoryIndex(context, memoryRequirements, ANGLE_TRY(memoryProperties.findCompatibleMemoryIndex(context, memoryRequirements,
memoryPropertyFlags, &memoryTypeIndex)); requestedMemoryPropertyFlags,
memoryPropertyFlagsOut, &memoryTypeIndex));
VkMemoryAllocateInfo allocInfo; VkMemoryAllocateInfo allocInfo;
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
...@@ -114,7 +116,8 @@ angle::Result FindAndAllocateCompatibleMemory(vk::Context *context, ...@@ -114,7 +116,8 @@ angle::Result FindAndAllocateCompatibleMemory(vk::Context *context,
template <typename T> template <typename T>
angle::Result AllocateBufferOrImageMemory(vk::Context *context, angle::Result AllocateBufferOrImageMemory(vk::Context *context,
VkMemoryPropertyFlags memoryPropertyFlags, VkMemoryPropertyFlags requestedMemoryPropertyFlags,
VkMemoryPropertyFlags *memoryPropertyFlagsOut,
T *bufferOrImage, T *bufferOrImage,
vk::DeviceMemory *deviceMemoryOut) vk::DeviceMemory *deviceMemoryOut)
{ {
...@@ -124,7 +127,8 @@ angle::Result AllocateBufferOrImageMemory(vk::Context *context, ...@@ -124,7 +127,8 @@ angle::Result AllocateBufferOrImageMemory(vk::Context *context,
VkMemoryRequirements memoryRequirements; VkMemoryRequirements memoryRequirements;
bufferOrImage->getMemoryRequirements(context->getDevice(), &memoryRequirements); bufferOrImage->getMemoryRequirements(context->getDevice(), &memoryRequirements);
ANGLE_TRY(FindAndAllocateCompatibleMemory(context, memoryProperties, memoryPropertyFlags, ANGLE_TRY(FindAndAllocateCompatibleMemory(context, memoryProperties,
requestedMemoryPropertyFlags, memoryPropertyFlagsOut,
memoryRequirements, deviceMemoryOut)); memoryRequirements, deviceMemoryOut));
ANGLE_TRY(bufferOrImage->bindMemory(context, *deviceMemoryOut)); ANGLE_TRY(bufferOrImage->bindMemory(context, *deviceMemoryOut));
...@@ -1000,7 +1004,8 @@ void MemoryProperties::destroy() ...@@ -1000,7 +1004,8 @@ void MemoryProperties::destroy()
angle::Result MemoryProperties::findCompatibleMemoryIndex( angle::Result MemoryProperties::findCompatibleMemoryIndex(
Context *context, Context *context,
const VkMemoryRequirements &memoryRequirements, const VkMemoryRequirements &memoryRequirements,
VkMemoryPropertyFlags memoryPropertyFlags, VkMemoryPropertyFlags requestedMemoryPropertyFlags,
VkMemoryPropertyFlags *memoryPropertyFlagsOut,
uint32_t *typeIndexOut) const uint32_t *typeIndexOut) const
{ {
ASSERT(mMemoryProperties.memoryTypeCount > 0 && mMemoryProperties.memoryTypeCount <= 32); ASSERT(mMemoryProperties.memoryTypeCount > 0 && mMemoryProperties.memoryTypeCount <= 32);
...@@ -1013,9 +1018,10 @@ angle::Result MemoryProperties::findCompatibleMemoryIndex( ...@@ -1013,9 +1018,10 @@ angle::Result MemoryProperties::findCompatibleMemoryIndex(
{ {
ASSERT(memoryIndex < mMemoryProperties.memoryTypeCount); ASSERT(memoryIndex < mMemoryProperties.memoryTypeCount);
if ((mMemoryProperties.memoryTypes[memoryIndex].propertyFlags & memoryPropertyFlags) == if ((mMemoryProperties.memoryTypes[memoryIndex].propertyFlags &
memoryPropertyFlags) requestedMemoryPropertyFlags) == requestedMemoryPropertyFlags)
{ {
*memoryPropertyFlagsOut = mMemoryProperties.memoryTypes[memoryIndex].propertyFlags;
*typeIndexOut = static_cast<uint32_t>(memoryIndex); *typeIndexOut = static_cast<uint32_t>(memoryIndex);
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -1054,7 +1060,8 @@ angle::Result StagingBuffer::init(Context *context, VkDeviceSize size, StagingUs ...@@ -1054,7 +1060,8 @@ angle::Result StagingBuffer::init(Context *context, VkDeviceSize size, StagingUs
(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
ANGLE_TRY(mBuffer.init(context, createInfo)); ANGLE_TRY(mBuffer.init(context, createInfo));
ANGLE_TRY(AllocateBufferMemory(context, flags, &mBuffer, &mDeviceMemory)); VkMemoryPropertyFlags flagsOut = 0;
ANGLE_TRY(AllocateBufferMemory(context, flags, &flagsOut, &mBuffer, &mDeviceMemory));
mSize = static_cast<size_t>(size); mSize = static_cast<size_t>(size);
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -1066,11 +1073,13 @@ void StagingBuffer::dumpResources(Serial serial, std::vector<vk::GarbageObject> ...@@ -1066,11 +1073,13 @@ void StagingBuffer::dumpResources(Serial serial, std::vector<vk::GarbageObject>
} }
angle::Result AllocateBufferMemory(vk::Context *context, angle::Result AllocateBufferMemory(vk::Context *context,
VkMemoryPropertyFlags memoryPropertyFlags, VkMemoryPropertyFlags requestedMemoryPropertyFlags,
VkMemoryPropertyFlags *memoryPropertyFlagsOut,
Buffer *buffer, Buffer *buffer,
DeviceMemory *deviceMemoryOut) DeviceMemory *deviceMemoryOut)
{ {
return AllocateBufferOrImageMemory(context, memoryPropertyFlags, buffer, deviceMemoryOut); return AllocateBufferOrImageMemory(context, requestedMemoryPropertyFlags,
memoryPropertyFlagsOut, buffer, deviceMemoryOut);
} }
angle::Result AllocateImageMemory(vk::Context *context, angle::Result AllocateImageMemory(vk::Context *context,
...@@ -1078,7 +1087,9 @@ angle::Result AllocateImageMemory(vk::Context *context, ...@@ -1078,7 +1087,9 @@ angle::Result AllocateImageMemory(vk::Context *context,
Image *image, Image *image,
DeviceMemory *deviceMemoryOut) DeviceMemory *deviceMemoryOut)
{ {
return AllocateBufferOrImageMemory(context, memoryPropertyFlags, image, deviceMemoryOut); VkMemoryPropertyFlags memoryPropertyFlagsOut = 0;
return AllocateBufferOrImageMemory(context, memoryPropertyFlags, &memoryPropertyFlagsOut, image,
deviceMemoryOut);
} }
angle::Result InitShaderAndSerial(Context *context, angle::Result InitShaderAndSerial(Context *context,
......
...@@ -48,7 +48,7 @@ struct VertexAttribute; ...@@ -48,7 +48,7 @@ struct VertexAttribute;
class VertexBinding; class VertexBinding;
ANGLE_GL_OBJECTS_X(ANGLE_PRE_DECLARE_OBJECT); ANGLE_GL_OBJECTS_X(ANGLE_PRE_DECLARE_OBJECT);
} } // namespace gl
#define ANGLE_PRE_DECLARE_VK_OBJECT(OBJ) class OBJ##Vk; #define ANGLE_PRE_DECLARE_VK_OBJECT(OBJ) class OBJ##Vk;
...@@ -274,7 +274,8 @@ class MemoryProperties final : angle::NonCopyable ...@@ -274,7 +274,8 @@ class MemoryProperties final : angle::NonCopyable
void init(VkPhysicalDevice physicalDevice); void init(VkPhysicalDevice physicalDevice);
angle::Result findCompatibleMemoryIndex(Context *context, angle::Result findCompatibleMemoryIndex(Context *context,
const VkMemoryRequirements &memoryRequirements, const VkMemoryRequirements &memoryRequirements,
VkMemoryPropertyFlags memoryPropertyFlags, VkMemoryPropertyFlags requestedMemoryPropertyFlags,
VkMemoryPropertyFlags *memoryPropertyFlagsOut,
uint32_t *indexOut) const; uint32_t *indexOut) const;
void destroy(); void destroy();
...@@ -654,7 +655,8 @@ class ObjectAndSerial final : angle::NonCopyable ...@@ -654,7 +655,8 @@ class ObjectAndSerial final : angle::NonCopyable
}; };
angle::Result AllocateBufferMemory(vk::Context *context, angle::Result AllocateBufferMemory(vk::Context *context,
VkMemoryPropertyFlags memoryPropertyFlags, VkMemoryPropertyFlags requestedMemoryPropertyFlags,
VkMemoryPropertyFlags *memoryPropertyFlagsOut,
Buffer *buffer, Buffer *buffer,
DeviceMemory *deviceMemoryOut); DeviceMemory *deviceMemoryOut);
......
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