From 589a7ac5a20f7c4da0b9a4756e13e73d9f7a19f3 Mon Sep 17 00:00:00 2001 From: Lars-Ivar Hesselberg Simonsen Date: Tue, 17 Sep 2024 11:22:12 +0200 Subject: [PATCH] panvk: Fix paths that assume a fragment shader A few places in PanVK assumes the fragment shader pointer is nonzero, which is not true for some VulkanCTS tests (*nocolor*), causing segfaults when dereferencing the pointer. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11881 Reviewed-by: Boris Brezillon Part-of: --- src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c | 8 ++++---- src/panfrost/vulkan/panvk_vX_shader.c | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c b/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c index ebb02d5aa8e..3012bdd7eb6 100644 --- a/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c +++ b/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c @@ -974,7 +974,8 @@ prepare_ds(struct panvk_cmd_buffer *cmdbuf) if (rs->depth_clamp_enable) cfg.depth_clamp_mode = MALI_DEPTH_CLAMP_MODE_BOUNDS; - cfg.depth_source = pan_depth_source(&fs->info); + if (fs) + cfg.depth_source = pan_depth_source(&fs->info); cfg.depth_write_enable = ds->depth.write_enable; cfg.depth_bias_enable = rs->depth_bias.enable; cfg.depth_function = test_z ? translate_compare_func(ds->depth.compare_op) @@ -997,7 +998,7 @@ prepare_dcd(struct panvk_cmd_buffer *cmdbuf) panvk_get_cs_builder(cmdbuf, PANVK_SUBQUEUE_VERTEX_TILER); const struct panvk_shader *fs = cmdbuf->state.gfx.fs.shader; bool fs_is_dirty = - cmdbuf->state.gfx.fs.spd != panvk_priv_mem_dev_addr(fs->spd); + cmdbuf->state.gfx.fs.spd != (fs ? panvk_priv_mem_dev_addr(fs->spd) : 0); bool dcd0_dirty = is_dirty(cmdbuf, RS_RASTERIZER_DISCARD_ENABLE) || is_dirty(cmdbuf, RS_CULL_MODE) || is_dirty(cmdbuf, RS_FRONT_FACE) || @@ -1117,8 +1118,7 @@ clear_dirty(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) cmdbuf->state.gfx.vs.spds.var = panvk_priv_mem_dev_addr(vs->spds.var); } - if (fs) - cmdbuf->state.gfx.fs.spd = panvk_priv_mem_dev_addr(fs->spd); + cmdbuf->state.gfx.fs.spd = fs ? panvk_priv_mem_dev_addr(fs->spd) : 0; if (draw->index.size) cmdbuf->state.gfx.ib.dirty = false; diff --git a/src/panfrost/vulkan/panvk_vX_shader.c b/src/panfrost/vulkan/panvk_vX_shader.c index 27b87f5aa8b..44d0b0567cc 100644 --- a/src/panfrost/vulkan/panvk_vX_shader.c +++ b/src/panfrost/vulkan/panvk_vX_shader.c @@ -1239,8 +1239,10 @@ panvk_per_arch(link_shaders)(struct panvk_pool *desc_pool, assert(vs->info.stage == MESA_SHADER_VERTEX); if (PAN_ARCH >= 9) { - link->buf_strides[PANVK_VARY_BUF_GENERAL] = - MAX2(fs->info.varyings.input_count, vs->info.varyings.output_count); + /* No need to calculate varying stride if there's no fragment shader. */ + if (fs) + link->buf_strides[PANVK_VARY_BUF_GENERAL] = + MAX2(fs->info.varyings.input_count, vs->info.varyings.output_count); return VK_SUCCESS; }