From a0d1ef7f619a330ea2807fb0eb6c5e55c438b470 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 6 Jul 2022 02:51:05 +0200 Subject: [PATCH] [dxvk] Handle null shader in DxvkShaderPipelineLibrary --- src/dxvk/dxvk_shader.cpp | 26 +++++++++++++++++++++----- src/dxvk/meson.build | 2 ++ src/dxvk/shaders/dxvk_dummy_frag.frag | 5 +++++ 3 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 src/dxvk/shaders/dxvk_dummy_frag.frag diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index acd8f822..361cbd9e 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -1,6 +1,8 @@ #include "dxvk_device.h" #include "dxvk_shader.h" +#include + #include #include #include @@ -444,14 +446,19 @@ namespace dxvk { const DxvkShaderPipelineLibraryCompileArgs& args) { std::lock_guard lock(m_mutex); - VkPipeline& pipeline = (m_shader->info().stage == VK_SHADER_STAGE_VERTEX_BIT && !args.depthClipEnable) + VkShaderStageFlagBits stage = VK_SHADER_STAGE_FRAGMENT_BIT; + + if (m_shader) + stage = m_shader->info().stage; + + VkPipeline& pipeline = (stage == VK_SHADER_STAGE_VERTEX_BIT && !args.depthClipEnable) ? m_pipelineNoDepthClip : m_pipeline; if (pipeline) return pipeline; - switch (m_shader->info().stage) { + switch (stage) { case VK_SHADER_STAGE_VERTEX_BIT: pipeline = compileVertexShaderPipeline(cache, args); break; @@ -555,9 +562,18 @@ namespace dxvk { VkPipeline DxvkShaderPipelineLibrary::compileFragmentShaderPipeline(VkPipelineCache cache) { auto vk = m_device->vkd(); + // Initialize code buffer. As a special case, it is possible that + // we have to deal with a null shader, but the pipeline library + // extension requires us to always specify a fragment shader. DxvkShaderStageInfo stageInfo(m_device); - stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, - m_shader->getCode(m_layout, DxvkShaderModuleCreateInfo()), nullptr); + + if (m_shader) { + stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, + m_shader->getCode(m_layout, DxvkShaderModuleCreateInfo()), nullptr); + } else { + stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, + SpirvCodeBuffer(dxvk_dummy_frag), nullptr); + } // Set up dynamic state. We do not know any pipeline state // at this time, so make as much state dynamic as we can. @@ -612,7 +628,7 @@ namespace dxvk { info.layout = m_layout->getPipelineLayout(); info.basePipelineIndex = -1; - if (m_shader->flags().test(DxvkShaderFlag::HasSampleRateShading)) + if (m_shader && m_shader->flags().test(DxvkShaderFlag::HasSampleRateShading)) info.pMultisampleState = &msInfo; VkPipeline pipeline = VK_NULL_HANDLE; diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index 0ed8caf6..e49c49b9 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -27,6 +27,8 @@ dxvk_shaders = files([ 'shaders/dxvk_copy_depth_stencil_2d.frag', 'shaders/dxvk_copy_depth_stencil_ms.frag', + 'shaders/dxvk_dummy_frag.frag', + 'shaders/dxvk_fullscreen_geom.geom', 'shaders/dxvk_fullscreen_vert.vert', 'shaders/dxvk_fullscreen_layer_vert.vert', diff --git a/src/dxvk/shaders/dxvk_dummy_frag.frag b/src/dxvk/shaders/dxvk_dummy_frag.frag new file mode 100644 index 00000000..0afc2bd1 --- /dev/null +++ b/src/dxvk/shaders/dxvk_dummy_frag.frag @@ -0,0 +1,5 @@ +#version 450 + +void main() { + +}