Examples: Vulkan: Moved code into shared helpers: ImGui_ImplVulkan_SelectSurfaceFormat, ImGui_ImplVulkan_SelectPresentMode.

This commit is contained in:
omar 2018-03-01 22:16:51 +01:00
parent 3171d61dfc
commit 296db2ed33
4 changed files with 87 additions and 110 deletions

View File

@ -720,3 +720,73 @@ void ImGui_ImplVulkan_Render(VkCommandBuffer command_buffer)
g_CommandBuffer = VK_NULL_HANDLE;
g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES;
}
//-------------------------------------------------------------------------
// Miscellaneous Vulkan Helpers
// (Those are currently not strictly needed by the binding, but will be once if we support multi-viewports)
//-------------------------------------------------------------------------
#include <stdlib.h> // malloc
VkSurfaceFormatKHR ImGui_ImplVulkan_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space)
{
IM_ASSERT(request_formats != NULL);
IM_ASSERT(request_formats_count > 0);
// Per Spec Format and View Format are expected to be the same unless VK_IMAGE_CREATE_MUTABLE_BIT was set at image creation
// Assuming that the default behavior is without setting this bit, there is no need for separate Swapchain image and image view format
// Additionally several new color spaces were introduced with Vulkan Spec v1.0.40,
// hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used.
uint32_t avail_count;
vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &avail_count, NULL);
ImVector<VkSurfaceFormatKHR> avail_format;
avail_format.resize((int)avail_count);
vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &avail_count, avail_format.Data);
// First check if only one format, VK_FORMAT_UNDEFINED, is available, which would imply that any format is available
if (avail_count == 1)
{
if (avail_format[0].format == VK_FORMAT_UNDEFINED)
{
VkSurfaceFormatKHR ret;
ret.format = request_formats[0];
ret.colorSpace = request_color_space;
return ret;
}
else
{
// No point in searching another format
return avail_format[0];
}
}
else
{
// Request several formats, the first found will be used
for (int request_i = 0; request_i < request_formats_count; request_i++)
for (uint32_t avail_i = 0; avail_i < avail_count; avail_i++)
if (avail_format[avail_i].format == request_formats[request_i] && avail_format[avail_i].colorSpace == request_color_space)
return avail_format[avail_i];
// If none of the requested image formats could be found, use the first available
return avail_format[0];
}
}
VkPresentModeKHR ImGui_ImplVulkan_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count)
{
IM_ASSERT(request_modes != NULL);
IM_ASSERT(request_modes_count > 0);
// Request a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory
uint32_t avail_count = 0;
vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &avail_count, NULL);
ImVector<VkPresentModeKHR> avail_modes;
avail_modes.resize((int)avail_count);
vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &avail_count, avail_modes.Data);
for (int request_i = 0; request_i < request_modes_count; request_i++)
for (uint32_t avail_i = 0; avail_i < avail_count; avail_i++)
if (request_modes[request_i] == avail_modes[avail_i])
return request_modes[request_i];
return VK_PRESENT_MODE_FIFO_KHR; // Always available
}

View File

@ -34,3 +34,7 @@ IMGUI_API void ImGui_ImplVulkan_InvalidateFontUploadObjects();
IMGUI_API void ImGui_ImplVulkan_InvalidateDeviceObjects();
IMGUI_API bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer);
IMGUI_API bool ImGui_ImplVulkan_CreateDeviceObjects();
// Miscellaneous Vulkan Helpers
IMGUI_API VkSurfaceFormatKHR ImGui_ImplVulkan_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space);
IMGUI_API VkPresentModeKHR ImGui_ImplVulkan_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count);

View File

