From e9fa840eed242812914dfd33d6c0c42d4e3d2197 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Sat, 8 Apr 2023 23:21:29 +0300 Subject: [PATCH] anv: implement EDS2.extendedDynamicState2PatchControlPoints We make the compiler assume the worst possible case (it's not great because we have to burn 32 GRFs of potential input data) and then we push the actual value through push constants. This enables VK_EXT_gpl usage on zink, which causes two traces to change their results. Raven is an imperceptible change, blender has missing original pngs but looks plausible. Signed-off-by: Lionel Landwerlin Reviewed-by: Emma Anholt Part-of: --- .../drivers/zink/ci/traces-zink-restricted.yml | 2 +- src/gallium/drivers/zink/ci/traces-zink.yml | 2 +- .../zink/ci/zink-anv-tgl-validation-settings.txt | 22 ++++- src/intel/vulkan/anv_blorp.c | 3 +- src/intel/vulkan/anv_cmd_buffer.c | 8 +- src/intel/vulkan/anv_device.c | 2 +- src/intel/vulkan/anv_generated_indirect_draws.c | 3 +- src/intel/vulkan/anv_nir.h | 2 + src/intel/vulkan/anv_nir_compute_push_layout.c | 4 +- .../vulkan/anv_nir_lower_load_patch_vertices_in.c | 69 ++++++++++++++ src/intel/vulkan/anv_pipeline.c | 101 ++++++++++++++++----- src/intel/vulkan/anv_pipeline_cache.c | 18 +++- src/intel/vulkan/anv_private.h | 31 +++++-- src/intel/vulkan/genX_cmd_buffer.c | 14 ++- src/intel/vulkan/grl/genX_grl_dispatch.c | 3 +- src/intel/vulkan/meson.build | 1 + 16 files changed, 240 insertions(+), 45 deletions(-) create mode 100644 src/intel/vulkan/anv_nir_lower_load_patch_vertices_in.c diff --git a/src/gallium/drivers/zink/ci/traces-zink-restricted.yml b/src/gallium/drivers/zink/ci/traces-zink-restricted.yml index 716e554..2fbfa9f 100644 --- a/src/gallium/drivers/zink/ci/traces-zink-restricted.yml +++ b/src/gallium/drivers/zink/ci/traces-zink-restricted.yml @@ -56,7 +56,7 @@ traces: checksum: 488ac7f0a747ed9f9255f60be7118650 TheRavenRemastered/Raven-f10900-v2.trace: gl-zink-anv-tgl: - checksum: e910141d9520739c653fa7de0d8a1c9b + checksum: db7b901177e7ac00cc489e0e13f71f76 TombRaider2013/TombRaider-f1430-v2.trace: gl-zink-anv-tgl: label: [crash] diff --git a/src/gallium/drivers/zink/ci/traces-zink.yml b/src/gallium/drivers/zink/ci/traces-zink.yml index 17fc0a3..de43a6f 100644 --- a/src/gallium/drivers/zink/ci/traces-zink.yml +++ b/src/gallium/drivers/zink/ci/traces-zink.yml @@ -29,7 +29,7 @@ traces: checksum: 433b69bea68cfe81914b857bbdc60ea5 gputest/pixmark-piano-v2.trace: gl-zink-anv-tgl: - checksum: acdfae98a5a31da0a4450af4eea00aa1 + checksum: cf7e480f3bdb79ece172a2ccedda2e9d gputest/triangle-v2.trace: gl-zink-anv-tgl: checksum: 5f694874b15bcd7a3689b387c143590b diff --git a/src/gallium/drivers/zink/ci/zink-anv-tgl-validation-settings.txt b/src/gallium/drivers/zink/ci/zink-anv-tgl-validation-settings.txt index 9c12fa3..1c347f8 100644 --- a/src/gallium/drivers/zink/ci/zink-anv-tgl-validation-settings.txt +++ b/src/gallium/drivers/zink/ci/zink-anv-tgl-validation-settings.txt @@ -1,6 +1,6 @@ # Please include a comment with the log message and a testcase triggering each # VUID at the bottom of the file. -khronos_validation.message_id_filter = UNASSIGNED-CoreValidation-Shader-InconsistentSpirv,VUID-vkDestroyDevice-device-00378,VUID-VkShaderModuleCreateInfo-pCode-01377,VUID-RuntimeSpirv-Location-06272,VUID-VkGraphicsPipelineCreateInfo-renderPass-06590,VUID-VkGraphicsPipelineCreateInfo-Geometry-07725,VUID-vkCmdDrawMultiIndexedEXT-format-07753,UNASSIGNED-CoreValidation-Shader-InterfaceTypeMismatch,VUID-RuntimeSpirv-OpEntryPoint-07754,VUID-VkShaderModuleCreateInfo-pCode-01379,VUID-RuntimeSpirv-OpEntryPoint-08743 +khronos_validation.message_id_filter = UNASSIGNED-CoreValidation-Shader-InconsistentSpirv,VUID-vkDestroyDevice-device-00378,VUID-VkShaderModuleCreateInfo-pCode-01377,VUID-RuntimeSpirv-Location-06272,VUID-VkGraphicsPipelineCreateInfo-renderPass-06590,VUID-VkGraphicsPipelineCreateInfo-Geometry-07725,VUID-vkCmdDrawMultiIndexedEXT-format-07753,UNASSIGNED-CoreValidation-Shader-InterfaceTypeMismatch,VUID-RuntimeSpirv-OpEntryPoint-07754,VUID-VkShaderModuleCreateInfo-pCode-01379,VUID-RuntimeSpirv-OpEntryPoint-08743,VUID-VkGraphicsPipelineCreateInfo-topology-00737,VUID-VkGraphicsPipelineCreateInfo-pStages-00736,VUID-vkCmdCopyImage-srcImage-07743,VUID-vkCmdDrawMultiIndexedEXT-format-07753,VUID-vkCmdDrawMultiEXT-pDepthAttachment-06181,VUID-vkCmdDrawMultiEXT-pStencilAttachment-06182,VUID-vkCmdDrawMultiIndexedEXT-pDepthAttachment-06181,VUID-vkCmdDrawMultiIndexedEXT-pStencilAttachment-06182 khronos_validation.report_flags = error khronos_validation.debug_action = VK_DBG_LAYER_ACTION_LOG_MSG,VK_DBG_LAYER_ACTION_BREAK VK_LAYER_ENABLES=VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT @@ -114,3 +114,23 @@ khronos_validation.log_filename = stdout # (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-RuntimeSpirv-OpEntryPoint-08743) # # VVL bug https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/5735 + + +# VUID-VkGraphicsPipelineCreateInfo-pStages-00736 +# VUID-VkGraphicsPipelineCreateInfo-topology-00737 +# spec bug https://gitlab.khronos.org/vulkan/vulkan/-/merge_requests/5916 + + +# VUID-vkCmdCopyImage-srcImage-07743 +# spec bug + +# VUID-vkCmdDrawMultiIndexedEXT-format-07753 +# KHR-GL46.shader_ballot_tests.ShaderBallotFunctionBallot +# https://gitlab.khronos.org/Tracker/vk-gl-cts/-/issues/4488 + + +# VUID-vkCmdDrawMultiEXT-pDepthAttachment-06181 +# VUID-vkCmdDrawMultiEXT-pStencilAttachment-06182 +# VUID-vkCmdDrawMultiIndexedEXT-pDepthAttachment-06181 +# VUID-vkCmdDrawMultiIndexedEXT-pStencilAttachment-06182 +# spec issue diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c index caeb8a4..f8d2b92 100644 --- a/src/intel/vulkan/anv_blorp.c +++ b/src/intel/vulkan/anv_blorp.c @@ -70,7 +70,8 @@ upload_blorp_shader(struct blorp_batch *batch, uint32_t stage, key, key_size, kernel, kernel_size, prog_data, prog_data_size, NULL, 0, NULL, &bind_map, - &push_desc_info); + &push_desc_info, + 0 /* dynamic_push_values */); if (!bin) return false; diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c index ddab251..6b986b1 100644 --- a/src/intel/vulkan/anv_cmd_buffer.c +++ b/src/intel/vulkan/anv_cmd_buffer.c @@ -457,10 +457,14 @@ void anv_CmdBindPipeline( } if ((gfx_pipeline->fs_msaa_flags & BRW_WM_MSAA_FLAG_ENABLE_DYNAMIC) && - push->fs.msaa_flags != gfx_pipeline->fs_msaa_flags) { - push->fs.msaa_flags = gfx_pipeline->fs_msaa_flags; + push->gfx.fs_msaa_flags != gfx_pipeline->fs_msaa_flags) { + push->gfx.fs_msaa_flags = gfx_pipeline->fs_msaa_flags; cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_FRAGMENT_BIT; } + if (gfx_pipeline->dynamic_patch_control_points) { + cmd_buffer->state.push_constants_dirty |= + VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; + } break; } diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index d544af0..c89f477 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -748,7 +748,7 @@ get_features(const struct anv_physical_device *pdevice, /* VK_EXT_extended_dynamic_state2 */ .extendedDynamicState2 = true, .extendedDynamicState2LogicOp = true, - .extendedDynamicState2PatchControlPoints = false, + .extendedDynamicState2PatchControlPoints = true, /* VK_EXT_extended_dynamic_state3 */ .extendedDynamicState3PolygonMode = true, diff --git a/src/intel/vulkan/anv_generated_indirect_draws.c b/src/intel/vulkan/anv_generated_indirect_draws.c index 700818c..820e7c4 100644 --- a/src/intel/vulkan/anv_generated_indirect_draws.c +++ b/src/intel/vulkan/anv_generated_indirect_draws.c @@ -274,7 +274,8 @@ compile_upload_spirv(struct anv_device *device, wm_prog_data.base.program_size, &wm_prog_data.base, sizeof(wm_prog_data), NULL, 0, NULL, &bind_map, - &push_desc_info); + &push_desc_info, + 0 /* dynamic_push_values */); ralloc_free(nir); diff --git a/src/intel/vulkan/anv_nir.h b/src/intel/vulkan/anv_nir.h index e280b03..fe4cf90 100644 --- a/src/intel/vulkan/anv_nir.h +++ b/src/intel/vulkan/anv_nir.h @@ -36,6 +36,8 @@ bool anv_check_for_primitive_replication(struct anv_device *device, nir_shader **shaders, uint32_t view_mask); +bool anv_nir_lower_load_patch_vertices_in(nir_shader *shader); + bool anv_nir_lower_multiview(nir_shader *shader, uint32_t view_mask, bool use_primitive_replication); diff --git a/src/intel/vulkan/anv_nir_compute_push_layout.c b/src/intel/vulkan/anv_nir_compute_push_layout.c index 06264be..bfe6a6c 100644 --- a/src/intel/vulkan/anv_nir_compute_push_layout.c +++ b/src/intel/vulkan/anv_nir_compute_push_layout.c @@ -105,7 +105,7 @@ anv_nir_compute_push_layout(nir_shader *nir, if (nir->info.stage == MESA_SHADER_FRAGMENT && fragment_dynamic) { const uint32_t fs_msaa_flags_start = - offsetof(struct anv_push_constants, fs.msaa_flags); + offsetof(struct anv_push_constants, gfx.fs_msaa_flags); const uint32_t fs_msaa_flags_end = fs_msaa_flags_start + sizeof(uint32_t); push_start = MIN2(push_start, fs_msaa_flags_start); push_end = MAX2(push_end, fs_msaa_flags_end); @@ -289,7 +289,7 @@ anv_nir_compute_push_layout(nir_shader *nir, container_of(prog_data, struct brw_wm_prog_data, base); const uint32_t fs_msaa_flags_offset = - offsetof(struct anv_push_constants, fs.msaa_flags); + offsetof(struct anv_push_constants, gfx.fs_msaa_flags); assert(fs_msaa_flags_offset >= push_start); wm_prog_data->msaa_flags_param = (fs_msaa_flags_offset - push_start) / 4; diff --git a/src/intel/vulkan/anv_nir_lower_load_patch_vertices_in.c b/src/intel/vulkan/anv_nir_lower_load_patch_vertices_in.c new file mode 100644 index 0000000..7b07a30 --- /dev/null +++ b/src/intel/vulkan/anv_nir_lower_load_patch_vertices_in.c @@ -0,0 +1,69 @@ +/* + * Copyright © 2023 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/** + * This file implements the lowering required for + * VK_EXT_extended_dynamic_state2 extendedDynamicState2PatchControlPoints. + * + * When VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT is set on a pipeline, we + * need to compile the TCS shader assuming the max (32) number of control + * points. The actually value is provided through push constants. + */ + +#include "anv_nir.h" +#include "nir_builder.h" + +#define sizeof_field(type, field) sizeof(((type *)0)->field) + +static bool +lower_patch_vertices_in_instr(nir_builder *b, nir_instr *instr, UNUSED void *_data) +{ + if (instr->type != nir_instr_type_intrinsic) + return false; + + nir_intrinsic_instr *load = nir_instr_as_intrinsic(instr); + if (load->intrinsic != nir_intrinsic_load_patch_vertices_in) + return false; + + b->cursor = nir_before_instr(instr); + + nir_ssa_def_rewrite_uses( + &load->dest.ssa, + nir_load_push_constant( + b, 1, 32, + nir_imm_int(b, 0), + .base = offsetof(struct anv_push_constants, gfx.tcs_input_vertices), + .range = sizeof_field(struct anv_push_constants, gfx.tcs_input_vertices))); + nir_instr_remove(&load->instr); + + return true; +} + +bool +anv_nir_lower_load_patch_vertices_in(nir_shader *shader) +{ + return nir_shader_instructions_pass(shader, lower_patch_vertices_in_instr, + nir_metadata_block_index | + nir_metadata_dominance, + NULL); +} diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c index 57c4651..0724488 100644 --- a/src/intel/vulkan/anv_pipeline.c +++ b/src/intel/vulkan/anv_pipeline.c @@ -670,6 +670,8 @@ struct anv_pipeline_stage { bool uses_bt_for_push_descs; + enum anv_dynamic_push_bits dynamic_push_values; + union brw_any_prog_data prog_data; uint32_t num_stats; @@ -863,6 +865,39 @@ shared_type_info(const struct glsl_type *type, unsigned *size, unsigned *align) *align = comp_size * (length == 3 ? 4 : length); } +static enum anv_dynamic_push_bits +anv_nir_compute_dynamic_push_bits(nir_shader *shader) +{ + enum anv_dynamic_push_bits ret = 0; + + nir_foreach_function(function, shader) { + if (!function->impl) + continue; + + nir_foreach_block(block, function->impl) { + nir_foreach_instr(instr, block) { + if (instr->type != nir_instr_type_intrinsic) + continue; + + nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); + if (intrin->intrinsic != nir_intrinsic_load_push_constant) + continue; + + switch (nir_intrinsic_base(intrin)) { + case offsetof(struct anv_push_constants, gfx.tcs_input_vertices): + ret |= ANV_DYNAMIC_PUSH_INPUT_VERTICES; + break; + + default: + break; + } + } + } + } + + return ret; +} + static void anv_pipeline_lower_nir(struct anv_pipeline *pipeline, void *mem_ctx, @@ -910,6 +945,13 @@ anv_pipeline_lower_nir(struct anv_pipeline *pipeline, use_primitive_replication); } + /* The patch control points are delivered through a push constant when + * dynamic. + */ + if (nir->info.stage == MESA_SHADER_TESS_CTRL && + stage->key.tcs.input_vertices == 0) + NIR_PASS(_, nir, anv_nir_lower_load_patch_vertices_in); + nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir)); NIR_PASS(_, nir, brw_nir_lower_storage_image, @@ -986,6 +1028,8 @@ anv_pipeline_lower_nir(struct anv_pipeline *pipeline, }); } + stage->dynamic_push_values = anv_nir_compute_dynamic_push_bits(nir); + NIR_PASS_V(nir, anv_nir_compute_push_layout, pdevice, pipeline->device->vk.enabled_features.robustBufferAccess, anv_graphics_pipeline_stage_fragment_dynamic(stage), @@ -1593,7 +1637,9 @@ anv_graphics_pipeline_init_keys(struct anv_graphics_base_pipeline *pipeline, case MESA_SHADER_TESS_CTRL: populate_tcs_prog_key(device, pipeline->base.device->vk.enabled_features.robustBufferAccess, - state->ts->patch_control_points, + BITSET_TEST(state->dynamic, + MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS) ? + 0 : state->ts->patch_control_points, &stages[s].key.tcs); break; case MESA_SHADER_TESS_EVAL: @@ -1868,7 +1914,8 @@ anv_fixup_subgroup_size(struct anv_device *device, struct shader_info *info) } static void -anv_pipeline_nir_preprocess(struct anv_pipeline *pipeline, nir_shader *nir) +anv_pipeline_nir_preprocess(struct anv_pipeline *pipeline, + struct anv_pipeline_stage *stage) { struct anv_device *device = pipeline->device; const struct brw_compiler *compiler = device->physical->compiler; @@ -1876,31 +1923,34 @@ anv_pipeline_nir_preprocess(struct anv_pipeline *pipeline, nir_shader *nir) const struct nir_lower_sysvals_to_varyings_options sysvals_to_varyings = { .point_coord = true, }; - NIR_PASS(_, nir, nir_lower_sysvals_to_varyings, &sysvals_to_varyings); + NIR_PASS(_, stage->nir, nir_lower_sysvals_to_varyings, &sysvals_to_varyings); const nir_opt_access_options opt_access_options = { .is_vulkan = true, }; - NIR_PASS(_, nir, nir_opt_access, &opt_access_options); + NIR_PASS(_, stage->nir, nir_opt_access, &opt_access_options); /* Vulkan uses the separate-shader linking model */ - nir->info.separate_shader = true; + stage->nir->info.separate_shader = true; struct brw_nir_compiler_opts opts = { .softfp64 = device->fp64_nir, .robust_image_access = device->vk.enabled_features.robustImageAccess || device->vk.enabled_features.robustImageAccess2, + .input_vertices = stage->nir->info.stage == MESA_SHADER_TESS_CTRL ? + stage->key.tcs.input_vertices : 0, }; - brw_preprocess_nir(compiler, nir, &opts); + brw_preprocess_nir(compiler, stage->nir, &opts); - if (nir->info.stage == MESA_SHADER_MESH && !nir->info.mesh.nv) { - NIR_PASS(_, nir, anv_nir_lower_set_vtx_and_prim_count); - NIR_PASS(_, nir, nir_opt_dce); - NIR_PASS(_, nir, nir_remove_dead_variables, nir_var_shader_out, NULL); + if (stage->nir->info.stage == MESA_SHADER_MESH && + !stage->nir->info.mesh.nv) { + NIR_PASS(_, stage->nir, anv_nir_lower_set_vtx_and_prim_count); + NIR_PASS(_, stage->nir, nir_opt_dce); + NIR_PASS(_, stage->nir, nir_remove_dead_variables, nir_var_shader_out, NULL); } - nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir)); + nir_shader_gather_info(stage->nir, nir_shader_get_entrypoint(stage->nir)); } static void @@ -2101,7 +2151,7 @@ anv_graphics_pipeline_compile(struct anv_graphics_base_pipeline *pipeline, link_optimize, s)) continue; - anv_pipeline_nir_preprocess(&pipeline->base, stages[s].nir); + anv_pipeline_nir_preprocess(&pipeline->base, &stages[s]); } if (stages[MESA_SHADER_MESH].info && stages[MESA_SHADER_FRAGMENT].info) { @@ -2310,7 +2360,8 @@ anv_graphics_pipeline_compile(struct anv_graphics_base_pipeline *pipeline, stage->stats, stage->num_stats, stage->nir->xfb_info, &stage->bind_map, - &stage->push_desc_info); + &stage->push_desc_info, + stage->dynamic_push_values); if (!bin) { ralloc_free(stage_ctx); result = vk_error(pipeline, VK_ERROR_OUT_OF_HOST_MEMORY); @@ -2451,7 +2502,7 @@ anv_pipeline_compile_cs(struct anv_compute_pipeline *pipeline, return vk_error(pipeline, VK_ERROR_UNKNOWN); } - anv_pipeline_nir_preprocess(&pipeline->base, stage.nir); + anv_pipeline_nir_preprocess(&pipeline->base, &stage); anv_pipeline_lower_nir(&pipeline->base, mem_ctx, &stage, &pipeline->base.layout, 0 /* view_mask */, @@ -2492,7 +2543,8 @@ anv_pipeline_compile_cs(struct anv_compute_pipeline *pipeline, sizeof(stage.prog_data.cs), stage.stats, stage.num_stats, NULL, &stage.bind_map, - &stage.push_desc_info); + &stage.push_desc_info, + stage.dynamic_push_values); if (!bin) { ralloc_free(mem_ctx); return vk_error(pipeline, VK_ERROR_OUT_OF_HOST_MEMORY); @@ -2696,8 +2748,12 @@ anv_graphics_pipeline_emit(struct anv_graphics_pipeline *pipeline, */ pipeline->rasterization_samples = state->ms != NULL ? state->ms->rasterization_samples : 1; - pipeline->patch_control_points = - state->ts != NULL ? state->ts->patch_control_points : 0; + + pipeline->dynamic_patch_control_points = + anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_CTRL) && + BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS) && + (pipeline->base.shaders[MESA_SHADER_TESS_CTRL]->dynamic_push_values & + ANV_DYNAMIC_PUSH_INPUT_VERTICES); if (pipeline->base.shaders[MESA_SHADER_FRAGMENT]) { const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline); @@ -3188,7 +3244,8 @@ compile_upload_rt_shader(struct anv_ray_tracing_pipeline *pipeline, sizeof(stage->prog_data.bs), stage->stats, 1, NULL, &empty_bind_map, - &stage->push_desc_info); + &stage->push_desc_info, + stage->dynamic_push_values); if (bin == NULL) return vk_error(pipeline, VK_ERROR_OUT_OF_HOST_MEMORY); @@ -3450,7 +3507,7 @@ anv_pipeline_compile_ray_tracing(struct anv_ray_tracing_pipeline *pipeline, return vk_error(pipeline, VK_ERROR_OUT_OF_HOST_MEMORY); } - anv_pipeline_nir_preprocess(&pipeline->base, stages[i].nir); + anv_pipeline_nir_preprocess(&pipeline->base, &stages[i]); anv_pipeline_lower_nir(&pipeline->base, pipeline_ctx, &stages[i], &pipeline->base.layout, 0 /* view_mask */, @@ -3666,7 +3723,8 @@ anv_device_init_rt_shaders(struct anv_device *device) &trampoline_prog_data.base, sizeof(trampoline_prog_data), NULL, 0, NULL, &bind_map, - &push_desc_info); + &push_desc_info, + 0 /* dynamic_push_values */); ralloc_free(tmp_ctx); @@ -3719,7 +3777,8 @@ anv_device_init_rt_shaders(struct anv_device *device) return_data, return_prog_data.base.program_size, &return_prog_data.base, sizeof(return_prog_data), NULL, 0, NULL, &bind_map, - &push_desc_info); + &push_desc_info, + 0 /* dynamic_push_values */); ralloc_free(tmp_ctx); diff --git a/src/intel/vulkan/anv_pipeline_cache.c b/src/intel/vulkan/anv_pipeline_cache.c index e27face..1c492d2 100644 --- a/src/intel/vulkan/anv_pipeline_cache.c +++ b/src/intel/vulkan/anv_pipeline_cache.c @@ -78,7 +78,8 @@ anv_shader_bin_create(struct anv_device *device, const struct brw_compile_stats *stats, uint32_t num_stats, const nir_xfb_info *xfb_info_in, const struct anv_pipeline_bind_map *bind_map, - const struct anv_push_descriptor_info *push_desc_info) + const struct anv_push_descriptor_info *push_desc_info, + enum anv_dynamic_push_bits dynamic_push_values) { VK_MULTIALLOC(ma); VK_MULTIALLOC_DECL(&ma, struct anv_shader_bin, shader, 1); @@ -179,6 +180,8 @@ anv_shader_bin_create(struct anv_device *device, shader->xfb_info = NULL; } + shader->dynamic_push_values = dynamic_push_values; + typed_memcpy(&shader->push_desc_info, push_desc_info, 1); shader->bind_map = *bind_map; @@ -226,6 +229,8 @@ anv_shader_bin_serialize(struct vk_pipeline_cache_object *object, blob_write_uint32(blob, 0); } + blob_write_uint32(blob, shader->dynamic_push_values); + blob_write_uint32(blob, shader->push_desc_info.used_descriptors); blob_write_uint32(blob, shader->push_desc_info.fully_promoted_ubo_descriptors); blob_write_uint8(blob, shader->push_desc_info.used_set_buffer); @@ -292,6 +297,8 @@ anv_shader_bin_deserialize(struct vk_pipeline_cache *cache, if (xfb_size) xfb_info = blob_read_bytes(blob, xfb_size); + enum anv_dynamic_push_bits dynamic_push_values = blob_read_uint32(blob); + struct anv_push_descriptor_info push_desc_info = {}; push_desc_info.used_descriptors = blob_read_uint32(blob); push_desc_info.fully_promoted_ubo_descriptors = blob_read_uint32(blob); @@ -328,7 +335,8 @@ anv_shader_bin_deserialize(struct vk_pipeline_cache *cache, kernel_data, kernel_size, &prog_data.base, prog_data_size, stats, num_stats, xfb_info, &bind_map, - &push_desc_info); + &push_desc_info, + dynamic_push_values); if (shader == NULL) return NULL; @@ -371,7 +379,8 @@ anv_device_upload_kernel(struct anv_device *device, uint32_t num_stats, const nir_xfb_info *xfb_info, const struct anv_pipeline_bind_map *bind_map, - const struct anv_push_descriptor_info *push_desc_info) + const struct anv_push_descriptor_info *push_desc_info, + enum anv_dynamic_push_bits dynamic_push_values) { /* Use the default pipeline cache if none is specified */ if (cache == NULL) @@ -384,7 +393,8 @@ anv_device_upload_kernel(struct anv_device *device, prog_data, prog_data_size, stats, num_stats, xfb_info, bind_map, - push_desc_info); + push_desc_info, + dynamic_push_values); if (shader == NULL) return NULL; diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 080c750..2dfadf3 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -1022,6 +1022,7 @@ struct anv_queue { struct nir_xfb_info; struct anv_pipeline_bind_map; struct anv_push_descriptor_info; +enum anv_dynamic_push_bits; extern const struct vk_pipeline_cache_object_ops *const anv_cache_import_ops[2]; @@ -1043,7 +1044,8 @@ anv_device_upload_kernel(struct anv_device *device, uint32_t num_stats, const struct nir_xfb_info *xfb_info, const struct anv_pipeline_bind_map *bind_map, - const struct anv_push_descriptor_info *push_desc_info); + const struct anv_push_descriptor_info *push_desc_info, + enum anv_dynamic_push_bits dynamic_push_values); struct nir_shader; struct nir_shader_compiler_options; @@ -2399,11 +2401,11 @@ struct anv_push_constants { union { struct { /** Dynamic MSAA value */ - uint32_t msaa_flags; + uint32_t fs_msaa_flags; - /** Pad out to a multiple of 32 bytes */ - uint32_t pad[1]; - } fs; + /** Dynamic TCS input vertices */ + uint32_t tcs_input_vertices; + } gfx; struct { /** Base workgroup ID @@ -3066,6 +3068,11 @@ struct anv_push_descriptor_info { uint8_t used_set_buffer; }; +/* A list of values we push to implement some of the dynamic states */ +enum anv_dynamic_push_bits { + ANV_DYNAMIC_PUSH_INPUT_VERTICES = BITFIELD_BIT(0), +}; + struct anv_shader_bin { struct vk_pipeline_cache_object base; @@ -3085,6 +3092,8 @@ struct anv_shader_bin { struct anv_push_descriptor_info push_desc_info; struct anv_pipeline_bind_map bind_map; + + enum anv_dynamic_push_bits dynamic_push_values; }; struct anv_shader_bin * @@ -3097,7 +3106,9 @@ anv_shader_bin_create(struct anv_device *device, const struct brw_compile_stats *stats, uint32_t num_stats, const struct nir_xfb_info *xfb_info, const struct anv_pipeline_bind_map *bind_map, - const struct anv_push_descriptor_info *push_desc_info); + const struct anv_push_descriptor_info *push_desc_info, + enum anv_dynamic_push_bits dynamic_push_values); + static inline struct anv_shader_bin * anv_shader_bin_ref(struct anv_shader_bin *shader) @@ -3235,10 +3246,14 @@ struct anv_graphics_pipeline { struct vk_sample_locations_state sample_locations; struct vk_dynamic_graphics_state dynamic_state; - /* These fields are required with dynamic primitive topology, + /* If true, the patch control points are passed through push constants + * (anv_push_constants::gfx::tcs_input_vertices) + */ + bool dynamic_patch_control_points; + + /* This field is required with dynamic primitive topology, * rasterization_samples used only with gen < 8. */ - uint32_t patch_control_points; uint32_t rasterization_samples; uint32_t view_mask; diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 54c9ff1..7faf29d 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -3292,6 +3292,18 @@ genX(cmd_buffer_flush_gfx_state)(struct anv_cmd_buffer *cmd_buffer) cmd_buffer->state.gfx.vb_dirty &= ~vb_emit; + /* If patch control points value is changed, let's just update the push + * constant data. If the current pipeline also use this, we need to reemit + * the 3DSTATE_CONSTANT packet. + */ + struct anv_push_constants *push = &cmd_buffer->state.gfx.base.push_constants; + if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS) && + push->gfx.tcs_input_vertices != dyn->ts.patch_control_points) { + push->gfx.tcs_input_vertices = dyn->ts.patch_control_points; + if (pipeline->dynamic_patch_control_points) + cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; + } + const bool any_dynamic_state_dirty = vk_dynamic_graphics_state_any_dirty(dyn); uint32_t descriptors_dirty = cmd_buffer->state.descriptors_dirty & @@ -3447,7 +3459,7 @@ genX(cmd_buffer_flush_gfx_state)(struct anv_cmd_buffer *cmd_buffer) BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY)) { uint32_t topology; if (anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_EVAL)) - topology = _3DPRIM_PATCHLIST(pipeline->patch_control_points); + topology = _3DPRIM_PATCHLIST(dyn->ts.patch_control_points); else topology = genX(vk_to_intel_primitive_type)[dyn->ia.primitive_topology]; diff --git a/src/intel/vulkan/grl/genX_grl_dispatch.c b/src/intel/vulkan/grl/genX_grl_dispatch.c index eff7c40..1bf9553 100644 --- a/src/intel/vulkan/grl/genX_grl_dispatch.c +++ b/src/intel/vulkan/grl/genX_grl_dispatch.c @@ -60,7 +60,8 @@ get_shader_bin(struct anv_device *device, &kernel_data.prog_data.base, sizeof(kernel_data.prog_data), NULL, 0, NULL, &bind_map, - &push_desc_info); + &push_desc_info, + 0 /* dynamic_push_values */); /* The cache already has a reference and it's not going anywhere so there * is no need to hold a second reference. diff --git a/src/intel/vulkan/meson.build b/src/intel/vulkan/meson.build index e0de5bf..7b975dc 100644 --- a/src/intel/vulkan/meson.build +++ b/src/intel/vulkan/meson.build @@ -168,6 +168,7 @@ libanv_files = files( 'anv_nir_apply_pipeline_layout.c', 'anv_nir_compute_push_layout.c', 'anv_nir_lower_multiview.c', + 'anv_nir_lower_load_patch_vertices_in.c', 'anv_nir_lower_ubo_loads.c', 'anv_nir_push_descriptor_analysis.c', 'anv_perf.c', -- 2.7.4