diff --git a/OptiScaler/NVNGX_Proxy.h b/OptiScaler/NVNGX_Proxy.h index bd71c98f..39b5f0ca 100644 --- a/OptiScaler/NVNGX_Proxy.h +++ b/OptiScaler/NVNGX_Proxy.h @@ -485,8 +485,11 @@ public: if (_dll != nullptr) { - HookNvApi(); - HookNgxApi(_dll); + if (!Config::Instance()->DE_Available) + { + HookNvApi(); + HookNgxApi(_dll); + } LOG_INFO("getting nvngx method addresses"); diff --git a/OptiScaler/OptiScaler.vcxproj b/OptiScaler/OptiScaler.vcxproj index b060261e..79303c9a 100644 --- a/OptiScaler/OptiScaler.vcxproj +++ b/OptiScaler/OptiScaler.vcxproj @@ -81,8 +81,8 @@ $(SolutionDir)external\vulkan\include;$(SolutionDir)external\nvngx_dlss_sdk;$(SolutionDir)external\xess\inc\xess;$(SolutionDir)external\FidelityFX-SDK\ffx-api\include\ffx_api;$(SolutionDir)external\simpleini;$(SolutionDir)external\unordered_dense\include;$(SolutionDir)external\spdlog\include;$(IncludePath) $(ProjectDir)fsr2\lib;$(ProjectDir)fsr2_212\lib;$(ProjectDir)vulkan;$(ProjectDir)d3dx;$(ProjectDir)detours;$(SolutionDir)external\xess\lib;$(LibraryPath) - dxgi - D:\Folders\Games\SteamLibrary\steamapps\common\Horizon Zero Dawn\ + nvngx + D:\Folders\Games\DOOM Eternal\ .\x64\Debug diff --git a/OptiScaler/imgui/imgui_overlay_vk.cpp b/OptiScaler/imgui/imgui_overlay_vk.cpp index 004eeb6c..1afd738a 100644 --- a/OptiScaler/imgui/imgui_overlay_vk.cpp +++ b/OptiScaler/imgui/imgui_overlay_vk.cpp @@ -30,475 +30,531 @@ struct ImGui_ImplVulkan_InitInfo g_ImVulkan_Info = { }; struct ImGui_ImplVulkanH_Frame* g_ImVulkan_Frames = NULL; static VkSemaphore* g_ImVulkan_Semaphores = NULL; +static int createCounter = 0; + static void DestroyVulkanObjects(bool shutdown) { - vkDeviceWaitIdle(_device); + vkDeviceWaitIdle(_device); - if (shutdown) - { - if (g_vkRenderPass) - vkDestroyRenderPass(g_ImVulkan_Info.Device, g_vkRenderPass, NULL); + if (shutdown) + { + if (g_vkRenderPass) + vkDestroyRenderPass(g_ImVulkan_Info.Device, g_vkRenderPass, NULL); - if (g_ImVulkan_Info.DescriptorPool) - vkDestroyDescriptorPool(g_ImVulkan_Info.Device, g_ImVulkan_Info.DescriptorPool, NULL); - } + if (g_ImVulkan_Info.DescriptorPool) + vkDestroyDescriptorPool(g_ImVulkan_Info.Device, g_ImVulkan_Info.DescriptorPool, NULL); + } - for (uint32_t i = 0; i < g_ImVulkan_Info.ImageCount; i++) - { - ImGui_ImplVulkanH_Frame* fd = &g_ImVulkan_Frames[i]; + for (uint32_t i = 0; i < g_ImVulkan_Info.ImageCount; i++) + { + ImGui_ImplVulkanH_Frame* fd = &g_ImVulkan_Frames[i]; - vkDestroyFence(g_ImVulkan_Info.Device, fd->Fence, NULL); - fd->Fence = NULL; + vkDestroyFence(g_ImVulkan_Info.Device, fd->Fence, NULL); + fd->Fence = NULL; - vkFreeCommandBuffers(g_ImVulkan_Info.Device, fd->CommandPool, 1, &fd->CommandBuffer); - fd->CommandBuffer = NULL; + vkFreeCommandBuffers(g_ImVulkan_Info.Device, fd->CommandPool, 1, &fd->CommandBuffer); + fd->CommandBuffer = NULL; - vkDestroyCommandPool(g_ImVulkan_Info.Device, fd->CommandPool, NULL); - fd->CommandPool = NULL; + vkDestroyCommandPool(g_ImVulkan_Info.Device, fd->CommandPool, NULL); + fd->CommandPool = NULL; - vkDestroyImageView(g_ImVulkan_Info.Device, fd->BackbufferView, NULL); - fd->BackbufferView = NULL; + vkDestroyImageView(g_ImVulkan_Info.Device, fd->BackbufferView, NULL); + fd->BackbufferView = NULL; - vkDestroyFramebuffer(g_ImVulkan_Info.Device, fd->Framebuffer, NULL); - fd->Framebuffer = NULL; + vkDestroyFramebuffer(g_ImVulkan_Info.Device, fd->Framebuffer, NULL); + fd->Framebuffer = NULL; - vkDestroySemaphore(g_ImVulkan_Info.Device, g_ImVulkan_Semaphores[i], NULL); - g_ImVulkan_Semaphores[i] = NULL; - } + vkDestroySemaphore(g_ImVulkan_Info.Device, g_ImVulkan_Semaphores[i], NULL); + g_ImVulkan_Semaphores[i] = NULL; + } } -static void CreateVulkanObjects(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain) +static void CreateVulkanObjects(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, VkSwapchainKHR* pSwapchain) { - if (g_bInitialized) - { - DestroyVulkanObjects(false); - } + if (g_bInitialized) + { + DestroyVulkanObjects(false); + } - // Initialize ImGui for IO. - if (!ImGuiOverlayBase::IsInited()) - ImGuiOverlayBase::Init(_hwnd); + // Initialize ImGui for IO. + if (!ImGuiOverlayBase::IsInited()) + ImGuiOverlayBase::Init(_hwnd); - ImGuiIO& io = ImGui::GetIO(); - io.DisplaySize.x = pCreateInfo->imageExtent.width; - io.DisplaySize.y = pCreateInfo->imageExtent.height; + ImGuiIO& io = ImGui::GetIO(); - // (Optional) - io.LogFilename = 0; - io.IniFilename = 0; + if (pCreateInfo != nullptr) + { + io.DisplaySize.x = pCreateInfo->imageExtent.width; + io.DisplaySize.y = pCreateInfo->imageExtent.height; + } + else + { + io.DisplaySize.x = Config::Instance()->CurrentFeature->DisplayWidth(); + io.DisplaySize.y = Config::Instance()->CurrentFeature->DisplayHeight(); + } - // Get swapchain image count. - uint32_t imageCount; - vkGetSwapchainImagesKHR(device, *pSwapchain, &imageCount, NULL); + // (Optional) + io.LogFilename = 0; + io.IniFilename = 0; - // Alloc ImGui frame structure/semaphores for every image. - // For convenience, I am using ImGui_ImplVulkanH_Frame in imgui_impl_vulkan.h - if (!g_bInitialized) - { - g_ImVulkan_Frames = (ImGui_ImplVulkanH_Frame*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_Frame) * imageCount); - g_ImVulkan_Semaphores = (VkSemaphore*)IM_ALLOC(sizeof(VkSemaphore) * imageCount); - } + // Get swapchain image count. + uint32_t imageCount; + VkImage images[8]; + vkGetSwapchainImagesKHR(device, *pSwapchain, &imageCount, NULL); + vkGetSwapchainImagesKHR(device, *pSwapchain, &imageCount, images); - // Select queue family. - uint32_t queueFamily = 0; - { - uint32_t count; - vkGetPhysicalDeviceQueueFamilyProperties(_PD, &count, NULL); - VkQueueFamilyProperties queues[8]; - vkGetPhysicalDeviceQueueFamilyProperties(_PD, &count, queues); - for (uint32_t i = 0; i < count; i++) - { - if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) - { - queueFamily = i; - break; - } - } - } + // Alloc ImGui frame structure/semaphores for every image. + // For convenience, I am using ImGui_ImplVulkanH_Frame in imgui_impl_vulkan.h + if (!g_bInitialized) + { + g_ImVulkan_Frames = (ImGui_ImplVulkanH_Frame*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_Frame) * imageCount); + g_ImVulkan_Semaphores = (VkSemaphore*)IM_ALLOC(sizeof(VkSemaphore) * imageCount); + } - // Get device queue - VkQueue queue; - vkGetDeviceQueue(device, queueFamily, 0, &queue); + // Select queue family. + uint32_t queueFamily = 0; + { + uint32_t count; + vkGetPhysicalDeviceQueueFamilyProperties(_PD, &count, NULL); + VkQueueFamilyProperties queues[8]; + vkGetPhysicalDeviceQueueFamilyProperties(_PD, &count, queues); + for (uint32_t i = 0; i < count; i++) + { + if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) + { + queueFamily = i; + break; + } + } + } - // Create our vulkan objects. - // Some code here is copied from imgui_impl_vulkan.cpp + // Get device queue + VkQueue queue; + vkGetDeviceQueue(device, queueFamily, 0, &queue); - // Create the render pool - VkDescriptorPool pool = VK_NULL_HANDLE; + // Create our vulkan objects. + // Some code here is copied from imgui_impl_vulkan.cpp - if (g_bInitialized == false) - { - VkDescriptorPoolSize sampler_pool_size = { }; - sampler_pool_size.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - sampler_pool_size.descriptorCount = 1; - VkDescriptorPoolCreateInfo desc_pool_info = { }; - desc_pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - desc_pool_info.maxSets = 1; - desc_pool_info.poolSizeCount = 1; - desc_pool_info.pPoolSizes = &sampler_pool_size; - vkCreateDescriptorPool(device, &desc_pool_info, NULL, &pool); - } + // Create the render pool + VkDescriptorPool pool = VK_NULL_HANDLE; - // Create the render pass - if (g_bInitialized == false) - { - VkAttachmentDescription attachment_desc = { }; - attachment_desc.format = pCreateInfo->imageFormat; - attachment_desc.samples = VK_SAMPLE_COUNT_1_BIT; - attachment_desc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachment_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachment_desc.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + if (g_bInitialized == false) + { + VkDescriptorPoolSize sampler_pool_size = { }; + sampler_pool_size.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + sampler_pool_size.descriptorCount = 1; + VkDescriptorPoolCreateInfo desc_pool_info = { }; + desc_pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + desc_pool_info.maxSets = 1; + desc_pool_info.poolSizeCount = 1; + desc_pool_info.pPoolSizes = &sampler_pool_size; + vkCreateDescriptorPool(device, &desc_pool_info, NULL, &pool); + } - VkAttachmentReference color_attachment = { }; - color_attachment.attachment = 0; - color_attachment.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + // Create the render pass + if (g_bInitialized == false) + { + VkAttachmentDescription attachment_desc = { }; - VkSubpassDescription subpass = { }; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &color_attachment; + if (pCreateInfo != nullptr) + attachment_desc.format = pCreateInfo->imageFormat; + else + attachment_desc.format = VK_FORMAT_R8G8B8A8_UNORM; - VkSubpassDependency dependency = { }; - dependency.srcSubpass = VK_SUBPASS_EXTERNAL; - dependency.dstSubpass = 0; - dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - dependency.srcAccessMask = 0; - dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + attachment_desc.samples = VK_SAMPLE_COUNT_1_BIT; + attachment_desc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachment_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachment_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachment_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachment_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + attachment_desc.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - VkRenderPassCreateInfo render_pass_info = { }; - render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - render_pass_info.attachmentCount = 1; - render_pass_info.pAttachments = &attachment_desc; - render_pass_info.subpassCount = 1; - render_pass_info.pSubpasses = &subpass; - render_pass_info.dependencyCount = 1; - render_pass_info.pDependencies = &dependency; + VkAttachmentReference color_attachment = { }; + color_attachment.attachment = 0; + color_attachment.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - vkCreateRenderPass(device, &render_pass_info, NULL, &g_vkRenderPass); - } + VkSubpassDescription subpass = { }; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.colorAttachmentCount = 1; + subpass.pColorAttachments = &color_attachment; - // Create The Image Views - { - VkImage images[8]; - vkGetSwapchainImagesKHR(device, *pSwapchain, &imageCount, images); + VkSubpassDependency dependency = { }; + dependency.srcSubpass = VK_SUBPASS_EXTERNAL; + dependency.dstSubpass = 0; + dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency.srcAccessMask = 0; + dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - VkImageViewCreateInfo info = { }; - info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - info.viewType = VK_IMAGE_VIEW_TYPE_2D; - info.format = pCreateInfo->imageFormat; - info.components.r = VK_COMPONENT_SWIZZLE_R; - info.components.g = VK_COMPONENT_SWIZZLE_G; - info.components.b = VK_COMPONENT_SWIZZLE_B; - info.components.a = VK_COMPONENT_SWIZZLE_A; + VkRenderPassCreateInfo render_pass_info = { }; + render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + render_pass_info.attachmentCount = 1; + render_pass_info.pAttachments = &attachment_desc; + render_pass_info.subpassCount = 1; + render_pass_info.pSubpasses = &subpass; + render_pass_info.dependencyCount = 1; + render_pass_info.pDependencies = &dependency; - VkImageSubresourceRange image_range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; - info.subresourceRange = image_range; + vkCreateRenderPass(device, &render_pass_info, NULL, &g_vkRenderPass); + } - for (uint32_t i = 0; i < imageCount; i++) - { - ImGui_ImplVulkanH_Frame* fd = &g_ImVulkan_Frames[i]; - fd->Backbuffer = images[i]; - info.image = fd->Backbuffer; + // Create The Image Views + { - vkCreateImageView(device, &info, NULL, &fd->BackbufferView); - } - } + VkImageViewCreateInfo info = { }; + info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + info.viewType = VK_IMAGE_VIEW_TYPE_2D; - // Create frame Buffer - { - VkImageView attachment[1]; - VkFramebufferCreateInfo info = { }; - info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - info.renderPass = g_vkRenderPass; - info.attachmentCount = 1; - info.pAttachments = attachment; - info.width = pCreateInfo->imageExtent.width; - info.height = pCreateInfo->imageExtent.height; - info.layers = 1; + if (pCreateInfo != nullptr) + info.format = pCreateInfo->imageFormat; + else + info.format = VK_FORMAT_R8G8B8A8_UNORM; - for (uint32_t i = 0; i < imageCount; i++) - { - ImGui_ImplVulkanH_Frame* fd = &g_ImVulkan_Frames[i]; - attachment[0] = fd->BackbufferView; - vkCreateFramebuffer(device, &info, NULL, &fd->Framebuffer); - } - } + info.components.r = VK_COMPONENT_SWIZZLE_R; + info.components.g = VK_COMPONENT_SWIZZLE_G; + info.components.b = VK_COMPONENT_SWIZZLE_B; + info.components.a = VK_COMPONENT_SWIZZLE_A; - // Create command pools, command buffers, fences, and semaphores for every image - for (uint32_t i = 0; i < imageCount; i++) - { - ImGui_ImplVulkanH_Frame* fd = &g_ImVulkan_Frames[i]; - VkSemaphore* fsd = &g_ImVulkan_Semaphores[i]; - { - VkCommandPoolCreateInfo info = { }; - info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - info.queueFamilyIndex = queueFamily; - vkCreateCommandPool(device, &info, NULL, &fd->CommandPool); - } - { - VkCommandBufferAllocateInfo info = { }; - info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - info.commandPool = fd->CommandPool; - info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - info.commandBufferCount = 1; - vkAllocateCommandBuffers(device, &info, &fd->CommandBuffer); - } - { - VkFenceCreateInfo info = { }; - info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - info.flags = VK_FENCE_CREATE_SIGNALED_BIT; - vkCreateFence(device, &info, NULL, &fd->Fence); - } - { - VkSemaphoreCreateInfo info = { }; - info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - vkCreateSemaphore(device, &info, NULL, fsd); - } - } + VkImageSubresourceRange image_range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; + info.subresourceRange = image_range; - // Initialize ImGui and upload fonts - if (!ImGui::GetIO().BackendRendererUserData) - { - g_ImVulkan_Info.Instance = _instance; - g_ImVulkan_Info.PhysicalDevice = _PD; - g_ImVulkan_Info.Device = device; - g_ImVulkan_Info.QueueFamily = queueFamily; - g_ImVulkan_Info.Queue = queue; - g_ImVulkan_Info.DescriptorPool = pool; - g_ImVulkan_Info.Subpass = 0; - g_ImVulkan_Info.MinImageCount = pCreateInfo->minImageCount; - g_ImVulkan_Info.ImageCount = imageCount; - g_ImVulkan_Info.Allocator = NULL; - g_ImVulkan_Info.RenderPass = g_vkRenderPass; + for (uint32_t i = 0; i < imageCount; i++) + { + ImGui_ImplVulkanH_Frame* fd = &g_ImVulkan_Frames[i]; + fd->Backbuffer = images[i]; + info.image = fd->Backbuffer; - ImGui_ImplVulkan_Init(&g_ImVulkan_Info); + vkCreateImageView(device, &info, NULL, &fd->BackbufferView); + } + } - // Upload Fonts - // Use any command queue - VkCommandPool command_pool = g_ImVulkan_Frames[0].CommandPool; - VkCommandBuffer command_buffer = g_ImVulkan_Frames[0].CommandBuffer; - vkResetCommandPool(device, command_pool, 0); + // Create frame Buffer + { + VkImageView attachment[1]; + VkFramebufferCreateInfo info = { }; + info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + info.renderPass = g_vkRenderPass; + info.attachmentCount = 1; + info.pAttachments = attachment; - VkCommandBufferBeginInfo begin_info = { }; - begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - vkBeginCommandBuffer(command_buffer, &begin_info); + if (pCreateInfo != nullptr) + { + info.width = pCreateInfo->imageExtent.width; + info.height = pCreateInfo->imageExtent.height; + } + else + { + info.width = Config::Instance()->CurrentFeature->DisplayWidth(); + info.height = Config::Instance()->CurrentFeature->DisplayHeight(); + } - ImGui_ImplVulkan_CreateFontsTexture(); + info.layers = 1; - VkSubmitInfo end_info = { }; - end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - end_info.commandBufferCount = 1; - end_info.pCommandBuffers = &command_buffer; - vkEndCommandBuffer(command_buffer); + for (uint32_t i = 0; i < imageCount; i++) + { + ImGui_ImplVulkanH_Frame* fd = &g_ImVulkan_Frames[i]; + attachment[0] = fd->BackbufferView; + vkCreateFramebuffer(device, &info, NULL, &fd->Framebuffer); + } + } - vkQueueSubmit(queue, 1, &end_info, VK_NULL_HANDLE); + // Create command pools, command buffers, fences, and semaphores for every image + for (uint32_t i = 0; i < imageCount; i++) + { + ImGui_ImplVulkanH_Frame* fd = &g_ImVulkan_Frames[i]; + VkSemaphore* fsd = &g_ImVulkan_Semaphores[i]; + { + VkCommandPoolCreateInfo info = { }; + info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + info.queueFamilyIndex = queueFamily; + vkCreateCommandPool(device, &info, NULL, &fd->CommandPool); + } + { + VkCommandBufferAllocateInfo info = { }; + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + info.commandPool = fd->CommandPool; + info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + info.commandBufferCount = 1; + vkAllocateCommandBuffers(device, &info, &fd->CommandBuffer); + } + { + VkFenceCreateInfo info = { }; + info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + info.flags = VK_FENCE_CREATE_SIGNALED_BIT; + vkCreateFence(device, &info, NULL, &fd->Fence); + } + { + VkSemaphoreCreateInfo info = { }; + info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + vkCreateSemaphore(device, &info, NULL, fsd); + } + } - vkDeviceWaitIdle(device); - } + // Initialize ImGui and upload fonts + if (!ImGui::GetIO().BackendRendererUserData) + { + g_ImVulkan_Info.Instance = _instance; + g_ImVulkan_Info.PhysicalDevice = _PD; + g_ImVulkan_Info.Device = device; + g_ImVulkan_Info.QueueFamily = queueFamily; + g_ImVulkan_Info.Queue = queue; + g_ImVulkan_Info.DescriptorPool = pool; + g_ImVulkan_Info.Subpass = 0; - g_bInitialized = true; - g_bEnabled = true; + if (pCreateInfo != nullptr) + g_ImVulkan_Info.MinImageCount = pCreateInfo->minImageCount; + else + g_ImVulkan_Info.MinImageCount = imageCount; + + g_ImVulkan_Info.ImageCount = imageCount; + g_ImVulkan_Info.Allocator = NULL; + g_ImVulkan_Info.RenderPass = g_vkRenderPass; + + ImGui_ImplVulkan_Init(&g_ImVulkan_Info); + + // Upload Fonts + // Use any command queue + VkCommandPool command_pool = g_ImVulkan_Frames[0].CommandPool; + VkCommandBuffer command_buffer = g_ImVulkan_Frames[0].CommandBuffer; + vkResetCommandPool(device, command_pool, 0); + + VkCommandBufferBeginInfo begin_info = { }; + begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + vkBeginCommandBuffer(command_buffer, &begin_info); + + ImGui_ImplVulkan_CreateFontsTexture(); + + VkSubmitInfo end_info = { }; + end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + end_info.commandBufferCount = 1; + end_info.pCommandBuffers = &command_buffer; + vkEndCommandBuffer(command_buffer); + + vkQueueSubmit(queue, 1, &end_info, VK_NULL_HANDLE); + + vkDeviceWaitIdle(device); + } + + g_bInitialized = true; + g_bEnabled = true; } typedef VkResult(__fastcall* PFN_AcquireNextImageKHR)(VkDevice, VkSwapchainKHR, uint64_t, VkSemaphore, VkFence, uint32_t*); PFN_AcquireNextImageKHR oAcquireNextImageKHR = nullptr; static VkResult VKAPI_CALL hkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, - VkFence fence, uint32_t* pImageIndex) + VkFence fence, uint32_t* pImageIndex) { - return oAcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex); + return oAcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex); } typedef VkResult(__fastcall* PFN_AcquireNextImage2KHR)(VkDevice, const VkAcquireNextImageInfoKHR*, uint32_t*); PFN_AcquireNextImage2KHR oAcquireNextImage2KHR = nullptr; static VkResult VKAPI_CALL hkAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR* pAcquireInfo, uint32_t* pImageIndex) { - return oAcquireNextImage2KHR(device, pAcquireInfo, pImageIndex); + return oAcquireNextImage2KHR(device, pAcquireInfo, pImageIndex); } typedef VkResult(__fastcall* PFN_QueuePresentKHR)(VkQueue, const VkPresentInfoKHR*); PFN_QueuePresentKHR oQueuePresentKHR = nullptr; static VkResult VKAPI_CALL hkQueuePresentKHR(VkQueue queue, VkPresentInfoKHR* pPresentInfo) { - if (!g_bInitialized) - return VK_ERROR_OUT_OF_DATE_KHR; + if (!g_bInitialized) + { + if (createCounter == 0) + { + createCounter++; + return VK_ERROR_OUT_OF_DATE_KHR; + } + else + { + if (pPresentInfo->swapchainCount > 0) + { + auto sc = pPresentInfo->pSwapchains[0]; + CreateVulkanObjects(_device, nullptr, &sc); + } + else + { + createCounter = 0; + } + } + } - if (!ImGuiOverlayBase::IsInited()) - ImGuiOverlayBase::Init(Util::GetProcessWindow()); + if (!ImGuiOverlayBase::IsInited()) + ImGuiOverlayBase::Init(Util::GetProcessWindow()); - if (ImGuiOverlayBase::IsInited() && ImGuiOverlayBase::IsResetRequested()) - { - LOG_INFO("Reset request detected, shutting down ImGui!"); - ImGuiOverlayVk::ReInitVk(Util::GetProcessWindow()); - return oQueuePresentKHR(queue, pPresentInfo); - } + if (ImGuiOverlayBase::IsInited() && ImGuiOverlayBase::IsResetRequested()) + { + LOG_INFO("Reset request detected, shutting down ImGui!"); + ImGuiOverlayVk::ReInitVk(Util::GetProcessWindow()); + return oQueuePresentKHR(queue, pPresentInfo); + } - if (!ImGuiOverlayBase::IsInited() || !ImGuiOverlayBase::IsVisible()) - return oQueuePresentKHR(queue, pPresentInfo); + if (!ImGuiOverlayBase::IsInited() || !ImGuiOverlayBase::IsVisible()) + return oQueuePresentKHR(queue, pPresentInfo); - ImGui_ImplVulkan_NewFrame(); - ImGui_ImplWin32_NewFrame(); + ImGui_ImplVulkan_NewFrame(); + ImGui_ImplWin32_NewFrame(); - ImGuiOverlayBase::RenderMenu(); + ImGuiOverlayBase::RenderMenu(); - ImGui::Render(); + ImGui::Render(); - uint32_t idx = pPresentInfo->pImageIndices[0]; + uint32_t idx = pPresentInfo->pImageIndices[0]; - ImGui_ImplVulkanH_Frame* fd = &g_ImVulkan_Frames[idx]; + ImGui_ImplVulkanH_Frame* fd = &g_ImVulkan_Frames[idx]; - vkWaitForFences(g_ImVulkan_Info.Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); - vkResetFences(g_ImVulkan_Info.Device, 1, &fd->Fence); + vkWaitForFences(g_ImVulkan_Info.Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); + vkResetFences(g_ImVulkan_Info.Device, 1, &fd->Fence); - { - vkResetCommandPool(g_ImVulkan_Info.Device, fd->CommandPool, 0); - VkCommandBufferBeginInfo info = { }; - info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - vkBeginCommandBuffer(fd->CommandBuffer, &info); - } - { - VkRenderPassBeginInfo info = { }; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - info.renderPass = g_vkRenderPass; - info.framebuffer = fd->Framebuffer; - info.renderArea.extent.width = ImGui::GetIO().DisplaySize.x; - info.renderArea.extent.height = ImGui::GetIO().DisplaySize.y; - vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); - } + { + vkResetCommandPool(g_ImVulkan_Info.Device, fd->CommandPool, 0); + VkCommandBufferBeginInfo info = { }; + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + vkBeginCommandBuffer(fd->CommandBuffer, &info); + } + { + VkRenderPassBeginInfo info = { }; + info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + info.renderPass = g_vkRenderPass; + info.framebuffer = fd->Framebuffer; + info.renderArea.extent.width = ImGui::GetIO().DisplaySize.x; + info.renderArea.extent.height = ImGui::GetIO().DisplaySize.y; + vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); + } - ImGui::Render(); - ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer); + ImGui::Render(); + ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer); - // Submit command buffer - vkCmdEndRenderPass(fd->CommandBuffer); - vkEndCommandBuffer(fd->CommandBuffer); + // Submit command buffer + vkCmdEndRenderPass(fd->CommandBuffer); + vkEndCommandBuffer(fd->CommandBuffer); - // Submit queue and semaphores - uint32_t semaphoreCount = pPresentInfo->waitSemaphoreCount; - if (semaphoreCount != 0) - { - VkPipelineStageFlags waitStages[8] = { VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT }; + // Submit queue and semaphores + uint32_t semaphoreCount = pPresentInfo->waitSemaphoreCount; + if (semaphoreCount != 0) + { + VkPipelineStageFlags waitStages[8] = { VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT }; - VkSubmitInfo submit_info = { }; - submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submit_info.commandBufferCount = 1; - submit_info.pCommandBuffers = &fd->CommandBuffer; - submit_info.pWaitDstStageMask = waitStages; - submit_info.waitSemaphoreCount = semaphoreCount; - submit_info.pWaitSemaphores = pPresentInfo->pWaitSemaphores; - submit_info.signalSemaphoreCount = 1; - submit_info.pSignalSemaphores = &g_ImVulkan_Semaphores[idx]; + VkSubmitInfo submit_info = { }; + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = &fd->CommandBuffer; + submit_info.pWaitDstStageMask = waitStages; + submit_info.waitSemaphoreCount = semaphoreCount; + submit_info.pWaitSemaphores = pPresentInfo->pWaitSemaphores; + submit_info.signalSemaphoreCount = 1; + submit_info.pSignalSemaphores = &g_ImVulkan_Semaphores[idx]; - if (vkQueueSubmit(g_ImVulkan_Info.Queue, 1, &submit_info, fd->Fence) == VK_SUCCESS) - { - pPresentInfo->pWaitSemaphores = &g_ImVulkan_Semaphores[idx]; - pPresentInfo->waitSemaphoreCount = 1; - } - } + if (vkQueueSubmit(g_ImVulkan_Info.Queue, 1, &submit_info, fd->Fence) == VK_SUCCESS) + { + pPresentInfo->pWaitSemaphores = &g_ImVulkan_Semaphores[idx]; + pPresentInfo->waitSemaphoreCount = 1; + } + } - return oQueuePresentKHR(queue, pPresentInfo); + return oQueuePresentKHR(queue, pPresentInfo); } typedef VkResult(__fastcall* PFN_CreateSwapchainKHR)(VkDevice, const VkSwapchainCreateInfoKHR*, const VkAllocationCallbacks*, VkSwapchainKHR*); PFN_CreateSwapchainKHR oCreateSwapchainKHR = nullptr; + static VkResult VKAPI_CALL hkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, VkAllocationCallbacks* pAllocator, - VkSwapchainKHR* pSwapchain) + VkSwapchainKHR* pSwapchain) { - auto result = oCreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain); + auto result = oCreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); - if (result == VK_SUCCESS && device != NULL && pCreateInfo != NULL && pSwapchain != NULL) - CreateVulkanObjects(device, pCreateInfo, pAllocator, pSwapchain); + if (result == VK_SUCCESS && device != NULL && pCreateInfo != NULL && pSwapchain != NULL) + CreateVulkanObjects(device, pCreateInfo, pSwapchain); - return result; + return result; } bool ImGuiOverlayVk::IsInitedVk() { - ImGuiOverlayBase::VulkanReady(); - return _isInited; + ImGuiOverlayBase::VulkanReady(); + return _isInited; } HWND ImGuiOverlayVk::Handle() { - return ImGuiOverlayBase::Handle(); + return ImGuiOverlayBase::Handle(); } void ImGuiOverlayVk::InitVk(HWND InHwnd, VkDevice InDevice, VkInstance InInstance, VkPhysicalDevice InPD) { - _hwnd = InHwnd; - _device = InDevice; - _instance = InInstance; - _PD = InPD; + _hwnd = InHwnd; + _device = InDevice; + _instance = InInstance; + _PD = InPD; - oAcquireNextImageKHR = (PFN_AcquireNextImageKHR)(vkGetDeviceProcAddr(InDevice, "vkAcquireNextImageKHR")); - oAcquireNextImage2KHR = (PFN_AcquireNextImage2KHR)(vkGetDeviceProcAddr(InDevice, "vkAcquireNextImage2KHR")); - oQueuePresentKHR = (PFN_QueuePresentKHR)(vkGetDeviceProcAddr(InDevice, "vkQueuePresentKHR")); - oCreateSwapchainKHR = (PFN_CreateSwapchainKHR)(vkGetDeviceProcAddr(InDevice, "vkCreateSwapchainKHR")); + oAcquireNextImageKHR = (PFN_AcquireNextImageKHR)(vkGetDeviceProcAddr(InDevice, "vkAcquireNextImageKHR")); + oAcquireNextImage2KHR = (PFN_AcquireNextImage2KHR)(vkGetDeviceProcAddr(InDevice, "vkAcquireNextImage2KHR")); + oQueuePresentKHR = (PFN_QueuePresentKHR)(vkGetDeviceProcAddr(InDevice, "vkQueuePresentKHR")); + oCreateSwapchainKHR = (PFN_CreateSwapchainKHR)(vkGetDeviceProcAddr(InDevice, "vkCreateSwapchainKHR")); - if (oAcquireNextImageKHR) - { - // Hook - DetourTransactionBegin(); - DetourUpdateThread(GetCurrentThread()); + if (oAcquireNextImageKHR) + { + // Hook + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); - DetourAttach(&(PVOID&)oAcquireNextImageKHR, hkAcquireNextImageKHR); - DetourAttach(&(PVOID&)oAcquireNextImage2KHR, hkAcquireNextImage2KHR); - DetourAttach(&(PVOID&)oQueuePresentKHR, hkQueuePresentKHR); - DetourAttach(&(PVOID&)oCreateSwapchainKHR, hkCreateSwapchainKHR); + DetourAttach(&(PVOID&)oAcquireNextImageKHR, hkAcquireNextImageKHR); + DetourAttach(&(PVOID&)oAcquireNextImage2KHR, hkAcquireNextImage2KHR); + DetourAttach(&(PVOID&)oQueuePresentKHR, hkQueuePresentKHR); + DetourAttach(&(PVOID&)oCreateSwapchainKHR, hkCreateSwapchainKHR); - DetourTransactionCommit(); + DetourTransactionCommit(); - _isInited = true; - } + _isInited = true; + } } void ImGuiOverlayVk::ShutdownVk() { - if (_isInited) - ImGui_ImplVulkan_Shutdown(); + if (_isInited) + ImGui_ImplVulkan_Shutdown(); - ImGuiOverlayBase::Shutdown(); + ImGuiOverlayBase::Shutdown(); - if (g_bInitialized) - DestroyVulkanObjects(true); + if (g_bInitialized) + DestroyVulkanObjects(true); - if (_isInited) - { - DetourTransactionBegin(); - DetourUpdateThread(GetCurrentThread()); + if (_isInited) + { + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); - DetourDetach(&(PVOID&)oAcquireNextImageKHR, hkAcquireNextImageKHR); - DetourDetach(&(PVOID&)oAcquireNextImage2KHR, hkAcquireNextImage2KHR); - DetourDetach(&(PVOID&)oQueuePresentKHR, hkQueuePresentKHR); - DetourDetach(&(PVOID&)oCreateSwapchainKHR, hkCreateSwapchainKHR); + DetourDetach(&(PVOID&)oAcquireNextImageKHR, hkAcquireNextImageKHR); + DetourDetach(&(PVOID&)oAcquireNextImage2KHR, hkAcquireNextImage2KHR); + DetourDetach(&(PVOID&)oQueuePresentKHR, hkQueuePresentKHR); + DetourDetach(&(PVOID&)oCreateSwapchainKHR, hkCreateSwapchainKHR); - DetourTransactionCommit(); - } + DetourTransactionCommit(); + } - _isInited = false; - g_bInitialized = false; + _isInited = false; + g_bInitialized = false; } void ImGuiOverlayVk::ReInitVk(HWND InNewHwnd) { - if (!_isInited || !g_bInitialized) - return; + if (!_isInited || !g_bInitialized) + return; - _vkCleanMutex.lock(); + _vkCleanMutex.lock(); - LOG_DEBUG("hwnd: {0:X}", (UINT64)InNewHwnd); + LOG_DEBUG("hwnd: {0:X}", (UINT64)InNewHwnd); - ImGui_ImplVulkan_Shutdown(); - ImGuiOverlayBase::Shutdown(); - ImGuiOverlayBase::Init(InNewHwnd); - g_bInitialized = false; + ImGui_ImplVulkan_Shutdown(); + ImGuiOverlayBase::Shutdown(); + ImGuiOverlayBase::Init(InNewHwnd); + g_bInitialized = false; + createCounter = 0; - _vkCleanMutex.unlock(); + _vkCleanMutex.unlock(); } diff --git a/OptiScaler/resource.h b/OptiScaler/resource.h index ffe09cb8..eb629747 100644 --- a/OptiScaler/resource.h +++ b/OptiScaler/resource.h @@ -20,10 +20,10 @@ #define VER_MAJOR_VERSION 0 #define VER_MINOR_VERSION 6 -#define VER_HOTFIX_VERSION 6 -#define VER_BUILD_NUMBER 6 +#define VER_HOTFIX_VERSION 7 +#define VER_BUILD_NUMBER 1 -// #define VER_PRE_RELEASE +#define VER_PRE_RELEASE #define VER_FILE_VERSION VER_MAJOR_VERSION, VER_MINOR_VERSION, VER_HOTFIX_VERSION, VER_BUILD_NUMBER #define VER_FILE_VERSION_STR STRINGIZE(VER_MAJOR_VERSION) "." STRINGIZE(VER_MINOR_VERSION) "." STRINGIZE(VER_HOTFIX_VERSION) "." STRINGIZE(VER_BUILD_NUMBER)