Skip to content

Commit c3540fd

Browse files
authored
Restored all my initial changes without all the reformatting of the code (#3)
1 parent 960e1ad commit c3540fd

1 file changed

Lines changed: 96 additions & 33 deletions

File tree

gfx/common/vulkan_common.c

Lines changed: 96 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,6 +1933,12 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
19331933
bool vsync = settings->bools.video_vsync;
19341934
bool adaptive_vsync = settings->bools.video_adaptive_vsync;
19351935

1936+
/* Bounds for safe copies into context arrays (minimal change). */
1937+
const uint32_t ctx_present_modes_cap =
1938+
(uint32_t)(sizeof(vk->context.present_modes) / sizeof(vk->context.present_modes[0]));
1939+
const uint32_t ctx_swap_images_cap =
1940+
(uint32_t)(sizeof(vk->context.swapchain_images) / sizeof(vk->context.swapchain_images[0]));
1941+
19361942
format.format = VK_FORMAT_UNDEFINED;
19371943
format.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
19381944

@@ -1945,7 +1951,19 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
19451951
/* Skip creation when window is minimized */
19461952
if ( !surface_properties.currentExtent.width
19471953
&& !surface_properties.currentExtent.height)
1948-
return false;
1954+
{
1955+
/* tear down existing swapchain and report handled. */
1956+
if (vk->swapchain != VK_NULL_HANDLE)
1957+
vkDestroySwapchainKHR(vk->context.device, vk->swapchain, NULL);
1958+
vk->swapchain = VK_NULL_HANDLE;
1959+
vk->context.swapchain_width = width;
1960+
vk->context.swapchain_height = height;
1961+
vk->context.num_swapchain_images = 0;
1962+
memset(vk->context.swapchain_images, 0, sizeof(vk->context.swapchain_images));
1963+
vk->context.flags &= ~VK_CTX_FLAG_HAS_ACQUIRED_SWAPCHAIN;
1964+
RARCH_DBG("[Vulkan] Window minimized; postponed swapchain creation.\n");
1965+
return true;
1966+
}
19491967

19501968
if ( (swap_interval == 0)
19511969
&& (vk->flags & VK_DATA_FLAG_EMULATE_MAILBOX)
@@ -2028,8 +2046,14 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
20282046

20292047
vk->context.swap_interval = swap_interval;
20302048

2031-
for (i = 0; i < present_mode_count; i++)
2032-
vk->context.present_modes[i] = present_modes[i];
2049+
/* copy only what fits in context array. */
2050+
{
2051+
uint32_t copy_count = present_mode_count;
2052+
if (copy_count > ctx_present_modes_cap)
2053+
copy_count = ctx_present_modes_cap;
2054+
for (i = 0; i < copy_count; i++)
2055+
vk->context.present_modes[i] = present_modes[i];
2056+
}
20332057

20342058
/* Prefer IMMEDIATE without vsync */
20352059
for (i = 0; i < present_mode_count; i++)
@@ -2107,10 +2131,23 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
21072131
}
21082132
}
21092133

2110-
vkGetPhysicalDeviceSurfaceFormatsKHR(vk->context.gpu,
2111-
vk->vk_surface, &format_count, NULL);
2112-
vkGetPhysicalDeviceSurfaceFormatsKHR(vk->context.gpu,
2113-
vk->vk_surface, &format_count, formats);
2134+
{
2135+
VkResult r;
2136+
r = vkGetPhysicalDeviceSurfaceFormatsKHR(vk->context.gpu,
2137+
vk->vk_surface, &format_count, NULL);
2138+
if (r != VK_SUCCESS || format_count == 0)
2139+
{
2140+
RARCH_ERR("[Vulkan] Surface has no formats (r=%d, count=%u).\n", r, format_count);
2141+
return false;
2142+
}
2143+
r = vkGetPhysicalDeviceSurfaceFormatsKHR(vk->context.gpu,
2144+
vk->vk_surface, &format_count, formats);
2145+
if (r != VK_SUCCESS)
2146+
{
2147+
RARCH_ERR("[Vulkan] Failed to get surface formats: %d\n", r);
2148+
return false;
2149+
}
2150+
}
21142151

21152152
format.format = VK_FORMAT_UNDEFINED;
21162153
if ( format_count == 1
@@ -2213,9 +2250,9 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
22132250
vk->swapchain = VK_NULL_HANDLE;
22142251
vk->context.swapchain_width = width;
22152252
vk->context.swapchain_height = height;
2216-
vk->context.num_swapchain_images = 1;
2217-
2253+
vk->context.num_swapchain_images = 0;
22182254
memset(vk->context.swapchain_images, 0, sizeof(vk->context.swapchain_images));
2255+
vk->context.flags &= ~VK_CTX_FLAG_HAS_ACQUIRED_SWAPCHAIN;
22192256
RARCH_DBG("[Vulkan] Cannot create a swapchain yet. Will try again later...\n");
22202257
return true;
22212258
}
@@ -2226,11 +2263,9 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
22262263
* for GPU-rendered cores. */
22272264
desired_swapchain_images = settings->uints.video_max_swapchain_images;
22282265

