From 5ec344df2c54c7b55f9ddf5f5aa9428c61930581 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 1 May 2026 17:10:47 +0800 Subject: [PATCH] pvr: setup viewindex if the shader wants it even when multiview disabled It's possible to use a shader that has ViewIndex input when multiview isn't enabled. According to the Vulkan specification, when multiview isn't enabled in a renderpass, the value of the ViewIndex input should be 0. However currently the driver does not emit execution of the PDS code setting up view index, which leads to stale value to remain in ViewIndex. Setup the PDS code for setting view index and emit the command stream for executing that PDS code when the shader wants ViewIndex, even if multiview isn't enabled. Fixes: 9d48088428bf ("pvr: add view index support for vertex shaders") Signed-off-by: Icenowy Zheng Reviewed-by: Nick Hamilton (cherry picked from commit 3afc792dc8969abb21dfd3395a19a4478ffca39e) Part-of: --- .pick_status.json | 2 +- src/imagination/vulkan/pvr_arch_cmd_buffer.c | 9 ++++++++- src/imagination/vulkan/pvr_arch_queue.c | 2 +- src/imagination/vulkan/pvr_cmd_buffer.h | 1 + 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index f21321d26ba..07df39f549f 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -2574,7 +2574,7 @@ "description": "pvr: setup viewindex if the shader wants it even when multiview disabled", "nominated": true, "nomination_type": 2, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "9d48088428bfe52d234319d2ec9c5b01d56edbc8", "notes": null diff --git a/src/imagination/vulkan/pvr_arch_cmd_buffer.c b/src/imagination/vulkan/pvr_arch_cmd_buffer.c index da95088ee1f..cb3ed7f602b 100644 --- a/src/imagination/vulkan/pvr_arch_cmd_buffer.c +++ b/src/imagination/vulkan/pvr_arch_cmd_buffer.c @@ -2459,7 +2459,7 @@ VkResult pvr_arch_cmd_buffer_end_sub_cmd(struct pvr_cmd_buffer *cmd_buffer) if (result != VK_SUCCESS) return pvr_cmd_buffer_set_error_unwarned(cmd_buffer, result); - if (gfx_sub_cmd->multiview_enabled) { + if (gfx_sub_cmd->view_index_wanted) { result = pvr_csb_gfx_build_view_index_ctrl_stream( device, pvr_csb_get_start_address(&gfx_sub_cmd->control_stream), @@ -2730,6 +2730,7 @@ VkResult pvr_arch_cmd_buffer_start_sub_cmd(struct pvr_cmd_buffer *cmd_buffer, ? state->render_pass_info.pass->multiview_enabled : false; } + sub_cmd->gfx.view_index_wanted = sub_cmd->gfx.multiview_enabled; if (state->vis_test_enabled) sub_cmd->gfx.query_pool = state->query_pool; @@ -8133,6 +8134,7 @@ static VkResult pvr_validate_draw_state(struct pvr_cmd_buffer *cmd_buffer) struct vk_dynamic_graphics_state *const dynamic_state = &cmd_buffer->vk.dynamic_graphics_state; const struct pvr_graphics_pipeline *const gfx_pipeline = state->gfx_pipeline; + const pco_data *const vs_data = &gfx_pipeline->vs_data; const pco_data *const fs_data = &gfx_pipeline->fs_data; struct pvr_sub_cmd_gfx *sub_cmd; bool fstencil_writemask_zero; @@ -8179,6 +8181,9 @@ static VkResult pvr_validate_draw_state(struct pvr_cmd_buffer *cmd_buffer) sub_cmd->frag_uses_texture_rw |= false; sub_cmd->vertex_uses_texture_rw |= false; + sub_cmd->view_index_wanted |= vs_data->common.multiview; + sub_cmd->view_index_wanted |= fs_data->common.multiview; + sub_cmd->job.get_vis_results = state->vis_test_enabled; fstencil_keep = @@ -9076,6 +9081,8 @@ pvr_execute_graphics_cmd_buffer(struct pvr_cmd_buffer *cmd_buffer, primary_sub_cmd->gfx.job.get_vis_results |= sec_sub_cmd->gfx.job.get_vis_results; + primary_sub_cmd->gfx.view_index_wanted |= + sec_sub_cmd->gfx.view_index_wanted; primary_sub_cmd->gfx.max_tiles_in_flight = MIN2(primary_sub_cmd->gfx.max_tiles_in_flight, diff --git a/src/imagination/vulkan/pvr_arch_queue.c b/src/imagination/vulkan/pvr_arch_queue.c index 4b62f150a79..ae18a26cce5 100644 --- a/src/imagination/vulkan/pvr_arch_queue.c +++ b/src/imagination/vulkan/pvr_arch_queue.c @@ -297,7 +297,7 @@ pvr_process_graphics_cmd_for_view(struct pvr_device *device, */ assert(sub_cmd->terminate_ctrl_stream); job->ctrl_stream_addr = sub_cmd->terminate_ctrl_stream->vma->dev_addr; - } else if (sub_cmd->multiview_enabled) { + } else if (sub_cmd->view_index_wanted) { original_ctrl_stream_addr = job->ctrl_stream_addr; job->ctrl_stream_addr.addr = sub_cmd->multiview_ctrl_stream->vma->dev_addr.addr + diff --git a/src/imagination/vulkan/pvr_cmd_buffer.h b/src/imagination/vulkan/pvr_cmd_buffer.h index f29fb624b56..0ca8a08fe24 100644 --- a/src/imagination/vulkan/pvr_cmd_buffer.h +++ b/src/imagination/vulkan/pvr_cmd_buffer.h @@ -217,6 +217,7 @@ struct pvr_sub_cmd_gfx { uint32_t view_mask; bool multiview_enabled; + bool view_index_wanted; /* Recorded deferred RTA clears for secondary command buffers */ struct util_dynarray unbound_deferred_clears;