Browse Source

Merge pull request #1858 from nikeinikei/12.0-development

vulkan: minor cleanup
slime73 2 years ago
parent
commit
6c47966b41

+ 1 - 8
.github/workflows/main.yml

@@ -15,8 +15,7 @@ jobs:
                                           libxfixes-dev libxi-dev libxinerama-dev libxxf86vm-dev libxss-dev \
                                           libxfixes-dev libxi-dev libxinerama-dev libxxf86vm-dev libxss-dev \
                                           libgl1-mesa-dev libdbus-1-dev libudev-dev libgles2-mesa-dev \
                                           libgl1-mesa-dev libdbus-1-dev libudev-dev libgles2-mesa-dev \
                                           libegl1-mesa-dev libibus-1.0-dev fcitx-libs-dev libsamplerate0-dev \
                                           libegl1-mesa-dev libibus-1.0-dev fcitx-libs-dev libsamplerate0-dev \
-                                          libsndio-dev libwayland-dev libxkbcommon-dev libdrm-dev libgbm-dev \
-                                          libvulkan-dev
+                                          libsndio-dev libwayland-dev libxkbcommon-dev libdrm-dev libgbm-dev
     - name: Checkout love-appimage-source
     - name: Checkout love-appimage-source
       uses: actions/checkout@v3
       uses: actions/checkout@v3
       with:
       with:
@@ -100,12 +99,6 @@ jobs:
       uses: actions/checkout@v3
       uses: actions/checkout@v3
       with:
       with:
         path: megasource/libs/love
         path: megasource/libs/love
-    - name: Prepare Vulkan SDK
-      uses: humbletim/[email protected]
-      with:
-        vulkan-query-version: 1.3.204.0
-        vulkan-components: Vulkan-Headers, Vulkan-Loader
-        vulkan-use-cache: true
     - name: Download ANGLE
     - name: Download ANGLE
       uses: robinraju/[email protected]
       uses: robinraju/[email protected]
       if: steps.vars.outputs.angle == '1'
       if: steps.vars.outputs.angle == '1'

+ 0 - 2
CMakeLists.txt

@@ -177,7 +177,6 @@ Please see https://github.com/love2d/megasource
 	find_package(Vorbis REQUIRED)
 	find_package(Vorbis REQUIRED)
 	find_package(ZLIB REQUIRED)
 	find_package(ZLIB REQUIRED)
 	find_package(Ogg REQUIRED)
 	find_package(Ogg REQUIRED)
-	find_package(Vulkan REQUIRED)
 
 
 	# required for enet
 	# required for enet
 	add_definitions(-D HAS_SOCKLEN_T)
 	add_definitions(-D HAS_SOCKLEN_T)
@@ -191,7 +190,6 @@ Please see https://github.com/love2d/megasource
 		${MODPLUG_INCLUDE_DIR}
 		${MODPLUG_INCLUDE_DIR}
 		${OGG_INCLUDE_DIR}
 		${OGG_INCLUDE_DIR}
 		${THEORA_INCLUDE_DIR}
 		${THEORA_INCLUDE_DIR}
