| 1476 | } |
| 1477 | |
| 1478 | bool InitializeVulkan(HContext _context) |
| 1479 | { |
| 1480 | VulkanContext* context = (VulkanContext*) _context; |
| 1481 | VkResult res = CreateWindowSurface(context->m_BaseContext.m_Window, context->m_Instance, &context->m_WindowSurface, dmPlatform::GetWindowStateParam(context->m_BaseContext.m_Window, WINDOW_STATE_HIGH_DPI)); |
| 1482 | if (res != VK_SUCCESS) |
| 1483 | { |
| 1484 | dmLogError("Could not create window surface for Vulkan, reason: %s.", VkResultToStr(res)); |
| 1485 | return false; |
| 1486 | } |
| 1487 | |
| 1488 | QueueFamily selected_queue_family; |
| 1489 | LogicalDevice logical_device; |
| 1490 | uint32_t created_width = context->m_BaseContext.m_Width; |
| 1491 | uint32_t created_height = context->m_BaseContext.m_Height; |
| 1492 | const bool want_vsync = context->m_SwapInterval != 0; |
| 1493 | VkSampleCountFlagBits vk_closest_multisample_flag; |
| 1494 | |
| 1495 | res = CreateVulkanLogicalDevice(context->m_Instance, context->m_WindowSurface, true, true, context->m_UseValidationLayers, |
| 1496 | &context->m_PhysicalDevice, &logical_device, &selected_queue_family, &context->m_SwapChainCapabilities, &context->m_FragmentShaderInterlockFeatures); |
| 1497 | if (res != VK_SUCCESS) |
| 1498 | { |
| 1499 | goto bail; |
| 1500 | } |
| 1501 | |
| 1502 | context->m_LogicalDevice = logical_device; |
| 1503 | context->m_WaitForPresent = (PFN_vkWaitForPresentKHR) vkGetDeviceProcAddr(logical_device.m_Device, "vkWaitForPresentKHR"); |
| 1504 | SetupVulkanAdapterInfo(context); |
| 1505 | vk_closest_multisample_flag = GetClosestSampleCountFlag(&context->m_PhysicalDevice, BUFFER_TYPE_COLOR0_BIT | BUFFER_TYPE_DEPTH_BIT, dmPlatform::GetWindowStateParam(context->m_BaseContext.m_Window, WINDOW_STATE_SAMPLE_COUNT)); |
| 1506 | |
| 1507 | // Create swap chain |
| 1508 | InitializeVulkanTexture(&context->m_ResolveTexture); |
| 1509 | context->m_SwapChain = new SwapChain(context->m_WindowSurface, vk_closest_multisample_flag, context->m_SwapChainCapabilities, selected_queue_family, &context->m_ResolveTexture, context->m_WaitForPresent); |
| 1510 | |
| 1511 | res = UpdateSwapChain(&context->m_PhysicalDevice, &context->m_LogicalDevice, &created_width, &created_height, want_vsync, context->m_SwapChainCapabilities, context->m_SwapChain); |
| 1512 | if (res != VK_SUCCESS) |
| 1513 | { |
| 1514 | dmLogError("Could not create a swap chain for Vulkan, reason: %s", VkResultToStr(res)); |
| 1515 | goto bail; |
| 1516 | } |
| 1517 | |
| 1518 | // GLFW3 handles window size changes differently, so we need to cater for that. |
| 1519 | #ifndef __MACH__ |
| 1520 | if (created_width != context->m_BaseContext.m_Width || created_height != context->m_BaseContext.m_Height) |
| 1521 | { |
| 1522 | dmPlatform::SetWindowSize(context->m_BaseContext.m_Window, created_width, created_height); |
| 1523 | } |
| 1524 | #endif |
| 1525 | |
| 1526 | context->m_PipelineCache.SetCapacity(32,64); |
| 1527 | |
| 1528 | // Create a Vulkan pipeline cache so the driver can reuse compiled |
| 1529 | // shader/pipeline state across pipeline creation calls within |
| 1530 | // the same session. Passing an empty initialData for now. |
| 1531 | // Disk serialization can be added later for cross-session warm starts. |
| 1532 | { |
| 1533 | VkPipelineCacheCreateInfo vk_pipeline_cache_info; |
| 1534 | memset(&vk_pipeline_cache_info, 0, sizeof(vk_pipeline_cache_info)); |
| 1535 | vk_pipeline_cache_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; |
no test coverage detected