GPU: Fix crash toggling border overlays

This commit is contained in:
Stenzek 2025-01-19 12:25:19 +10:00
parent 6131ddbefe
commit 725dcea05a
No known key found for this signature in database
2 changed files with 44 additions and 42 deletions

View File

@ -167,29 +167,6 @@ bool GPUPresenter::CompileDisplayPipelines(bool display, bool deinterlace, bool
// blended variants
if (m_border_overlay_texture)
{
if (m_border_overlay_alpha_blend)
{
// destination blend the main present, not source
plconfig.blend.enable = true;
plconfig.blend.src_blend = GPUPipeline::BlendFunc::InvDstAlpha;
plconfig.blend.blend_op = GPUPipeline::BlendOp::Add;
plconfig.blend.dst_blend = GPUPipeline::BlendFunc::One;
plconfig.blend.src_alpha_blend = GPUPipeline::BlendFunc::One;
plconfig.blend.alpha_blend_op = GPUPipeline::BlendOp::Add;
plconfig.blend.dst_alpha_blend = GPUPipeline::BlendFunc::Zero;
}
plconfig.fragment_shader = fso.get();
if (!(m_display_blend_pipeline = g_gpu_device->CreatePipeline(plconfig, error)))
return false;
GL_OBJECT_NAME_FMT(m_display_blend_pipeline, "Display Pipeline [Blended, {}]",
Settings::GetDisplayScalingName(g_gpu_settings.display_scaling));
plconfig.fragment_shader = rotate_copy_fso.get();
if (!(m_present_copy_blend_pipeline = g_gpu_device->CreatePipeline(plconfig, error)))
return false;
GL_OBJECT_NAME(m_present_copy_blend_pipeline, "Display Rotate/Copy Pipeline [Blended]");
std::unique_ptr<GPUShader> clear_fso =
g_gpu_device->CreateShader(GPUShaderStage::Fragment, shadergen.GetLanguage(),
shadergen.GenerateFillFragmentShader(GSVector4i::zero()), error);
@ -201,6 +178,41 @@ bool GPUPresenter::CompileDisplayPipelines(bool display, bool deinterlace, bool
if (!(m_present_clear_pipeline = g_gpu_device->CreatePipeline(plconfig, error)))
return false;
GL_OBJECT_NAME(m_present_clear_pipeline, "Display Clear Pipeline");
if (m_border_overlay_alpha_blend)
{
// destination blend the main present, not source
plconfig.blend.enable = true;
plconfig.blend.src_blend = GPUPipeline::BlendFunc::InvDstAlpha;
plconfig.blend.blend_op = GPUPipeline::BlendOp::Add;
plconfig.blend.dst_blend = GPUPipeline::BlendFunc::One;
plconfig.blend.src_alpha_blend = GPUPipeline::BlendFunc::One;
plconfig.blend.alpha_blend_op = GPUPipeline::BlendOp::Add;
plconfig.blend.dst_alpha_blend = GPUPipeline::BlendFunc::Zero;
plconfig.fragment_shader = fso.get();
if (!(m_display_blend_pipeline = g_gpu_device->CreatePipeline(plconfig, error)))
return false;
GL_OBJECT_NAME_FMT(m_display_blend_pipeline, "Display Pipeline [Blended, {}]",
Settings::GetDisplayScalingName(g_gpu_settings.display_scaling));
plconfig.fragment_shader = rotate_copy_fso.get();
if (!(m_present_copy_blend_pipeline = g_gpu_device->CreatePipeline(plconfig, error)))
return false;
GL_OBJECT_NAME(m_present_copy_blend_pipeline, "Display Rotate/Copy Pipeline [Blended]");
plconfig.fragment_shader = clear_fso.get();
if (!(m_present_clear_blend_pipeline = g_gpu_device->CreatePipeline(plconfig, error)))
return false;
GL_OBJECT_NAME(m_present_clear_blend_pipeline, "Display Clear Pipeline [Blended]");
}
}
else
{
m_present_clear_pipeline.reset();
m_display_blend_pipeline.reset();
m_present_copy_blend_pipeline.reset();
m_present_clear_blend_pipeline.reset();
}
}
@ -526,7 +538,8 @@ GPUDevice::PresentResult GPUPresenter::RenderDisplay(GPUTexture* target, const G
{
// Need to fill in the borders.
GL_SCOPE_FMT("Fill in overlay borders - odisplay={}, draw={}", overlay_display_rect, draw_rect);
g_gpu_device->SetPipeline(m_present_clear_pipeline.get());
g_gpu_device->SetPipeline(m_border_overlay_alpha_blend ? m_present_clear_blend_pipeline.get() :
m_present_clear_pipeline.get());
DrawScreenQuad(overlay_display_rect, GSVector4::zero(), target_size, g_settings.display_rotation, prerotation);
}
}
@ -683,18 +696,6 @@ GPUDevice::PresentResult GPUPresenter::ApplyDisplayPostProcess(GPUTexture* targe
m_display_height);
}
void GPUPresenter::DrawTextureCopy(const GSVector2i target_size, const GSVector4i draw_rect, GPUTexture* input,
bool dst_alpha_blend, bool linear, WindowInfo::PreRotation prerotation)
{
GL_SCOPE_FMT("DrawTextureCopy({}, blend={}, linear={}, prerotation={})", draw_rect, dst_alpha_blend, draw_rect,
static_cast<u32>(prerotation));
g_gpu_device->SetPipeline(dst_alpha_blend ? m_present_copy_blend_pipeline.get() : m_present_copy_pipeline.get());
g_gpu_device->SetTextureSampler(0, input, g_gpu_device->GetNearestSampler());
DrawScreenQuad(draw_rect, GSVector4::cxpr(0.0f, 0.0f, 1.0f, 1.0f), target_size, DisplayRotation::Normal, prerotation);
}
void GPUPresenter::SendDisplayToMediaCapture(MediaCapture* cap)
{
GPUTexture* target = cap->GetRenderTexture();
@ -1140,9 +1141,11 @@ bool GPUPresenter::UpdatePostProcessingSettings(bool force_reload, Error* error)
{
if (LoadOverlaySettings())
{
// something changed, need to recompile pipelines
if (LoadOverlayTexture() && m_border_overlay_alpha_blend &&
(!m_present_copy_blend_pipeline || !m_display_blend_pipeline || !m_present_clear_pipeline) &&
// something changed, need to recompile pipelines, the needed pipelines are based on alpha blend
if (LoadOverlayTexture() &&
((m_border_overlay_alpha_blend &&
(!m_present_copy_blend_pipeline || !m_display_blend_pipeline || !m_present_clear_blend_pipeline)) ||
!m_present_clear_pipeline) &&
!CompileDisplayPipelines(true, false, false, error))
{
return false;

View File

@ -111,8 +111,6 @@ private:
DisplayRotation rotation, WindowInfo::PreRotation prerotation);
GPUDevice::PresentResult ApplyDisplayPostProcess(GPUTexture* target, GPUTexture* input,
const GSVector4i display_rect);
void DrawTextureCopy(const GSVector2i target_size, const GSVector4i draw_rect, GPUTexture* input,
bool dst_alpha_blend, bool linear, WindowInfo::PreRotation prerotation);
void DrawScreenQuad(const GSVector4i rect, const GSVector4 uv_rect, const GSVector2i target_size,
DisplayRotation uv_rotation, WindowInfo::PreRotation prerotation);
@ -158,11 +156,12 @@ private:
std::unique_ptr<PostProcessing::Chain> m_display_postfx;
std::unique_ptr<GPUTexture> m_border_overlay_texture;
std::unique_ptr<GPUPipeline> m_present_clear_pipeline;
// blended variants of pipelines, used when overlays are enabled
std::unique_ptr<GPUPipeline> m_display_blend_pipeline;
std::unique_ptr<GPUPipeline> m_present_copy_blend_pipeline;
std::unique_ptr<GPUPipeline> m_present_clear_pipeline;
std::unique_ptr<GPUPipeline> m_present_clear_blend_pipeline;
GSVector4i m_border_overlay_display_rect = GSVector4i::zero();