@ -297,69 +297,20 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e
// Get Surface Format
{
// Per Spec Format and View Format are expected to be the same unless VK_IMAGE_CREATE_MUTABLE_BIT was set at image creation
// Assuming that the default behavior is without setting this bit, there is no need for separate Swapchain image and image view format
// Additionally several new color spaces were introduced with Vulkan Spec v1.0.40,
// hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used.
uint32_t count;
vkGetPhysicalDeviceSurfaceFormatsKHR(g_PhysicalDevice, g_Surface, &count, NULL);
VkSurfaceFormatKHR* formats = (VkSurfaceFormatKHR*)malloc(sizeof(VkSurfaceFormatKHR) * count);
vkGetPhysicalDeviceSurfaceFormatsKHR(g_PhysicalDevice, g_Surface, &count, formats);
// First check if only one format, VK_FORMAT_UNDEFINED, is available, which would imply that any format is available
if (count == 1)
{
if (formats[0].format == VK_FORMAT_UNDEFINED)
{
g_SurfaceFormat.format = VK_FORMAT_B8G8R8A8_UNORM;
g_SurfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
}
else
{
// No point in searching another format
g_SurfaceFormat = formats[0];
}
}
else
{
// Request several formats, the first found will be used
VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM };
VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
bool found = false;
for (size_t i = 0; found == false && i < sizeof(requestSurfaceImageFormat) / sizeof(requestSurfaceImageFormat[0]); i++)
for (uint32_t j = 0; j < count; j++)
if (formats[j].format == requestSurfaceImageFormat[i] && formats[j].colorSpace == requestSurfaceColorSpace)
{
g_SurfaceFormat = formats[j];
found = true;
}
// If none of the requested image formats could be found, use the first available
if (!found)
g_SurfaceFormat = formats[0];
}
free(formats);
const VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM };
const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
g_SurfaceFormat = ImGui_ImplVulkan_SelectSurfaceFormat(g_PhysicalDevice, g_Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace);
}
// Get Present Mode
{
// Request a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory
#ifdef IMGUI_UNLIMITED_FRAME_RATE
g_PresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
VkPresentModeKHR present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR;
#else
g_PresentMode = VK_PRESENT_MODE_FIFO_KHR;
VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR;
#endif
uint32_t count = 0;
vkGetPhysicalDeviceSurfacePresentModesKHR(g_PhysicalDevice, g_Surface, &count, nullptr);
VkPresentModeKHR* presentModes = (VkPresentModeKHR*)malloc(sizeof(VkQueueFamilyProperties) * count);
vkGetPhysicalDeviceSurfacePresentModesKHR(g_PhysicalDevice, g_Surface, &count, presentModes);
bool presentModeAvailable = false;
for (size_t i = 0; i < count && !presentModeAvailable; i++)
if (presentModes[i] == g_PresentMode)
presentModeAvailable = true;
if (!presentModeAvailable)
g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; // Always available
g_PresentMode = ImGui_ImplVulkan_SelectPresentMode(g_PhysicalDevice, g_Surface, &present_mode, 1);
}

View File

@ -294,71 +294,23 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e
}
}
// Get Surface Format
{
// Per Spec Format and View Format are expected to be the same unless VK_IMAGE_CREATE_MUTABLE_BIT was set at image creation
// Assuming that the default behavior is without setting this bit, there is no need for separate Swapchain image and image view format
// Additionally several new color spaces were introduced with Vulkan Spec v1.0.40,
// hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used.
uint32_t count;
vkGetPhysicalDeviceSurfaceFormatsKHR(g_PhysicalDevice, g_Surface, &count, NULL);
VkSurfaceFormatKHR* formats = (VkSurfaceFormatKHR*)malloc(sizeof(VkSurfaceFormatKHR) * count);
vkGetPhysicalDeviceSurfaceFormatsKHR(g_PhysicalDevice, g_Surface, &count, formats);
// First check if only one format, VK_FORMAT_UNDEFINED, is available, which would imply that any format is available
if (count == 1)
{
if (formats[0].format == VK_FORMAT_UNDEFINED)
{
g_SurfaceFormat.format = VK_FORMAT_B8G8R8A8_UNORM;
g_SurfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
}
else
{
// No point in searching another format
g_SurfaceFormat = formats[0];
}
}
else
{
// Request several formats, the first found will be used
VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM };
VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
bool found = false;
for (size_t i = 0; found == false && i < sizeof(requestSurfaceImageFormat) / sizeof(requestSurfaceImageFormat[0]); i++)
for (uint32_t j = 0; j < count; j++)
if (formats[j].format == requestSurfaceImageFormat[i] && formats[j].colorSpace == requestSurfaceColorSpace)
{
g_SurfaceFormat = formats[j];
found = true;
}
// If none of the requested image formats could be found, use the first available
if (!found)
g_SurfaceFormat = formats[0];
}
free(formats);
const VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM };
const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
g_SurfaceFormat = ImGui_ImplVulkan_SelectSurfaceFormat(g_PhysicalDevice, g_Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace);
}
// Get Present Mode
{
// Request a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory
#ifdef IMGUI_UNLIMITED_FRAME_RATE
g_PresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
VkPresentModeKHR present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR;
#else
g_PresentMode = VK_PRESENT_MODE_FIFO_KHR;
VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR;
#endif
uint32_t count = 0;
vkGetPhysicalDeviceSurfacePresentModesKHR(g_PhysicalDevice, g_Surface, &count, nullptr);
VkPresentModeKHR* presentModes = (VkPresentModeKHR*)malloc(sizeof(VkQueueFamilyProperties) * count);
vkGetPhysicalDeviceSurfacePresentModesKHR(g_PhysicalDevice, g_Surface, &count, presentModes);
bool presentModeAvailable = false;
for (size_t i = 0; i < count && !presentModeAvailable; i++)
if (presentModes[i] == g_PresentMode)
presentModeAvailable = true;
if (!presentModeAvailable)
g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; // Always available
g_PresentMode = ImGui_ImplVulkan_SelectPresentMode(g_PhysicalDevice, g_Surface, &present_mode, 1);
}