Add additional logic for skip VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT

Added checks for:
```
Memory types must not have both VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
and VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set.
```
And
```
A memory type with this flag set is only allowed to be bound to a VkImage
whose usage flags include VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT.
```

https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkMemoryPropertyFlagBits.html
This commit is contained in:
Denis Pauk 2022-07-24 00:10:31 +03:00
parent 41057458e4
commit e5f7bf7e82
4 changed files with 41 additions and 15 deletions

View file

@ -49,7 +49,8 @@ typedef struct ImageResource_s {
VkResult buffer_create(BufferResource_t *buf,
VkBufferCreateInfo buf_create_info,
VkMemoryPropertyFlags mem_properties,
VkMemoryPropertyFlags mem_preferences);
VkMemoryPropertyFlags mem_preferences,
VkMemoryPropertyFlags mem_skip);
VkResult buffer_destroy(BufferResource_t *buf);
void buffer_unmap(BufferResource_t *buf);
@ -60,7 +61,8 @@ VkResult buffer_invalidate(BufferResource_t *buf);
VkResult image_create(ImageResource_t *img,
VkImageCreateInfo img_create_info,
VkMemoryPropertyFlags mem_properties,
VkMemoryPropertyFlags mem_preferences);
VkMemoryPropertyFlags mem_preferences,
VkMemoryPropertyFlags mem_skip);
VkResult image_destroy(ImageResource_t *img);
void vulkan_memory_init(void);

View file

@ -99,7 +99,8 @@ QVk_CreateBuffer(VkDeviceSize size, qvkbuffer_t *dstBuffer,
dstBuffer->currentOffset = 0;
return buffer_create(&dstBuffer->resource, bcInfo,
options.reqMemFlags, options.prefMemFlags);
options.reqMemFlags, options.prefMemFlags,
/*skip memory*/ 0);
}
void
@ -136,7 +137,7 @@ QVk_CreateStagingBuffer(VkDeviceSize size, qvkstagingbuffer_t *dstBuffer,
dstBuffer->currentOffset = 0;
return buffer_create(&dstBuffer->resource, bcInfo, reqMemFlags,
prefMemFlags);
prefMemFlags, /*skip memory*/ 0);
}
VkResult

View file

@ -316,6 +316,7 @@ VkResult QVk_CreateImageView(const VkImage *image, VkImageAspectFlags aspectFlag
VkResult QVk_CreateImage(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, qvktexture_t *texture)
{
VkMemoryPropertyFlags mem_skip = 0;
VkImageCreateInfo imageInfo = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.imageType = VK_IMAGE_TYPE_2D,
@ -341,11 +342,17 @@ VkResult QVk_CreateImage(uint32_t width, uint32_t height, VkFormat format, VkIma
imageInfo.pQueueFamilyIndices = queueFamilies;
}
if (!(usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT))
{
mem_skip |= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
}
texture->sharingMode = imageInfo.sharingMode;
return image_create(
&texture->resource, imageInfo,
/*mem_properties*/ 0,
/*mem_preferences*/ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
/*mem_preferences*/ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
/*mem_skip*/ mem_skip);
}
void QVk_CreateDepthBuffer(VkSampleCountFlagBits sampleCount, qvktexture_t *depthBuffer)
@ -517,7 +524,10 @@ void QVk_ReadPixels(uint8_t *dstBuffer, const VkOffset2D *offset, const VkExtent
.pQueueFamilyIndices = NULL,
};
VK_VERIFY(buffer_create(&buff, bcInfo, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_CACHED_BIT));
VK_VERIFY(buffer_create(&buff, bcInfo,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
0));
cmdBuffer = QVk_CreateCommandBuffer(&vk_commandPool[vk_activeBufferIdx], VK_COMMAND_BUFFER_LEVEL_PRIMARY);
VK_VERIFY(QVk_BeginCommand(&cmdBuffer));

View file

@ -49,17 +49,27 @@ static inline uint32_t count_bits_set(uint32_t v)
static uint32_t
get_memory_type(uint32_t mem_req_type_bits,
VkMemoryPropertyFlags mem_prop,
VkMemoryPropertyFlags mem_pref)
VkMemoryPropertyFlags mem_pref,
VkMemoryPropertyFlags mem_skip)
{
uint32_t mem_type_index = VK_MAX_MEMORY_TYPES;
int max_cost = 0;
// update prefered with requiredVK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
// update prefered with required
mem_pref |= mem_prop;
// skip for host visible memory
if (mem_pref & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
{
mem_skip |= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
}
for(uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; i++) {
if(mem_req_type_bits & (1 << i)) {
// This memory type contains mem_prop.
if((vk_device.mem_properties.memoryTypes[i].propertyFlags & mem_prop) == mem_prop)
// This memory type contains mem_prop and no mem_skip
if(
(vk_device.mem_properties.memoryTypes[i].propertyFlags & mem_prop) == mem_prop &&
!(vk_device.mem_properties.memoryTypes[i].propertyFlags & mem_skip)
)
{
#if defined(__APPLE__)
// code has some flags issues with MoltenVK
@ -432,6 +442,7 @@ static VkResult
memory_create_by_property(VkMemoryRequirements* mem_reqs,
VkMemoryPropertyFlags mem_properties,
VkMemoryPropertyFlags mem_preferences,
VkMemoryPropertyFlags mem_skip,
VkDeviceMemory *memory,
VkDeviceSize *offset)
{
@ -439,7 +450,7 @@ memory_create_by_property(VkMemoryRequirements* mem_reqs,
VkMemoryPropertyFlags host_visible;
memory_index = get_memory_type(mem_reqs->memoryTypeBits,
mem_properties, mem_preferences);
mem_properties, mem_preferences, mem_skip);
if (memory_index == VK_MAX_MEMORY_TYPES)
{
@ -460,7 +471,8 @@ VkResult
buffer_create(BufferResource_t *buf,
VkBufferCreateInfo buf_create_info,
VkMemoryPropertyFlags mem_properties,
VkMemoryPropertyFlags mem_preferences)
VkMemoryPropertyFlags mem_preferences,
VkMemoryPropertyFlags mem_skip)
{
assert(buf_create_info.size > 0);
assert(buf);
@ -481,7 +493,7 @@ buffer_create(BufferResource_t *buf,
vkGetBufferMemoryRequirements(vk_device.logical, buf->buffer, &mem_reqs);
result = memory_create_by_property(&mem_reqs, mem_properties, mem_preferences,
&buf->memory, &buf->offset);
mem_skip, &buf->memory, &buf->offset);
if(result != VK_SUCCESS) {
R_Printf(PRINT_ALL, "%s:%d: VkResult verification: %s\n",
__func__, __LINE__, QVk_GetError(result));
@ -514,7 +526,8 @@ VkResult
image_create(ImageResource_t *img,
VkImageCreateInfo img_create_info,
VkMemoryPropertyFlags mem_properties,
VkMemoryPropertyFlags mem_preferences)
VkMemoryPropertyFlags mem_preferences,
VkMemoryPropertyFlags mem_skip)
{
assert(img);
VkResult result = VK_SUCCESS;
@ -532,7 +545,7 @@ image_create(ImageResource_t *img,
img->size = mem_reqs.size;
result = memory_create_by_property(&mem_reqs, mem_properties, mem_preferences,
&img->memory, &img->offset);
mem_skip, &img->memory, &img->offset);
if(result != VK_SUCCESS) {
R_Printf(PRINT_ALL, "%s:%d: VkResult verification: %s\n",
__func__, __LINE__, QVk_GetError(result));