Skip to content

Commit

Permalink
Vulkan: Detect swapchain init failure.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
unknownbrackets committed Apr 15, 2017
1 parent 627c280 commit bf02f7d
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 18 deletions.
33 changes: 24 additions & 9 deletions Common/Vulkan/VulkanContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ void VulkanBeginCommandBuffer(VkCommandBuffer cmd) {
assert(res == VK_SUCCESS);
}

void VulkanContext::InitObjects(bool depthPresent) {
bool VulkanContext::InitObjects(bool depthPresent) {
InitQueue();
InitCommandPool();

Expand All @@ -364,13 +364,17 @@ void VulkanContext::InitObjects(bool depthPresent) {
frame_[1].fence = CreateFence(true);

VkCommandBuffer cmd = GetInitCommandBuffer();
InitSwapchain(cmd);
if (!InitSwapchain(cmd)) {
return false;
}
InitDepthStencilBuffer(cmd);

InitSurfaceRenderPass(depthPresent, true);
InitFramebuffers(depthPresent);

// The init command buffer will be executed as part of the first frame.

return true;
}

void VulkanContext::DestroyObjects() {
Expand Down Expand Up @@ -948,7 +952,7 @@ void VulkanContext::InitQueue() {
assert(res == VK_SUCCESS);
}

void VulkanContext::InitSwapchain(VkCommandBuffer cmd) {
bool VulkanContext::InitSwapchain(VkCommandBuffer cmd) {
VkResult U_ASSERT_ONLY res;
VkSurfaceCapabilitiesKHR surfCapabilities;

Expand Down Expand Up @@ -1051,6 +1055,9 @@ void VulkanContext::InitSwapchain(VkCommandBuffer cmd) {

res = vkCreateSwapchainKHR(device_, &swap_chain_info, NULL, &swap_chain_);
assert(res == VK_SUCCESS);
if (res != VK_SUCCESS) {
return false;
}

res = vkGetSwapchainImagesKHR(device_, swap_chain_,
&swapchainImageCount, NULL);
Expand Down Expand Up @@ -1097,6 +1104,8 @@ void VulkanContext::InitSwapchain(VkCommandBuffer cmd) {
free(swapchainImages);

current_buffer = 0;

return true;
}

void VulkanContext::InitSurfaceRenderPass(bool include_depth, bool clear) {
Expand Down Expand Up @@ -1206,14 +1215,18 @@ void VulkanContext::WaitAndResetFence(VkFence fence) {
}

void VulkanContext::DestroyCommandPool() {
vkDestroyCommandPool(device_, cmd_pool_, NULL);
if (cmd_pool_ != VK_NULL_HANDLE)
vkDestroyCommandPool(device_, cmd_pool_, NULL);
cmd_pool_ = VK_NULL_HANDLE;
}

void VulkanContext::DestroyDepthStencilBuffer() {
vkDestroyImageView(device_, depth.view, NULL);
vkDestroyImage(device_, depth.image, NULL);
vkFreeMemory(device_, depth.mem, NULL);
if (depth.view != VK_NULL_HANDLE)
vkDestroyImageView(device_, depth.view, NULL);
if (depth.image != VK_NULL_HANDLE)
vkDestroyImage(device_, depth.image, NULL);
if (depth.mem != VK_NULL_HANDLE)
vkFreeMemory(device_, depth.mem, NULL);

depth.view = VK_NULL_HANDLE;
depth.image = VK_NULL_HANDLE;
Expand All @@ -1224,7 +1237,8 @@ void VulkanContext::DestroySwapChain() {
for (uint32_t i = 0; i < swapchainImageCount; i++) {
vkDestroyImageView(device_, swapChainBuffers[i].view, NULL);
}
vkDestroySwapchainKHR(device_, swap_chain_, NULL);
if (swap_chain_ != VK_NULL_HANDLE)
vkDestroySwapchainKHR(device_, swap_chain_, NULL);
swap_chain_ = VK_NULL_HANDLE;
swapChainBuffers.clear();
vkDestroySemaphore(device_, acquireSemaphore, NULL);
Expand All @@ -1238,7 +1252,8 @@ void VulkanContext::DestroyFramebuffers() {
}

void VulkanContext::DestroySurfaceRenderPass() {
vkDestroyRenderPass(device_, surface_render_pass_, NULL);
if (surface_render_pass_ != VK_NULL_HANDLE)
vkDestroyRenderPass(device_, surface_render_pass_, NULL);
surface_render_pass_ = VK_NULL_HANDLE;
}

Expand Down
16 changes: 8 additions & 8 deletions Common/Vulkan/VulkanContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@ class VulkanContext {
void ReinitSurfaceAndroid(int width, int height);
#endif
void InitQueue();
void InitObjects(bool depthPresent);
void InitSwapchain(VkCommandBuffer cmd);
bool InitObjects(bool depthPresent);
bool InitSwapchain(VkCommandBuffer cmd);
void InitSurfaceRenderPass(bool include_depth, bool clear);
void InitFramebuffers(bool include_depth);
void InitDepthStencilBuffer(VkCommandBuffer cmd);
Expand Down Expand Up @@ -365,14 +365,14 @@ class VulkanContext {

struct {
VkFormat format;
VkImage image;
VkDeviceMemory mem;
VkImageView view;
VkImage image = VK_NULL_HANDLE;
VkDeviceMemory mem = VK_NULL_HANDLE;
VkImageView view = VK_NULL_HANDLE;
} depth;

VkRenderPass surface_render_pass_;
uint32_t current_buffer;
uint32_t queue_count;
VkRenderPass surface_render_pass_ = VK_NULL_HANDLE;
uint32_t current_buffer = 0;
uint32_t queue_count = 0;

VkPhysicalDeviceFeatures featuresAvailable_;
VkPhysicalDeviceFeatures featuresEnabled_;
Expand Down
5 changes: 4 additions & 1 deletion Windows/GPU/WindowsVulkanContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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->InitSurfaceWin32(hInst, hWnd);
g_Vulkan->InitObjects(true);
if (!g_Vulkan->InitObjects(true)) {
Shutdown();
return false;
}

draw_ = Draw::T3DCreateVulkanContext(g_Vulkan);

Expand Down

0 comments on commit bf02f7d

Please sign in to comment.