mirror of
https://github.com/optiscaler/OptiScaler.git
synced 2026-11-07 06:23:05 +00:00
Fix imgui causing a crash when using DLSSG on Vulkan
Slopped.
This commit is contained in:
1 parent
e7e28a2a34
commit
01195e9bfe
6 files changed
+73
-97
No files matched your search
@@ -194,7 +194,6 @@ class State
|
||||
bool dlssgDebugView = false;
|
||||
bool dlssgInterpolatedOnly = false;
|
||||
uint64_t dlssgLastFrame = 0;
|
||||
uint32_t delayMenuRenderBy = 0;
|
||||
|
||||
// FSR Common
|
||||
float lastFsrCameraNear = 0.0f;
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
#include <nvapi/fakenvapi.h>
|
||||
#include <misc/IdentifyGpu.h>
|
||||
#include <hooks/Reflex_Hooks.h>
|
||||
#include <menu/menu_overlay_base.h>
|
||||
#include <framegen/nvngx/Nvngx_FG.h>
|
||||
#include <framegen/xefg/XeFG_Dx12.h>
|
||||
#include <proxies/KernelBase_Proxy.h>
|
||||
@@ -1349,20 +1347,6 @@ sl::Result StreamlineHooks::hkslDLSSGSetOptions(const sl::ViewportHandle& viewpo
|
||||
newOptions.dynamicTargetFrameRate = Config::Instance()->FGDLSSGFramerateTargetDMFG.value();
|
||||
}
|
||||
|
||||
if (state.swapchainApi == API::Vulkan)
|
||||
{
|
||||
// Only matters for Vulkan, DX doesn't use this delay
|
||||
if (dlssgPotentiallyActive && !MenuOverlayBase::IsVisible())
|
||||
state.delayMenuRenderBy = 10;
|
||||
|
||||
if (MenuOverlayBase::IsVisible())
|
||||
{
|
||||
newOptions.mode = sl::DLSSGMode::eOff;
|
||||
newOptions.flags |= sl::DLSSGFlags::eRetainResourcesWhenOff;
|
||||
ReflexHooks::setDlssgFrameCount(0);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_TRACE("DLSSG Modified Mode: {}", magic_enum::enum_name(newOptions.mode));
|
||||
|
||||
if (dlssgPotentiallyActive && state.streamlineVersion >= feature_version { 2, 7, 1 })
|
||||
|
||||
@@ -1328,6 +1328,12 @@ void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count)
|
||||
bd->VulkanInitInfo.MinImageCount = min_image_count;
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkan_SetQueue(VkQueue queue)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
bd->VulkanInitInfo.Queue = queue;
|
||||
}
|
||||
|
||||
// Register a texture by creating a descriptor
|
||||
// FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem, please post to https://github.com/ocornut/imgui/pull/914 if you have suggestions.
|
||||
VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout)
|
||||
|
||||
@@ -114,6 +114,7 @@ IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown(bool shutdown_platform
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_SetQueue(VkQueue queue); // Queue used for texture uploads
|
||||
|
||||
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_UpdateTexture(ImTextureData* tex);
|
||||
|
||||
@@ -5027,12 +5027,6 @@ void MenuCommon::RenderFrameGenerationRuntimeSettings(RenderMenuContext& ctx)
|
||||
"GPUs under Windows\nCan cause stutters, so best to use only when necessary");
|
||||
}
|
||||
}
|
||||
else if (state.swapchainApi == Vulkan)
|
||||
{
|
||||
ImGui::TextColored(toneMapColor(ImVec4(1.f, 0.8f, 0.f, 1.f)),
|
||||
"DLSSG is purposefully disabled when this menu is visible");
|
||||
ImGui::Spacing();
|
||||
}
|
||||
}
|
||||
|
||||
bool isLoaded = false;
|
||||
|
||||
@@ -554,11 +554,11 @@ bool MenuOverlayVk::QueuePresent(VkQueue queue, VkPresentInfoKHR* pPresentInfo)
|
||||
{
|
||||
auto semaphoreIndex = _frameCount % _scImageCount;
|
||||
|
||||
// With DLSSG the present comes from Streamline's thread, while the game's queue
|
||||
// can be waiting on that thread. Using the presenting queue avoids a deadlock.
|
||||
ImGui_ImplVulkan_SetQueue(queue);
|
||||
ImGui_ImplVulkan_NewFrame();
|
||||
|
||||
if (State::Instance().delayMenuRenderBy > 0)
|
||||
State::Instance().delayMenuRenderBy--;
|
||||
|
||||
// Blur images are only created once the menu is opened, menu decides if they are used
|
||||
bool blurReady = false;
|
||||
if (_menuBlur || MenuOverlayBase::IsVisible())
|
||||
@@ -576,81 +576,73 @@ bool MenuOverlayVk::QueuePresent(VkQueue queue, VkPresentInfoKHR* pPresentInfo)
|
||||
|
||||
if (MenuOverlayBase::RenderMenu())
|
||||
{
|
||||
if (State::Instance().delayMenuRenderBy == 0)
|
||||
uint32_t idx = pPresentInfo->pImageIndices[0];
|
||||
ImGui_ImplVulkanH_Frame* fd = &_ImVulkan_Frames[idx];
|
||||
const bool blurMenu = blurReady && MenuCommon::BackgroundBlurUsed();
|
||||
|
||||
vkWaitForFences(_ImVulkan_Info.Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX);
|
||||
vkResetFences(_ImVulkan_Info.Device, 1, &fd->Fence);
|
||||
|
||||
{
|
||||
uint32_t idx = pPresentInfo->pImageIndices[0];
|
||||
ImGui_ImplVulkanH_Frame* fd = &_ImVulkan_Frames[idx];
|
||||
const bool blurMenu = blurReady && MenuCommon::BackgroundBlurUsed();
|
||||
|
||||
vkWaitForFences(_ImVulkan_Info.Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX);
|
||||
vkResetFences(_ImVulkan_Info.Device, 1, &fd->Fence);
|
||||
|
||||
{
|
||||
vkResetCommandPool(_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);
|
||||
}
|
||||
|
||||
// Needs to be outside of the render pass
|
||||
if (blurMenu)
|
||||
_menuBlur->Dispatch(fd->CommandBuffer, fd->Backbuffer);
|
||||
|
||||
{
|
||||
VkRenderPassBeginInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
info.renderPass = _vkRenderPass;
|
||||
info.framebuffer = fd->Framebuffer;
|
||||
info.renderArea.extent.width = static_cast<uint32_t>(ImGui::GetIO().DisplaySize.x);
|
||||
info.renderArea.extent.height = static_cast<uint32_t>(ImGui::GetIO().DisplaySize.y);
|
||||
vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE);
|
||||
}
|
||||
|
||||
ImGui::Render();
|
||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer);
|
||||
|
||||
// Submit command buffer
|
||||
vkCmdEndRenderPass(fd->CommandBuffer);
|
||||
auto ecbResult = vkEndCommandBuffer(fd->CommandBuffer);
|
||||
if (ecbResult != VK_SUCCESS)
|
||||
{
|
||||
LOG_ERROR("vkQueueSubmit error: {0:X}", (UINT) ecbResult);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Submit queue and semaphores
|
||||
LOG_DEBUG("waitSemaphoreCount: {0}", pPresentInfo->waitSemaphoreCount);
|
||||
// Blur copies the image with a transfer, so everything has to wait for the game
|
||||
VkPipelineStageFlags waitStages[8];
|
||||
std::fill(std::begin(waitStages), std::end(waitStages),
|
||||
blurMenu ? VK_PIPELINE_STAGE_ALL_COMMANDS_BIT : 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 = pPresentInfo->waitSemaphoreCount;
|
||||
submit_info.pWaitSemaphores = pPresentInfo->pWaitSemaphores;
|
||||
submit_info.signalSemaphoreCount = 1;
|
||||
submit_info.pSignalSemaphores = &_ImVulkan_Semaphores[semaphoreIndex];
|
||||
|
||||
auto qResult = vkQueueSubmit(_ImVulkan_Info.Queue, 1, &submit_info, fd->Fence);
|
||||
if (qResult != VK_SUCCESS)
|
||||
{
|
||||
LOG_ERROR("vkQueueSubmit error: {0:X}", (UINT) qResult);
|
||||
return false;
|
||||
}
|
||||
|
||||
pPresentInfo->waitSemaphoreCount = 1;
|
||||
pPresentInfo->pWaitSemaphores = &_ImVulkan_Semaphores[semaphoreIndex];
|
||||
vkResetCommandPool(_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);
|
||||
}
|
||||
else
|
||||
|
||||
// Needs to be outside of the render pass
|
||||
if (blurMenu)
|
||||
_menuBlur->Dispatch(fd->CommandBuffer, fd->Backbuffer);
|
||||
|
||||
{
|
||||
// To make RenderMenu happy as it expects this
|
||||
ImGui::Render();
|
||||
VkRenderPassBeginInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
info.renderPass = _vkRenderPass;
|
||||
info.framebuffer = fd->Framebuffer;
|
||||
info.renderArea.extent.width = static_cast<uint32_t>(ImGui::GetIO().DisplaySize.x);
|
||||
info.renderArea.extent.height = static_cast<uint32_t>(ImGui::GetIO().DisplaySize.y);
|
||||
vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE);
|
||||
}
|
||||
|
||||
ImGui::Render();
|
||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer);
|
||||
|
||||
// Submit command buffer
|
||||
vkCmdEndRenderPass(fd->CommandBuffer);
|
||||
auto ecbResult = vkEndCommandBuffer(fd->CommandBuffer);
|
||||
if (ecbResult != VK_SUCCESS)
|
||||
{
|
||||
LOG_ERROR("vkQueueSubmit error: {0:X}", (UINT) ecbResult);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Submit queue and semaphores
|
||||
LOG_DEBUG("waitSemaphoreCount: {0}", pPresentInfo->waitSemaphoreCount);
|
||||
// Blur copies the image with a transfer, so everything has to wait for the game
|
||||
VkPipelineStageFlags waitStages[8];
|
||||
std::fill(std::begin(waitStages), std::end(waitStages),
|
||||
blurMenu ? VK_PIPELINE_STAGE_ALL_COMMANDS_BIT : 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 = pPresentInfo->waitSemaphoreCount;
|
||||
submit_info.pWaitSemaphores = pPresentInfo->pWaitSemaphores;
|
||||
submit_info.signalSemaphoreCount = 1;
|
||||
submit_info.pSignalSemaphores = &_ImVulkan_Semaphores[semaphoreIndex];
|
||||
|
||||
auto qResult = vkQueueSubmit(queue, 1, &submit_info, fd->Fence);
|
||||
if (qResult != VK_SUCCESS)
|
||||
{
|
||||
LOG_ERROR("vkQueueSubmit error: {0:X}", (UINT) qResult);
|
||||
return false;
|
||||
}
|
||||
|
||||
pPresentInfo->waitSemaphoreCount = 1;
|
||||
pPresentInfo->pWaitSemaphores = &_ImVulkan_Semaphores[semaphoreIndex];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user