diff --git a/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c b/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c index 5fa85b4ab3e..c83b9d423f2 100644 --- a/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c +++ b/src/panfrost/vulkan/csf/panvk_vX_cmd_draw.c @@ -1122,7 +1122,8 @@ prepare_dcd(struct panvk_cmd_buffer *cmdbuf) dyn_gfx_state_dirty(cmdbuf, DS_STENCIL_TEST_ENABLE) || dyn_gfx_state_dirty(cmdbuf, DS_STENCIL_OP) || dyn_gfx_state_dirty(cmdbuf, DS_STENCIL_WRITE_MASK) || - fs_user_dirty(cmdbuf) || gfx_state_dirty(cmdbuf, RENDER_STATE); + fs_user_dirty(cmdbuf) || gfx_state_dirty(cmdbuf, RENDER_STATE) || + gfx_state_dirty(cmdbuf, OQ); bool dcd1_dirty = dyn_gfx_state_dirty(cmdbuf, MS_RASTERIZATION_SAMPLES) || dyn_gfx_state_dirty(cmdbuf, MS_SAMPLE_MASK) || fs_user_dirty(cmdbuf) || @@ -1150,7 +1151,8 @@ prepare_dcd(struct panvk_cmd_buffer *cmdbuf) bool writes_zs = writes_z || writes_s; bool zs_always_passes = ds_test_always_passes(cmdbuf); - bool oq = false; /* TODO: Occlusion queries */ + bool oq = cmdbuf->state.gfx.occlusion_query.mode != + MALI_OCCLUSION_MODE_DISABLED; struct pan_earlyzs_state earlyzs = pan_earlyzs_get(pan_earlyzs_analyze(&fs->info), writes_zs || oq, @@ -1172,6 +1174,7 @@ prepare_dcd(struct panvk_cmd_buffer *cmdbuf) cfg.cull_back_face = (rs->cull_mode & VK_CULL_MODE_BACK_BIT) != 0; cfg.multisample_enable = dyns->ms.rasterization_samples > 1; + cfg.occlusion_query = cmdbuf->state.gfx.occlusion_query.mode; } cs_update_vt_ctx(b) @@ -1368,6 +1371,10 @@ prepare_draw(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) prepare_dcd(cmdbuf); prepare_vp(cmdbuf); prepare_tiler_primitive_size(cmdbuf); + + if (gfx_state_dirty(cmdbuf, OQ)) + cs_move64_to(b, cs_reg64(b, 46), + cmdbuf->state.gfx.occlusion_query.ptr); } clear_dirty_after_draw(cmdbuf); diff --git a/src/panfrost/vulkan/jm/panvk_vX_cmd_draw.c b/src/panfrost/vulkan/jm/panvk_vX_cmd_draw.c index 038bbf02dbb..851b8976641 100644 --- a/src/panfrost/vulkan/jm/panvk_vX_cmd_draw.c +++ b/src/panfrost/vulkan/jm/panvk_vX_cmd_draw.c @@ -313,7 +313,7 @@ panvk_draw_prepare_fs_rsd(struct panvk_cmd_buffer *cmdbuf, dyn_gfx_state_dirty(cmdbuf, MS_SAMPLE_MASK) || dyn_gfx_state_dirty(cmdbuf, MS_ALPHA_TO_COVERAGE_ENABLE) || dyn_gfx_state_dirty(cmdbuf, MS_ALPHA_TO_ONE_ENABLE) || - gfx_state_dirty(cmdbuf, FS) || + gfx_state_dirty(cmdbuf, FS) || gfx_state_dirty(cmdbuf, OQ) || gfx_state_dirty(cmdbuf, RENDER_STATE); if (!dirty) { @@ -382,7 +382,8 @@ panvk_draw_prepare_fs_rsd(struct panvk_cmd_buffer *cmdbuf, bool writes_zs = writes_z || writes_s; bool zs_always_passes = ds_test_always_passes(cmdbuf); - bool oq = false; /* TODO: Occlusion queries */ + bool oq = cmdbuf->state.gfx.occlusion_query.mode != + MALI_OCCLUSION_MODE_DISABLED; struct pan_earlyzs_state earlyzs = pan_earlyzs_get(pan_earlyzs_analyze(fs_info), writes_zs || oq, @@ -1005,7 +1006,8 @@ panvk_emit_tiler_dcd(struct panvk_cmd_buffer *cmdbuf, cfg.textures = fs_desc_state->tables[PANVK_BIFROST_DESC_TABLE_TEXTURE]; cfg.samplers = fs_desc_state->tables[PANVK_BIFROST_DESC_TABLE_SAMPLER]; - /* TODO: occlusion queries */ + cfg.occlusion_query = cmdbuf->state.gfx.occlusion_query.mode; + cfg.occlusion = cmdbuf->state.gfx.occlusion_query.ptr; } } @@ -1223,7 +1225,9 @@ panvk_cmd_draw(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) return; } - bool needs_tiling = !rs->rasterizer_discard_enable; + bool active_occlusion = + cmdbuf->state.gfx.occlusion_query.mode != MALI_OCCLUSION_MODE_DISABLED; + bool needs_tiling = !rs->rasterizer_discard_enable || active_occlusion; if (!rs->rasterizer_discard_enable) { struct pan_fb_info *fbinfo = &cmdbuf->state.gfx.render.fb.info; diff --git a/src/panfrost/vulkan/panvk_cmd_draw.h b/src/panfrost/vulkan/panvk_cmd_draw.h index ace89963f85..ca260a80b5e 100644 --- a/src/panfrost/vulkan/panvk_cmd_draw.h +++ b/src/panfrost/vulkan/panvk_cmd_draw.h @@ -11,6 +11,7 @@ #endif #include "panvk_blend.h" +#include "panvk_cmd_oq.h" #include "panvk_entrypoints.h" #include "panvk_image.h" #include "panvk_image_view.h" @@ -77,6 +78,7 @@ enum panvk_cmd_graphics_dirty_state { PANVK_CMD_GRAPHICS_DIRTY_FS, PANVK_CMD_GRAPHICS_DIRTY_VB, PANVK_CMD_GRAPHICS_DIRTY_IB, + PANVK_CMD_GRAPHICS_DIRTY_OQ, PANVK_CMD_GRAPHICS_DIRTY_DESC_STATE, PANVK_CMD_GRAPHICS_DIRTY_RENDER_STATE, PANVK_CMD_GRAPHICS_DIRTY_PUSH_UNIFORMS, @@ -91,6 +93,7 @@ struct panvk_cmd_graphics_state { struct vk_sample_locations_state sl; } dynamic; + struct panvk_occlusion_query_state occlusion_query; struct panvk_graphics_sysvals sysvals; #if PAN_ARCH <= 7 diff --git a/src/panfrost/vulkan/panvk_cmd_meta.h b/src/panfrost/vulkan/panvk_cmd_meta.h index 354815d36fe..757ae519c81 100644 --- a/src/panfrost/vulkan/panvk_cmd_meta.h +++ b/src/panfrost/vulkan/panvk_cmd_meta.h @@ -65,6 +65,8 @@ struct panvk_cmd_meta_graphics_save_ctx { const struct panvk_shader *shader; struct panvk_shader_desc_state desc; } vs; + + struct panvk_occlusion_query_state occlusion_query; }; void panvk_per_arch(cmd_meta_gfx_start)( diff --git a/src/panfrost/vulkan/panvk_cmd_oq.h b/src/panfrost/vulkan/panvk_cmd_oq.h new file mode 100644 index 00000000000..75cf144976e --- /dev/null +++ b/src/panfrost/vulkan/panvk_cmd_oq.h @@ -0,0 +1,21 @@ +/* + * Copyright © 2024 Collabora Ltd. + * SPDX-License-Identifier: MIT + */ + +#ifndef PANVK_CMD_OQ_H +#define PANVK_CMD_OQ_H + +#ifndef PAN_ARCH +#error "PAN_ARCH must be defined" +#endif + +#include "genxml/gen_macros.h" +#include "panfrost-job.h" + +struct panvk_occlusion_query_state { + mali_ptr ptr; + enum mali_occlusion_mode mode; +}; + +#endif \ No newline at end of file diff --git a/src/panfrost/vulkan/panvk_vX_cmd_meta.c b/src/panfrost/vulkan/panvk_vX_cmd_meta.c index 07e060a9f09..edb643ef478 100644 --- a/src/panfrost/vulkan/panvk_vX_cmd_meta.c +++ b/src/panfrost/vulkan/panvk_vX_cmd_meta.c @@ -103,6 +103,12 @@ panvk_per_arch(cmd_meta_gfx_start)( save_ctx->dyn_state.all = cmdbuf->vk.dynamic_graphics_state; save_ctx->dyn_state.vi = cmdbuf->state.gfx.dynamic.vi; save_ctx->dyn_state.sl = cmdbuf->state.gfx.dynamic.sl; + save_ctx->occlusion_query = cmdbuf->state.gfx.occlusion_query; + + /* Ensure occlusion queries are disabled */ + cmdbuf->state.gfx.occlusion_query.ptr = 0; + cmdbuf->state.gfx.occlusion_query.mode = MALI_OCCLUSION_MODE_DISABLED; + gfx_state_set_dirty(cmdbuf, OQ); } void @@ -146,12 +152,14 @@ panvk_per_arch(cmd_meta_gfx_end)( cmdbuf->vk.dynamic_graphics_state = save_ctx->dyn_state.all; cmdbuf->state.gfx.dynamic.vi = save_ctx->dyn_state.vi; cmdbuf->state.gfx.dynamic.sl = save_ctx->dyn_state.sl; + cmdbuf->state.gfx.occlusion_query = save_ctx->occlusion_query; memcpy(cmdbuf->vk.dynamic_graphics_state.dirty, cmdbuf->vk.dynamic_graphics_state.set, sizeof(cmdbuf->vk.dynamic_graphics_state.set)); gfx_state_set_dirty(cmdbuf, VS); gfx_state_set_dirty(cmdbuf, FS); gfx_state_set_dirty(cmdbuf, VB); + gfx_state_set_dirty(cmdbuf, OQ); gfx_state_set_dirty(cmdbuf, DESC_STATE); gfx_state_set_dirty(cmdbuf, RENDER_STATE); }