2229-
/* We don't clamp the number of images requested to what is reported
2230-
* as supported by the implementation in surface_properties.minImageCount,
2231-
* because MESA always reports a minImageCount of 4, but 3 and 2 work
2232-
* perfectly well, even if it's out of spec. */
2233-
2266+
/* Ensure desired image count respects min/max. */
2267+
if (desired_swapchain_images < surface_properties.minImageCount)
2268+
desired_swapchain_images = surface_properties.minImageCount;
22342269
if ( (surface_properties.maxImageCount > 0)
22352270
&& (desired_swapchain_images > surface_properties.maxImageCount))
22362271
desired_swapchain_images = surface_properties.maxImageCount;
@@ -2262,25 +2297,35 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
22622297
info.imageExtent.width = swapchain_size.width;
22632298
info.imageExtent.height = swapchain_size.height;
22642299
info.imageArrayLayers = 1;
2265-
info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
2266-
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
2267-
| VK_IMAGE_USAGE_TRANSFER_DST_BIT
2268-
| VK_IMAGE_USAGE_SAMPLED_BIT;
2300+
2301+
/* Validate usage bits against supportedUsageFlags, but keep essential bit. */
2302+
{
2303+
VkImageUsageFlags desired_usage =
2304+
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
2305+
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
2306+
| VK_IMAGE_USAGE_TRANSFER_DST_BIT
2307+
| VK_IMAGE_USAGE_SAMPLED_BIT;
2308+
VkImageUsageFlags supported = surface_properties.supportedUsageFlags;
2309+
VkImageUsageFlags final_usage = desired_usage & supported;
2310+
2311+
if (!(supported & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
2312+
{
2313+
RARCH_ERR("[Vulkan] Surface does not support COLOR_ATTACHMENT usage.\n");
2314+
return false;
2315+
}
2316+
2317+
final_usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2318+
info.imageUsage = final_usage;
2319+
}
2320+
22692321
info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
22702322
info.queueFamilyIndexCount = 0;
22712323
info.pQueueFamilyIndices = NULL;
22722324
info.preTransform = pre_transform;
22732325
info.compositeAlpha = composite;
22742326
info.presentMode = swapchain_present_mode;
22752327
info.clipped = VK_TRUE;
2276-
info.oldSwapchain = old_swapchain;
2277-
2278-
/* Only destroy old swapchain before creation on non-Android. */
2279-
#ifndef ANDROID
2280-
info.oldSwapchain = VK_NULL_HANDLE;
2281-
if (old_swapchain != VK_NULL_HANDLE)
2282-
vkDestroySwapchainKHR(vk->context.device, old_swapchain, NULL);
2283-
#endif
2328+
info.oldSwapchain = old_swapchain; /* keep old alive until after creation */
22842329

22852330
if (vkCreateSwapchainKHR(vk->context.device,
22862331
&info, NULL, &vk->swapchain) != VK_SUCCESS)
@@ -2289,11 +2334,9 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
22892334
return false;
22902335
}
22912336

2292-
/* On Android, now that creation succeeded, destroy the old swapchain. */
2293-
#ifdef ANDROID
2337+
/* Now safe to destroy the old one. */
22942338
if (old_swapchain != VK_NULL_HANDLE)
22952339
vkDestroySwapchainKHR(vk->context.device, old_swapchain, NULL);
2296-
#endif
22972340

22982341
vk->context.swapchain_width = swapchain_size.width;
22992342
vk->context.swapchain_height = swapchain_size.height;
@@ -2326,13 +2369,31 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
23262369

23272370
default:
23282371
vk->context.swapchain_format = format.format;
2372+
vk->context.flags &= ~VK_CTX_FLAG_SWAPCHAIN_IS_SRGB;
23292373
break;
23302374
}
23312375

2332-
vkGetSwapchainImagesKHR(vk->context.device, vk->swapchain,
2333-
&vk->context.num_swapchain_images, NULL);
2334-
vkGetSwapchainImagesKHR(vk->context.device, vk->swapchain,
2335-
&vk->context.num_swapchain_images, vk->context.swapchain_images);
2376+
/* Get image count first, clamp to capacity, then fetch. */
2377+
{
2378+
VkResult r;
2379+
uint32_t count = 0;
2380+
r = vkGetSwapchainImagesKHR(vk->context.device, vk->swapchain, &count, NULL);
2381+
if (r != VK_SUCCESS || count == 0)
2382+
{
2383+
RARCH_ERR("[Vulkan] Failed to query swapchain images: %d (count=%u)\n", r, count);
2384+
return false;
2385+
}
2386+
if (count > ctx_swap_images_cap)
2387+
count = ctx_swap_images_cap;
2388+
r = vkGetSwapchainImagesKHR(vk->context.device, vk->swapchain,
2389+
&count, vk->context.swapchain_images);
2390+
if (r != VK_SUCCESS)
2391+
{
2392+
RARCH_ERR("[Vulkan] Failed to get swapchain images: %d\n", r);
2393+
return false;
2394+
}
2395+
vk->context.num_swapchain_images = count;
2396+
}
23362397

23372398
if (old_swapchain == VK_NULL_HANDLE)
23382399
RARCH_LOG("[Vulkan] Got %u swapchain images.\n",
@@ -2346,9 +2407,11 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
23462407
if (vk->flags & VK_DATA_FLAG_EMULATING_MAILBOX)
23472408
vulkan_emulated_mailbox_init(&vk->mailbox, vk->context.device, vk->swapchain);
23482409

2410+
vk->flags &= ~VK_DATA_FLAG_CREATED_NEW_SWAPCHAIN;
23492411
return true;
23502412
}
23512413

2414+
23522415
bool vulkan_context_init(gfx_ctx_vulkan_data_t *vk,
23532416
enum vulkan_wsi_type type)
23542417
{

0 commit comments

Comments
 (0)