diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 94c4351..6c95d11 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -709,6 +709,7 @@ struct VulkanBuffer uint8_t requireHostVisible; uint8_t preferDeviceLocal; + uint8_t requireHostLocal; SDL_atomic_t referenceCount; /* Tracks command buffer usage */ @@ -2350,6 +2351,7 @@ static uint8_t VULKAN_INTERNAL_FindMemoryType( VulkanRenderer *renderer, uint32_t typeFilter, VkMemoryPropertyFlags requiredProperties, + VkMemoryPropertyFlags ignoredProperties, uint32_t *memoryTypeIndex ) { uint32_t i; @@ -2357,7 +2359,8 @@ static uint8_t VULKAN_INTERNAL_FindMemoryType( for (i = *memoryTypeIndex; i < renderer->memoryProperties.memoryTypeCount; i += 1) { if ( (typeFilter & (1 << i)) && - (renderer->memoryProperties.memoryTypes[i].propertyFlags & requiredProperties) == requiredProperties) + (renderer->memoryProperties.memoryTypes[i].propertyFlags & requiredProperties) == requiredProperties && + (renderer->memoryProperties.memoryTypes[i].propertyFlags & ignoredProperties) == 0 ) { *memoryTypeIndex = i; return 1; @@ -2371,6 +2374,7 @@ static uint8_t VULKAN_INTERNAL_FindBufferMemoryRequirements( VulkanRenderer *renderer, VkBuffer buffer, VkMemoryPropertyFlags requiredMemoryProperties, + VkMemoryPropertyFlags ignoredMemoryProperties, VkMemoryRequirements2KHR *pMemoryRequirements, uint32_t *pMemoryTypeIndex ) { @@ -2390,6 +2394,7 @@ static uint8_t VULKAN_INTERNAL_FindBufferMemoryRequirements( renderer, pMemoryRequirements->memoryRequirements.memoryTypeBits, requiredMemoryProperties, + ignoredMemoryProperties, pMemoryTypeIndex ); } @@ -2417,6 +2422,7 @@ static uint8_t VULKAN_INTERNAL_FindImageMemoryRequirements( renderer, pMemoryRequirements->memoryRequirements.memoryTypeBits, requiredMemoryPropertyFlags, + 0, pMemoryTypeIndex ); } @@ -2925,6 +2931,7 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( VkBuffer buffer, VkDeviceSize size, uint8_t requireHostVisible, + uint8_t requireHostLocal, uint8_t preferDeviceLocal, uint8_t dedicatedAllocation, VulkanMemoryUsedRegion** usedRegion @@ -2932,6 +2939,7 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( uint8_t bindResult = 0; uint32_t memoryTypeIndex = 0; VkMemoryPropertyFlags requiredMemoryPropertyFlags = 0; + VkMemoryPropertyFlags ignoredMemoryPropertyFlags = 0; VkMemoryRequirements2KHR memoryRequirements = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR, @@ -2945,7 +2953,11 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; } - if (preferDeviceLocal) + if (requireHostLocal) + { + ignoredMemoryPropertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + } + else if (preferDeviceLocal) { requiredMemoryPropertyFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; @@ -2955,6 +2967,7 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( renderer, buffer, requiredMemoryPropertyFlags, + ignoredMemoryPropertyFlags, &memoryRequirements, &memoryTypeIndex )) { @@ -2979,7 +2992,7 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( } } - /* Bind failed, try again without preferred flags */ + /* Bind failed, try again with fallback flags */ if (bindResult != 1) { memoryTypeIndex = 0; @@ -2992,6 +3005,11 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; } + if (requireHostLocal) + { + ignoredMemoryPropertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + } + /* Follow-up for the warning logged by FindMemoryType */ if (!renderer->unifiedMemoryWarning) { @@ -3003,6 +3021,7 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForBuffer( renderer, buffer, requiredMemoryPropertyFlags, + ignoredMemoryPropertyFlags, &memoryRequirements, &memoryTypeIndex )) { @@ -4106,6 +4125,7 @@ static VulkanBuffer* VULKAN_INTERNAL_CreateBuffer( VulkanResourceAccessType resourceAccessType, VkBufferUsageFlags usage, uint8_t requireHostVisible, + uint8_t requireHostLocal, uint8_t preferDeviceLocal, uint8_t dedicatedAllocation ) { @@ -4120,6 +4140,7 @@ static VulkanBuffer* VULKAN_INTERNAL_CreateBuffer( buffer->resourceAccessType = resourceAccessType; buffer->usage = usage; buffer->requireHostVisible = requireHostVisible; + buffer->requireHostLocal = requireHostLocal; buffer->preferDeviceLocal = preferDeviceLocal; bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; @@ -4144,6 +4165,7 @@ static VulkanBuffer* VULKAN_INTERNAL_CreateBuffer( buffer->buffer, buffer->size, buffer->requireHostVisible, + buffer->requireHostLocal, buffer->preferDeviceLocal, dedicatedAllocation, &buffer->usedRegion @@ -4235,6 +4257,7 @@ static VulkanUniformBufferObject* VULKAN_INTERNAL_CreateUniformBufferObject( resourceAccessType, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 1, + 0, 1, 1 ); @@ -4290,7 +4313,7 @@ static VulkanUniformBufferObject* VULKAN_INTERNAL_CreateUniformBufferObject( return uniformBufferObject; } -/* Buffer indirection so we can cleanly defrag */ +/* Buffer indirection so we can cleanly defrag GpuBuffers */ static VulkanBufferContainer* VULKAN_INTERNAL_CreateBufferContainer( VulkanRenderer *renderer, uint32_t sizeInBytes, @@ -4309,6 +4332,7 @@ static VulkanBufferContainer* VULKAN_INTERNAL_CreateBufferContainer( resourceAccessType, usageFlags, 0, + 0, 1, 0 ); @@ -6803,6 +6827,7 @@ static Refresh_CpuBuffer* VULKAN_CreateCpuBuffer( RESOURCE_ACCESS_NONE, vulkanUsageFlags, 1, + 1, 0, 1 ); @@ -10134,6 +10159,7 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory( RESOURCE_ACCESS_NONE, currentRegion->vulkanBuffer->usage, currentRegion->vulkanBuffer->requireHostVisible, + currentRegion->vulkanBuffer->requireHostLocal, currentRegion->vulkanBuffer->preferDeviceLocal, 0 );