-		${Vulkan_INCLUDE_DIRS}
 	)
 	)
 
 
 	set(LOVE_LINK_LIBRARIES
 	set(LOVE_LINK_LIBRARIES

+ 15 - 0
license.txt

@@ -142,6 +142,21 @@ This distribution contains code from the following projects (full license text b
 			Copyright © 2013 Mike Gorchak
 			Copyright © 2013 Mike Gorchak
 			Copyright © 2014 Timothy Arceri
 			Copyright © 2014 Timothy Arceri
 
 
+ - Vulkan Memory Allocator
+	Website: https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
+	License: MIT/Expat
+	Copyright (c) 2017-2022 Advanced Micro Devices, Inc.
+
+ - volk
+	Website: https://github.com/zeux/volk
+	License: MIT/Expat
+	Copyright (c) 2018-2022 Arseny Kapoulkine
+
+ - Vulkan-Headers
+	Website: https://github.com/KhronosGroup/Vulkan-Headers
+	License: Apache 2.0
+	Copyright (c) 2022 Khronos Group
+
 License text
 License text
 ============
 ============
 
 

+ 62 - 31
src/modules/graphics/vulkan/Buffer.cpp

@@ -102,6 +102,13 @@ bool Buffer::loadVolatile()
 			throw love::Exception("failed to create texel buffer view");
 			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;
 	return true;
 }
 }
 
 
@@ -141,8 +148,25 @@ ptrdiff_t Buffer::getTexelBufferHandle() const
 
 
 void *Buffer::map(MapType map, size_t offset, size_t size)
 void *Buffer::map(MapType map, size_t offset, size_t size)
 {
 {
+	if (size == 0)
+		return nullptr;
+
+	if (map == MAP_WRITE_INVALIDATE && (isImmutable() || dataUsage == BUFFERDATAUSAGE_READBACK))
+		return nullptr;
+
+	if (map == MAP_READ_ONLY && dataUsage != BUFFERDATAUSAGE_READBACK)
+		return  nullptr;
+
+	mappedRange = Range(offset, size);
+
+	if (!Range(0, getSize()).contains(mappedRange))
+		return nullptr;
+
 	if (dataUsage == BUFFERDATAUSAGE_READBACK)
 	if (dataUsage == BUFFERDATAUSAGE_READBACK)
 	{
 	{
+		if (!coherent)
+			vmaInvalidateAllocation(allocator, allocation, offset, size);
+
 		char *data = (char*)allocInfo.pMappedData;
 		char *data = (char*)allocInfo.pMappedData;
 		return (void*) (data + offset);
 		return (void*) (data + offset);
 	}
 	}
@@ -160,50 +184,52 @@ void *Buffer::map(MapType map, size_t offset, size_t size)
 		if (vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &stagingBuffer, &stagingAllocation, &stagingAllocInfo) != VK_SUCCESS)
 		if (vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &stagingBuffer, &stagingAllocation, &stagingAllocInfo) != VK_SUCCESS)
 			throw love::Exception("failed to create staging buffer");
 			throw love::Exception("failed to create staging buffer");
 
 
-		mappedRange = Range(offset, size);
-
 		return stagingAllocInfo.pMappedData;
 		return stagingAllocInfo.pMappedData;
 	}
 	}
 }
 }
 
 
 bool Buffer::fill(size_t offset, size_t size, const void *data)
 bool Buffer::fill(size_t offset, size_t size, const void *data)
 {
 {
-	if (dataUsage == BUFFERDATAUSAGE_READBACK)
-	{
-		void *dst = (void*)((char*)allocInfo.pMappedData + offset);
-		memcpy(dst, data, size);
-	}
-	else
-	{
-		VkBufferCreateInfo bufferInfo{};
-		bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
-		bufferInfo.size = size;
-		bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
+	if (size == 0 || isImmutable() || dataUsage == BUFFERDATAUSAGE_READBACK)
+		return false;
 
 
-		VmaAllocationCreateInfo allocInfo{};
-		allocInfo.usage = VMA_MEMORY_USAGE_AUTO;
-		allocInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT;
+	if (!Range(0, getSize()).contains(Range(offset, size)))
+		return false;
 
 
-		VkBuffer fillBuffer;
-		VmaAllocation fillAllocation;
-		VmaAllocationInfo fillAllocInfo;
+	VkBufferCreateInfo bufferInfo{};
+	bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+	bufferInfo.size = size;
+	bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
 
 
-		if (vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &fillBuffer, &fillAllocation, &fillAllocInfo) != VK_SUCCESS)
-			throw love::Exception("failed to create fill buffer");
+	VmaAllocationCreateInfo allocInfo{};
+	allocInfo.usage = VMA_MEMORY_USAGE_AUTO;
+	allocInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT;
 
 
-		memcpy(fillAllocInfo.pMappedData, data, size);
+	VkBuffer fillBuffer;
+	VmaAllocation fillAllocation;
+	VmaAllocationInfo fillAllocInfo;
 
 
-		VkBufferCopy bufferCopy{};
-		bufferCopy.srcOffset = 0;
-		bufferCopy.dstOffset = offset;
-		bufferCopy.size = size;
+	if (vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &fillBuffer, &fillAllocation, &fillAllocInfo) != VK_SUCCESS)
+		throw love::Exception("failed to create fill buffer");
 
 
-		vkCmdCopyBuffer(vgfx->getCommandBufferForDataTransfer(), fillBuffer, buffer, 1, &bufferCopy);
+	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;
+	bufferCopy.size = size;
+
+	vkCmdCopyBuffer(vgfx->getCommandBufferForDataTransfer(), fillBuffer, buffer, 1, &bufferCopy);
+
+	vgfx->queueCleanUp([allocator = allocator, fillBuffer = fillBuffer, fillAllocation = fillAllocation]() {
+		vmaDestroyBuffer(allocator, fillBuffer, fillAllocation);
+	});
 
 
-		vgfx->queueCleanUp([allocator = allocator, fillBuffer = fillBuffer, fillAllocation = fillAllocation]() {
-			vmaDestroyBuffer(allocator, fillBuffer, fillAllocation);
-		});
-	}
 	return true;
 	return true;
 }
 }
 
 
@@ -216,6 +242,11 @@ void Buffer::unmap(size_t usedoffset, size_t usedsize)
 		bufferCopy.dstOffset = usedoffset;
 		bufferCopy.dstOffset = usedoffset;
 		bufferCopy.size = usedsize;
 		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);
 		vkCmdCopyBuffer(vgfx->getCommandBufferForDataTransfer(), stagingBuffer, buffer, 1, &bufferCopy);
 
 
 		vgfx->queueCleanUp([allocator = allocator, stagingBuffer = stagingBuffer, stagingAllocation = stagingAllocation]() {
 		vgfx->queueCleanUp([allocator = allocator, stagingBuffer = stagingBuffer, stagingAllocation = stagingAllocation]() {

+ 1 - 0
src/modules/graphics/vulkan/Buffer.h

@@ -69,6 +69,7 @@ private:
 	VmaAllocationInfo stagingAllocInfo;
 	VmaAllocationInfo stagingAllocInfo;
 	BufferUsageFlags usageFlags;
 	BufferUsageFlags usageFlags;
 	Range mappedRange;
 	Range mappedRange;
+	bool coherent;
 };
 };
 
 
 } // vulkan
 } // vulkan

+ 17 - 93
src/modules/graphics/vulkan/Graphics.cpp

@@ -34,7 +34,6 @@
 #include <vector>
 #include <vector>
 #include <cstring>
 #include <cstring>
 #include <set>
 #include <set>
-#include <fstream>
 #include <sstream>
 #include <sstream>
 #include <array>
 #include <array>
 
 
@@ -83,7 +82,7 @@ Graphics::Graphics()
 
 
 	volkInitializeCustom((PFN_vkGetInstanceProcAddr)SDL_Vulkan_GetVkGetInstanceProcAddr());
 	volkInitializeCustom((PFN_vkGetInstanceProcAddr)SDL_Vulkan_GetVkGetInstanceProcAddr());
 
 
-	vulkanApiVersion = Vulkan::getSupportedVulkanApiVersion(volkGetInstanceVersion());
+	instanceVersion = volkGetInstanceVersion();
 }
 }
 
 
 Graphics::~Graphics()
 Graphics::~Graphics()
@@ -92,13 +91,6 @@ Graphics::~Graphics()
 	defaultTexture.set(nullptr);
 	defaultTexture.set(nullptr);
 
 
 	SDL_Vulkan_UnloadLibrary();
 	SDL_Vulkan_UnloadLibrary();
