diff --git a/src/vk/header/util.h b/src/vk/header/util.h index 92ffc1a..71ed96b 100644 --- a/src/vk/header/util.h +++ b/src/vk/header/util.h @@ -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); diff --git a/src/vk/vk_buffer.c b/src/vk/vk_buffer.c index b5f9587..88d3912 100644 --- a/src/vk/vk_buffer.c +++ b/src/vk/vk_buffer.c @@ -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 diff --git a/src/vk/vk_image.c b/src/vk/vk_image.c index 9d4e71b..43de3a0 100644 --- a/src/vk/vk_image.c +++ b/src/vk/vk_image.c @@ -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)); diff --git a/src/vk/vk_util.c b/src/vk/vk_util.c index dc71511..49773b7 100644 --- a/src/vk/vk_util.c +++ b/src/vk/vk_util.c @@ -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));