Commit 78a85f2c by Mohan Maiya Committed by Commit Bot

Vulkan: Request device local memory for glBuffer with GL_STATIC* usage

glBuffer objects with GL_STATIC_* usage patterns will now request the storage to be allocated in device local memory. For glBuffer objects with GL_DYNAMIC_* usage patterns we request a host cached memory. Bug: angleproject:4480 Change-Id: I7ca968f5ddfb59e4df3ecd07ae65df2bbf734190 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2102958 Commit-Queue: Mohan Maiya <m.maiya@samsung.com> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com>
parent f98084ed
...@@ -58,6 +58,38 @@ size_t CalculateStagingBufferSize(gl::BufferBinding target, size_t size, size_t ...@@ -58,6 +58,38 @@ size_t CalculateStagingBufferSize(gl::BufferBinding target, size_t size, size_t
return kStagingBufferBaseSize; return kStagingBufferBaseSize;
} }
} }
// Buffers that have a static usage pattern will be allocated in
// device local memory to speed up access to and from the GPU.
// Dynamic usage patterns or that are frequently mapped
// will now request host cached memory to speed up access from the CPU.
ANGLE_INLINE VkMemoryPropertyFlags GetPreferredMemoryType(gl::BufferBinding target,
gl::BufferUsage usage)
{
constexpr VkMemoryPropertyFlags kDeviceLocalFlags =
(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
constexpr VkMemoryPropertyFlags kHostCachedFlags =
(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
if (target == gl::BufferBinding::PixelUnpack)
{
return kHostCachedFlags;
}
switch (usage)
{
case gl::BufferUsage::StaticCopy:
case gl::BufferUsage::StaticDraw:
case gl::BufferUsage::StaticRead:
// For static usage, request a device local memory
return kDeviceLocalFlags;
default:
// For non-static usage, request a host cached memory
return kHostCachedFlags;
}
}
} // namespace } // namespace
// ConversionBuffer implementation. // ConversionBuffer implementation.
...@@ -164,8 +196,7 @@ angle::Result BufferVk::setData(const gl::Context *context, ...@@ -164,8 +196,7 @@ angle::Result BufferVk::setData(const gl::Context *context,
createInfo.pQueueFamilyIndices = nullptr; createInfo.pQueueFamilyIndices = nullptr;
// Assume host visible/coherent memory available. // Assume host visible/coherent memory available.
const VkMemoryPropertyFlags memoryPropertyFlags = VkMemoryPropertyFlags memoryPropertyFlags = GetPreferredMemoryType(target, usage);
(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
ANGLE_TRY(mBuffer.init(contextVk, createInfo, memoryPropertyFlags)); ANGLE_TRY(mBuffer.init(contextVk, createInfo, memoryPropertyFlags));
......
...@@ -351,6 +351,29 @@ angle::Result MemoryProperties::findCompatibleMemoryIndex( ...@@ -351,6 +351,29 @@ angle::Result MemoryProperties::findCompatibleMemoryIndex(
} }
} }
// We did not find a compatible memory type, the Vulkan spec says the following -
// There must be at least one memory type with both the
// VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
// bits set in its propertyFlags
constexpr VkMemoryPropertyFlags fallbackMemoryPropertyFlags =
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
// If the caller wanted a host visible memory, just return the memory index
// with the fallback memory flags.
if (requestedMemoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
{
for (size_t memoryIndex : angle::BitSet32<32>(memoryRequirements.memoryTypeBits))
{
if ((mMemoryProperties.memoryTypes[memoryIndex].propertyFlags &
fallbackMemoryPropertyFlags) == fallbackMemoryPropertyFlags)
{
*memoryPropertyFlagsOut = mMemoryProperties.memoryTypes[memoryIndex].propertyFlags;
*typeIndexOut = static_cast<uint32_t>(memoryIndex);
return angle::Result::Continue;
}
}
}
// TODO(jmadill): Add error message to error. // TODO(jmadill): Add error message to error.
context->handleError(VK_ERROR_INCOMPATIBLE_DRIVER, __FILE__, ANGLE_FUNCTION, __LINE__); context->handleError(VK_ERROR_INCOMPATIBLE_DRIVER, __FILE__, ANGLE_FUNCTION, __LINE__);
return angle::Result::Stop; return angle::Result::Stop;
......
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