diff --git a/src/modules/graphics/vulkan/Buffer.cpp b/src/modules/graphics/vulkan/Buffer.cpp index 496563da7..e82b6ed0a 100644 --- a/src/modules/graphics/vulkan/Buffer.cpp +++ b/src/modules/graphics/vulkan/Buffer.cpp @@ -102,6 +102,13 @@ bool Buffer::loadVolatile() throw love::Exception("failed to create texel buffer view"); } + VkMemoryPropertyFlags memoryProperties; + vmaGetAllocationMemoryProperties(allocator, allocation, &memoryProperties); + if (memoryProperties & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) + coherent = true; + else + coherent = false; + return true; } @@ -172,6 +179,9 @@ bool Buffer::fill(size_t offset, size_t size, const void *data) { void *dst = (void*)((char*)allocInfo.pMappedData + offset); memcpy(dst, data, size); + + if (!coherent) + vmaFlushAllocation(allocator, allocation, offset, size); } else { @@ -193,6 +203,11 @@ bool Buffer::fill(size_t offset, size_t size, const void *data) memcpy(fillAllocInfo.pMappedData, data, size); + VkMemoryPropertyFlags memoryProperties; + vmaGetAllocationMemoryProperties(allocator, fillAllocation, &memoryProperties); + if (!(memoryProperties & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) + vmaFlushAllocation(allocator, fillAllocation, 0, size); + VkBufferCopy bufferCopy{}; bufferCopy.srcOffset = 0; bufferCopy.dstOffset = offset; @@ -209,13 +224,23 @@ bool Buffer::fill(size_t offset, size_t size, const void *data) void Buffer::unmap(size_t usedoffset, size_t usedsize) { - if (dataUsage != BUFFERDATAUSAGE_READBACK) + if (dataUsage == BUFFERDATAUSAGE_READBACK) + { + if (!coherent) + vmaFlushAllocation(allocator, allocation, usedoffset, usedsize); + } + else { VkBufferCopy bufferCopy{}; bufferCopy.srcOffset = usedoffset - mappedRange.getOffset(); bufferCopy.dstOffset = usedoffset; bufferCopy.size = usedsize; + VkMemoryPropertyFlags memoryProperties; + vmaGetAllocationMemoryProperties(allocator, stagingAllocation, &memoryProperties); + if (!(memoryProperties & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) + vmaFlushAllocation(allocator, stagingAllocation, bufferCopy.srcOffset, usedsize); + vkCmdCopyBuffer(vgfx->getCommandBufferForDataTransfer(), stagingBuffer, buffer, 1, &bufferCopy); vgfx->queueCleanUp([allocator = allocator, stagingBuffer = stagingBuffer, stagingAllocation = stagingAllocation]() { diff --git a/src/modules/graphics/vulkan/Buffer.h b/src/modules/graphics/vulkan/Buffer.h index 809bcd848..1c4fe2cae 100644 --- a/src/modules/graphics/vulkan/Buffer.h +++ b/src/modules/graphics/vulkan/Buffer.h @@ -69,6 +69,7 @@ private: VmaAllocationInfo stagingAllocInfo; BufferUsageFlags usageFlags; Range mappedRange; + bool coherent; }; } // vulkan diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index 454dcfc5e..7630d13a3 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -1557,7 +1557,7 @@ void Graphics::createLogicalDevice() optionalDeviceFeatures.memoryBudget = false; if (optionalDeviceFeatures.spirv14 && !optionalDeviceFeatures.shaderFloatControls) optionalDeviceFeatures.spirv14 = false; - if (optionalDeviceFeatures.spirv14 && vulkanApiVersion < VK_MAKE_API_VERSION(0, 1, 1, 0)) + if (optionalDeviceFeatures.spirv14 && vulkanApiVersion < VK_API_VERSION_1_1) optionalDeviceFeatures.spirv14 = false; VkPhysicalDeviceFeatures deviceFeatures{}; diff --git a/src/modules/graphics/vulkan/StreamBuffer.cpp b/src/modules/graphics/vulkan/StreamBuffer.cpp index 3e87ecdea..3dce085b0 100644 --- a/src/modules/graphics/vulkan/StreamBuffer.cpp +++ b/src/modules/graphics/vulkan/StreamBuffer.cpp @@ -65,6 +65,13 @@ bool StreamBuffer::loadVolatile() if (vmaCreateBuffer(allocator, &bufferInfo, &allocCreateInfo, &buffer, &allocation, &allocInfo) != VK_SUCCESS) throw love::Exception("Cannot create stream buffer: out of graphics memory."); + VkMemoryPropertyFlags properties; + vmaGetAllocationMemoryProperties(allocator, allocation, &properties); + if (properties & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) + coherent = true; + else + coherent = false; + return true; } @@ -99,9 +106,13 @@ love::graphics::StreamBuffer::MapInfo StreamBuffer::map(size_t /*minsize*/) return info; } -size_t StreamBuffer::unmap(size_t /*usedSize*/) +size_t StreamBuffer::unmap(size_t usedSize) { size_t offset = (frameIndex * bufferSize) + frameGPUReadOffset; + + if (!coherent) + vmaFlushAllocation(allocator, allocation, offset, usedSize); + return offset; } diff --git a/src/modules/graphics/vulkan/StreamBuffer.h b/src/modules/graphics/vulkan/StreamBuffer.h index b86548066..6efb95b83 100644 --- a/src/modules/graphics/vulkan/StreamBuffer.h +++ b/src/modules/graphics/vulkan/StreamBuffer.h @@ -62,6 +62,7 @@ private: VmaAllocationInfo allocInfo; VkBuffer buffer = VK_NULL_HANDLE; int frameIndex = 0; + bool coherent; }; diff --git a/src/modules/graphics/vulkan/VulkanWrapper.h b/src/modules/graphics/vulkan/VulkanWrapper.h index 18932e8b2..a1ac0b581 100644 --- a/src/modules/graphics/vulkan/VulkanWrapper.h +++ b/src/modules/graphics/vulkan/VulkanWrapper.h @@ -23,23 +23,6 @@ #define VK_NO_PROTOTYPES #include "libraries/vulkanheaders/vulkan.h" -#ifndef VK_MAKE_API_VERSION -#define VK_MAKE_API_VERSION(variant, major, minor, patch) \ - ((((uint32_t)(variant)) << 29) | (((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch))) -#endif - -#ifndef VK_API_VERSION_MAJOR -#define VK_API_VERSION_MAJOR(version) (((uint32_t)(version) >> 22) & 0x7FU) -#endif - -#ifndef VK_API_VERSION_MINOR -#define VK_API_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3FFU) -#endif - -#ifndef VK_API_VERSION_PATCH -#define VK_API_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU) -#endif - #include "libraries/volk/volk.h" #define VMA_STATIC_VULKAN_FUNCTIONS 0 #define VMA_DYNAMIC_VULKAN_FUNCTIONS 0