diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index 8ac43081a1..97caad8963 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -83,7 +83,7 @@ Level3 - ../common;..;../ext/native;../ext/native/ext/glew; + ../common;..;../ext;../ext/native;../ext/native/ext/glew; _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) StreamingSIMDExtensions2 Fast @@ -105,7 +105,7 @@ Level3 - ../common;..;../ext/native;../ext/native/ext/glew; + ../common;..;../ext;../ext/native;../ext/native/ext/glew; NotSet Fast false @@ -131,7 +131,7 @@ MaxSpeed true true - ../common;..;../ext/native;../ext/native/ext/glew; + ../common;..;../ext;../ext/native;../ext/native/ext/glew; false StreamingSIMDExtensions2 Fast @@ -157,7 +157,7 @@ MaxSpeed true true - ../common;..;../ext/native;../ext/native/ext/glew; + ../common;..;../ext;../ext/native;../ext/native/ext/glew; false NotSet Fast diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index 0f37bb0d96..77cc2fc877 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -135,6 +135,8 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m return false; } + init_glslang(); + g_Vulkan = new VulkanContext("PPSSPP", VULKAN_FLAG_VALIDATE); g_Vulkan->CreateDevice(0); g_Vulkan->InitDebugMsgCallback(Vulkan_Dbg); @@ -157,6 +159,8 @@ void WindowsVulkanContext::Shutdown() { g_Vulkan->DestroyDevice(); delete g_Vulkan; g_Vulkan = nullptr; + + finalize_glslang(); } Thin3DContext *WindowsVulkanContext::CreateThin3DContext() { diff --git a/ext/native/thin3d/VulkanContext.cpp b/ext/native/thin3d/VulkanContext.cpp index 6a60bc0f22..d5189dd71b 100644 --- a/ext/native/thin3d/VulkanContext.cpp +++ b/ext/native/thin3d/VulkanContext.cpp @@ -1134,10 +1134,10 @@ void VulkanTexture::Create(VulkanContext *vulkan, int w, int h) { /* Create a mappable image. It will be the texture if linear images are ok to be textures */ /* or it will be the staging image if they are not. */ - VkResult res = vkCreateImage(vulkan->Device(), &image_create_info, NULL, &mappableImage); + VkResult res = vkCreateImage(vulkan->GetDevice(), &image_create_info, NULL, &mappableImage); assert(res == VK_SUCCESS); - vkGetImageMemoryRequirements(vulkan->Device(), mappableImage, &mem_reqs); + vkGetImageMemoryRequirements(vulkan->GetDevice(), mappableImage, &mem_reqs); assert(res == VK_SUCCESS); mem_alloc.allocationSize = mem_reqs.size; @@ -1146,10 +1146,10 @@ void VulkanTexture::Create(VulkanContext *vulkan, int w, int h) { pass = vulkan->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &mem_alloc.memoryTypeIndex); assert(pass); - res = vkAllocateMemory(vulkan->Device(), &mem_alloc, NULL, &(mappableMemory)); + res = vkAllocateMemory(vulkan->GetDevice(), &mem_alloc, NULL, &(mappableMemory)); assert(res == VK_SUCCESS); - res = vkBindImageMemory(vulkan->Device(), mappableImage, mappableMemory, 0); + res = vkBindImageMemory(vulkan->GetDevice(), mappableImage, mappableMemory, 0); assert(res == VK_SUCCESS); } @@ -1628,3 +1628,36 @@ void init_glslang() { void finalize_glslang() { glslang::FinalizeProcess(); } + +const char *VulkanResultToString(VkResult res) { + switch (res) { + case VK_NOT_READY: return "VK_NOT_READY"; + case VK_TIMEOUT: return "VK_TIMEOUT"; + case VK_EVENT_SET: return "VK_EVENT_SET"; + case VK_EVENT_RESET: return "VK_EVENT_RESET"; + case VK_INCOMPLETE: return "VK_INCOMPLETE"; + case VK_ERROR_OUT_OF_HOST_MEMORY: return "VK_ERROR_OUT_OF_HOST_MEMORY"; + case VK_ERROR_OUT_OF_DEVICE_MEMORY: return "VK_ERROR_OUT_OF_DEVICE_MEMORY"; + case VK_ERROR_INITIALIZATION_FAILED: return "VK_ERROR_INITIALIZATION_FAILED"; + case VK_ERROR_DEVICE_LOST: return "VK_ERROR_DEVICE_LOST"; + case VK_ERROR_MEMORY_MAP_FAILED: return "VK_ERROR_MEMORY_MAP_FAILED"; + case VK_ERROR_LAYER_NOT_PRESENT: return "VK_ERROR_LAYER_NOT_PRESENT"; + case VK_ERROR_EXTENSION_NOT_PRESENT: return "VK_ERROR_EXTENSION_NOT_PRESENT"; + case VK_ERROR_FEATURE_NOT_PRESENT: return "VK_ERROR_FEATURE_NOT_PRESENT"; + case VK_ERROR_INCOMPATIBLE_DRIVER: return "VK_ERROR_INCOMPATIBLE_DRIVER"; + case VK_ERROR_TOO_MANY_OBJECTS: return "VK_ERROR_TOO_MANY_OBJECTS"; + case VK_ERROR_FORMAT_NOT_SUPPORTED: return "VK_ERROR_FORMAT_NOT_SUPPORTED"; + case VK_ERROR_SURFACE_LOST_KHR: return "VK_ERROR_SURFACE_LOST_KHR"; + case VK_SUBOPTIMAL_KHR: return "VK_SUBOPTIMAL_KHR"; + case VK_ERROR_OUT_OF_DATE_KHR: return "VK_ERROR_OUT_OF_DATE_KHR"; + case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR"; + case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR"; + default: + return "Unknown"; + } +} + +void VulkanAssertImpl(VkResult check, const char *function, const char *file, int line) { + const char *error = "(none)"; + +} diff --git a/ext/native/thin3d/VulkanContext.h b/ext/native/thin3d/VulkanContext.h index ad382958fa..71aa2a4379 100644 --- a/ext/native/thin3d/VulkanContext.h +++ b/ext/native/thin3d/VulkanContext.h @@ -71,7 +71,7 @@ public: VkResult CreateDevice(int physical_device); - VkDevice Device() { + VkDevice GetDevice() { return device_; } @@ -274,5 +274,10 @@ void TransitionImageLayout( VkImageLayout old_image_layout, VkImageLayout new_image_layout); +void VulkanAssertImpl(VkResult check, const char *function, const char *file, int line); + +// DO NOT call vulkan functions within this! Instead, store the result in a variable and check that. +#define VulkanAssert(x) if ((x) != VK_SUCCESS) VulkanAssertImpl((x), __FUNCTION__, __FILE__, __LINE__); + #endif // UTIL_INIT diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 3a2a2adb3e..3502331495 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -114,7 +114,7 @@ static inline void Uint8x4ToFloat4(uint32_t u, float f[4]) { // their own similar buffer solutions. class VulkanPushBuffer { public: - VulkanPushBuffer(VkDevice device, VulkanDeviceMemoryManager *memMan, size_t size) : offset_(0), size_(size), writePtr_(nullptr) { + VulkanPushBuffer(VkDevice device, VulkanContext *vulkan, size_t size) : offset_(0), size_(size), writePtr_(nullptr) { VkBufferCreateInfo b; b.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; b.pNext = nullptr; @@ -131,7 +131,7 @@ public: VkMemoryAllocateInfo alloc; alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; alloc.pNext = nullptr; - memMan->memory_type_from_properties(0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &alloc.memoryTypeIndex); + vulkan->MemoryTypeFromProperties(0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &alloc.memoryTypeIndex); alloc.allocationSize = size; res = vkAllocateMemory(device, &alloc, nullptr, &deviceMemory_); @@ -511,8 +511,6 @@ private: VulkanContext *vulkan_; - VulkanDeviceMemoryManager vulkanMem_; - // These are used to compose the pipeline cache key. Thin3DVKBlendState *curBlendState_; Thin3DVKDepthStencilState *curDepthStencilState_; @@ -633,10 +631,10 @@ enum class TextureState { class Thin3DVKTexture : public Thin3DTexture { public: - Thin3DVKTexture(VkDevice device, VulkanDeviceMemoryManager *memMan) : device_(device), memMan_(memMan), state_(TextureState::UNINITIALIZED) { + Thin3DVKTexture(VulkanContext *vulkan) : vulkan_(vulkan), state_(TextureState::UNINITIALIZED) { } - Thin3DVKTexture(VkDevice device, VulkanDeviceMemoryManager *memMan, T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels) - : device_(device), memMan_(memMan), format_(format), mipLevels_(mipLevels) { + Thin3DVKTexture(VulkanContext *vulkan, T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels) + : vulkan_(vulkan), format_(format), mipLevels_(mipLevels) { Create(type, format, width, height, depth, mipLevels); } @@ -671,7 +669,7 @@ public: VkImageView GetImageView() { return view_; } private: - VulkanDeviceMemoryManager *memMan_; + VulkanContext *vulkan_; VkDevice device_; VulkanImage image_; VulkanImage staging_; @@ -685,8 +683,8 @@ private: }; Thin3DVKContext::Thin3DVKContext(VulkanContext *vulkan) - : viewportDirty_(false), scissorDirty_(false) { - device_ = vulkan->Device(); + : viewportDirty_(false), scissorDirty_(false), vulkan_(vulkan) { + device_ = vulkan->GetDevice(); noScissor_.offset.x = 0; noScissor_.offset.y = 0; @@ -723,8 +721,8 @@ Thin3DVKContext::Thin3DVKContext(VulkanContext *vulkan) dp.poolSizeCount = ARRAY_SIZE(dpTypes); res = vkCreateDescriptorPool(device_, &dp, nullptr, &descriptorPool_); assert(VK_SUCCESS == res); - pushBuffer_[0] = new VulkanPushBuffer(device_, &vulkanMem_, 1024 * 1024); - pushBuffer_[1] = new VulkanPushBuffer(device_, &vulkanMem_, 1024 * 1024); + pushBuffer_[0] = new VulkanPushBuffer(device_, vulkan_, 1024 * 1024); + pushBuffer_[1] = new VulkanPushBuffer(device_, vulkan_, 1024 * 1024); // binding 0 - vertex data // binding 1 - uniform data @@ -1120,11 +1118,11 @@ Thin3DVertexFormat *Thin3DVKContext::CreateVertexFormat(const std::vector>= 1; - } - // No memory types matched, return failure - return VK_ERROR_FORMAT_NOT_SUPPORTED; -} - -void VulkanImage::Create2D(VkDevice device, VulkanDeviceMemoryManager *memMan, VkFormat format, VkFlags required_props, VkImageUsageFlags usage, int width, int height) { +void VulkanImage::Create2D(VkDevice device, VulkanContext *vulkan, VkFormat format, VkFlags required_props, VkImageUsageFlags usage, int width, int height) { width_ = width; height_ = height; @@ -94,8 +73,8 @@ void VulkanImage::Create2D(VkDevice device, VulkanDeviceMemoryManager *memMan, V mem_alloc_.allocationSize = mem_reqs.size; mem_alloc_.memoryTypeIndex = 0; - err = memMan->memory_type_from_properties(mem_reqs.memoryTypeBits, required_props, &mem_alloc_.memoryTypeIndex); - assert(!err); + bool res = vulkan->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, required_props, &mem_alloc_.memoryTypeIndex); + assert(res); err = vkAllocateMemory(device, &mem_alloc_, nullptr, &memory_); assert(!err); diff --git a/ext/native/thin3d/vulkan_utils.h b/ext/native/thin3d/vulkan_utils.h index a2dd321843..7a0266fe20 100644 --- a/ext/native/thin3d/vulkan_utils.h +++ b/ext/native/thin3d/vulkan_utils.h @@ -21,18 +21,7 @@ #define VK_PROTOTYPES #include "ext/vulkan/vulkan.h" - -// -class VulkanDeviceMemoryManager { -public: - VulkanDeviceMemoryManager() {} - void Init(VkPhysicalDevice gpu); - - VkResult memory_type_from_properties(uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex); - -private: - VkPhysicalDeviceMemoryProperties memory_properties_; -}; +#include "VulkanContext.h" // Utility class to handle images without going insane. @@ -43,7 +32,7 @@ public: bool IsValid() const { return image_ != nullptr; } // This can be done completely unsynchronized. - void Create2D(VkDevice device, VulkanDeviceMemoryManager *memMan, VkFormat format, VkFlags required_props, VkImageUsageFlags usage, int width, int height); + void Create2D(VkDevice device, VulkanContext *vulkan, VkFormat format, VkFlags required_props, VkImageUsageFlags usage, int width, int height); // This can only be used if you pass in VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in required_props in Create2D. void SetImageData2D(VkDevice device, const uint8_t *data, int width, int height, int pitch); diff --git a/headless/Headless.vcxproj b/headless/Headless.vcxproj index d155cb76af..2e84a6801e 100644 --- a/headless/Headless.vcxproj +++ b/headless/Headless.vcxproj @@ -246,6 +246,9 @@ {533f1d30-d04d-47cc-ad71-20f658907e36} + + {edfa2e87-8ac1-4853-95d4-d7594ff81947} + {3baae095-e0ab-4b0e-b5df-ce39c8ae31de} @@ -269,4 +272,4 @@ - + \ No newline at end of file