From c8906260d6061d31d4890c813ec720592586d329 Mon Sep 17 00:00:00 2001 From: Axel Gneiting Date: Sun, 19 Nov 2017 22:36:07 -0600 Subject: [PATCH] Proper fix for swap chain issues (still run game loop, but don't render). Fix pipeline leaks & make sure we don't leak anything in the future. --- Quake/gl_rmisc.c | 45 ++++++++++++++- Quake/gl_screen.c | 17 +++++- Quake/gl_vidsdl.c | 137 +++++++++++++++++++++++++++++++--------------- Quake/glquake.h | 2 +- 4 files changed, 151 insertions(+), 50 deletions(-) diff --git a/Quake/gl_rmisc.c b/Quake/gl_rmisc.c index 42fbb3f03..e6e9cb083 100644 --- a/Quake/gl_rmisc.c +++ b/Quake/gl_rmisc.c @@ -26,6 +26,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" #include "float.h" +#include + //johnfitz -- new cvars extern cvar_t r_clearcolor; extern cvar_t r_drawflat; @@ -1280,6 +1282,7 @@ void R_CreatePipelines() pipeline_create_info.renderPass = (render_pass == 0) ? vulkan_globals.main_render_pass : vulkan_globals.ui_render_pass; multisample_state_create_info.rasterizationSamples = (render_pass == 0) ? vulkan_globals.sample_count : VK_SAMPLE_COUNT_1_BIT; + assert(vulkan_globals.basic_alphatest_pipeline[render_pass] == VK_NULL_HANDLE); err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.basic_alphatest_pipeline[render_pass]); if (err != VK_SUCCESS) Sys_Error("vkCreateGraphicsPipelines failed"); @@ -1302,6 +1305,7 @@ void R_CreatePipelines() pipeline_create_info.renderPass = (render_pass == 0) ? vulkan_globals.main_render_pass : vulkan_globals.ui_render_pass; multisample_state_create_info.rasterizationSamples = (render_pass == 0) ? vulkan_globals.sample_count : VK_SAMPLE_COUNT_1_BIT; + assert(vulkan_globals.basic_notex_blend_pipeline[render_pass] == VK_NULL_HANDLE); err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.basic_notex_blend_pipeline[render_pass]); if (err != VK_SUCCESS) Sys_Error("vkCreateGraphicsPipelines failed"); @@ -1315,6 +1319,7 @@ void R_CreatePipelines() input_assembly_state_create_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN; + assert(vulkan_globals.basic_poly_blend_pipeline == VK_NULL_HANDLE); err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.basic_poly_blend_pipeline); if (err != VK_SUCCESS) Sys_Error("vkCreateGraphicsPipelines failed"); @@ -1330,6 +1335,7 @@ void R_CreatePipelines() pipeline_create_info.renderPass = (render_pass == 0) ? vulkan_globals.main_render_pass : vulkan_globals.ui_render_pass; multisample_state_create_info.rasterizationSamples = (render_pass == 0) ? vulkan_globals.sample_count : VK_SAMPLE_COUNT_1_BIT; + assert(vulkan_globals.basic_blend_pipeline[render_pass] == VK_NULL_HANDLE); err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.basic_blend_pipeline[render_pass]); if (err != VK_SUCCESS) Sys_Error("vkCreateGraphicsPipelines failed"); @@ -1353,6 +1359,7 @@ void R_CreatePipelines() pipeline_create_info.renderPass = vulkan_globals.warp_render_pass; + assert(vulkan_globals.warp_pipeline == VK_NULL_HANDLE); err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.warp_pipeline); if (err != VK_SUCCESS) Sys_Error("vkCreateGraphicsPipelines failed"); @@ -1373,6 +1380,7 @@ void R_CreatePipelines() blend_attachment_state.blendEnable = VK_TRUE; + assert(vulkan_globals.particle_pipeline == VK_NULL_HANDLE); err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.particle_pipeline); if (err != VK_SUCCESS) Sys_Error("vkCreateGraphicsPipelines failed"); @@ -1386,6 +1394,7 @@ void R_CreatePipelines() depth_stencil_state_create_info.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; blend_attachment_state.blendEnable = VK_FALSE; + assert(vulkan_globals.water_pipeline == VK_NULL_HANDLE); err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.water_pipeline); if (err != VK_SUCCESS) Sys_Error("vkCreateGraphicsPipelines failed"); @@ -1395,6 +1404,7 @@ void R_CreatePipelines() depth_stencil_state_create_info.depthWriteEnable = VK_FALSE; blend_attachment_state.blendEnable = VK_TRUE; + assert(vulkan_globals.water_blend_pipeline == VK_NULL_HANDLE); err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.water_blend_pipeline); if (err != VK_SUCCESS) Sys_Error("vkCreateGraphicsPipelines failed"); @@ -1409,6 +1419,7 @@ void R_CreatePipelines() dynamic_states[dynamic_state_create_info.dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BIAS; + assert(vulkan_globals.sprite_pipeline == VK_NULL_HANDLE); err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.sprite_pipeline); if (err != VK_SUCCESS) Sys_Error("vkCreateGraphicsPipelines failed"); @@ -1428,6 +1439,7 @@ void R_CreatePipelines() depth_stencil_state_create_info.depthWriteEnable = VK_FALSE; depth_stencil_state_create_info.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; + assert(vulkan_globals.sky_color_pipeline == VK_NULL_HANDLE); err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.sky_color_pipeline); if (err != VK_SUCCESS) Sys_Error("vkCreateGraphicsPipelines failed"); @@ -1436,6 +1448,7 @@ void R_CreatePipelines() shader_stages[1].module = basic_frag_module; + assert(vulkan_globals.sky_box_pipeline == VK_NULL_HANDLE); err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.sky_box_pipeline); if (err != VK_SUCCESS) Sys_Error("vkCreateGraphicsPipelines failed"); @@ -1476,6 +1489,7 @@ void R_CreatePipelines() pipeline_create_info.layout = vulkan_globals.sky_layer_pipeline_layout; + assert(vulkan_globals.sky_layer_pipeline == VK_NULL_HANDLE); err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.sky_layer_pipeline); if (err != VK_SUCCESS) Sys_Error("vkCreateGraphicsPipelines failed"); @@ -1561,6 +1575,7 @@ void R_CreatePipelines() pipeline_create_info.flags = VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT; } + assert(vulkan_globals.world_pipelines[pipeline_index] == VK_NULL_HANDLE); err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.world_pipelines[pipeline_index]); if (err != VK_SUCCESS) Sys_Error("vkCreateGraphicsPipelines failed"); @@ -1620,6 +1635,7 @@ void R_CreatePipelines() pipeline_create_info.layout = vulkan_globals.alias_pipeline_layout; + assert(vulkan_globals.alias_pipeline == VK_NULL_HANDLE); err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.alias_pipeline); if (err != VK_SUCCESS) Sys_Error("vkCreateGraphicsPipelines failed"); @@ -1628,6 +1644,7 @@ void R_CreatePipelines() shader_stages[1].module = alias_alphatest_frag_module; + assert(vulkan_globals.alias_alphatest_pipeline == VK_NULL_HANDLE); err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.alias_alphatest_pipeline); if (err != VK_SUCCESS) Sys_Error("vkCreateGraphicsPipelines failed"); @@ -1638,6 +1655,7 @@ void R_CreatePipelines() blend_attachment_state.blendEnable = VK_TRUE; shader_stages[1].module = alias_frag_module; + assert(vulkan_globals.alias_blend_pipeline == VK_NULL_HANDLE); err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.alias_blend_pipeline); if (err != VK_SUCCESS) Sys_Error("vkCreateGraphicsPipelines failed"); @@ -1663,6 +1681,7 @@ void R_CreatePipelines() pipeline_create_info.layout = vulkan_globals.postprocess_pipeline_layout; pipeline_create_info.subpass = 1; + assert(vulkan_globals.postprocess_pipeline == VK_NULL_HANDLE); err = vkCreateGraphicsPipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &pipeline_create_info, NULL, &vulkan_globals.postprocess_pipeline); if (err != VK_SUCCESS) Sys_Error("vkCreateGraphicsPipelines failed"); @@ -1686,6 +1705,7 @@ void R_CreatePipelines() compute_pipeline_create_info.stage = compute_shader_stage; compute_pipeline_create_info.layout = vulkan_globals.screen_warp_pipeline_layout; + assert(vulkan_globals.screen_warp_pipeline == VK_NULL_HANDLE); err = vkCreateComputePipelines(vulkan_globals.device, VK_NULL_HANDLE, 1, &compute_pipeline_create_info, NULL, &vulkan_globals.screen_warp_pipeline); if (err != VK_SUCCESS) Sys_Error("vkCreateGraphicsPipelines failed"); @@ -1717,26 +1737,47 @@ R_DestroyPipelines void R_DestroyPipelines(void) { int i; - for (i = 0; i < 2; ++i) + for (i = 0; i < 2; ++i) { vkDestroyPipeline(vulkan_globals.device, vulkan_globals.basic_alphatest_pipeline[i], NULL); + vulkan_globals.basic_alphatest_pipeline[i] = VK_NULL_HANDLE; vkDestroyPipeline(vulkan_globals.device, vulkan_globals.basic_blend_pipeline[i], NULL); + vulkan_globals.basic_blend_pipeline[i] = VK_NULL_HANDLE; vkDestroyPipeline(vulkan_globals.device, vulkan_globals.basic_notex_blend_pipeline[i], NULL); + vulkan_globals.basic_notex_blend_pipeline[i] = VK_NULL_HANDLE; } vkDestroyPipeline(vulkan_globals.device, vulkan_globals.basic_poly_blend_pipeline, NULL); - for (i = 0; i < WORLD_PIPELINE_COUNT; ++i) + vulkan_globals.basic_poly_blend_pipeline = VK_NULL_HANDLE; + for (i = 0; i < WORLD_PIPELINE_COUNT; ++i) { vkDestroyPipeline(vulkan_globals.device, vulkan_globals.world_pipelines[i], NULL); + vulkan_globals.world_pipelines[i] = VK_NULL_HANDLE; + } vkDestroyPipeline(vulkan_globals.device, vulkan_globals.water_pipeline, NULL); + vulkan_globals.water_pipeline = VK_NULL_HANDLE; vkDestroyPipeline(vulkan_globals.device, vulkan_globals.water_blend_pipeline, NULL); + vulkan_globals.water_blend_pipeline = VK_NULL_HANDLE; vkDestroyPipeline(vulkan_globals.device, vulkan_globals.warp_pipeline, NULL); + vulkan_globals.warp_pipeline = VK_NULL_HANDLE; vkDestroyPipeline(vulkan_globals.device, vulkan_globals.particle_pipeline, NULL); + vulkan_globals.particle_pipeline = VK_NULL_HANDLE; vkDestroyPipeline(vulkan_globals.device, vulkan_globals.sprite_pipeline, NULL); + vulkan_globals.sprite_pipeline = VK_NULL_HANDLE; vkDestroyPipeline(vulkan_globals.device, vulkan_globals.sky_color_pipeline, NULL); + vulkan_globals.sky_color_pipeline = VK_NULL_HANDLE; vkDestroyPipeline(vulkan_globals.device, vulkan_globals.sky_box_pipeline, NULL); + vulkan_globals.sky_box_pipeline = VK_NULL_HANDLE; vkDestroyPipeline(vulkan_globals.device, vulkan_globals.sky_layer_pipeline, NULL); + vulkan_globals.sky_layer_pipeline = VK_NULL_HANDLE; vkDestroyPipeline(vulkan_globals.device, vulkan_globals.alias_pipeline, NULL); + vulkan_globals.alias_pipeline = VK_NULL_HANDLE; + vkDestroyPipeline(vulkan_globals.device, vulkan_globals.alias_alphatest_pipeline, NULL); + vulkan_globals.alias_alphatest_pipeline = VK_NULL_HANDLE; vkDestroyPipeline(vulkan_globals.device, vulkan_globals.alias_blend_pipeline, NULL); + vulkan_globals.alias_blend_pipeline = VK_NULL_HANDLE; vkDestroyPipeline(vulkan_globals.device, vulkan_globals.postprocess_pipeline, NULL); + vulkan_globals.postprocess_pipeline = VK_NULL_HANDLE; + vkDestroyPipeline(vulkan_globals.device, vulkan_globals.screen_warp_pipeline, NULL); + vulkan_globals.screen_warp_pipeline = VK_NULL_HANDLE; } /* diff --git a/Quake/gl_screen.c b/Quake/gl_screen.c index 0264c77a5..2cebfd9b1 100644 --- a/Quake/gl_screen.c +++ b/Quake/gl_screen.c @@ -944,9 +944,13 @@ needs almost the entire 256k of stack space! */ void SCR_UpdateScreen (void) { - if (!scr_initialized || !con_initialized) + static qboolean in_update_screen = false; + + if (!scr_initialized || !con_initialized || in_update_screen) return; // not initialized yet + in_update_screen = true; + vid.numpages = (gl_triplebuffer.value) ? 3 : 2; if (scr_disabled_for_loading) @@ -956,11 +960,16 @@ void SCR_UpdateScreen (void) scr_disabled_for_loading = false; Con_Printf ("load failed.\n"); } - else + else { + in_update_screen = false; return; + } } - GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + if (!GL_BeginRendering (&glx, &gly, &glwidth, &glheight)) { + in_update_screen = false; + return; + } // // determine size of refresh window @@ -977,6 +986,7 @@ void SCR_UpdateScreen (void) if (GL_Set2D () == false) { GL_EndRendering (false); + in_update_screen = false; return; } @@ -1025,5 +1035,6 @@ void SCR_UpdateScreen (void) V_UpdateBlend (); //johnfitz -- V_UpdatePalette cleaned up and renamed GL_EndRendering (true); + in_update_screen = false; } diff --git a/Quake/gl_vidsdl.c b/Quake/gl_vidsdl.c index 62c2de35d..0277a0063 100644 --- a/Quake/gl_vidsdl.c +++ b/Quake/gl_vidsdl.c @@ -31,6 +31,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "SDL_syswm.h" #include "SDL_vulkan.h" +#include + #define MAX_MODE_LIST 600 //johnfitz -- was 30 #define MAX_BPPS_LIST 5 #define MAX_RATES_LIST 20 @@ -73,7 +75,7 @@ static void ClearAllStates (void); static void GL_InitInstance (void); static void GL_InitDevice (void); static void GL_CreateFrameBuffers(void); -static void GL_DestroyBeforeSetMode(void); +static void GL_DestroyRenderResources(void); viddef_t vid; // global video state modestate_t modestate = MS_UNINIT; @@ -107,6 +109,7 @@ static VkSurfaceCapabilitiesKHR vulkan_surface_capabilities; static VkSwapchainKHR vulkan_swapchain; static uint32_t num_swap_chain_images; +static qboolean render_resources_created = false; static uint32_t current_command_buffer; static VkCommandPool command_pool; static VkCommandPool transient_command_pool; @@ -999,6 +1002,7 @@ static void GL_CreateRenderPasses() render_pass_create_info.subpassCount = 1; render_pass_create_info.pSubpasses = subpass_descriptions; + assert(vulkan_globals.main_render_pass == VK_NULL_HANDLE); err = vkCreateRenderPass(vulkan_globals.device, &render_pass_create_info, NULL, &vulkan_globals.main_render_pass); if (err != VK_SUCCESS) Sys_Error("Couldn't create Vulkan render pass"); @@ -1061,6 +1065,7 @@ static void GL_CreateRenderPasses() render_pass_create_info.dependencyCount = 1; render_pass_create_info.pDependencies = subpass_dependencies; + assert(vulkan_globals.ui_render_pass == VK_NULL_HANDLE); err = vkCreateRenderPass(vulkan_globals.device, &render_pass_create_info, NULL, &vulkan_globals.ui_render_pass); if (err != VK_SUCCESS) Sys_Error("Couldn't create Vulkan render pass"); @@ -1108,6 +1113,9 @@ static void GL_CreateDepthBuffer( void ) { Con_Printf("Creating depth buffer\n"); + if(depth_buffer != VK_NULL_HANDLE) + return; + VkResult err; VkImageCreateInfo image_create_info; @@ -1125,6 +1133,7 @@ static void GL_CreateDepthBuffer( void ) image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + assert(depth_buffer == VK_NULL_HANDLE); err = vkCreateImage(vulkan_globals.device, &image_create_info, NULL, &depth_buffer); if (err != VK_SUCCESS) Sys_Error("vkCreateImage failed"); @@ -1148,6 +1157,7 @@ static void GL_CreateDepthBuffer( void ) if (vulkan_globals.dedicated_allocation) memory_allocate_info.pNext = &dedicated_allocation_info; + assert(depth_buffer_memory == VK_NULL_HANDLE); num_vulkan_misc_allocations += 1; err = vkAllocateMemory(vulkan_globals.device, &memory_allocate_info, NULL, &depth_buffer_memory); if (err != VK_SUCCESS) @@ -1172,6 +1182,7 @@ static void GL_CreateDepthBuffer( void ) image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; image_view_create_info.flags = 0; + assert(depth_buffer_view == VK_NULL_HANDLE); err = vkCreateImageView(vulkan_globals.device, &image_view_create_info, NULL, &depth_buffer_view); if (err != VK_SUCCESS) Sys_Error("vkCreateImageView failed"); @@ -1208,6 +1219,7 @@ static void GL_CreateColorBuffer( void ) for (i = 0; i < NUM_COLOR_BUFFERS; ++i) { + assert(vulkan_globals.color_buffers[i] == VK_NULL_HANDLE); err = vkCreateImage(vulkan_globals.device, &image_create_info, NULL, &vulkan_globals.color_buffers[i]); if (err != VK_SUCCESS) Sys_Error("vkCreateImage failed"); @@ -1231,6 +1243,7 @@ static void GL_CreateColorBuffer( void ) if (vulkan_globals.dedicated_allocation) memory_allocate_info.pNext = &dedicated_allocation_info; + assert(color_buffers_memory[i] == VK_NULL_HANDLE); num_vulkan_misc_allocations += 1; err = vkAllocateMemory(vulkan_globals.device, &memory_allocate_info, NULL, &color_buffers_memory[i]); if (err != VK_SUCCESS) @@ -1255,6 +1268,7 @@ static void GL_CreateColorBuffer( void ) image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; image_view_create_info.flags = 0; + assert(color_buffers_view[i] == VK_NULL_HANDLE); err = vkCreateImageView(vulkan_globals.device, &image_view_create_info, NULL, &color_buffers_view[i]); if (err != VK_SUCCESS) Sys_Error("vkCreateImageView failed"); @@ -1309,6 +1323,7 @@ static void GL_CreateColorBuffer( void ) image_create_info.samples = vulkan_globals.sample_count; + assert(msaa_color_buffer == VK_NULL_HANDLE); err = vkCreateImage(vulkan_globals.device, &image_create_info, NULL, &msaa_color_buffer); if (err != VK_SUCCESS) Sys_Error("vkCreateImage failed"); @@ -1332,6 +1347,7 @@ static void GL_CreateColorBuffer( void ) if (vulkan_globals.dedicated_allocation) memory_allocate_info.pNext = &dedicated_allocation_info; + assert(msaa_color_buffer_memory == VK_NULL_HANDLE); num_vulkan_misc_allocations += 1; err = vkAllocateMemory(vulkan_globals.device, &memory_allocate_info, NULL, &msaa_color_buffer_memory); if (err != VK_SUCCESS) @@ -1356,6 +1372,7 @@ static void GL_CreateColorBuffer( void ) image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; image_view_create_info.flags = 0; + assert(msaa_color_buffer_view == VK_NULL_HANDLE); err = vkCreateImageView(vulkan_globals.device, &image_view_create_info, NULL, &msaa_color_buffer_view); if (err != VK_SUCCESS) Sys_Error("vkCreateImageView failed"); @@ -1378,6 +1395,7 @@ static void GL_CreateDescriptorSets(void) descriptor_set_allocate_info.descriptorSetCount = 1; descriptor_set_allocate_info.pSetLayouts = &vulkan_globals.input_attachment_set_layout; + assert(postprocess_descriptor_set == VK_NULL_HANDLE); vkAllocateDescriptorSets(vulkan_globals.device, &descriptor_set_allocate_info, &postprocess_descriptor_set); VkDescriptorImageInfo image_info; @@ -1402,6 +1420,7 @@ static void GL_CreateDescriptorSets(void) descriptor_set_allocate_info.descriptorSetCount = 1; descriptor_set_allocate_info.pSetLayouts = &vulkan_globals.screen_warp_set_layout; + assert(vulkan_globals.screen_warp_desc_set == VK_NULL_HANDLE); vkAllocateDescriptorSets(vulkan_globals.device, &descriptor_set_allocate_info, &vulkan_globals.screen_warp_desc_set); VkDescriptorImageInfo input_image_info; @@ -1440,28 +1459,17 @@ static void GL_CreateDescriptorSets(void) GL_CreateSwapChain =============== */ -static void GL_CreateSwapChain( void ) +static qboolean GL_CreateSwapChain( void ) { uint32_t i; - - Con_Printf("Creating swap chain\n"); - VkResult err; - while(true) - { - err = fpGetPhysicalDeviceSurfaceCapabilitiesKHR(vulkan_physical_device, vulkan_surface, &vulkan_surface_capabilities); - if (err != VK_SUCCESS) - Sys_Error("Couldn't get surface capabilities"); - - if (vulkan_surface_capabilities.currentExtent.width != vid.width || vulkan_surface_capabilities.currentExtent.height != vid.height) { - // Try again later - SDL_Delay(30); - SDL_PumpEvents(); - continue; - } + err = fpGetPhysicalDeviceSurfaceCapabilitiesKHR(vulkan_physical_device, vulkan_surface, &vulkan_surface_capabilities); + if (err != VK_SUCCESS) + Sys_Error("Couldn't get surface capabilities"); - break; + if (vulkan_surface_capabilities.currentExtent.width != vid.width || vulkan_surface_capabilities.currentExtent.height != vid.height) { + return false; } uint32_t format_count; @@ -1543,14 +1551,17 @@ static void GL_CreateSwapChain( void ) if (!(vulkan_surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)) swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR; - vulkan_globals.swap_chain_format = surface_formats[0].format; free(surface_formats); + Sys_Printf("fpCreateSwapchainKHR\n"); + assert(vulkan_swapchain == VK_NULL_HANDLE); err = fpCreateSwapchainKHR(vulkan_globals.device, &swapchain_create_info, NULL, &vulkan_swapchain); if (err != VK_SUCCESS) Sys_Error("Couldn't create swap chain"); + for (i = 0; i < num_swap_chain_images; ++i) + assert(swapchain_images[i] == VK_NULL_HANDLE); err = fpGetSwapchainImagesKHR(vulkan_globals.device, vulkan_swapchain, &num_swap_chain_images, NULL); if (err != VK_SUCCESS || num_swap_chain_images > MAX_SWAP_CHAIN_IMAGES) Sys_Error("Couldn't get swap chain images"); @@ -1581,6 +1592,7 @@ static void GL_CreateSwapChain( void ) { GL_SetObjectName((uint64_t)swapchain_images[i], VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, "Swap Chain"); + assert(swapchain_images_views[i] == VK_NULL_HANDLE); image_view_create_info.image = swapchain_images[i]; err = vkCreateImageView(vulkan_globals.device, &image_view_create_info, NULL, &swapchain_images_views[i]); if (err != VK_SUCCESS) @@ -1588,10 +1600,13 @@ static void GL_CreateSwapChain( void ) GL_SetObjectName((uint64_t)swapchain_images_views[i], VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, "Swap Chain View"); + assert(image_aquired_semaphores[i] == VK_NULL_HANDLE); err = vkCreateSemaphore(vulkan_globals.device, &semaphore_create_info, NULL, &image_aquired_semaphores[i]); if (err != VK_SUCCESS) Sys_Error("vkCreateSemaphore failed"); } + + return true; } @@ -1624,6 +1639,7 @@ static void GL_CreateFrameBuffers( void ) VkImageView attachments[3] = { color_buffers_view[i], depth_buffer_view, msaa_color_buffer_view }; framebuffer_create_info.pAttachments = attachments; + assert(main_framebuffers[i] == VK_NULL_HANDLE); err = vkCreateFramebuffer(vulkan_globals.device, &framebuffer_create_info, NULL, &main_framebuffers[i]); if (err != VK_SUCCESS) Sys_Error("vkCreateFramebuffer failed"); @@ -1642,9 +1658,10 @@ static void GL_CreateFrameBuffers( void ) framebuffer_create_info.height = vid.height; framebuffer_create_info.layers = 1; - VkImageView attachments[2] = { color_buffers_view[0], swapchain_images_views[i] }; + VkImageView attachments[2] = { color_buffers_view[0], swapchain_images_views[i] }; framebuffer_create_info.pAttachments = attachments; + assert(ui_framebuffers[i] == VK_NULL_HANDLE); err = vkCreateFramebuffer(vulkan_globals.device, &framebuffer_create_info, NULL, &ui_framebuffers[i]); if (err != VK_SUCCESS) Sys_Error("vkCreateFramebuffer failed"); @@ -1655,15 +1672,41 @@ static void GL_CreateFrameBuffers( void ) /* =============== -GL_DestroyBeforeSetMode +GL_CreateRenderResources +=============== +*/ +static void GL_CreateRenderResources( void ) +{ + if (!GL_CreateSwapChain()) { + render_resources_created = false; + return; + } + + GL_CreateColorBuffer(); + GL_CreateDepthBuffer(); + GL_CreateRenderPasses(); + GL_CreateFrameBuffers(); + R_CreatePipelines(); + GL_CreateDescriptorSets(); + + render_resources_created = true; +} + +/* +=============== +GL_DestroyRenderResources =============== */ -static void GL_DestroyBeforeSetMode( void ) +static void GL_DestroyRenderResources( void ) { uint32_t i; + render_resources_created = false; + GL_WaitForDeviceIdle(); + R_DestroyPipelines(); + vkFreeDescriptorSets(vulkan_globals.device, vulkan_globals.descriptor_pool, 1, &postprocess_descriptor_set); postprocess_descriptor_set = VK_NULL_HANDLE; @@ -1703,24 +1746,32 @@ static void GL_DestroyBeforeSetMode( void ) depth_buffer = VK_NULL_HANDLE; depth_buffer_memory = VK_NULL_HANDLE; + for (i = 0; i < NUM_COLOR_BUFFERS; ++i) + { + vkDestroyFramebuffer(vulkan_globals.device, main_framebuffers[i], NULL); + main_framebuffers[i] = VK_NULL_HANDLE; + } + for (i = 0; i < num_swap_chain_images; ++i) { vkDestroyImageView(vulkan_globals.device, swapchain_images_views[i], NULL); swapchain_images_views[i] = VK_NULL_HANDLE; vkDestroyFramebuffer(vulkan_globals.device, ui_framebuffers[i], NULL); ui_framebuffers[i] = VK_NULL_HANDLE; - } + vkDestroySemaphore(vulkan_globals.device, image_aquired_semaphores[i], NULL); + image_aquired_semaphores[i] = VK_NULL_HANDLE; - for (i = 0; i < NUM_COLOR_BUFFERS; ++i) - { - vkDestroyFramebuffer(vulkan_globals.device, main_framebuffers[i], NULL); - main_framebuffers[i] = VK_NULL_HANDLE; + // Swapchain images do not need to be destroyed + swapchain_images[i] = VK_NULL_HANDLE; } fpDestroySwapchainKHR(vulkan_globals.device, vulkan_swapchain, NULL); + vulkan_swapchain = VK_NULL_HANDLE; vkDestroyRenderPass(vulkan_globals.device, vulkan_globals.ui_render_pass, NULL); + vulkan_globals.ui_render_pass = VK_NULL_HANDLE; vkDestroyRenderPass(vulkan_globals.device, vulkan_globals.main_render_pass, NULL); + vulkan_globals.main_render_pass = VK_NULL_HANDLE; } /* @@ -1728,10 +1779,18 @@ static void GL_DestroyBeforeSetMode( void ) GL_BeginRendering ================= */ -void GL_BeginRendering (int *x, int *y, int *width, int *height) +qboolean GL_BeginRendering (int *x, int *y, int *width, int *height) { int i; + if (!render_resources_created) { + GL_CreateRenderResources(); + + if (!render_resources_created) { + return false; + } + } + R_SwapDynamicBuffers(); vulkan_globals.device_idle = false; @@ -1800,6 +1859,8 @@ void GL_BeginRendering (int *x, int *y, int *width, int *height) viewport.maxDepth = 1.0f; vkCmdSetViewport(vulkan_globals.command_buffer, 0, 1, &viewport); + + return true; } /* @@ -2206,19 +2267,14 @@ void VID_Init (void) GL_InitInstance(); GL_InitDevice(); GL_InitCommandBuffers(); - GL_CreateSwapChain(); - GL_CreateColorBuffer(); - GL_CreateDepthBuffer(); - GL_CreateRenderPasses(); - GL_CreateFrameBuffers(); R_InitStagingBuffers(); R_CreateDescriptorSetLayouts(); R_CreateDescriptorPool(); R_InitDynamicBuffers(); R_InitSamplers(); R_CreatePipelineLayouts(); - R_CreatePipelines(); - GL_CreateDescriptorSets(); + + GL_CreateRenderResources(); //johnfitz -- removed code creating "glquake" subdirectory @@ -2266,21 +2322,14 @@ static void VID_Restart (void) scr_initialized = false; GL_WaitForDeviceIdle(); - R_DestroyPipelines(); - GL_DestroyBeforeSetMode(); + GL_DestroyRenderResources(); // // set new mode // VID_SetMode (width, height, refreshrate, bpp, fullscreen); - GL_CreateSwapChain(); - GL_CreateColorBuffer(); - GL_CreateDepthBuffer(); - GL_CreateRenderPasses(); - GL_CreateFrameBuffers(); - R_CreatePipelines(); - GL_CreateDescriptorSets(); + GL_CreateRenderResources(); //conwidth and conheight need to be recalculated vid.conwidth = (scr_conwidth.value > 0) ? (int)scr_conwidth.value : (scr_conscale.value > 0) ? (int)(vid.width/scr_conscale.value) : vid.width; diff --git a/Quake/glquake.h b/Quake/glquake.h index 5d3b6e1ed..283a4e468 100644 --- a/Quake/glquake.h +++ b/Quake/glquake.h @@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define __GLQUAKE_H void GL_WaitForDeviceIdle (void); -void GL_BeginRendering (int *x, int *y, int *width, int *height); +qboolean GL_BeginRendering (int *x, int *y, int *width, int *height); qboolean GL_AcquireNextSwapChainImage (void); void GL_EndRendering (qboolean swapchain_acquired); qboolean GL_Set2D (void);