From 2481714a8e35b7fae0ca799d64edbd4beacf2297 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sun, 21 Feb 2016 18:05:01 +0100 Subject: [PATCH] Load Vulkan dynamically. Fix Android build (though - Vulkan is not working on Android yet) --- Common/Common.vcxproj | 4 +- Common/Common.vcxproj.filters | 8 +- Common/Vulkan/VulkanLoader.cpp | 393 +++++++++++++++++++++ Common/Vulkan/VulkanLoader.h | 198 +++++++++++ GPU/Vulkan/DrawEngineVulkan.cpp | 10 +- GPU/Vulkan/FramebufferVulkan.cpp | 2 - GPU/Vulkan/FramebufferVulkan.h | 2 +- GPU/Vulkan/PipelineManagerVulkan.cpp | 8 +- GPU/Vulkan/ShaderManagerVulkan.cpp | 16 +- GPU/Vulkan/StateMappingVulkan.cpp | 3 +- GPU/Vulkan/StateMappingVulkan.h | 2 +- GPU/Vulkan/TextureCacheVulkan.cpp | 6 +- GPU/Vulkan/VertexShaderGeneratorVulkan.cpp | 1 + GPU/Vulkan/VulkanUtil.h | 2 +- Windows/GPU/WindowsVulkanContext.cpp | 2 +- android/jni/Android.mk | 8 +- android/jni/Locals.mk | 2 +- ext/native/Android.mk | 4 +- ext/native/thin3d/VulkanContext.cpp | 175 ++++----- ext/native/thin3d/VulkanContext.h | 51 +-- ext/native/thin3d/thin3d_vulkan.cpp | 7 +- 21 files changed, 733 insertions(+), 171 deletions(-) create mode 100644 Common/Vulkan/VulkanLoader.cpp create mode 100644 Common/Vulkan/VulkanLoader.h diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index c8fc1adc26..59f1e261fc 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -241,6 +241,7 @@ + @@ -310,6 +311,7 @@ + @@ -324,4 +326,4 @@ - + \ No newline at end of file diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 62356cf7e1..8f32f6e506 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -61,6 +61,9 @@ Vulkan + + Vulkan + @@ -109,6 +112,9 @@ Vulkan + + Vulkan + @@ -127,4 +133,4 @@ {c14d66ef-5f7c-4565-975a-72774e7ccfb9} - + \ No newline at end of file diff --git a/Common/Vulkan/VulkanLoader.cpp b/Common/Vulkan/VulkanLoader.cpp new file mode 100644 index 0000000000..7b6b143510 --- /dev/null +++ b/Common/Vulkan/VulkanLoader.cpp @@ -0,0 +1,393 @@ +// Copyright (c) 2016- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include "Common/Vulkan/VulkanLoader.h" + +#ifndef _WIN32 +#include +#endif + + +PFN_vkCreateInstance vkCreateInstance; +PFN_vkDestroyInstance vkDestroyInstance; +PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices; +PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures; +PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties; +PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties; +PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties; +PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties; +PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties; +PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; +PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr; +PFN_vkCreateDevice vkCreateDevice; +PFN_vkDestroyDevice vkDestroyDevice; +PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties; +PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties; +PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties; +PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties; +PFN_vkGetDeviceQueue vkGetDeviceQueue; +PFN_vkQueueSubmit vkQueueSubmit; +PFN_vkQueueWaitIdle vkQueueWaitIdle; +PFN_vkDeviceWaitIdle vkDeviceWaitIdle; +PFN_vkAllocateMemory vkAllocateMemory; +PFN_vkFreeMemory vkFreeMemory; +PFN_vkMapMemory vkMapMemory; +PFN_vkUnmapMemory vkUnmapMemory; +PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges; +PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges; +PFN_vkGetDeviceMemoryCommitment vkGetDeviceMemoryCommitment; +PFN_vkBindBufferMemory vkBindBufferMemory; +PFN_vkBindImageMemory vkBindImageMemory; +PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements; +PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements; +PFN_vkGetImageSparseMemoryRequirements vkGetImageSparseMemoryRequirements; +PFN_vkGetPhysicalDeviceSparseImageFormatProperties vkGetPhysicalDeviceSparseImageFormatProperties; +PFN_vkQueueBindSparse vkQueueBindSparse; +PFN_vkCreateFence vkCreateFence; +PFN_vkDestroyFence vkDestroyFence; +PFN_vkResetFences vkResetFences; +PFN_vkGetFenceStatus vkGetFenceStatus; +PFN_vkWaitForFences vkWaitForFences; +PFN_vkCreateSemaphore vkCreateSemaphore; +PFN_vkDestroySemaphore vkDestroySemaphore; +PFN_vkCreateEvent vkCreateEvent; +PFN_vkDestroyEvent vkDestroyEvent; +PFN_vkGetEventStatus vkGetEventStatus; +PFN_vkSetEvent vkSetEvent; +PFN_vkResetEvent vkResetEvent; +PFN_vkCreateQueryPool vkCreateQueryPool; +PFN_vkDestroyQueryPool vkDestroyQueryPool; +PFN_vkGetQueryPoolResults vkGetQueryPoolResults; +PFN_vkCreateBuffer vkCreateBuffer; +PFN_vkDestroyBuffer vkDestroyBuffer; +PFN_vkCreateBufferView vkCreateBufferView; +PFN_vkDestroyBufferView vkDestroyBufferView; +PFN_vkCreateImage vkCreateImage; +PFN_vkDestroyImage vkDestroyImage; +PFN_vkGetImageSubresourceLayout vkGetImageSubresourceLayout; +PFN_vkCreateImageView vkCreateImageView; +PFN_vkDestroyImageView vkDestroyImageView; +PFN_vkCreateShaderModule vkCreateShaderModule; +PFN_vkDestroyShaderModule vkDestroyShaderModule; +PFN_vkCreatePipelineCache vkCreatePipelineCache; +PFN_vkDestroyPipelineCache vkDestroyPipelineCache; +PFN_vkGetPipelineCacheData vkGetPipelineCacheData; +PFN_vkMergePipelineCaches vkMergePipelineCaches; +PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines; +PFN_vkCreateComputePipelines vkCreateComputePipelines; +PFN_vkDestroyPipeline vkDestroyPipeline; +PFN_vkCreatePipelineLayout vkCreatePipelineLayout; +PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout; +PFN_vkCreateSampler vkCreateSampler; +PFN_vkDestroySampler vkDestroySampler; +PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout; +PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout; +PFN_vkCreateDescriptorPool vkCreateDescriptorPool; +PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool; +PFN_vkResetDescriptorPool vkResetDescriptorPool; +PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets; +PFN_vkFreeDescriptorSets vkFreeDescriptorSets; +PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets; +PFN_vkCreateFramebuffer vkCreateFramebuffer; +PFN_vkDestroyFramebuffer vkDestroyFramebuffer; +PFN_vkCreateRenderPass vkCreateRenderPass; +PFN_vkDestroyRenderPass vkDestroyRenderPass; +PFN_vkGetRenderAreaGranularity vkGetRenderAreaGranularity; +PFN_vkCreateCommandPool vkCreateCommandPool; +PFN_vkDestroyCommandPool vkDestroyCommandPool; +PFN_vkResetCommandPool vkResetCommandPool; +PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers; +PFN_vkFreeCommandBuffers vkFreeCommandBuffers; +PFN_vkBeginCommandBuffer vkBeginCommandBuffer; +PFN_vkEndCommandBuffer vkEndCommandBuffer; +PFN_vkResetCommandBuffer vkResetCommandBuffer; +PFN_vkCmdBindPipeline vkCmdBindPipeline; +PFN_vkCmdSetViewport vkCmdSetViewport; +PFN_vkCmdSetScissor vkCmdSetScissor; +PFN_vkCmdSetLineWidth vkCmdSetLineWidth; +PFN_vkCmdSetDepthBias vkCmdSetDepthBias; +PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants; +PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds; +PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask; +PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask; +PFN_vkCmdSetStencilReference vkCmdSetStencilReference; +PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets; +PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer; +PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers; +PFN_vkCmdDraw vkCmdDraw; +PFN_vkCmdDrawIndexed vkCmdDrawIndexed; +PFN_vkCmdDrawIndirect vkCmdDrawIndirect; +PFN_vkCmdDrawIndexedIndirect vkCmdDrawIndexedIndirect; +PFN_vkCmdDispatch vkCmdDispatch; +PFN_vkCmdDispatchIndirect vkCmdDispatchIndirect; +PFN_vkCmdCopyBuffer vkCmdCopyBuffer; +PFN_vkCmdCopyImage vkCmdCopyImage; +PFN_vkCmdBlitImage vkCmdBlitImage; +PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage; +PFN_vkCmdCopyImageToBuffer vkCmdCopyImageToBuffer; +PFN_vkCmdUpdateBuffer vkCmdUpdateBuffer; +PFN_vkCmdFillBuffer vkCmdFillBuffer; +PFN_vkCmdClearColorImage vkCmdClearColorImage; +PFN_vkCmdClearDepthStencilImage vkCmdClearDepthStencilImage; +PFN_vkCmdClearAttachments vkCmdClearAttachments; +PFN_vkCmdResolveImage vkCmdResolveImage; +PFN_vkCmdSetEvent vkCmdSetEvent; +PFN_vkCmdResetEvent vkCmdResetEvent; +PFN_vkCmdWaitEvents vkCmdWaitEvents; +PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier; +PFN_vkCmdBeginQuery vkCmdBeginQuery; +PFN_vkCmdEndQuery vkCmdEndQuery; +PFN_vkCmdResetQueryPool vkCmdResetQueryPool; +PFN_vkCmdWriteTimestamp vkCmdWriteTimestamp; +PFN_vkCmdCopyQueryPoolResults vkCmdCopyQueryPoolResults; +PFN_vkCmdPushConstants vkCmdPushConstants; +PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass; +PFN_vkCmdNextSubpass vkCmdNextSubpass; +PFN_vkCmdEndRenderPass vkCmdEndRenderPass; +PFN_vkCmdExecuteCommands vkCmdExecuteCommands; + +#ifdef ANDROID +PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR; +#elif defined(_WIN32) +PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR; +#endif + +PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR; + +// WSI extension. +PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR; +PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR; +PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR; +PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR; +PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR; +PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR; +PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR; +PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR; +PFN_vkQueuePresentKHR vkQueuePresentKHR; + +// And the DEBUG_REPORT extension. +PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT; +PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT; + +#ifdef _WIN32 +static HINSTANCE vulkanLibrary; +#define dlsym(x, y) GetProcAddress(x, y) +#else +static void *vulkanLibrary; +#endif + +bool VulkanLoad() { + +#ifndef _WIN32 + vulkanLibrary = dlopen("libvulkan.sh", RTLD_NOW | RTLD_LOCAL); + if (!vulkanLibrary) { + return false; + } +#else + // LoadLibrary etc + vulkanLibrary = LoadLibrary(L"vulkan-1.dll"); +#endif + + vkCreateInstance = (PFN_vkCreateInstance)dlsym(vulkanLibrary, "vkCreateInstance"); + vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)dlsym(vulkanLibrary, "vkGetInstanceProcAddr"); + vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)dlsym(vulkanLibrary, "vkGetDeviceProcAddr"); + + // Why do we need to load these separately? + vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)dlsym(vulkanLibrary, "vkEnumerateInstanceExtensionProperties"); + vkEnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties)dlsym(vulkanLibrary, "vkEnumerateInstanceLayerProperties"); + return true; +} + +void VulkanLoadInstanceFunctions(VkInstance instance) { + // OK, let's use the above functions to get the rest. + vkDestroyInstance = (PFN_vkDestroyInstance)vkGetInstanceProcAddr(instance, "vkDestroyInstance"); + vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices)vkGetInstanceProcAddr(instance, "vkEnumeratePhysicalDevices"); + vkGetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures"); + vkGetPhysicalDeviceFormatProperties = (PFN_vkGetPhysicalDeviceFormatProperties)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties"); + vkGetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceImageFormatProperties"); + vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties"); + vkGetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyProperties"); + vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMemoryProperties"); + vkCreateDevice = (PFN_vkCreateDevice)vkGetInstanceProcAddr(instance, "vkCreateDevice"); + vkDestroyDevice = (PFN_vkDestroyDevice)vkGetInstanceProcAddr(instance, "vkDestroyDevice"); + vkEnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties)vkGetInstanceProcAddr(instance, "vkEnumerateDeviceExtensionProperties"); + vkEnumerateDeviceLayerProperties = (PFN_vkEnumerateDeviceLayerProperties)vkGetInstanceProcAddr(instance, "vkEnumerateDeviceLayerProperties"); + vkGetDeviceQueue = (PFN_vkGetDeviceQueue)vkGetInstanceProcAddr(instance, "vkGetDeviceQueue"); + vkQueueSubmit = (PFN_vkQueueSubmit)vkGetInstanceProcAddr(instance, "vkQueueSubmit"); + vkQueueWaitIdle = (PFN_vkQueueWaitIdle)vkGetInstanceProcAddr(instance, "vkQueueWaitIdle"); + vkDeviceWaitIdle = (PFN_vkDeviceWaitIdle)vkGetInstanceProcAddr(instance, "vkDeviceWaitIdle"); + vkAllocateMemory = (PFN_vkAllocateMemory)vkGetInstanceProcAddr(instance, "vkAllocateMemory"); + vkFreeMemory = (PFN_vkFreeMemory)vkGetInstanceProcAddr(instance, "vkFreeMemory"); + vkMapMemory = (PFN_vkMapMemory)vkGetInstanceProcAddr(instance, "vkMapMemory"); + vkUnmapMemory = (PFN_vkUnmapMemory)vkGetInstanceProcAddr(instance, "vkUnmapMemory"); + vkFlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges)vkGetInstanceProcAddr(instance, "vkFlushMappedMemoryRanges"); + vkInvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges)vkGetInstanceProcAddr(instance, "vkInvalidateMappedMemoryRanges"); + vkGetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment)vkGetInstanceProcAddr(instance, "vkGetDeviceMemoryCommitment"); + vkBindBufferMemory = (PFN_vkBindBufferMemory)vkGetInstanceProcAddr(instance, "vkBindBufferMemory"); + vkBindImageMemory = (PFN_vkBindImageMemory)vkGetInstanceProcAddr(instance, "vkBindImageMemory"); + vkGetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements)vkGetInstanceProcAddr(instance, "vkGetBufferMemoryRequirements"); + vkGetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements)vkGetInstanceProcAddr(instance, "vkGetImageMemoryRequirements"); + vkGetImageSparseMemoryRequirements = (PFN_vkGetImageSparseMemoryRequirements)vkGetInstanceProcAddr(instance, "vkGetImageSparseMemoryRequirements"); + vkGetPhysicalDeviceSparseImageFormatProperties = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSparseImageFormatProperties"); + vkQueueBindSparse = (PFN_vkQueueBindSparse)vkGetInstanceProcAddr(instance, "vkQueueBindSparse"); + vkCreateFence = (PFN_vkCreateFence)vkGetInstanceProcAddr(instance, "vkCreateFence"); + vkDestroyFence = (PFN_vkDestroyFence)vkGetInstanceProcAddr(instance, "vkDestroyFence"); + vkResetFences = (PFN_vkResetFences)vkGetInstanceProcAddr(instance, "vkResetFences"); + vkGetFenceStatus = (PFN_vkGetFenceStatus)vkGetInstanceProcAddr(instance, "vkGetFenceStatus"); + vkWaitForFences = (PFN_vkWaitForFences)vkGetInstanceProcAddr(instance, "vkWaitForFences"); + vkCreateSemaphore = (PFN_vkCreateSemaphore)vkGetInstanceProcAddr(instance, "vkCreateSemaphore"); + vkDestroySemaphore = (PFN_vkDestroySemaphore)vkGetInstanceProcAddr(instance, "vkDestroySemaphore"); + vkCreateEvent = (PFN_vkCreateEvent)vkGetInstanceProcAddr(instance, "vkCreateEvent"); + vkDestroyEvent = (PFN_vkDestroyEvent)vkGetInstanceProcAddr(instance, "vkDestroyEvent"); + vkGetEventStatus = (PFN_vkGetEventStatus)vkGetInstanceProcAddr(instance, "vkGetEventStatus"); + vkSetEvent = (PFN_vkSetEvent)vkGetInstanceProcAddr(instance, "vkSetEvent"); + vkResetEvent = (PFN_vkResetEvent)vkGetInstanceProcAddr(instance, "vkResetEvent"); + vkCreateQueryPool = (PFN_vkCreateQueryPool)vkGetInstanceProcAddr(instance, "vkCreateQueryPool"); + vkDestroyQueryPool = (PFN_vkDestroyQueryPool)vkGetInstanceProcAddr(instance, "vkDestroyQueryPool"); + vkGetQueryPoolResults = (PFN_vkGetQueryPoolResults)vkGetInstanceProcAddr(instance, "vkGetQueryPoolResults"); + vkCreateBuffer = (PFN_vkCreateBuffer)vkGetInstanceProcAddr(instance, "vkCreateBuffer"); + vkDestroyBuffer = (PFN_vkDestroyBuffer)vkGetInstanceProcAddr(instance, "vkDestroyBuffer"); + vkCreateBufferView = (PFN_vkCreateBufferView)vkGetInstanceProcAddr(instance, "vkCreateBufferView"); + vkDestroyBufferView = (PFN_vkDestroyBufferView)vkGetInstanceProcAddr(instance, "vkDestroyBufferView"); + vkCreateImage = (PFN_vkCreateImage)vkGetInstanceProcAddr(instance, "vkCreateImage"); + vkDestroyImage = (PFN_vkDestroyImage)vkGetInstanceProcAddr(instance, "vkDestroyImage"); + vkGetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout)vkGetInstanceProcAddr(instance, "vkGetImageSubresourceLayout"); + vkCreateImageView = (PFN_vkCreateImageView)vkGetInstanceProcAddr(instance, "vkCreateImageView"); + vkDestroyImageView = (PFN_vkDestroyImageView)vkGetInstanceProcAddr(instance, "vkDestroyImageView"); + vkCreateShaderModule = (PFN_vkCreateShaderModule)vkGetInstanceProcAddr(instance, "vkCreateShaderModule"); + vkDestroyShaderModule = (PFN_vkDestroyShaderModule)vkGetInstanceProcAddr(instance, "vkDestroyShaderModule"); + vkCreatePipelineCache = (PFN_vkCreatePipelineCache)vkGetInstanceProcAddr(instance, "vkCreatePipelineCache"); + vkDestroyPipelineCache = (PFN_vkDestroyPipelineCache)vkGetInstanceProcAddr(instance, "vkDestroyPipelineCache"); + vkGetPipelineCacheData = (PFN_vkGetPipelineCacheData)vkGetInstanceProcAddr(instance, "vkGetPipelineCacheData"); + vkMergePipelineCaches = (PFN_vkMergePipelineCaches)vkGetInstanceProcAddr(instance, "vkMergePipelineCaches"); + vkCreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines)vkGetInstanceProcAddr(instance, "vkCreateGraphicsPipelines"); + vkCreateComputePipelines = (PFN_vkCreateComputePipelines)vkGetInstanceProcAddr(instance, "vkCreateComputePipelines"); + vkDestroyPipeline = (PFN_vkDestroyPipeline)vkGetInstanceProcAddr(instance, "vkDestroyPipeline"); + vkCreatePipelineLayout = (PFN_vkCreatePipelineLayout)vkGetInstanceProcAddr(instance, "vkCreatePipelineLayout"); + vkDestroyPipelineLayout = (PFN_vkDestroyPipelineLayout)vkGetInstanceProcAddr(instance, "vkDestroyPipelineLayout"); + vkCreateSampler = (PFN_vkCreateSampler)vkGetInstanceProcAddr(instance, "vkCreateSampler"); + vkDestroySampler = (PFN_vkDestroySampler)vkGetInstanceProcAddr(instance, "vkDestroySampler"); + vkCreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout)vkGetInstanceProcAddr(instance, "vkCreateDescriptorSetLayout"); + vkDestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout)vkGetInstanceProcAddr(instance, "vkDestroyDescriptorSetLayout"); + vkCreateDescriptorPool = (PFN_vkCreateDescriptorPool)vkGetInstanceProcAddr(instance, "vkCreateDescriptorPool"); + vkDestroyDescriptorPool = (PFN_vkDestroyDescriptorPool)vkGetInstanceProcAddr(instance, "vkDestroyDescriptorPool"); + vkResetDescriptorPool = (PFN_vkResetDescriptorPool)vkGetInstanceProcAddr(instance, "vkResetDescriptorPool"); + vkAllocateDescriptorSets = (PFN_vkAllocateDescriptorSets)vkGetInstanceProcAddr(instance, "vkAllocateDescriptorSets"); + vkFreeDescriptorSets = (PFN_vkFreeDescriptorSets)vkGetInstanceProcAddr(instance, "vkFreeDescriptorSets"); + vkUpdateDescriptorSets = (PFN_vkUpdateDescriptorSets)vkGetInstanceProcAddr(instance, "vkUpdateDescriptorSets"); + vkCreateFramebuffer = (PFN_vkCreateFramebuffer)vkGetInstanceProcAddr(instance, "vkCreateFramebuffer"); + vkDestroyFramebuffer = (PFN_vkDestroyFramebuffer)vkGetInstanceProcAddr(instance, "vkDestroyFramebuffer"); + vkCreateRenderPass = (PFN_vkCreateRenderPass)vkGetInstanceProcAddr(instance, "vkCreateRenderPass"); + vkDestroyRenderPass = (PFN_vkDestroyRenderPass)vkGetInstanceProcAddr(instance, "vkDestroyRenderPass"); + vkGetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity)vkGetInstanceProcAddr(instance, "vkGetRenderAreaGranularity"); + vkCreateCommandPool = (PFN_vkCreateCommandPool)vkGetInstanceProcAddr(instance, "vkCreateCommandPool"); + vkDestroyCommandPool = (PFN_vkDestroyCommandPool)vkGetInstanceProcAddr(instance, "vkDestroyCommandPool"); + vkResetCommandPool = (PFN_vkResetCommandPool)vkGetInstanceProcAddr(instance, "vkResetCommandPool"); + vkAllocateCommandBuffers = (PFN_vkAllocateCommandBuffers)vkGetInstanceProcAddr(instance, "vkAllocateCommandBuffers"); + vkFreeCommandBuffers = (PFN_vkFreeCommandBuffers)vkGetInstanceProcAddr(instance, "vkFreeCommandBuffers"); + vkBeginCommandBuffer = (PFN_vkBeginCommandBuffer)vkGetInstanceProcAddr(instance, "vkBeginCommandBuffer"); + vkEndCommandBuffer = (PFN_vkEndCommandBuffer)vkGetInstanceProcAddr(instance, "vkEndCommandBuffer"); + vkResetCommandBuffer = (PFN_vkResetCommandBuffer)vkGetInstanceProcAddr(instance, "vkResetCommandBuffer"); + vkCmdBindPipeline = (PFN_vkCmdBindPipeline)vkGetInstanceProcAddr(instance, "vkCmdBindPipeline"); + vkCmdSetViewport = (PFN_vkCmdSetViewport)vkGetInstanceProcAddr(instance, "vkCmdSetViewport"); + vkCmdSetScissor = (PFN_vkCmdSetScissor)vkGetInstanceProcAddr(instance, "vkCmdSetScissor"); + vkCmdSetLineWidth = (PFN_vkCmdSetLineWidth)vkGetInstanceProcAddr(instance, "vkCmdSetLineWidth"); + vkCmdSetDepthBias = (PFN_vkCmdSetDepthBias)vkGetInstanceProcAddr(instance, "vkCmdSetDepthBias"); + vkCmdSetBlendConstants = (PFN_vkCmdSetBlendConstants)vkGetInstanceProcAddr(instance, "vkCmdSetBlendConstants"); + vkCmdSetDepthBounds = (PFN_vkCmdSetDepthBounds)vkGetInstanceProcAddr(instance, "vkCmdSetDepthBounds"); + vkCmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask)vkGetInstanceProcAddr(instance, "vkCmdSetStencilCompareMask"); + vkCmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask)vkGetInstanceProcAddr(instance, "vkCmdSetStencilWriteMask"); + vkCmdSetStencilReference = (PFN_vkCmdSetStencilReference)vkGetInstanceProcAddr(instance, "vkCmdSetStencilReference"); + vkCmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets)vkGetInstanceProcAddr(instance, "vkCmdBindDescriptorSets"); + vkCmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer)vkGetInstanceProcAddr(instance, "vkCmdBindIndexBuffer"); + vkCmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers)vkGetInstanceProcAddr(instance, "vkCmdBindVertexBuffers"); + vkCmdDraw = (PFN_vkCmdDraw)vkGetInstanceProcAddr(instance, "vkCmdDraw"); + vkCmdDrawIndexed = (PFN_vkCmdDrawIndexed)vkGetInstanceProcAddr(instance, "vkCmdDrawIndexed"); + vkCmdDrawIndirect = (PFN_vkCmdDrawIndirect)vkGetInstanceProcAddr(instance, "vkCmdDrawIndirect"); + vkCmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect)vkGetInstanceProcAddr(instance, "vkCmdDrawIndexedIndirect"); + vkCmdDispatch = (PFN_vkCmdDispatch)vkGetInstanceProcAddr(instance, "vkCmdDispatch"); + vkCmdDispatchIndirect = (PFN_vkCmdDispatchIndirect)vkGetInstanceProcAddr(instance, "vkCmdDispatchIndirect"); + vkCmdCopyBuffer = (PFN_vkCmdCopyBuffer)vkGetInstanceProcAddr(instance, "vkCmdCopyBuffer"); + vkCmdCopyImage = (PFN_vkCmdCopyImage)vkGetInstanceProcAddr(instance, "vkCmdCopyImage"); + vkCmdBlitImage = (PFN_vkCmdBlitImage)vkGetInstanceProcAddr(instance, "vkCmdBlitImage"); + vkCmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage)vkGetInstanceProcAddr(instance, "vkCmdCopyBufferToImage"); + vkCmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer)vkGetInstanceProcAddr(instance, "vkCmdCopyImageToBuffer"); + vkCmdUpdateBuffer = (PFN_vkCmdUpdateBuffer)vkGetInstanceProcAddr(instance, "vkCmdUpdateBuffer"); + vkCmdFillBuffer = (PFN_vkCmdFillBuffer)vkGetInstanceProcAddr(instance, "vkCmdFillBuffer"); + vkCmdClearColorImage = (PFN_vkCmdClearColorImage)vkGetInstanceProcAddr(instance, "vkCmdClearColorImage"); + vkCmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage)vkGetInstanceProcAddr(instance, "vkCmdClearDepthStencilImage"); + vkCmdClearAttachments = (PFN_vkCmdClearAttachments)vkGetInstanceProcAddr(instance, "vkCmdClearAttachments"); + vkCmdResolveImage = (PFN_vkCmdResolveImage)vkGetInstanceProcAddr(instance, "vkCmdResolveImage"); + vkCmdSetEvent = (PFN_vkCmdSetEvent)vkGetInstanceProcAddr(instance, "vkCmdSetEvent"); + vkCmdResetEvent = (PFN_vkCmdResetEvent)vkGetInstanceProcAddr(instance, "vkCmdResetEvent"); + vkCmdWaitEvents = (PFN_vkCmdWaitEvents)vkGetInstanceProcAddr(instance, "vkCmdWaitEvents"); + vkCmdPipelineBarrier = (PFN_vkCmdPipelineBarrier)vkGetInstanceProcAddr(instance, "vkCmdPipelineBarrier"); + vkCmdBeginQuery = (PFN_vkCmdBeginQuery)vkGetInstanceProcAddr(instance, "vkCmdBeginQuery"); + vkCmdEndQuery = (PFN_vkCmdEndQuery)vkGetInstanceProcAddr(instance, "vkCmdEndQuery"); + vkCmdResetQueryPool = (PFN_vkCmdResetQueryPool)vkGetInstanceProcAddr(instance, "vkCmdResetQueryPool"); + vkCmdWriteTimestamp = (PFN_vkCmdWriteTimestamp)vkGetInstanceProcAddr(instance, "vkCmdWriteTimestamp"); + vkCmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults)vkGetInstanceProcAddr(instance, "vkCmdCopyQueryPoolResults"); + vkCmdPushConstants = (PFN_vkCmdPushConstants)vkGetInstanceProcAddr(instance, "vkCmdPushConstants"); + vkCmdBeginRenderPass = (PFN_vkCmdBeginRenderPass)vkGetInstanceProcAddr(instance, "vkCmdBeginRenderPass"); + vkCmdNextSubpass = (PFN_vkCmdNextSubpass)vkGetInstanceProcAddr(instance, "vkCmdNextSubpass"); + vkCmdEndRenderPass = (PFN_vkCmdEndRenderPass)vkGetInstanceProcAddr(instance, "vkCmdEndRenderPass"); + vkCmdExecuteCommands = (PFN_vkCmdExecuteCommands)vkGetInstanceProcAddr(instance, "vkCmdExecuteCommands"); + + vkGetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceSupportKHR"); + vkGetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"); + vkGetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR"); + vkGetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfacePresentModesKHR"); + + vkCreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)vkGetInstanceProcAddr(instance, "vkCreateSwapchainKHR"); + vkDestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)vkGetInstanceProcAddr(instance, "vkDestroySwapchainKHR"); + vkGetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)vkGetInstanceProcAddr(instance, "vkGetSwapchainImagesKHR"); + vkAcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)vkGetInstanceProcAddr(instance, "vkAcquireNextImageKHR"); + vkQueuePresentKHR = (PFN_vkQueuePresentKHR)vkGetInstanceProcAddr(instance, "vkQueuePresentKHR"); + +#ifdef _WIN32 + vkCreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)vkGetInstanceProcAddr(instance, "vkCreateWin32SurfaceKHR"); +#elif defined(ANDROID) + vkCreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR)vkGetInstanceProcAddr(instance, "vkCreateAndroidSurfaceKHR"); +#endif + + vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"); + vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"); +} + +// On some implementations, loading functions (that have Device as their first parameter) via vkGetDeviceProcAddr may +// increase performance - but then these function pointers will only work on that specific device. Thus, this loader is not very +// good for multi-device. +void VulkanLoadDeviceFunctions(VkDevice device) { + // TODO: Move more functions VulkanLoadInstanceFunctions to here. + vkCreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)vkGetDeviceProcAddr(device, "vkCreateSwapchainKHR"); + vkDestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)vkGetDeviceProcAddr(device, "vkDestroySwapchainKHR"); + vkGetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)vkGetDeviceProcAddr(device, "vkGetSwapchainImagesKHR"); + vkAcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)vkGetDeviceProcAddr(device, "vkAcquireNextImageKHR"); + vkQueuePresentKHR = (PFN_vkQueuePresentKHR)vkGetDeviceProcAddr(device, "vkQueuePresentKHR"); +} + +void VulkanFree() { +#ifdef _WIN32 + if (vulkanLibrary) { + FreeLibrary(vulkanLibrary); + } +#else + if (vulkanLibrary) { + dlclose(vulkanLibrary); + } +#endif +} diff --git a/Common/Vulkan/VulkanLoader.h b/Common/Vulkan/VulkanLoader.h new file mode 100644 index 0000000000..5c36804596 --- /dev/null +++ b/Common/Vulkan/VulkanLoader.h @@ -0,0 +1,198 @@ +// Copyright (c) 2016- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once + +#ifdef ANDROID +#define VK_USE_PLATFORM_ANDROID_KHR +#elif defined(_WIN32) +#define VK_USE_PLATFORM_WIN32_KHR +#define WIN32_LEAN_AND_MEAN +#define NOMINMAX +#endif + +#define VK_NO_PROTOTYPES + +#include "ext/vulkan/vulkan.h" + +extern PFN_vkCreateInstance vkCreateInstance; +extern PFN_vkDestroyInstance vkDestroyInstance; +extern PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices; +extern PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures; +extern PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties; +extern PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties; +extern PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties; +extern PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties; +extern PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties; +extern PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; +extern PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr; +extern PFN_vkCreateDevice vkCreateDevice; +extern PFN_vkDestroyDevice vkDestroyDevice; +extern PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties; +extern PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties; +extern PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties; +extern PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties; +extern PFN_vkGetDeviceQueue vkGetDeviceQueue; +extern PFN_vkQueueSubmit vkQueueSubmit; +extern PFN_vkQueueWaitIdle vkQueueWaitIdle; +extern PFN_vkDeviceWaitIdle vkDeviceWaitIdle; +extern PFN_vkAllocateMemory vkAllocateMemory; +extern PFN_vkFreeMemory vkFreeMemory; +extern PFN_vkMapMemory vkMapMemory; +extern PFN_vkUnmapMemory vkUnmapMemory; +extern PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges; +extern PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges; +extern PFN_vkGetDeviceMemoryCommitment vkGetDeviceMemoryCommitment; +extern PFN_vkBindBufferMemory vkBindBufferMemory; +extern PFN_vkBindImageMemory vkBindImageMemory; +extern PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements; +extern PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements; +extern PFN_vkGetImageSparseMemoryRequirements vkGetImageSparseMemoryRequirements; +extern PFN_vkGetPhysicalDeviceSparseImageFormatProperties vkGetPhysicalDeviceSparseImageFormatProperties; +extern PFN_vkQueueBindSparse vkQueueBindSparse; +extern PFN_vkCreateFence vkCreateFence; +extern PFN_vkDestroyFence vkDestroyFence; +extern PFN_vkResetFences vkResetFences; +extern PFN_vkGetFenceStatus vkGetFenceStatus; +extern PFN_vkWaitForFences vkWaitForFences; +extern PFN_vkCreateSemaphore vkCreateSemaphore; +extern PFN_vkDestroySemaphore vkDestroySemaphore; +extern PFN_vkCreateEvent vkCreateEvent; +extern PFN_vkDestroyEvent vkDestroyEvent; +extern PFN_vkGetEventStatus vkGetEventStatus; +extern PFN_vkSetEvent vkSetEvent; +extern PFN_vkResetEvent vkResetEvent; +extern PFN_vkCreateQueryPool vkCreateQueryPool; +extern PFN_vkDestroyQueryPool vkDestroyQueryPool; +extern PFN_vkGetQueryPoolResults vkGetQueryPoolResults; +extern PFN_vkCreateBuffer vkCreateBuffer; +extern PFN_vkDestroyBuffer vkDestroyBuffer; +extern PFN_vkCreateBufferView vkCreateBufferView; +extern PFN_vkDestroyBufferView vkDestroyBufferView; +extern PFN_vkCreateImage vkCreateImage; +extern PFN_vkDestroyImage vkDestroyImage; +extern PFN_vkGetImageSubresourceLayout vkGetImageSubresourceLayout; +extern PFN_vkCreateImageView vkCreateImageView; +extern PFN_vkDestroyImageView vkDestroyImageView; +extern PFN_vkCreateShaderModule vkCreateShaderModule; +extern PFN_vkDestroyShaderModule vkDestroyShaderModule; +extern PFN_vkCreatePipelineCache vkCreatePipelineCache; +extern PFN_vkDestroyPipelineCache vkDestroyPipelineCache; +extern PFN_vkGetPipelineCacheData vkGetPipelineCacheData; +extern PFN_vkMergePipelineCaches vkMergePipelineCaches; +extern PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines; +extern PFN_vkCreateComputePipelines vkCreateComputePipelines; +extern PFN_vkDestroyPipeline vkDestroyPipeline; +extern PFN_vkCreatePipelineLayout vkCreatePipelineLayout; +extern PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout; +extern PFN_vkCreateSampler vkCreateSampler; +extern PFN_vkDestroySampler vkDestroySampler; +extern PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout; +extern PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout; +extern PFN_vkCreateDescriptorPool vkCreateDescriptorPool; +extern PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool; +extern PFN_vkResetDescriptorPool vkResetDescriptorPool; +extern PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets; +extern PFN_vkFreeDescriptorSets vkFreeDescriptorSets; +extern PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets; +extern PFN_vkCreateFramebuffer vkCreateFramebuffer; +extern PFN_vkDestroyFramebuffer vkDestroyFramebuffer; +extern PFN_vkCreateRenderPass vkCreateRenderPass; +extern PFN_vkDestroyRenderPass vkDestroyRenderPass; +extern PFN_vkGetRenderAreaGranularity vkGetRenderAreaGranularity; +extern PFN_vkCreateCommandPool vkCreateCommandPool; +extern PFN_vkDestroyCommandPool vkDestroyCommandPool; +extern PFN_vkResetCommandPool vkResetCommandPool; +extern PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers; +extern PFN_vkFreeCommandBuffers vkFreeCommandBuffers; +extern PFN_vkBeginCommandBuffer vkBeginCommandBuffer; +extern PFN_vkEndCommandBuffer vkEndCommandBuffer; +extern PFN_vkResetCommandBuffer vkResetCommandBuffer; +extern PFN_vkCmdBindPipeline vkCmdBindPipeline; +extern PFN_vkCmdSetViewport vkCmdSetViewport; +extern PFN_vkCmdSetScissor vkCmdSetScissor; +extern PFN_vkCmdSetLineWidth vkCmdSetLineWidth; +extern PFN_vkCmdSetDepthBias vkCmdSetDepthBias; +extern PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants; +extern PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds; +extern PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask; +extern PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask; +extern PFN_vkCmdSetStencilReference vkCmdSetStencilReference; +extern PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets; +extern PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer; +extern PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers; +extern PFN_vkCmdDraw vkCmdDraw; +extern PFN_vkCmdDrawIndexed vkCmdDrawIndexed; +extern PFN_vkCmdDrawIndirect vkCmdDrawIndirect; +extern PFN_vkCmdDrawIndexedIndirect vkCmdDrawIndexedIndirect; +extern PFN_vkCmdDispatch vkCmdDispatch; +extern PFN_vkCmdDispatchIndirect vkCmdDispatchIndirect; +extern PFN_vkCmdCopyBuffer vkCmdCopyBuffer; +extern PFN_vkCmdCopyImage vkCmdCopyImage; +extern PFN_vkCmdBlitImage vkCmdBlitImage; +extern PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage; +extern PFN_vkCmdCopyImageToBuffer vkCmdCopyImageToBuffer; +extern PFN_vkCmdUpdateBuffer vkCmdUpdateBuffer; +extern PFN_vkCmdFillBuffer vkCmdFillBuffer; +extern PFN_vkCmdClearColorImage vkCmdClearColorImage; +extern PFN_vkCmdClearDepthStencilImage vkCmdClearDepthStencilImage; +extern PFN_vkCmdClearAttachments vkCmdClearAttachments; +extern PFN_vkCmdResolveImage vkCmdResolveImage; +extern PFN_vkCmdSetEvent vkCmdSetEvent; +extern PFN_vkCmdResetEvent vkCmdResetEvent; +extern PFN_vkCmdWaitEvents vkCmdWaitEvents; +extern PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier; +extern PFN_vkCmdBeginQuery vkCmdBeginQuery; +extern PFN_vkCmdEndQuery vkCmdEndQuery; +extern PFN_vkCmdResetQueryPool vkCmdResetQueryPool; +extern PFN_vkCmdWriteTimestamp vkCmdWriteTimestamp; +extern PFN_vkCmdCopyQueryPoolResults vkCmdCopyQueryPoolResults; +extern PFN_vkCmdPushConstants vkCmdPushConstants; +extern PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass; +extern PFN_vkCmdNextSubpass vkCmdNextSubpass; +extern PFN_vkCmdEndRenderPass vkCmdEndRenderPass; +extern PFN_vkCmdExecuteCommands vkCmdExecuteCommands; + +#ifdef ANDROID +extern PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR; +#elif defined(_WIN32) +extern PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR; +#endif + +extern PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR; + +// Simple loader for the WSI extension. +extern PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR; +extern PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR; +extern PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR; +extern PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR; + +extern PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR; +extern PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR; +extern PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR; +extern PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR; +extern PFN_vkQueuePresentKHR vkQueuePresentKHR; + +// And the DEBUG_REPORT extension. +extern PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT; +extern PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT; + +bool VulkanLoad(); +void VulkanLoadInstanceFunctions(VkInstance instance); +void VulkanLoadDeviceFunctions(VkDevice device); +void VulkanFree(); + diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index af495f53ff..c12f8d9390 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -183,10 +183,10 @@ DrawEngineVulkan::~DrawEngineVulkan() { FreeMemoryPages(transformedExpanded, 3 * TRANSFORMED_VERTEX_BUFFER_SIZE); for (int i = 0; i < 2; i++) { - vulkan_->QueueDelete(frame_[i].descPool); + vulkan_->Delete().QueueDeleteDescriptorPool(frame_[i].descPool); delete frame_[i].pushData; } - vulkan_->QueueDelete(depalSampler_); + vulkan_->Delete().QueueDeleteSampler(depalSampler_); } void DrawEngineVulkan::BeginFrame() { @@ -379,7 +379,7 @@ VkDescriptorSet DrawEngineVulkan::GetDescriptorSet(VkImageView imageView, VkSamp DescriptorSetKey key; key.imageView_ = imageView; key.sampler_ = sampler; - key.secondaryImageView_ = nullptr; + key.secondaryImageView_ = VK_NULL_HANDLE; key.buffer_ = dynamicUbo; FrameData *frame = &frame_[curFrame_ & 1]; @@ -461,8 +461,8 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) { // the three ubo pushes. The reason is that the three UBOs must be in the same buffer as that's how we // designed the descriptor set. - VkImageView imageView = nullptr; - VkSampler sampler = nullptr; + VkImageView imageView = VK_NULL_HANDLE; + VkSampler sampler = VK_NULL_HANDLE; if (gstate_c.textureChanged != TEXCHANGE_UNCHANGED && !gstate.isModeClear() && gstate.isTextureMapEnabled()) { textureCache_->SetTexture(); diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferVulkan.cpp index 76c621c6f2..ae5c1ca13e 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferVulkan.cpp @@ -15,8 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#pragma once - #include #include diff --git a/GPU/Vulkan/FramebufferVulkan.h b/GPU/Vulkan/FramebufferVulkan.h index 2bd75f9cc7..510714458e 100644 --- a/GPU/Vulkan/FramebufferVulkan.h +++ b/GPU/Vulkan/FramebufferVulkan.h @@ -17,7 +17,7 @@ #pragma once -#include "GPU/Vulkan/VulkanUtil.h" +#include "Common/Vulkan/VulkanLoader.h" #include "GPU/Common/FramebufferCommon.h" #include "GPU/GPUInterface.h" #include "GPU/Common/GPUDebugInterface.h" diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index 155a65be91..a666094708 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -14,7 +14,7 @@ PipelineManagerVulkan::PipelineManagerVulkan(VulkanContext *vulkan) : vulkan_(vu PipelineManagerVulkan::~PipelineManagerVulkan() { Clear(); - vulkan_->QueueDelete(pipelineCache_); + vulkan_->Delete().QueueDeletePipelineCache(pipelineCache_); } void PipelineManagerVulkan::Clear() { @@ -29,7 +29,7 @@ void PipelineManagerVulkan::Clear() { struct DeclTypeInfo { VkFormat type; - const char * name; + const char *name; }; static const DeclTypeInfo VComp[] = { @@ -264,7 +264,7 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip pipe.pInputAssemblyState = &inputAssembly; pipe.pMultisampleState = &ms; pipe.layout = layout; - pipe.basePipelineHandle = nullptr; + pipe.basePipelineHandle = VK_NULL_HANDLE; pipe.basePipelineIndex = 0; pipe.renderPass = renderPass; pipe.subpass = 0; @@ -317,6 +317,8 @@ std::vector PipelineManagerVulkan::DebugGetObjectIDs(DebugShaderTyp } } break; + default: + break; } return ids; } diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index 3a0230d53d..691b8667ef 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -42,7 +42,7 @@ #include "UI/OnScreenDisplay.h" VulkanFragmentShader::VulkanFragmentShader(VulkanContext *vulkan, ShaderID id, const char *code, bool useHWTransform) - : vulkan_(vulkan), id_(id), failed_(false), useHWTransform_(useHWTransform), module_(nullptr) { + : vulkan_(vulkan), id_(id), failed_(false), useHWTransform_(useHWTransform), module_(0) { source_ = code; std::string errorMessage; @@ -83,7 +83,7 @@ VulkanFragmentShader::VulkanFragmentShader(VulkanContext *vulkan, ShaderID id, c VulkanFragmentShader::~VulkanFragmentShader() { if (module_) { - vulkan_->QueueDelete(module_); + vulkan_->Delete().QueueDeleteShaderModule(module_); } } @@ -99,7 +99,7 @@ std::string VulkanFragmentShader::GetShaderString(DebugShaderStringType type) co } VulkanVertexShader::VulkanVertexShader(VulkanContext *vulkan, ShaderID id, const char *code, int vertType, bool useHWTransform) - : vulkan_(vulkan), id_(id), failed_(false), useHWTransform_(useHWTransform), module_(nullptr) { + : vulkan_(vulkan), id_(id), failed_(false), useHWTransform_(useHWTransform), module_(VK_NULL_HANDLE) { source_ = code; std::string errorMessage; std::vector spirv; @@ -127,7 +127,7 @@ VulkanVertexShader::VulkanVertexShader(VulkanContext *vulkan, ShaderID id, const if (!success) { failed_ = true; - module_ = nullptr; + module_ = VK_NULL_HANDLE; return; } else { DEBUG_LOG(G3D, "Compiled shader:\n%s\n", (const char *)code); @@ -136,7 +136,7 @@ VulkanVertexShader::VulkanVertexShader(VulkanContext *vulkan, ShaderID id, const VulkanVertexShader::~VulkanVertexShader() { if (module_) { - vulkan_->QueueDelete(module_); + vulkan_->Delete().QueueDeleteShaderModule(module_); } } @@ -536,16 +536,18 @@ std::vector ShaderManagerVulkan::DebugGetShaderIDs(DebugShaderType iter.first.ToString(&id); ids.push_back(id); } + break; } - break; case SHADER_TYPE_FRAGMENT: { for (auto iter : fsCache_) { iter.first.ToString(&id); ids.push_back(id); } + break; } - break; + default: + break; } return ids; } diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index 0a095d6345..488439999f 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -15,8 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#define VK_PROTOTYPES -#include "ext/vulkan/vulkan.h" +#include "Common/Vulkan/VulkanLoader.h" #include "GPU/Math3D.h" #include "GPU/GPUState.h" diff --git a/GPU/Vulkan/StateMappingVulkan.h b/GPU/Vulkan/StateMappingVulkan.h index 3275fc268b..8bb8aa0a07 100644 --- a/GPU/Vulkan/StateMappingVulkan.h +++ b/GPU/Vulkan/StateMappingVulkan.h @@ -1,6 +1,6 @@ #pragma once -#include "ext/vulkan/vulkan.h" +#include "Common/Vulkan/VulkanLoader.h" #include diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 8bfc89f90e..a38835dff6 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -75,7 +75,7 @@ extern int g_iNumVideos; SamplerCache::~SamplerCache() { for (auto iter : cache_) { - vulkan_->QueueDelete(iter.second); + vulkan_->Delete().QueueDeleteSampler(iter.second); } } @@ -848,8 +848,8 @@ void TextureCacheVulkan::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFram void TextureCacheVulkan::ApplyTexture(VkImageView &imageView, VkSampler &sampler) { if (nextTexture_ == nullptr) { - imageView = nullptr; - sampler = nullptr; + imageView = VK_NULL_HANDLE; + sampler = VK_NULL_HANDLE; return; } VkCommandBuffer cmd = nullptr; diff --git a/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp b/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp index 83ad78d3f9..152a274ee4 100644 --- a/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp +++ b/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp @@ -26,6 +26,7 @@ #endif #include "base/stringutil.h" +#include "Common/Vulkan/VulkanLoader.h" #include "GPU/ge_constants.h" #include "GPU/GPUState.h" #include "GPU/Common/ShaderId.h" diff --git a/GPU/Vulkan/VulkanUtil.h b/GPU/Vulkan/VulkanUtil.h index f0c8496d91..fe41a2b8e0 100644 --- a/GPU/Vulkan/VulkanUtil.h +++ b/GPU/Vulkan/VulkanUtil.h @@ -1,4 +1,4 @@ #pragma once -#include "ext/vulkan/vulkan.h" +#include "Common/Vulkan/VulkanLoader.h" diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index b6462aa651..b30f7788e8 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -50,7 +50,7 @@ #include #include -#include "ext/vulkan/vulkan.h" +#include "Common/Vulkan/VulkanLoader.h" #include "ext/native/thin3d/VulkanContext.h" #include "thin3d/thin3d.h" diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 04ad94d17f..fc6cd779ec 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -124,9 +124,8 @@ EGL_FILES := \ $(SRC)/Common/GL/GLInterface/EGLAndroid.cpp \ $(SRC)/Common/GL/GLInterface/GLInterface.cpp -# Only build Vulkan on ARM64 for now. -ifeq ($(TARGET_ARCH_ABI),arm64-v8a) VULKAN_FILES := \ + $(SRC)/Common/Vulkan/VulkanLoader.cpp \ $(SRC)/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp \ $(SRC)/GPU/Vulkan/DrawEngineVulkan.cpp \ $(SRC)/GPU/Vulkan/FramebufferVulkan.cpp \ @@ -138,9 +137,7 @@ VULKAN_FILES := \ $(SRC)/GPU/Vulkan/TextureScalerVulkan.cpp \ $(SRC)/GPU/Vulkan/DepalettizeShaderVulkan.cpp \ $(SRC)/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp -else -VULKAN_FILES := -endif +#endif EXEC_AND_LIB_FILES := \ $(ARCH_FILES) \ @@ -511,6 +508,7 @@ endif $(call import-module,libzip) $(call import-module,native) +$(call import-module,glslang) ifeq ($(ANDROID_NDK_PROFILER),1) $(call import-module,android-ndk-profiler) diff --git a/android/jni/Locals.mk b/android/jni/Locals.mk index 67c19581f7..bc8dea52b8 100644 --- a/android/jni/Locals.mk +++ b/android/jni/Locals.mk @@ -15,7 +15,7 @@ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/$(NATIVE) \ $(LOCAL_PATH) -LOCAL_STATIC_LIBRARIES := native libzip +LOCAL_STATIC_LIBRARIES := native libzip glslang LOCAL_LDLIBS := -lz -landroid -lGLESv2 -lOpenSLES -lEGL -ldl -llog # ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) diff --git a/ext/native/Android.mk b/ext/native/Android.mk index 28542deac3..9ac0f5f8db 100644 --- a/ext/native/Android.mk +++ b/ext/native/Android.mk @@ -81,6 +81,8 @@ LOCAL_SRC_FILES :=\ image/png_load.cpp \ thin3d/thin3d.cpp \ thin3d/thin3d_gl.cpp \ + thin3d/thin3d_vulkan.cpp \ + thin3d/VulkanContext.cpp \ ui/view.cpp \ ui/viewgroup.cpp \ ui/ui.cpp \ @@ -94,7 +96,7 @@ LOCAL_SRC_FILES :=\ LOCAL_CFLAGS := -O3 -DUSING_GLES2 -fsigned-char -fno-strict-aliasing -Wall -Wno-multichar -D__STDC_CONSTANT_MACROS LOCAL_CPPFLAGS := -fno-exceptions -std=gnu++11 -fno-rtti -Wno-reorder -LOCAL_C_INCLUDES := $(LOCAL_PATH)/ext $(LOCAL_PATH)/ext/libzip +LOCAL_C_INCLUDES := $(LOCAL_PATH)/ext $(LOCAL_PATH)/ext/libzip .. #Portable native and separate code on android in future is easy you needs add files #by ($(target_arch_ABI),arquitecture (armeabi-v7a , armeabi , x86 , MIPS) diff --git a/ext/native/thin3d/VulkanContext.cpp b/ext/native/thin3d/VulkanContext.cpp index 4d47968627..d0634669a9 100644 --- a/ext/native/thin3d/VulkanContext.cpp +++ b/ext/native/thin3d/VulkanContext.cpp @@ -1,4 +1,6 @@ +#define __STDC_LIMIT_MACROS #include +#include #include #include #include @@ -9,73 +11,70 @@ #undef new #endif +#ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4996) -#include "glslang/SPIRV/GlslangToSpv.h" +#endif + +#include "ext/glslang/SPIRV/GlslangToSpv.h" + +#ifdef _MSC_VER #pragma warning(pop) +#endif #ifdef USE_CRT_DBG #define new DBG_NEW #endif -#define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \ -{ \ - fp##entrypoint = (PFN_vk##entrypoint) vkGetInstanceProcAddr(inst, "vk"#entrypoint); \ - if (fp##entrypoint == NULL) { \ - std::cout << "vkGetDeviceProcAddr failed to find vk"#entrypoint; \ - exit(-1); \ - } \ -} - -#define GET_DEVICE_PROC_ADDR(dev, entrypoint) \ -{ \ - fp##entrypoint = (PFN_vk##entrypoint) vkGetDeviceProcAddr(dev, "vk"#entrypoint); \ - if (fp##entrypoint == NULL) { \ - std::cout << "vkGetDeviceProcAddr failed to find vk"#entrypoint; \ - exit(-1); \ - } \ -} - using namespace std; VulkanContext::VulkanContext(const char *app_name, uint32_t flags) : device_(nullptr), - gfx_queue_(nullptr), + gfx_queue_(VK_NULL_HANDLE), +#ifdef _WIN32 connection(nullptr), - graphics_queue_family_index_(-1), - surface(nullptr), window(nullptr), +#elif defined(ANDROID) + native_window(nullptr), +#endif + graphics_queue_family_index_(-1), + surface(VK_NULL_HANDLE), prepared(false), use_staging_buffer_(false), - instance_(nullptr), + instance_(VK_NULL_HANDLE), width(0), height(0), flags_(flags), swapchain_format(VK_FORMAT_UNDEFINED), swapchainImageCount(0), - swap_chain_(nullptr), - cmd_pool_(nullptr), - dbgCreateMsgCallback(nullptr), - dbgDestroyMsgCallback(nullptr), + swap_chain_(VK_NULL_HANDLE), + cmd_pool_(VK_NULL_HANDLE), queue_count(0), curFrame_(0) { + if (!VulkanLoad()) { + // No DLL? + return; + } // List extensions to try to enable. instance_extension_names.push_back(VK_KHR_SURFACE_EXTENSION_NAME); +#ifdef _WIN32 instance_extension_names.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); +#elif defined(ANDROID) + instance_extension_names.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); +#endif device_extension_names.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - // DrawState validation is broken, hangs on vkResetDescriptorPool. if (flags & VULKAN_FLAG_VALIDATE) { instance_layer_names.push_back("VK_LAYER_LUNARG_threading"); - // instance_layer_names.push_back("VK_LAYER_LUNARG_draw_state"); + instance_layer_names.push_back("VK_LAYER_LUNARG_draw_state"); instance_layer_names.push_back("VK_LAYER_LUNARG_image"); instance_layer_names.push_back("VK_LAYER_LUNARG_mem_tracker"); instance_layer_names.push_back("VK_LAYER_LUNARG_object_tracker"); instance_layer_names.push_back("VK_LAYER_LUNARG_param_checker"); device_layer_names.push_back("VK_LAYER_LUNARG_threading"); - // device_layer_names.push_back("VK_LAYER_LUNARG_draw_state"); + device_layer_names.push_back("VK_LAYER_LUNARG_draw_state"); device_layer_names.push_back("VK_LAYER_LUNARG_image"); device_layer_names.push_back("VK_LAYER_LUNARG_mem_tracker"); device_layer_names.push_back("VK_LAYER_LUNARG_object_tracker"); @@ -106,10 +105,7 @@ VulkanContext::VulkanContext(const char *app_name, uint32_t flags) VkResult res = vkCreateInstance(&inst_info, NULL, &instance_); assert(res == VK_SUCCESS); - GET_INSTANCE_PROC_ADDR(instance_, GetPhysicalDeviceSurfaceSupportKHR); - GET_INSTANCE_PROC_ADDR(instance_, GetPhysicalDeviceSurfaceCapabilitiesKHR); - GET_INSTANCE_PROC_ADDR(instance_, GetPhysicalDeviceSurfaceFormatsKHR); - GET_INSTANCE_PROC_ADDR(instance_, GetPhysicalDeviceSurfacePresentModesKHR); + VulkanLoadInstanceFunctions(instance_); uint32_t gpu_count = 1; res = vkEnumeratePhysicalDevices(instance_, &gpu_count, NULL); @@ -133,6 +129,7 @@ VulkanContext::VulkanContext(const char *app_name, uint32_t flags) VulkanContext::~VulkanContext() { vkDestroyInstance(instance_, NULL); + VulkanFree(); } void TransitionToPresent(VkCommandBuffer cmd, VkImage image) { @@ -193,8 +190,7 @@ VkCommandBuffer VulkanContext::BeginSurfaceRenderPass(VkClearValue clear_values[ // Get the index of the next available swapchain image, and a semaphore to block command buffer execution on. // Now, I wonder if we should do this early in the frame or late? Right now we do it early, which should be fine. - VkResult res = fpAcquireNextImageKHR(device_, swap_chain_, - UINT64_MAX, acquireSemaphore, NULL, ¤t_buffer); + VkResult res = vkAcquireNextImageKHR(device_, swap_chain_, UINT64_MAX, acquireSemaphore, NULL, ¤t_buffer); // TODO: Deal with the VK_SUBOPTIMAL_KHR and VK_ERROR_OUT_OF_DATE_KHR // return codes @@ -282,7 +278,7 @@ void VulkanContext::EndSurfaceRenderPass() { present.waitSemaphoreCount = 0; present.pResults = NULL; - res = fpQueuePresentKHR(gfx_queue_, &present); + res = vkQueuePresentKHR(gfx_queue_, &present); // TODO: Deal with the VK_SUBOPTIMAL_WSI and VK_ERROR_OUT_OF_DATE_WSI // return codes assert(!res); @@ -645,11 +641,7 @@ VkResult VulkanContext::CreateDevice(int physical_device) { res = vkCreateDevice(physical_devices_[0], &device_info, NULL, &device_); assert(res == VK_SUCCESS); - GET_DEVICE_PROC_ADDR(device_, CreateSwapchainKHR); - GET_DEVICE_PROC_ADDR(device_, DestroySwapchainKHR); - GET_DEVICE_PROC_ADDR(device_, GetSwapchainImagesKHR); - GET_DEVICE_PROC_ADDR(device_, AcquireNextImageKHR); - GET_DEVICE_PROC_ADDR(device_, QueuePresentKHR); + VulkanLoadDeviceFunctions(device_); return res; } @@ -658,25 +650,13 @@ VkResult VulkanContext::InitDebugMsgCallback(PFN_vkDebugReportCallbackEXT dbgFun VkResult res; VkDebugReportCallbackEXT msg_callback; - dbgCreateMsgCallback = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance_, "vkCreateDebugReportCallbackEXT"); - if (!dbgCreateMsgCallback) { - std::cout << "GetInstanceProcAddr: Unable to find vkDbgCreateMsgCallback function." << std::endl; - return VK_ERROR_INITIALIZATION_FAILED; - } - - dbgDestroyMsgCallback = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance_, "vkDestroyDebugReportCallbackEXT"); - if (!dbgDestroyMsgCallback) { - std::cout << "GetInstanceProcAddr: Unable to find vkDbgDestroyMsgCallback function." << std::endl; - return VK_ERROR_INITIALIZATION_FAILED; - } - VkDebugReportCallbackCreateInfoEXT cb; cb.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; cb.pNext = nullptr; cb.flags = bits; cb.pfnCallback = dbgFunc; cb.pUserData = userdata; - res = dbgCreateMsgCallback(instance_, &cb, nullptr, &msg_callback); + res = vkCreateDebugReportCallbackEXT(instance_, &cb, nullptr, &msg_callback); switch (res) { case VK_SUCCESS: msg_callbacks.push_back(msg_callback); @@ -695,7 +675,7 @@ VkResult VulkanContext::InitDebugMsgCallback(PFN_vkDebugReportCallbackEXT dbgFun void VulkanContext::DestroyDebugMsgCallback() { while (msg_callbacks.size() > 0) { - dbgDestroyMsgCallback(instance_, msg_callbacks.back(), nullptr); + vkDestroyDebugReportCallbackEXT(instance_, msg_callbacks.back(), nullptr); msg_callbacks.pop_back(); } } @@ -816,9 +796,8 @@ void VulkanContext::InitSurfaceWin32(HINSTANCE conn, HWND wnd) { assert(res == VK_SUCCESS); } #elif defined(ANDROID) -void VulkanContext::InitSurfaceAndroid(ANativeWindow *native_window, int width, int height) { - connection = conn; - window = wnd; +void VulkanContext::InitSurfaceAndroid(ANativeWindow *wnd, int width, int height) { + native_window = wnd; VkResult U_ASSERT_ONLY res; @@ -840,7 +819,7 @@ void VulkanContext::InitQueue() { // Iterate over each queue to learn whether it supports presenting: VkBool32* supportsPresent = new VkBool32[queue_count]; for (uint32_t i = 0; i < queue_count; i++) { - fpGetPhysicalDeviceSurfaceSupportKHR(physical_devices_[0], i, surface, &supportsPresent[i]); + vkGetPhysicalDeviceSurfaceSupportKHR(physical_devices_[0], i, surface, &supportsPresent[i]); } // Search for a graphics queue and a present queue in the array of queue @@ -882,12 +861,12 @@ void VulkanContext::InitQueue() { // Get the list of VkFormats that are supported: uint32_t formatCount; - VkResult res = fpGetPhysicalDeviceSurfaceFormatsKHR(physical_devices_[0], + VkResult res = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_devices_[0], surface, &formatCount, NULL); assert(res == VK_SUCCESS); VkSurfaceFormatKHR *surfFormats = new VkSurfaceFormatKHR[formatCount]; - res = fpGetPhysicalDeviceSurfaceFormatsKHR(physical_devices_[0], + res = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_devices_[0], surface, &formatCount, surfFormats); assert(res == VK_SUCCESS); @@ -920,26 +899,26 @@ void VulkanContext::InitSwapchain(VkCommandBuffer cmd) { VkResult U_ASSERT_ONLY res; VkSurfaceCapabilitiesKHR surfCapabilities; - res = fpGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_devices_[0], + res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_devices_[0], surface, &surfCapabilities); assert(res == VK_SUCCESS); uint32_t presentModeCount; - res = fpGetPhysicalDeviceSurfacePresentModesKHR(physical_devices_[0], + res = vkGetPhysicalDeviceSurfacePresentModesKHR(physical_devices_[0], surface, &presentModeCount, NULL); assert(res == VK_SUCCESS); VkPresentModeKHR *presentModes = new VkPresentModeKHR[presentModeCount]; assert(presentModes); - res = fpGetPhysicalDeviceSurfacePresentModesKHR(physical_devices_[0], + res = vkGetPhysicalDeviceSurfacePresentModesKHR(physical_devices_[0], surface, &presentModeCount, presentModes); assert(res == VK_SUCCESS); VkExtent2D swapChainExtent; // width and height are either both -1, or both not -1. - if (surfCapabilities.currentExtent.width == -1) { + if (surfCapabilities.currentExtent.width == (uint32_t)-1) { // If the surface size is undefined, the size is set to // the size of the images requested. swapChainExtent.width = width; @@ -1006,16 +985,16 @@ void VulkanContext::InitSwapchain(VkCommandBuffer cmd) { swap_chain_info.queueFamilyIndexCount = 0; swap_chain_info.pQueueFamilyIndices = NULL; - res = fpCreateSwapchainKHR(device_, &swap_chain_info, NULL, &swap_chain_); + res = vkCreateSwapchainKHR(device_, &swap_chain_info, NULL, &swap_chain_); assert(res == VK_SUCCESS); - res = fpGetSwapchainImagesKHR(device_, swap_chain_, + res = vkGetSwapchainImagesKHR(device_, swap_chain_, &swapchainImageCount, NULL); assert(res == VK_SUCCESS); VkImage* swapchainImages = (VkImage*)malloc(swapchainImageCount * sizeof(VkImage)); assert(swapchainImages); - res = fpGetSwapchainImagesKHR(device_, swap_chain_, &swapchainImageCount, swapchainImages); + res = vkGetSwapchainImagesKHR(device_, swap_chain_, &swapchainImageCount, swapchainImages); assert(res == VK_SUCCESS); for (uint32_t i = 0; i < swapchainImageCount; i++) { @@ -1175,12 +1154,12 @@ VkResult VulkanTexture::Create(int w, int h, VkFormat format) { void VulkanTexture::CreateMappableImage() { // If we already have a mappableImage, forget it. if (mappableImage) { - vulkan_->QueueDelete(mappableImage); - mappableImage = nullptr; + vulkan_->Delete().QueueDeleteImage(mappableImage); + mappableImage = VK_NULL_HANDLE; } if (mappableMemory) { - vulkan_->QueueDelete(mappableMemory); - mappableMemory = nullptr; + vulkan_->Delete().QueueDeleteDeviceMemory(mappableMemory); + mappableMemory = VK_NULL_HANDLE; } bool U_ASSERT_ONLY pass; @@ -1257,16 +1236,16 @@ void VulkanTexture::Unlock() { // if we already have an image, queue it for destruction and forget it. if (image) { - vulkan_->QueueDelete(image); - image = nullptr; + vulkan_->Delete().QueueDeleteImage(image); + image = VK_NULL_HANDLE; } if (view) { - vulkan_->QueueDelete(view); - view = nullptr; + vulkan_->Delete().QueueDeleteImageView(view); + view = VK_NULL_HANDLE; } if (mem) { - vulkan_->QueueDelete(mem); - mem = nullptr; + vulkan_->Delete().QueueDeleteDeviceMemory(mem); + mem = VK_NULL_HANDLE; } if (!needStaging) { /* If we can use the linear tiled image as a texture, just do it */ @@ -1362,10 +1341,10 @@ void VulkanTexture::Unlock() { VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, imageLayout); - vulkan_->QueueDelete(mappableMemory); - vulkan_->QueueDelete(mappableImage); - mappableImage = nullptr; - mappableMemory = nullptr; + vulkan_->Delete().QueueDeleteDeviceMemory(mappableMemory); + vulkan_->Delete().QueueDeleteImage(mappableImage); + mappableImage = VK_NULL_HANDLE; + mappableMemory = VK_NULL_HANDLE; } VkImageViewCreateInfo view_info = {}; @@ -1392,24 +1371,24 @@ void VulkanTexture::Unlock() { void VulkanTexture::Destroy() { if (view) { - vulkan_->QueueDelete(view); + vulkan_->Delete().QueueDeleteImageView(view); } if (image) { - vulkan_->QueueDelete(image); + vulkan_->Delete().QueueDeleteImage(image); if (mappableImage == image) { - mappableImage = nullptr; + mappableImage = VK_NULL_HANDLE; } } if (mem) { - vulkan_->QueueDelete(mem); + vulkan_->Delete().QueueDeleteDeviceMemory(mem); if (mappableMemory == mem) { - mappableMemory = nullptr; + mappableMemory = VK_NULL_HANDLE; } } - view = nullptr; - image = nullptr; - mem = nullptr; + view = VK_NULL_HANDLE; + image = VK_NULL_HANDLE; + mem = VK_NULL_HANDLE; } VkFence VulkanContext::CreateFence(bool presignalled) { @@ -1429,24 +1408,24 @@ void VulkanContext::WaitAndResetFence(VkFence fence) { void VulkanContext::DestroyCommandPool() { vkDestroyCommandPool(device_, cmd_pool_, NULL); - cmd_pool_ = nullptr; + cmd_pool_ = VK_NULL_HANDLE; } void VulkanContext::DestroyDepthStencilBuffer() { vkDestroyImageView(device_, depth.view, NULL); vkDestroyImage(device_, depth.image, NULL); vkFreeMemory(device_, depth.mem, NULL); - depth.view = NULL; - depth.image = NULL; - depth.mem = NULL; + depth.view = VK_NULL_HANDLE; + depth.image = VK_NULL_HANDLE; + depth.mem = VK_NULL_HANDLE; } void VulkanContext::DestroySwapChain() { for (uint32_t i = 0; i < swapchainImageCount; i++) { vkDestroyImageView(device_, swapChainBuffers[i].view, NULL); } - fpDestroySwapchainKHR(device_, swap_chain_, NULL); - swap_chain_ = nullptr; + vkDestroySwapchainKHR(device_, swap_chain_, NULL); + swap_chain_ = VK_NULL_HANDLE; swapChainBuffers.clear(); vkDestroySemaphore(device_, acquireSemaphore, NULL); } @@ -1772,5 +1751,5 @@ void VulkanFramebuffer::TransitionToTexture(VkCommandBuffer cmd) { } VkImageView VulkanFramebuffer::GetColorImageView() { - return nullptr; + return VK_NULL_HANDLE; } diff --git a/ext/native/thin3d/VulkanContext.h b/ext/native/thin3d/VulkanContext.h index c721ac4925..1b7ac7ce9c 100644 --- a/ext/native/thin3d/VulkanContext.h +++ b/ext/native/thin3d/VulkanContext.h @@ -44,8 +44,7 @@ #include #endif // _WIN32 -#include "vulkan/vulkan.h" -#include "vulkan/vk_sdk_platform.h" +#include "Common/Vulkan/VulkanLoader.h" /* Amount of time, in nanoseconds, to wait for a command buffer to complete */ #define FENCE_TIMEOUT 10000000000 @@ -72,15 +71,15 @@ struct layer_properties { // This is a bit repetitive... class VulkanDeleteList { public: - void QueueDelete(VkDescriptorPool pool) { descPools_.push_back(pool); } - void QueueDelete(VkShaderModule module) { modules_.push_back(module); } - void QueueDelete(VkBuffer buffer) { buffers_.push_back(buffer); } - void QueueDelete(VkBufferView bufferView) { bufferViews_.push_back(bufferView); } - void QueueDelete(VkImage image) { images_.push_back(image); } - void QueueDelete(VkImageView imageView) { imageViews_.push_back(imageView); } - void QueueDelete(VkDeviceMemory deviceMemory) { deviceMemory_.push_back(deviceMemory); } - void QueueDelete(VkSampler sampler) { samplers_.push_back(sampler); } - void QueueDelete(VkPipelineCache pipelineCache) { pipelineCaches_.push_back(pipelineCache); } + void QueueDeleteDescriptorPool(VkDescriptorPool pool) { descPools_.push_back(pool); } + void QueueDeleteShaderModule(VkShaderModule module) { modules_.push_back(module); } + void QueueDeleteBuffer(VkBuffer buffer) { buffers_.push_back(buffer); } + void QueueDeleteBufferView(VkBufferView bufferView) { bufferViews_.push_back(bufferView); } + void QueueDeleteImage(VkImage image) { images_.push_back(image); } + void QueueDeleteImageView(VkImageView imageView) { imageViews_.push_back(imageView); } + void QueueDeleteDeviceMemory(VkDeviceMemory deviceMemory) { deviceMemory_.push_back(deviceMemory); } + void QueueDeleteSampler(VkSampler sampler) { samplers_.push_back(sampler); } + void QueueDeletePipelineCache(VkPipelineCache pipelineCache) { pipelineCaches_.push_back(pipelineCache); } void Take(VulkanDeleteList &del) { descPools_ = std::move(del.descPools_); @@ -154,10 +153,7 @@ public: return device_; } - template - void QueueDelete(T mem) { - globalDeleteList_.QueueDelete(mem); - } + VulkanDeleteList &Delete() { return globalDeleteList_; } VkPipelineCache CreatePipelineCache(); @@ -254,7 +250,7 @@ private: #ifdef _WIN32 HINSTANCE connection; // hInstance - Windows Instance - HWND window; // hWnd - window handle + HWND window; // hWnd - window handle #elif ANDROID // _WIN32 ANativeWindow *native_window; #else @@ -325,19 +321,6 @@ private: // the next time the frame comes around again. VulkanDeleteList globalDeleteList_; - // Simple loader for the WSI extension. - PFN_vkGetPhysicalDeviceSurfaceSupportKHR fpGetPhysicalDeviceSurfaceSupportKHR; - PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR fpGetPhysicalDeviceSurfaceCapabilitiesKHR; - PFN_vkGetPhysicalDeviceSurfaceFormatsKHR fpGetPhysicalDeviceSurfaceFormatsKHR; - PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fpGetPhysicalDeviceSurfacePresentModesKHR; - PFN_vkCreateSwapchainKHR fpCreateSwapchainKHR; - PFN_vkDestroySwapchainKHR fpDestroySwapchainKHR; - PFN_vkGetSwapchainImagesKHR fpGetSwapchainImagesKHR; - PFN_vkAcquireNextImageKHR fpAcquireNextImageKHR; - PFN_vkQueuePresentKHR fpQueuePresentKHR; - // And the DEBUG_REPORT extension. - PFN_vkCreateDebugReportCallbackEXT dbgCreateMsgCallback; - PFN_vkDestroyDebugReportCallbackEXT dbgDestroyMsgCallback; std::vector msg_callbacks; struct { @@ -363,8 +346,8 @@ private: class VulkanTexture { public: VulkanTexture(VulkanContext *vulkan) - : vulkan_(vulkan), image(nullptr), imageLayout(VK_IMAGE_LAYOUT_UNDEFINED), mem(nullptr), view(nullptr), tex_width(0), tex_height(0), format_(VK_FORMAT_UNDEFINED), - mappableImage(nullptr), mappableMemory(nullptr), needStaging(false) { + : vulkan_(vulkan), image(0), imageLayout(VK_IMAGE_LAYOUT_UNDEFINED), mem(0), view(0), tex_width(0), tex_height(0), format_(VK_FORMAT_UNDEFINED), + mappableImage(0), mappableMemory(0), needStaging(false) { memset(&mem_reqs, 0, sizeof(mem_reqs)); } ~VulkanTexture() { @@ -424,7 +407,7 @@ private: // buffer handle on overflow. class VulkanPushBuffer { public: - VulkanPushBuffer(VulkanContext *vulkan, size_t size) : offset_(0), size_(size), writePtr_(nullptr), deviceMemory_(nullptr) { + VulkanPushBuffer(VulkanContext *vulkan, size_t size) : offset_(0), size_(size), writePtr_(nullptr), deviceMemory_(0) { VkDevice device = vulkan->GetDevice(); VkBufferCreateInfo b = {}; @@ -453,8 +436,8 @@ public: } void Destroy(VulkanContext *vulkan) { - vulkan->QueueDelete(buffer_); - vulkan->QueueDelete(deviceMemory_); + vulkan->Delete().QueueDeleteBuffer(buffer_); + vulkan->Delete().QueueDeleteDeviceMemory(deviceMemory_); } void Reset() { offset_ = 0; } diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index c91d9e7c3e..660c12c918 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -38,8 +38,7 @@ // // Vertex data lives in a separate namespace (location = 0, 1, etc) -#define VK_PROTOTYPES -#include "ext/vulkan/vulkan.h" +#include "Common/Vulkan/VulkanLoader.h" // This can actually be replaced with a cast as the values are in the right order. static const VkCompareOp compToVK[] = { @@ -186,7 +185,7 @@ private: // invoke Compile again to recreate the shader then link them together. class Thin3DVKShader : public Thin3DShader { public: - Thin3DVKShader(bool isFragmentShader) : module_(nullptr), ok_(false) { + Thin3DVKShader(bool isFragmentShader) : module_(VK_NULL_HANDLE), ok_(false) { stage_ = isFragmentShader ? VK_SHADER_STAGE_FRAGMENT_BIT : VK_SHADER_STAGE_VERTEX_BIT; } bool Compile(VulkanContext *vulkan, const char *source); @@ -894,7 +893,7 @@ VkPipeline Thin3DVKContext::GetOrCreatePipeline() { VkResult result = vkCreateGraphicsPipelines(device_, pipelineCache_, 1, &info, nullptr, &pipeline); if (result != VK_SUCCESS) { ELOG("Failed to create graphics pipeline"); - return nullptr; + return VK_NULL_HANDLE; } pipelines_.insert(std::make_pair(key, pipeline));