-
-	// We already cleaned those up by clearing out batchedDrawBuffers.
-	// We set them to nullptr here so the base class doesn't crash
-	// when it tries to free this.
-	batchedDrawState.vb[0] = nullptr;
-	batchedDrawState.vb[1] = nullptr;
-	batchedDrawState.indexBuffer = nullptr;
 }
 }
 
 
 // START OVERRIDEN FUNCTIONS
 // START OVERRIDEN FUNCTIONS
@@ -293,17 +285,6 @@ void Graphics::submitGpuCommands(bool present, void *screenshotCallbackData)
 				VK_IMAGE_LAYOUT_UNDEFINED,
 				VK_IMAGE_LAYOUT_UNDEFINED,
 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
 
 
-			VkImageCopy imageCopy{};
-			imageCopy.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
-			imageCopy.srcSubresource.layerCount = 1;
-			imageCopy.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
-			imageCopy.dstSubresource.layerCount = 1;
-			imageCopy.extent = {
-				swapChainExtent.width,
-				swapChainExtent.height,
-				1
-			};
-
 			VkImageBlit blit{};
 			VkImageBlit blit{};
 			blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
 			blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
 			blit.srcSubresource.layerCount = 1;
 			blit.srcSubresource.layerCount = 1;
@@ -652,12 +633,10 @@ void Graphics::setFrontFaceWinding(Winding winding)
 
 
 	states.back().winding = winding;
 	states.back().winding = winding;
 
 
-#ifdef VK_EXT_extended_dynamic_state
 	if (optionalDeviceFeatures.extendedDynamicState)
 	if (optionalDeviceFeatures.extendedDynamicState)
 		vkCmdSetFrontFaceEXT(
 		vkCmdSetFrontFaceEXT(
 			commandBuffers.at(currentFrame),
 			commandBuffers.at(currentFrame),
 			Vulkan::getFrontFace(winding));
 			Vulkan::getFrontFace(winding));
-#endif
 }
 }
 
 
 void Graphics::setColorMask(ColorChannelMask mask)
 void Graphics::setColorMask(ColorChannelMask mask)
