From 4d9dd5c3a2450fcc21e640d87813a86d79ee0996 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Sun, 29 Jun 2025 22:13:50 +0300 Subject: [PATCH] anv: store a few default instructions We will use those where no associated shaders is active but we still need some default values programmed. Signed-off-by: Lionel Landwerlin Reviewed-by: Ivan Briano Reviewed-by: Caio Oliveira Part-of: --- src/intel/vulkan/anv_genX.h | 3 ++ src/intel/vulkan/anv_physical_device.c | 1 + src/intel/vulkan/anv_private.h | 26 +++++++++++--- src/intel/vulkan/genX_init_state.c | 9 ----- src/intel/vulkan/genX_pipeline.c | 4 +-- src/intel/vulkan/genX_shader.c | 50 ++++++++++++++++++++++++-- 6 files changed, 75 insertions(+), 18 deletions(-) diff --git a/src/intel/vulkan/anv_genX.h b/src/intel/vulkan/anv_genX.h index d1a6ca2bde0..ed079f59cec 100644 --- a/src/intel/vulkan/anv_genX.h +++ b/src/intel/vulkan/anv_genX.h @@ -40,6 +40,7 @@ struct intel_sample_positions; struct intel_urb_config; struct anv_async_submit; struct anv_embedded_sampler; +struct anv_physical_device; struct anv_pipeline_embedded_sampler_binding; struct anv_trtt_bind; @@ -537,6 +538,8 @@ genX(cmd_dispatch_unaligned)( uint32_t invocations_y, uint32_t invocations_z); +void genX(init_instructions)(struct anv_physical_device *device); + void genX(shader_emit)(struct anv_batch *batch, struct anv_device *device, struct anv_shader *shader); diff --git a/src/intel/vulkan/anv_physical_device.c b/src/intel/vulkan/anv_physical_device.c index 650217f864a..e3caef7a452 100644 --- a/src/intel/vulkan/anv_physical_device.c +++ b/src/intel/vulkan/anv_physical_device.c @@ -2805,6 +2805,7 @@ anv_physical_device_try_create(struct vk_instance *vk_instance, anv_measure_device_init(device); anv_genX(&device->info, init_physical_device_state)(device); + anv_genX(&device->info, init_instructions)(device); *out = &device->vk; diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index a832312511c..de85f360815 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -1606,11 +1606,27 @@ struct anv_physical_device { /* Value of PIPELINE_SELECT::PipelineSelection == GPGPU */ uint32_t gpgpu_pipeline_value; - /** A pre packed VERTEX_ELEMENT_STATE feeding 0s to the VS stage - * - * For use when a pipeline has no VS input - */ - uint32_t empty_vs_input[2]; + struct { + /** A pre packed VERTEX_ELEMENT_STATE feeding 0s to the VS stage + * + * For use when a pipeline has no VS input + */ + uint32_t empty_vs_input[2]; + + /** A few default instructions */ + uint32_t vs[9]; + uint32_t hs[9]; + uint32_t ds[11]; + uint32_t gs[10]; + uint32_t te[5]; + uint32_t so[5]; + uint32_t wm[2]; + uint32_t ps[12]; + uint32_t ps_extra[2]; + uint32_t ps_extra_dep[2]; + uint32_t mesh_control[3]; + uint32_t task_control[3]; + } gfx_default; }; VkResult anv_physical_device_try_create(struct vk_instance *vk_instance, diff --git a/src/intel/vulkan/genX_init_state.c b/src/intel/vulkan/genX_init_state.c index 439b13a269a..ff08ea811f4 100644 --- a/src/intel/vulkan/genX_init_state.c +++ b/src/intel/vulkan/genX_init_state.c @@ -926,15 +926,6 @@ genX(init_physical_device_state)(ASSERTED struct anv_physical_device *pdevice) pdevice->cmd_capture_data = genX(cmd_capture_data); pdevice->gpgpu_pipeline_value = GPGPU; - - struct GENX(VERTEX_ELEMENT_STATE) empty_ve = { - .Valid = true, - .Component0Control = VFCOMP_STORE_0, - .Component1Control = VFCOMP_STORE_0, - .Component2Control = VFCOMP_STORE_0, - .Component3Control = VFCOMP_STORE_0, - }; - GENX(VERTEX_ELEMENT_STATE_pack)(NULL, pdevice->empty_vs_input, &empty_ve); } VkResult diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c index bbccd79c4eb..f46609e4eda 100644 --- a/src/intel/vulkan/genX_pipeline.c +++ b/src/intel/vulkan/genX_pipeline.c @@ -290,8 +290,8 @@ genX(batch_emit_pipeline_vertex_input)(struct anv_batch *batch, return; if (ve_count == 0) { - memcpy(p + 1, device->physical->empty_vs_input, - sizeof(device->physical->empty_vs_input)); + memcpy(p + 1, device->physical->gfx_default.empty_vs_input, + sizeof(device->physical->gfx_default.empty_vs_input)); } else if (ve_count == pipeline->vertex_input_elems) { /* MESA_VK_DYNAMIC_VI is not dynamic for this pipeline, so everything is * in pipeline->vertex_input_data and we can just memcpy diff --git a/src/intel/vulkan/genX_shader.c b/src/intel/vulkan/genX_shader.c index f6d202dff8c..3dbe549d244 100644 --- a/src/intel/vulkan/genX_shader.c +++ b/src/intel/vulkan/genX_shader.c @@ -16,6 +16,16 @@ #define device_needs_protected(device) \ ((device)->vk.enabled_features.protectedMemory) +#define anv_gfx_pack(dest, cmd, name) \ + for (struct cmd name = (struct cmd) { __anv_cmd_header(cmd) }, \ + *_dst = (struct cmd *)dest; \ + __builtin_expect(_dst != NULL, 1); \ + ({ \ + assert(sizeof(dest) >= 4 * __anv_cmd_length(cmd)); \ + __anv_cmd_pack(cmd)(NULL, _dst, &name); \ + _dst = NULL; \ + })) + static uint32_t get_sampler_count(const struct anv_shader *shader) { @@ -387,8 +397,8 @@ genX(batch_emit_vertex_input)(struct anv_batch *batch, return; if (ve_count == 0) { - memcpy(p + 1, device->physical->empty_vs_input, - sizeof(device->physical->empty_vs_input)); + memcpy(p + 1, device->physical->gfx_default.empty_vs_input, + sizeof(device->physical->gfx_default.empty_vs_input)); } else { /* Use dyn->vi to emit the dynamic VERTEX_ELEMENT_STATE input. */ emit_ves_vf_instancing(batch, p + 1, device, shader, vi); @@ -1296,6 +1306,42 @@ emit_cs_shader(struct anv_batch *batch, #endif } +void +genX(init_instructions)(struct anv_physical_device *device) +{ + struct GENX(VERTEX_ELEMENT_STATE) empty_ve = { + .Valid = true, + .Component0Control = VFCOMP_STORE_0, + .Component1Control = VFCOMP_STORE_0, + .Component2Control = VFCOMP_STORE_0, + .Component3Control = VFCOMP_STORE_0, + }; + GENX(VERTEX_ELEMENT_STATE_pack)( + NULL, device->gfx_default.empty_vs_input, &empty_ve); + + anv_gfx_pack(device->gfx_default.vs, GENX(3DSTATE_VS), vs); + anv_gfx_pack(device->gfx_default.hs, GENX(3DSTATE_HS), hs); + anv_gfx_pack(device->gfx_default.ds, GENX(3DSTATE_DS), ds); + anv_gfx_pack(device->gfx_default.gs, GENX(3DSTATE_GS), gs); + anv_gfx_pack(device->gfx_default.te, GENX(3DSTATE_TE), te); + anv_gfx_pack(device->gfx_default.so, GENX(3DSTATE_STREAMOUT), so); + anv_gfx_pack(device->gfx_default.wm, GENX(3DSTATE_WM), wm) { + wm.StatisticsEnable = true; + } + anv_gfx_pack(device->gfx_default.ps, GENX(3DSTATE_PS), ps); + anv_gfx_pack(device->gfx_default.ps_extra, GENX(3DSTATE_PS_EXTRA), pse); + anv_gfx_pack(device->gfx_default.ps_extra_dep, GENX(3DSTATE_PS_EXTRA), pse) { +#if GFX_VERx10 >= 125 + pse.EnablePSDependencyOnCPsizeChange = true; +#endif + } + +#if GFX_VERx10 >= 125 + anv_gfx_pack(device->gfx_default.task_control, GENX(3DSTATE_TASK_CONTROL), ts); + anv_gfx_pack(device->gfx_default.mesh_control, GENX(3DSTATE_MESH_CONTROL), ms); +#endif +} + void genX(shader_emit)(struct anv_batch *batch, struct anv_device *device,