1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-05 19:46:15 +01:00

[dxvk] Handle null shader in DxvkShaderPipelineLibrary

This commit is contained in:
Philip Rebohle 2022-07-06 02:51:05 +02:00
parent 2cb9ceba1d
commit a0d1ef7f61
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 28 additions and 5 deletions

View File

@ -1,6 +1,8 @@
#include "dxvk_device.h" #include "dxvk_device.h"
#include "dxvk_shader.h" #include "dxvk_shader.h"
#include <dxvk_dummy_frag.h>
#include <algorithm> #include <algorithm>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
@ -444,14 +446,19 @@ namespace dxvk {
const DxvkShaderPipelineLibraryCompileArgs& args) { const DxvkShaderPipelineLibraryCompileArgs& args) {
std::lock_guard lock(m_mutex); 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_pipelineNoDepthClip
: m_pipeline; : m_pipeline;
if (pipeline) if (pipeline)
return pipeline; return pipeline;
switch (m_shader->info().stage) { switch (stage) {
case VK_SHADER_STAGE_VERTEX_BIT: case VK_SHADER_STAGE_VERTEX_BIT:
pipeline = compileVertexShaderPipeline(cache, args); pipeline = compileVertexShaderPipeline(cache, args);
break; break;
@ -555,9 +562,18 @@ namespace dxvk {
VkPipeline DxvkShaderPipelineLibrary::compileFragmentShaderPipeline(VkPipelineCache cache) { VkPipeline DxvkShaderPipelineLibrary::compileFragmentShaderPipeline(VkPipelineCache cache) {
auto vk = m_device->vkd(); 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); 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 // Set up dynamic state. We do not know any pipeline state
// at this time, so make as much state dynamic as we can. // at this time, so make as much state dynamic as we can.
@ -612,7 +628,7 @@ namespace dxvk {
info.layout = m_layout->getPipelineLayout(); info.layout = m_layout->getPipelineLayout();
info.basePipelineIndex = -1; info.basePipelineIndex = -1;
if (m_shader->flags().test(DxvkShaderFlag::HasSampleRateShading)) if (m_shader && m_shader->flags().test(DxvkShaderFlag::HasSampleRateShading))
info.pMultisampleState = &msInfo; info.pMultisampleState = &msInfo;
VkPipeline pipeline = VK_NULL_HANDLE; VkPipeline pipeline = VK_NULL_HANDLE;

View File

@ -27,6 +27,8 @@ dxvk_shaders = files([
'shaders/dxvk_copy_depth_stencil_2d.frag', 'shaders/dxvk_copy_depth_stencil_2d.frag',
'shaders/dxvk_copy_depth_stencil_ms.frag', 'shaders/dxvk_copy_depth_stencil_ms.frag',
'shaders/dxvk_dummy_frag.frag',
'shaders/dxvk_fullscreen_geom.geom', 'shaders/dxvk_fullscreen_geom.geom',
'shaders/dxvk_fullscreen_vert.vert', 'shaders/dxvk_fullscreen_vert.vert',
'shaders/dxvk_fullscreen_layer_vert.vert', 'shaders/dxvk_fullscreen_layer_vert.vert',

View File

@ -0,0 +1,5 @@
#version 450
void main() {
}