@@ -895,14 +874,12 @@ void Graphics::setStencilMode(StencilAction action, CompareMode compare, int val
 	vkCmdSetStencilCompareMask(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, readmask);
 	vkCmdSetStencilCompareMask(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, readmask);
 	vkCmdSetStencilReference(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, value);
 	vkCmdSetStencilReference(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, value);
 
 
-#ifdef VK_EXT_extended_dynamic_state
 	if (optionalDeviceFeatures.extendedDynamicState)
 	if (optionalDeviceFeatures.extendedDynamicState)
 		vkCmdSetStencilOpEXT(
 		vkCmdSetStencilOpEXT(
 			commandBuffers.at(currentFrame),
 			commandBuffers.at(currentFrame),
 			VK_STENCIL_FRONT_AND_BACK,
 			VK_STENCIL_FRONT_AND_BACK,
 			VK_STENCIL_OP_KEEP, Vulkan::getStencilOp(action),
 			VK_STENCIL_OP_KEEP, Vulkan::getStencilOp(action),
 			VK_STENCIL_OP_KEEP, Vulkan::getCompareOp(getReversedCompareMode(compare)));
 			VK_STENCIL_OP_KEEP, Vulkan::getCompareOp(getReversedCompareMode(compare)));
-#endif
 
 
 	states.back().stencil.action = action;
 	states.back().stencil.action = action;
 	states.back().stencil.compare = compare;
 	states.back().stencil.compare = compare;
@@ -915,7 +892,6 @@ void Graphics::setDepthMode(CompareMode compare, bool write)
 {
 {
 	flushBatchedDraws();
 	flushBatchedDraws();
 
 
-#ifdef VK_EXT_extended_dynamic_state
 	if (optionalDeviceFeatures.extendedDynamicState)
 	if (optionalDeviceFeatures.extendedDynamicState)
 	{
 	{
 		vkCmdSetDepthCompareOpEXT(
 		vkCmdSetDepthCompareOpEXT(
@@ -924,7 +900,6 @@ void Graphics::setDepthMode(CompareMode compare, bool write)
 		vkCmdSetDepthWriteEnableEXT(
 		vkCmdSetDepthWriteEnableEXT(
 			commandBuffers.at(currentFrame), Vulkan::getBool(write));
 			commandBuffers.at(currentFrame), Vulkan::getBool(write));
 	}
 	}
-#endif
 
 
 	states.back().depthTest = compare;
 	states.back().depthTest = compare;
 	states.back().depthWrite = write;
 	states.back().depthWrite = write;
@@ -1102,7 +1077,6 @@ void Graphics::initDynamicState()
 	vkCmdSetStencilCompareMask(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, states.back().stencil.readMask);
 	vkCmdSetStencilCompareMask(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, states.back().stencil.readMask);
 	vkCmdSetStencilReference(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, states.back().stencil.value);
 	vkCmdSetStencilReference(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, states.back().stencil.value);
 
 
-#ifdef VK_EXT_extended_dynamic_state
 	if (optionalDeviceFeatures.extendedDynamicState)
 	if (optionalDeviceFeatures.extendedDynamicState)
 	{
 	{
 		 vkCmdSetStencilOpEXT(
 		 vkCmdSetStencilOpEXT(
@@ -1120,7 +1094,6 @@ void Graphics::initDynamicState()
 		vkCmdSetFrontFaceEXT(
 		vkCmdSetFrontFaceEXT(
 			commandBuffers.at(currentFrame), Vulkan::getFrontFace(states.back().winding));
 			commandBuffers.at(currentFrame), Vulkan::getFrontFace(states.back().winding));
 	}
 	}
-#endif
 }
 }
 
 
 void Graphics::beginFrame()
 void Graphics::beginFrame()
@@ -1306,10 +1279,8 @@ static void checkOptionalInstanceExtensions(OptionalInstanceExtensions &ext)
 
 
 	for (const auto &extension : extensions)
 	for (const auto &extension : extensions)
 	{
 	{
-#ifdef VK_KHR_get_physical_device_properties2
 		if (strcmp(extension.extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0)
 		if (strcmp(extension.extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0)
 			ext.physicalDeviceProperties2 = true;
 			ext.physicalDeviceProperties2 = true;
-#endif
 	}
 	}
 }
 }
 
 
@@ -1324,7 +1295,7 @@ void Graphics::createVulkanInstance()
 	appInfo.applicationVersion = VK_MAKE_API_VERSION(0, 1, 0, 0);	// get this version from somewhere else?
 	appInfo.applicationVersion = VK_MAKE_API_VERSION(0, 1, 0, 0);	// get this version from somewhere else?
 	appInfo.pEngineName = "LOVE Game Framework";
 	appInfo.pEngineName = "LOVE Game Framework";
 	appInfo.engineVersion = VK_MAKE_API_VERSION(0, VERSION_MAJOR, VERSION_MINOR, VERSION_REV);
 	appInfo.engineVersion = VK_MAKE_API_VERSION(0, VERSION_MAJOR, VERSION_MINOR, VERSION_REV);
-	appInfo.apiVersion = vulkanApiVersion;
+	appInfo.apiVersion = instanceVersion;
 
 
 	VkInstanceCreateInfo createInfo{};
 	VkInstanceCreateInfo createInfo{};
 	createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
 	createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
@@ -1342,10 +1313,8 @@ void Graphics::createVulkanInstance()
 
 
 	checkOptionalInstanceExtensions(optionalInstanceExtensions);
 	checkOptionalInstanceExtensions(optionalInstanceExtensions);
 
 
-#ifdef VK_KHR_get_physical_device_properties2
 	if (optionalInstanceExtensions.physicalDeviceProperties2)
 	if (optionalInstanceExtensions.physicalDeviceProperties2)
 		extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
 		extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
-#endif
 
 
 	size_t additional_extension_count = extensions.size();
 	size_t additional_extension_count = extensions.size();
 	extensions.resize(additional_extension_count + count);
 	extensions.resize(additional_extension_count + count);
@@ -1361,11 +1330,6 @@ void Graphics::createVulkanInstance()
 		createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
 		createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
 		createInfo.ppEnabledLayerNames = validationLayers.data();
 		createInfo.ppEnabledLayerNames = validationLayers.data();
 	}
 	}
-	else
-	{
-		createInfo.enabledLayerCount = 0;
-		createInfo.ppEnabledLayerNames = nullptr;
-	}
 
 
 	if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS)
 	if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS)
 		throw love::Exception("couldn't create vulkan instance");
 		throw love::Exception("couldn't create vulkan instance");
@@ -1385,12 +1349,14 @@ bool Graphics::checkValidationSupport()
 	{
 	{
 		bool layerFound = false;
 		bool layerFound = false;
 
 
-		for (const auto &layerProperties : availableLayers)
+		for (const auto& layerProperties : availableLayers)
+		{
 			if (strcmp(layerName, layerProperties.layerName) == 0)
 			if (strcmp(layerName, layerProperties.layerName) == 0)
 			{
 			{
 				layerFound = true;
 				layerFound = true;
 				break;
 				break;
 			}
 			}
+		}
 
 
 		if (!layerFound)
 		if (!layerFound)
 			return false;
 			return false;
@@ -1426,6 +1392,7 @@ void Graphics::pickPhysicalDevice()
 	VkPhysicalDeviceProperties properties;
 	VkPhysicalDeviceProperties properties;
 	vkGetPhysicalDeviceProperties(physicalDevice, &properties);
 	vkGetPhysicalDeviceProperties(physicalDevice, &properties);
 	minUniformBufferOffsetAlignment = properties.limits.minUniformBufferOffsetAlignment;
 	minUniformBufferOffsetAlignment = properties.limits.minUniformBufferOffsetAlignment;
+	deviceApiVersion = properties.apiVersion;
 
 
 	msaaSamples = getMsaaCount(requestedMsaa);
 	msaaSamples = getMsaaCount(requestedMsaa);
 }
 }
@@ -1535,34 +1502,20 @@ static void findOptionalDeviceExtensions(VkPhysicalDevice physicalDevice, Option
 
 
 	for (const auto &extension : availableExtensions)
 	for (const auto &extension : availableExtensions)
 	{
 	{
-#ifdef VK_EXT_extended_dynamic_state
 		if (strcmp(extension.extensionName, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME) == 0)
 		if (strcmp(extension.extensionName, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME) == 0)
 			optionalDeviceFeatures.extendedDynamicState = true;
 			optionalDeviceFeatures.extendedDynamicState = true;
-#endif
-#ifdef VK_KHR_get_memory_requirements2
 		if (strcmp(extension.extensionName, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME) == 0)
 		if (strcmp(extension.extensionName, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME) == 0)
 			optionalDeviceFeatures.memoryRequirements2 = true;
 			optionalDeviceFeatures.memoryRequirements2 = true;
-#endif
-#ifdef VK_KHR_dedicated_allocation
 		if (strcmp(extension.extensionName, VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME) == 0)
 		if (strcmp(extension.extensionName, VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME) == 0)
 			optionalDeviceFeatures.dedicatedAllocation = true;
 			optionalDeviceFeatures.dedicatedAllocation = true;
-#endif
-#ifdef VK_KHR_buffer_device_address
 		if (strcmp(extension.extensionName, VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME) == 0)
 		if (strcmp(extension.extensionName, VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME) == 0)
 			optionalDeviceFeatures.bufferDeviceAddress = true;
 			optionalDeviceFeatures.bufferDeviceAddress = true;
-#endif
-#ifdef VK_EXT_memory_budget
 		if (strcmp(extension.extensionName, VK_EXT_MEMORY_BUDGET_EXTENSION_NAME) == 0)
 		if (strcmp(extension.extensionName, VK_EXT_MEMORY_BUDGET_EXTENSION_NAME) == 0)
 			optionalDeviceFeatures.memoryBudget = true;
 			optionalDeviceFeatures.memoryBudget = true;
-#endif
-#ifdef VK_KHR_shader_float_controls
 		if (strcmp(extension.extensionName, VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME) == 0)
 		if (strcmp(extension.extensionName, VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME) == 0)
 			optionalDeviceFeatures.shaderFloatControls = true;
 			optionalDeviceFeatures.shaderFloatControls = true;
-#endif
-#ifdef VK_KHR_spirv_1_4
 		if (strcmp(extension.extensionName, VK_KHR_SPIRV_1_4_EXTENSION_NAME) == 0)
 		if (strcmp(extension.extensionName, VK_KHR_SPIRV_1_4_EXTENSION_NAME) == 0)
 			optionalDeviceFeatures.spirv14 = true;
 			optionalDeviceFeatures.spirv14 = true;
-#endif
 	}
 	}
 }
 }
 
 
