mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Vulkan: Detect swapchain init failure.
This seems to be a driver bug, and occurs on NVIDIA when OpenGL has previously been inited. Or we're not cleaning something up properly... but there's a driver error logged to debug output.
This commit is contained in:
parent
627c280031
commit
bf02f7d98b
3 changed files with 36 additions and 18 deletions
|
@ -341,7 +341,7 @@ void VulkanBeginCommandBuffer(VkCommandBuffer cmd) {
|
||||||
assert(res == VK_SUCCESS);
|
assert(res == VK_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanContext::InitObjects(bool depthPresent) {
|
bool VulkanContext::InitObjects(bool depthPresent) {
|
||||||
InitQueue();
|
InitQueue();
|
||||||
InitCommandPool();
|
InitCommandPool();
|
||||||
|
|
||||||
|
@ -364,13 +364,17 @@ void VulkanContext::InitObjects(bool depthPresent) {
|
||||||
frame_[1].fence = CreateFence(true);
|
frame_[1].fence = CreateFence(true);
|
||||||
|
|
||||||
VkCommandBuffer cmd = GetInitCommandBuffer();
|
VkCommandBuffer cmd = GetInitCommandBuffer();
|
||||||
InitSwapchain(cmd);
|
if (!InitSwapchain(cmd)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
InitDepthStencilBuffer(cmd);
|
InitDepthStencilBuffer(cmd);
|
||||||
|
|
||||||
InitSurfaceRenderPass(depthPresent, true);
|
InitSurfaceRenderPass(depthPresent, true);
|
||||||
InitFramebuffers(depthPresent);
|
InitFramebuffers(depthPresent);
|
||||||
|
|
||||||
// The init command buffer will be executed as part of the first frame.
|
// The init command buffer will be executed as part of the first frame.
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanContext::DestroyObjects() {
|
void VulkanContext::DestroyObjects() {
|
||||||
|
@ -948,7 +952,7 @@ void VulkanContext::InitQueue() {
|
||||||
assert(res == VK_SUCCESS);
|
assert(res == VK_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanContext::InitSwapchain(VkCommandBuffer cmd) {
|
bool VulkanContext::InitSwapchain(VkCommandBuffer cmd) {
|
||||||
VkResult U_ASSERT_ONLY res;
|
VkResult U_ASSERT_ONLY res;
|
||||||
VkSurfaceCapabilitiesKHR surfCapabilities;
|
VkSurfaceCapabilitiesKHR surfCapabilities;
|
||||||
|
|
||||||
|
@ -1051,6 +1055,9 @@ void VulkanContext::InitSwapchain(VkCommandBuffer cmd) {
|
||||||
|
|
||||||
res = vkCreateSwapchainKHR(device_, &swap_chain_info, NULL, &swap_chain_);
|
res = vkCreateSwapchainKHR(device_, &swap_chain_info, NULL, &swap_chain_);
|
||||||
assert(res == VK_SUCCESS);
|
assert(res == VK_SUCCESS);
|
||||||
|
if (res != VK_SUCCESS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
res = vkGetSwapchainImagesKHR(device_, swap_chain_,
|
res = vkGetSwapchainImagesKHR(device_, swap_chain_,
|
||||||
&swapchainImageCount, NULL);
|
&swapchainImageCount, NULL);
|
||||||
|
@ -1097,6 +1104,8 @@ void VulkanContext::InitSwapchain(VkCommandBuffer cmd) {
|
||||||
free(swapchainImages);
|
free(swapchainImages);
|
||||||
|
|
||||||
current_buffer = 0;
|
current_buffer = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanContext::InitSurfaceRenderPass(bool include_depth, bool clear) {
|
void VulkanContext::InitSurfaceRenderPass(bool include_depth, bool clear) {
|
||||||
|
@ -1206,13 +1215,17 @@ void VulkanContext::WaitAndResetFence(VkFence fence) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanContext::DestroyCommandPool() {
|
void VulkanContext::DestroyCommandPool() {
|
||||||
|
if (cmd_pool_ != VK_NULL_HANDLE)
|
||||||
vkDestroyCommandPool(device_, cmd_pool_, NULL);
|
vkDestroyCommandPool(device_, cmd_pool_, NULL);
|
||||||
cmd_pool_ = VK_NULL_HANDLE;
|
cmd_pool_ = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanContext::DestroyDepthStencilBuffer() {
|
void VulkanContext::DestroyDepthStencilBuffer() {
|
||||||
|
if (depth.view != VK_NULL_HANDLE)
|
||||||
vkDestroyImageView(device_, depth.view, NULL);
|
vkDestroyImageView(device_, depth.view, NULL);
|
||||||
|
if (depth.image != VK_NULL_HANDLE)
|
||||||
vkDestroyImage(device_, depth.image, NULL);
|
vkDestroyImage(device_, depth.image, NULL);
|
||||||
|
if (depth.mem != VK_NULL_HANDLE)
|
||||||
vkFreeMemory(device_, depth.mem, NULL);
|
vkFreeMemory(device_, depth.mem, NULL);
|
||||||
|
|
||||||
depth.view = VK_NULL_HANDLE;
|
depth.view = VK_NULL_HANDLE;
|
||||||
|
@ -1224,6 +1237,7 @@ void VulkanContext::DestroySwapChain() {
|
||||||
for (uint32_t i = 0; i < swapchainImageCount; i++) {
|
for (uint32_t i = 0; i < swapchainImageCount; i++) {
|
||||||
vkDestroyImageView(device_, swapChainBuffers[i].view, NULL);
|
vkDestroyImageView(device_, swapChainBuffers[i].view, NULL);
|
||||||
}
|
}
|
||||||
|
if (swap_chain_ != VK_NULL_HANDLE)
|
||||||
vkDestroySwapchainKHR(device_, swap_chain_, NULL);
|
vkDestroySwapchainKHR(device_, swap_chain_, NULL);
|
||||||
swap_chain_ = VK_NULL_HANDLE;
|
swap_chain_ = VK_NULL_HANDLE;
|
||||||
swapChainBuffers.clear();
|
swapChainBuffers.clear();
|
||||||
|
@ -1238,6 +1252,7 @@ void VulkanContext::DestroyFramebuffers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanContext::DestroySurfaceRenderPass() {
|
void VulkanContext::DestroySurfaceRenderPass() {
|
||||||
|
if (surface_render_pass_ != VK_NULL_HANDLE)
|
||||||
vkDestroyRenderPass(device_, surface_render_pass_, NULL);
|
vkDestroyRenderPass(device_, surface_render_pass_, NULL);
|
||||||
surface_render_pass_ = VK_NULL_HANDLE;
|
surface_render_pass_ = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,8 +206,8 @@ public:
|
||||||
void ReinitSurfaceAndroid(int width, int height);
|
void ReinitSurfaceAndroid(int width, int height);
|
||||||
#endif
|
#endif
|
||||||
void InitQueue();
|
void InitQueue();
|
||||||
void InitObjects(bool depthPresent);
|
bool InitObjects(bool depthPresent);
|
||||||
void InitSwapchain(VkCommandBuffer cmd);
|
bool InitSwapchain(VkCommandBuffer cmd);
|
||||||
void InitSurfaceRenderPass(bool include_depth, bool clear);
|
void InitSurfaceRenderPass(bool include_depth, bool clear);
|
||||||
void InitFramebuffers(bool include_depth);
|
void InitFramebuffers(bool include_depth);
|
||||||
void InitDepthStencilBuffer(VkCommandBuffer cmd);
|
void InitDepthStencilBuffer(VkCommandBuffer cmd);
|
||||||
|
@ -365,14 +365,14 @@ private:
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
VkFormat format;
|
VkFormat format;
|
||||||
VkImage image;
|
VkImage image = VK_NULL_HANDLE;
|
||||||
VkDeviceMemory mem;
|
VkDeviceMemory mem = VK_NULL_HANDLE;
|
||||||
VkImageView view;
|
VkImageView view = VK_NULL_HANDLE;
|
||||||
} depth;
|
} depth;
|
||||||
|
|
||||||
VkRenderPass surface_render_pass_;
|
VkRenderPass surface_render_pass_ = VK_NULL_HANDLE;
|
||||||
uint32_t current_buffer;
|
uint32_t current_buffer = 0;
|
||||||
uint32_t queue_count;
|
uint32_t queue_count = 0;
|
||||||
|
|
||||||
VkPhysicalDeviceFeatures featuresAvailable_;
|
VkPhysicalDeviceFeatures featuresAvailable_;
|
||||||
VkPhysicalDeviceFeatures featuresEnabled_;
|
VkPhysicalDeviceFeatures featuresEnabled_;
|
||||||
|
|
|
@ -191,7 +191,10 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m
|
||||||
g_Vulkan->InitDebugMsgCallback(&Vulkan_Dbg, bits, &g_LogOptions);
|
g_Vulkan->InitDebugMsgCallback(&Vulkan_Dbg, bits, &g_LogOptions);
|
||||||
}
|
}
|
||||||
g_Vulkan->InitSurfaceWin32(hInst, hWnd);
|
g_Vulkan->InitSurfaceWin32(hInst, hWnd);
|
||||||
g_Vulkan->InitObjects(true);
|
if (!g_Vulkan->InitObjects(true)) {
|
||||||
|
Shutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
draw_ = Draw::T3DCreateVulkanContext(g_Vulkan);
|
draw_ = Draw::T3DCreateVulkanContext(g_Vulkan);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue