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 @@
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,
// Assume host vislble/coherent memory available.
const VkMemoryPropertyFlags memoryPropertyFlags =
(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
ANGLE_TRY(
vk::AllocateBufferMemory(contextVk, memoryPropertyFlags, &mBuffer, &mBufferMemory));
ANGLE_TRY(vk::AllocateBufferMemory(contextVk, memoryPropertyFlags,
&mAllocatedMemoryPropertyFlags, &mBuffer,
&mBufferMemory));
}
if (data && size > 0)
......
......@@ -70,6 +70,7 @@ class BufferVk : public BufferImpl, public vk::CommandGraphResource
vk::Buffer mBuffer;
vk::DeviceMemory mBufferMemory;
VkMemoryPropertyFlags mAllocatedMemoryPropertyFlags;
};
} // namespace rx
......
......@@ -436,7 +436,9 @@ angle::Result ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
// Assume host visible/coherent memory available.
VkMemoryPropertyFlags flags =
(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));
}
}
......
......@@ -82,6 +82,7 @@ VkImageCreateFlags GetImageCreateFlags(gl::TextureType textureType)
DynamicBuffer::DynamicBuffer(VkBufferUsageFlags usage, size_t minSize)
: mUsage(usage),
mMinSize(minSize),
mHostCoherent(false),
mNextAllocationOffset(0),
mLastFlushOrInvalidateOffset(0),
mSize(0),
......@@ -137,8 +138,11 @@ angle::Result DynamicBuffer::allocate(Context *context,
createInfo.pQueueFamilyIndices = nullptr;
ANGLE_TRY(mBuffer.init(context, createInfo));
ANGLE_TRY(
AllocateBufferMemory(context, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &mBuffer, &mMemory));
VkMemoryPropertyFlags actualMemoryPropertyFlags = 0;
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));
mNextAllocationOffset = 0;
......@@ -170,7 +174,7 @@ angle::Result DynamicBuffer::allocate(Context *context,
angle::Result DynamicBuffer::flush(Context *context)
{
if (mNextAllocationOffset > mLastFlushOrInvalidateOffset)
if (!mHostCoherent && (mNextAllocationOffset > mLastFlushOrInvalidateOffset))
{
VkMappedMemoryRange range;
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
......@@ -187,7 +191,7 @@ angle::Result DynamicBuffer::flush(Context *context)
angle::Result DynamicBuffer::invalidate(Context *context)
{
if (mNextAllocationOffset > mLastFlushOrInvalidateOffset)
if (!mHostCoherent && (mNextAllocationOffset > mLastFlushOrInvalidateOffset))
{
VkMappedMemoryRange range;
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
......
......@@ -75,6 +75,7 @@ class DynamicBuffer : angle::NonCopyable
size_t mMinSize;
Buffer mBuffer;
DeviceMemory mMemory;
bool mHostCoherent;
uint32_t mNextAllocationOffset;
uint32_t mLastFlushOrInvalidateOffset;
size_t mSize;
......
......@@ -94,13 +94,15 @@ bool HasValidationLayers(const std::vector<VkLayerProperties> &layerProps)
angle::Result FindAndAllocateCompatibleMemory(vk::Context *context,
const vk::MemoryProperties &memoryProperties,
VkMemoryPropertyFlags memoryPropertyFlags,
VkMemoryPropertyFlags requestedMemoryPropertyFlags,
VkMemoryPropertyFlags *memoryPropertyFlagsOut,
const VkMemoryRequirements &memoryRequirements,
vk::DeviceMemory *deviceMemoryOut)
{
uint32_t memoryTypeIndex = 0;
ANGLE_TRY(memoryProperties.findCompatibleMemoryIndex(context, memoryRequirements,
memoryPropertyFlags, &memoryTypeIndex));
requestedMemoryPropertyFlags,
memoryPropertyFlagsOut, &memoryTypeIndex));
VkMemoryAllocateInfo allocInfo;
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
......@@ -114,7 +116,8 @@ angle::Result FindAndAllocateCompatibleMemory(vk::Context *context,
template <typename T>
angle::Result AllocateBufferOrImageMemory(vk::Context *context,
VkMemoryPropertyFlags memoryPropertyFlags,
VkMemoryPropertyFlags requestedMemoryPropertyFlags,
VkMemoryPropertyFlags *memoryPropertyFlagsOut,
T *bufferOrImage,
vk::DeviceMemory *deviceMemoryOut)
{
......@@ -124,7 +127,8 @@ angle::Result AllocateBufferOrImageMemory(vk::Context *context,
VkMemoryRequirements memoryRequirements;
bufferOrImage->getMemoryRequirements(context->getDevice(), &memoryRequirements);
ANGLE_TRY(FindAndAllocateCompatibleMemory(context, memoryProperties, memoryPropertyFlags,
ANGLE_TRY(FindAndAllocateCompatibleMemory(context, memoryProperties,
requestedMemoryPropertyFlags, memoryPropertyFlagsOut,
memoryRequirements, deviceMemoryOut));
ANGLE_TRY(bufferOrImage->bindMemory(context, *deviceMemoryOut));
......@@ -1000,7 +1004,8 @@ void MemoryProperties::destroy()
angle::Result MemoryProperties::findCompatibleMemoryIndex(
Context *context,
const VkMemoryRequirements &memoryRequirements,
VkMemoryPropertyFlags memoryPropertyFlags,
VkMemoryPropertyFlags requestedMemoryPropertyFlags,
VkMemoryPropertyFlags *memoryPropertyFlagsOut,
uint32_t *typeIndexOut) const
{
ASSERT(mMemoryProperties.memoryTypeCount > 0 && mMemoryProperties.memoryTypeCount <= 32);
......@@ -1013,9 +1018,10 @@ angle::Result MemoryProperties::findCompatibleMemoryIndex(
{
ASSERT(memoryIndex < mMemoryProperties.memoryTypeCount);
if ((mMemoryProperties.memoryTypes[memoryIndex].propertyFlags & memoryPropertyFlags) ==
memoryPropertyFlags)
if ((mMemoryProperties.memoryTypes[memoryIndex].propertyFlags &
requestedMemoryPropertyFlags) == requestedMemoryPropertyFlags)
{
*memoryPropertyFlagsOut = mMemoryProperties.memoryTypes[memoryIndex].propertyFlags;
*typeIndexOut = static_cast<uint32_t>(memoryIndex);
return angle::Result::Continue();
}
......@@ -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);
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);
return angle::Result::Continue();
}
......@@ -1066,11 +1073,13 @@ void StagingBuffer::dumpResources(Serial serial, std::vector<vk::GarbageObject>
}
angle::Result AllocateBufferMemory(vk::Context *context,
VkMemoryPropertyFlags memoryPropertyFlags,
VkMemoryPropertyFlags requestedMemoryPropertyFlags,
VkMemoryPropertyFlags *memoryPropertyFlagsOut,
Buffer *buffer,
DeviceMemory *deviceMemoryOut)
{
return AllocateBufferOrImageMemory(context, memoryPropertyFlags, buffer, deviceMemoryOut);
return AllocateBufferOrImageMemory(context, requestedMemoryPropertyFlags,
memoryPropertyFlagsOut, buffer, deviceMemoryOut);
}
angle::Result AllocateImageMemory(vk::Context *context,
......@@ -1078,7 +1087,9 @@ angle::Result AllocateImageMemory(vk::Context *context,
Image *image,
DeviceMemory *deviceMemoryOut)
{
return AllocateBufferOrImageMemory(context, memoryPropertyFlags, image, deviceMemoryOut);
VkMemoryPropertyFlags memoryPropertyFlagsOut = 0;
return AllocateBufferOrImageMemory(context, memoryPropertyFlags, &memoryPropertyFlagsOut, image,
deviceMemoryOut);
}
angle::Result InitShaderAndSerial(Context *context,
......
......@@ -48,7 +48,7 @@ struct VertexAttribute;
class VertexBinding;
ANGLE_GL_OBJECTS_X(ANGLE_PRE_DECLARE_OBJECT);
}
} // namespace gl
#define ANGLE_PRE_DECLARE_VK_OBJECT(OBJ) class OBJ##Vk;
......@@ -274,7 +274,8 @@ class MemoryProperties final : angle::NonCopyable
void init(VkPhysicalDevice physicalDevice);
angle::Result findCompatibleMemoryIndex(Context *context,
const VkMemoryRequirements &memoryRequirements,
VkMemoryPropertyFlags memoryPropertyFlags,
VkMemoryPropertyFlags requestedMemoryPropertyFlags,
VkMemoryPropertyFlags *memoryPropertyFlagsOut,
uint32_t *indexOut) const;
void destroy();
......@@ -654,7 +655,8 @@ class ObjectAndSerial final : angle::NonCopyable
};
angle::Result AllocateBufferMemory(vk::Context *context,
VkMemoryPropertyFlags memoryPropertyFlags,
VkMemoryPropertyFlags requestedMemoryPropertyFlags,
VkMemoryPropertyFlags *memoryPropertyFlagsOut,
Buffer *buffer,
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