@@ -1601,7 +1554,7 @@ void Graphics::createLogicalDevice()
 		optionalDeviceFeatures.memoryBudget = false;
 		optionalDeviceFeatures.memoryBudget = false;
 	if (optionalDeviceFeatures.spirv14 && !optionalDeviceFeatures.shaderFloatControls)
 	if (optionalDeviceFeatures.spirv14 && !optionalDeviceFeatures.shaderFloatControls)
 		optionalDeviceFeatures.spirv14 = false;
 		optionalDeviceFeatures.spirv14 = false;
-	if (optionalDeviceFeatures.spirv14 && vulkanApiVersion < VK_MAKE_API_VERSION(0, 1, 1, 0))
+	if (optionalDeviceFeatures.spirv14 && deviceApiVersion < VK_API_VERSION_1_1)
 		optionalDeviceFeatures.spirv14 = false;
 		optionalDeviceFeatures.spirv14 = false;
 
 
 	VkPhysicalDeviceFeatures deviceFeatures{};
 	VkPhysicalDeviceFeatures deviceFeatures{};
@@ -1615,38 +1568,22 @@ void Graphics::createLogicalDevice()
 	createInfo.pEnabledFeatures = &deviceFeatures;
 	createInfo.pEnabledFeatures = &deviceFeatures;
 
 
 	std::vector<const char*> enabledExtensions(deviceExtensions.begin(), deviceExtensions.end());
 	std::vector<const char*> enabledExtensions(deviceExtensions.begin(), deviceExtensions.end());
-#ifdef VK_EXT_extended_dynamic_state
 	if (optionalDeviceFeatures.extendedDynamicState)
 	if (optionalDeviceFeatures.extendedDynamicState)
 		enabledExtensions.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
 		enabledExtensions.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
-#endif
-#ifdef VK_KHR_get_memory_requirements2
 	if (optionalDeviceFeatures.memoryRequirements2)
 	if (optionalDeviceFeatures.memoryRequirements2)
 		enabledExtensions.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
 		enabledExtensions.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
-#endif
-#ifdef VK_KHR_dedicated_allocation
 	if (optionalDeviceFeatures.dedicatedAllocation)
 	if (optionalDeviceFeatures.dedicatedAllocation)
 		enabledExtensions.push_back(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
 		enabledExtensions.push_back(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
-#endif
-#ifdef VK_KHR_buffer_device_address
 	if (optionalDeviceFeatures.bufferDeviceAddress)
 	if (optionalDeviceFeatures.bufferDeviceAddress)
 		enabledExtensions.push_back(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
 		enabledExtensions.push_back(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
-#endif
-#ifdef VK_EXT_memory_budget
 	if (optionalDeviceFeatures.memoryBudget)
 	if (optionalDeviceFeatures.memoryBudget)
 		enabledExtensions.push_back(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME);
 		enabledExtensions.push_back(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME);
-#endif
-#ifdef VK_KHR_shader_float_controls
 	if (optionalDeviceFeatures.shaderFloatControls)
 	if (optionalDeviceFeatures.shaderFloatControls)
 		enabledExtensions.push_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
 		enabledExtensions.push_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
-#endif
-#ifdef VK_KHR_spirv_1_4
 	if (optionalDeviceFeatures.spirv14)
 	if (optionalDeviceFeatures.spirv14)
 		enabledExtensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME);
 		enabledExtensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME);
-#endif
-#ifdef VK_KHR_bind_memory2
-	if (vulkanApiVersion >= VK_API_VERSION_1_1)
+	if (deviceApiVersion >= VK_API_VERSION_1_1)
 		enabledExtensions.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
 		enabledExtensions.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
-#endif
 
 
 	createInfo.enabledExtensionCount = static_cast<uint32_t>(enabledExtensions.size());
 	createInfo.enabledExtensionCount = static_cast<uint32_t>(enabledExtensions.size());
 	createInfo.ppEnabledExtensionNames = enabledExtensions.data();
 	createInfo.ppEnabledExtensionNames = enabledExtensions.data();
@@ -1656,17 +1593,13 @@ void Graphics::createLogicalDevice()
 		createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
 		createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
 		createInfo.ppEnabledLayerNames = validationLayers.data();
 		createInfo.ppEnabledLayerNames = validationLayers.data();
 	}
 	}
-	else
-		createInfo.enabledLayerCount = 0;
 
 
-#ifdef VK_EXT_extended_dynamic_state
 	VkPhysicalDeviceExtendedDynamicStateFeaturesEXT extendedDynamicStateFeatures{};
 	VkPhysicalDeviceExtendedDynamicStateFeaturesEXT extendedDynamicStateFeatures{};
 	extendedDynamicStateFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT;
 	extendedDynamicStateFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT;
 	extendedDynamicStateFeatures.extendedDynamicState = Vulkan::getBool(optionalDeviceFeatures.extendedDynamicState);
 	extendedDynamicStateFeatures.extendedDynamicState = Vulkan::getBool(optionalDeviceFeatures.extendedDynamicState);
 	extendedDynamicStateFeatures.pNext = nullptr;
 	extendedDynamicStateFeatures.pNext = nullptr;
 
 
 	createInfo.pNext = &extendedDynamicStateFeatures;
 	createInfo.pNext = &extendedDynamicStateFeatures;
-#endif
 
 
 	if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS)
 	if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS)
 		throw love::Exception("failed to create logical device");
 		throw love::Exception("failed to create logical device");
@@ -1680,7 +1613,7 @@ void Graphics::createLogicalDevice()
 void Graphics::initVMA()
 void Graphics::initVMA()
 {
 {
 	VmaAllocatorCreateInfo allocatorCreateInfo = {};
 	VmaAllocatorCreateInfo allocatorCreateInfo = {};
-	allocatorCreateInfo.vulkanApiVersion = vulkanApiVersion;
+	allocatorCreateInfo.vulkanApiVersion = deviceApiVersion;
 	allocatorCreateInfo.physicalDevice = physicalDevice;
 	allocatorCreateInfo.physicalDevice = physicalDevice;
 	allocatorCreateInfo.device = device;
 	allocatorCreateInfo.device = device;
 	allocatorCreateInfo.instance = instance;
 	allocatorCreateInfo.instance = instance;
@@ -1707,22 +1640,13 @@ void Graphics::initVMA()
 	vulkanFunctions.vkDestroyImage = vkDestroyImage;
 	vulkanFunctions.vkDestroyImage = vkDestroyImage;
 	vulkanFunctions.vkCmdCopyBuffer = vkCmdCopyBuffer;
 	vulkanFunctions.vkCmdCopyBuffer = vkCmdCopyBuffer;
 
 
-#ifdef VK_KHR_get_memory_requirements2
 	vulkanFunctions.vkGetBufferMemoryRequirements2KHR = vkGetBufferMemoryRequirements2KHR;
 	vulkanFunctions.vkGetBufferMemoryRequirements2KHR = vkGetBufferMemoryRequirements2KHR;
 	vulkanFunctions.vkGetImageMemoryRequirements2KHR = vkGetImageMemoryRequirements2KHR;
 	vulkanFunctions.vkGetImageMemoryRequirements2KHR = vkGetImageMemoryRequirements2KHR;
-#endif
-#ifdef VK_KHR_bind_memory2
 	vulkanFunctions.vkBindBufferMemory2KHR = vkBindBufferMemory2KHR;
 	vulkanFunctions.vkBindBufferMemory2KHR = vkBindBufferMemory2KHR;
 	vulkanFunctions.vkBindImageMemory2KHR = vkBindImageMemory2KHR;
 	vulkanFunctions.vkBindImageMemory2KHR = vkBindImageMemory2KHR;
-#endif
-#ifdef VK_KHR_get_physical_device_properties2
 	vulkanFunctions.vkGetPhysicalDeviceMemoryProperties2KHR = vkGetPhysicalDeviceMemoryProperties2KHR;
 	vulkanFunctions.vkGetPhysicalDeviceMemoryProperties2KHR = vkGetPhysicalDeviceMemoryProperties2KHR;
-#endif
-
-#ifdef VK_KHR_maintenance4
 	vulkanFunctions.vkGetDeviceBufferMemoryRequirements = vkGetDeviceBufferMemoryRequirements;
 	vulkanFunctions.vkGetDeviceBufferMemoryRequirements = vkGetDeviceBufferMemoryRequirements;
 	vulkanFunctions.vkGetDeviceImageMemoryRequirements = vkGetDeviceImageMemoryRequirements;
 	vulkanFunctions.vkGetDeviceImageMemoryRequirements = vkGetDeviceImageMemoryRequirements;
-#endif
 
 
 	allocatorCreateInfo.pVulkanFunctions = &vulkanFunctions;
 	allocatorCreateInfo.pVulkanFunctions = &vulkanFunctions;
 
 
@@ -2260,17 +2184,18 @@ void Graphics::createVulkanVertexFormat(
 {
 {
 	std::set<uint32_t> usedBuffers;
 	std::set<uint32_t> usedBuffers;
 
 
-	auto allBits = vertexAttributes.enableBits;
+	auto enableBits = vertexAttributes.enableBits;
+	auto allBits = enableBits;
 
 
 	bool usesColor = false;
 	bool usesColor = false;
 
 
 	uint8_t highestBufferBinding = 0;
 	uint8_t highestBufferBinding = 0;
 
 
-	// fixme: change to loop like in opengl implementation ?
-	for (uint32_t i = 0; i < VertexAttributes::MAX; i++)
+	uint32_t i = 0;
+	while (allBits)
 	{
 	{
 		uint32 bit = 1u << i;
 		uint32 bit = 1u << i;
-		if (allBits & bit)
+		if (enableBits & bit)
 		{
 		{
 			if (i == ATTRIB_COLOR)
 			if (i == ATTRIB_COLOR)
 				usesColor = true;
 				usesColor = true;
@@ -2301,6 +2226,9 @@ void Graphics::createVulkanVertexFormat(
 
 
 			attributeDescriptions.push_back(attributeDescription);
 			attributeDescriptions.push_back(attributeDescription);
 		}
 		}
+
+		i++;
+		allBits >>= 1;
 	}
 	}
 
 
 	if (!usesColor)
 	if (!usesColor)
@@ -2343,11 +2271,9 @@ void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindi
 	configuration.numColorAttachments = renderPassState.numColorAttachments;
 	configuration.numColorAttachments = renderPassState.numColorAttachments;
 	configuration.primitiveType = primitiveType;
 	configuration.primitiveType = primitiveType;
 
 
-#ifdef VK_EXT_extended_dynamic_state
 	if (optionalDeviceFeatures.extendedDynamicState)
 	if (optionalDeviceFeatures.extendedDynamicState)
 		vkCmdSetCullModeEXT(commandBuffers.at(currentFrame), Vulkan::getCullMode(cullmode));
 		vkCmdSetCullModeEXT(commandBuffers.at(currentFrame), Vulkan::getCullMode(cullmode));
 	else
 	else
-#endif
 	{
 	{
 		configuration.dynamicState.winding = states.back().winding;
 		configuration.dynamicState.winding = states.back().winding;
 		configuration.dynamicState.depthState.compare = states.back().depthTest;
 		configuration.dynamicState.depthState.compare = states.back().depthTest;
@@ -2721,7 +2647,6 @@ VkPipeline Graphics::createGraphicsPipeline(GraphicsPipelineConfiguration &confi
 
 
 	std::vector<VkDynamicState> dynamicStates;
 	std::vector<VkDynamicState> dynamicStates;
 
 
-#ifdef VK_EXT_extended_dynamic_state
 	if (optionalDeviceFeatures.extendedDynamicState)
 	if (optionalDeviceFeatures.extendedDynamicState)
 		dynamicStates = {
 		dynamicStates = {
 			VK_DYNAMIC_STATE_SCISSOR,
 			VK_DYNAMIC_STATE_SCISSOR,
@@ -2737,7 +2662,6 @@ VkPipeline Graphics::createGraphicsPipeline(GraphicsPipelineConfiguration &confi
 			VK_DYNAMIC_STATE_STENCIL_OP_EXT,
 			VK_DYNAMIC_STATE_STENCIL_OP_EXT,
 		};
 		};
 	else
 	else
-#endif
 		dynamicStates = {
 		dynamicStates = {
 			VK_DYNAMIC_STATE_SCISSOR,
 			VK_DYNAMIC_STATE_SCISSOR,
 			VK_DYNAMIC_STATE_VIEWPORT,
 			VK_DYNAMIC_STATE_VIEWPORT,

+ 3 - 2
src/modules/graphics/vulkan/Graphics.h

@@ -365,9 +365,10 @@ private:
 	VkSampler createSampler(const SamplerState &sampler);
 	VkSampler createSampler(const SamplerState &sampler);
 	void cleanupUnusedObjects();
 	void cleanupUnusedObjects();
 
 
-	uint32_t vulkanApiVersion = VK_VERSION_1_0;
+	uint32_t instanceVersion = VK_API_VERSION_1_0;
 	VkInstance instance = VK_NULL_HANDLE;
 	VkInstance instance = VK_NULL_HANDLE;
 	VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
 	VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
+	uint32_t deviceApiVersion = VK_API_VERSION_1_0;
 	bool windowHasStencil = false;
 	bool windowHasStencil = false;
 	int requestedMsaa = 0;
 	int requestedMsaa = 0;
 	VkDevice device = VK_NULL_HANDLE; 
 	VkDevice device = VK_NULL_HANDLE; 
@@ -417,7 +418,7 @@ private:
 	StrongRef<love::graphics::Texture> defaultTexture;
 	StrongRef<love::graphics::Texture> defaultTexture;
 	StrongRef<love::graphics::Buffer> defaultConstantColor;
 	StrongRef<love::graphics::Buffer> defaultConstantColor;
 	// functions that need to be called to cleanup objects that were needed for rendering a frame.
 	// functions that need to be called to cleanup objects that were needed for rendering a frame.
-	// just like batchedDrawBuffers we need a vector for each frame in flight.
+	// We need a vector for each frame in flight.
 	std::vector<std::vector<std::function<void()>>> cleanUpFunctions;
 	std::vector<std::vector<std::function<void()>>> cleanUpFunctions;
 	std::vector<std::vector<std::function<void()>>> readbackCallbacks;
 	std::vector<std::vector<std::function<void()>>> readbackCallbacks;
 	std::vector<ScreenshotReadbackBuffer> screenshotReadbackBuffers;
 	std::vector<ScreenshotReadbackBuffer> screenshotReadbackBuffers;

+ 5 - 1
src/modules/graphics/vulkan/Shader.cpp

@@ -355,6 +355,7 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
 	};
 	};
 
 
 	for (const auto &builtin : builtinUniformTextures)
 	for (const auto &builtin : builtinUniformTextures)
+	{
 		if (builtinUniformInfo[builtin] != nullptr)
 		if (builtinUniformInfo[builtin] != nullptr)
 		{
 		{
 			auto texture = dynamic_cast<Texture*>(builtinUniformInfo[builtin]->textures[0]);
 			auto texture = dynamic_cast<Texture*>(builtinUniformInfo[builtin]->textures[0]);
@@ -374,6 +375,7 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
 
 
 			vkUpdateDescriptorSets(device, 1, &textureWrite, 0, nullptr);
 			vkUpdateDescriptorSets(device, 1, &textureWrite, 0, nullptr);
 		}
 		}
+	}
 
 
 	vkCmdBindDescriptorSets(commandBuffer, bindPoint, pipelineLayout, 0, 1, &currentDescriptorSet, 0, nullptr);
 	vkCmdBindDescriptorSets(commandBuffer, bindPoint, pipelineLayout, 0, 1, &currentDescriptorSet, 0, nullptr);
 
 
@@ -765,7 +767,7 @@ void Shader::compileShaders()
 		auto shaderResources = comp.get_shader_resources(active);
 		auto shaderResources = comp.get_shader_resources(active);
 		comp.set_enabled_interface_variables(std::move(active));
 		comp.set_enabled_interface_variables(std::move(active));
 
 
-		for (const auto  &resource : shaderResources.uniform_buffers)
+		for (const auto &resource : shaderResources.uniform_buffers)
 		{
 		{
 			if (resource.name == "gl_DefaultUniformBlock")
 			if (resource.name == "gl_DefaultUniformBlock")
 			{
 			{
@@ -1039,12 +1041,14 @@ void Shader::setVideoTextures(graphics::Texture *ytexture, graphics::Texture *cb
 	static_assert(textures.size() == builtIns.size(), "expected number of textures to be the same");
 	static_assert(textures.size() == builtIns.size(), "expected number of textures to be the same");
 
 
 	for (size_t i = 0; i < textures.size(); i++)
 	for (size_t i = 0; i < textures.size(); i++)
+	{
 		if (builtinUniformInfo[builtIns[i]] != nullptr)
 		if (builtinUniformInfo[builtIns[i]] != nullptr)
 		{
 		{
 			textures[i]->retain();
 			textures[i]->retain();
 			builtinUniformInfo[builtIns[i]]->textures[0]->release();
 			builtinUniformInfo[builtIns[i]]->textures[0]->release();
 			builtinUniformInfo[builtIns[i]]->textures[0] = textures[i];
 			builtinUniformInfo[builtIns[i]]->textures[0] = textures[i];
 		}
 		}
+	}
 }
 }
 
 
 bool Shader::hasUniform(const std::string &name) const
 bool Shader::hasUniform(const std::string &name) const

+ 0 - 7
src/modules/graphics/vulkan/ShaderStage.cpp

@@ -19,13 +19,6 @@
  **/
  **/
 
 
 #include "ShaderStage.h"
 #include "ShaderStage.h"
-#include "Graphics.h"
-
-#include "libraries/glslang/glslang/Public/ShaderLang.h"
-#include "libraries/glslang/SPIRV/GlslangToSpv.h"
-
-#include <fstream>
-#include <cstdio>
 
 
 namespace love
 namespace love
 {
 {

+ 0 - 2
src/modules/graphics/vulkan/ShaderStage.h

@@ -23,8 +23,6 @@
 #include "graphics/ShaderStage.h"
 #include "graphics/ShaderStage.h"
 #include "modules/graphics/Graphics.h"
 #include "modules/graphics/Graphics.h"
 
 
-#include "VulkanWrapper.h"
-
 namespace love
 namespace love
 {
 {
 namespace graphics
 namespace graphics

+ 12 - 1
src/modules/graphics/vulkan/StreamBuffer.cpp

@@ -65,6 +65,13 @@ bool StreamBuffer::loadVolatile()
 	if (vmaCreateBuffer(allocator, &bufferInfo, &allocCreateInfo, &buffer, &allocation, &allocInfo) != VK_SUCCESS)
 	if (vmaCreateBuffer(allocator, &bufferInfo, &allocCreateInfo, &buffer, &allocation, &allocInfo) != VK_SUCCESS)
 		throw love::Exception("Cannot create stream buffer: out of graphics memory.");
 		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;
 	return true;
 }
 }
 
 
@@ -99,9 +106,13 @@ love::graphics::StreamBuffer::MapInfo StreamBuffer::map(size_t /*minsize*/)
 	return info;
 	return info;
 }
 }
 
 
-size_t StreamBuffer::unmap(size_t /*usedSize*/)
+size_t StreamBuffer::unmap(size_t usedSize)
 {
 {
 	size_t offset = (frameIndex * bufferSize) + frameGPUReadOffset;
 	size_t offset = (frameIndex * bufferSize) + frameGPUReadOffset;
+
+	if (!coherent)
+		vmaFlushAllocation(allocator, allocation, offset, usedSize);
+
 	return offset;
 	return offset;
 }
 }
 
 

+ 1 - 0
src/modules/graphics/vulkan/StreamBuffer.h

@@ -62,6 +62,7 @@ private:
 	VmaAllocationInfo allocInfo;
 	VmaAllocationInfo allocInfo;
 	VkBuffer buffer = VK_NULL_HANDLE;
 	VkBuffer buffer = VK_NULL_HANDLE;
 	int frameIndex = 0;
 	int frameIndex = 0;
+	bool coherent;
 
 
 };
 };
 
 

+ 0 - 18
src/modules/graphics/vulkan/Vulkan.cpp

@@ -58,24 +58,6 @@ int Vulkan::getVsync()
 	return vsync;
 	return vsync;
 }
 }
 
 
-uint32_t Vulkan::getSupportedVulkanApiVersion(uint32_t suggested)
-{
-#ifdef VK_VERSION_1_3
-	if (suggested >= VK_API_VERSION_1_3)
-		return VK_API_VERSION_1_3;
-#endif
-#ifdef VK_VERSION_1_2
-	if (suggested >= VK_API_VERSION_1_2)
-		return VK_API_VERSION_1_2;
-#endif
-#ifdef VK_VERSION_1_1
-	if (suggested >= VK_API_VERSION_1_1)
-		return VK_API_VERSION_1_1;
-#endif
-
-	return VK_API_VERSION_1_0;
-}
-
 VkFormat Vulkan::getVulkanVertexFormat(DataFormat format)
 VkFormat Vulkan::getVulkanVertexFormat(DataFormat format)
 {
 {
 	switch (format)
 	switch (format)

+ 0 - 1
src/modules/graphics/vulkan/Vulkan.h

@@ -61,7 +61,6 @@ public:
 	static void setVsync(int vsync);
 	static void setVsync(int vsync);
 	static int getVsync();
 	static int getVsync();
 
 
-	static uint32_t getSupportedVulkanApiVersion(uint32_t suggested);
 	static VkFormat getVulkanVertexFormat(DataFormat format);
 	static VkFormat getVulkanVertexFormat(DataFormat format);
 	static TextureFormat getTextureFormat(PixelFormat, bool sRGB);
 	static TextureFormat getTextureFormat(PixelFormat, bool sRGB);
 	static std::string getVendorName(uint32_t vendorId);
 	static std::string getVendorName(uint32_t vendorId);

+ 0 - 17
src/modules/graphics/vulkan/VulkanWrapper.h

@@ -23,23 +23,6 @@
 #define VK_NO_PROTOTYPES
 #define VK_NO_PROTOTYPES
 #include "libraries/vulkanheaders/vulkan.h"
 #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"
 #include "libraries/volk/volk.h"
 #define VMA_STATIC_VULKAN_FUNCTIONS 0
 #define VMA_STATIC_VULKAN_FUNCTIONS 0
 #define VMA_DYNAMIC_VULKAN_FUNCTIONS 0
 #define VMA_DYNAMIC_VULKAN_FUNCTIONS 0