diff --git a/src/gallium/drivers/zink/ci/traces-zink-restricted.yml b/src/gallium/drivers/zink/ci/traces-zink-restricted.yml index 716e554e4d7..2fbfa9fd012 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 17fc0a3e397..de43a6f43a7 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 9c12fa381bc..1c347f8bdca 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 caeb8a4212b..f8d2b9215e4 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 ddab251cbb0..6b986b1bb71 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 d544af0e5c5..c89f477d003 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 700818c33b5..820e7c4981e 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 e280b03312f..fe4cf90cd99 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 06264be0af1..bfe6a6c5c7e 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 00000000000..7b07a30815a --- /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 57c4651b535..0724488c50c 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 e27facef921..1c492d278e5 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 080c75030c8..2dfadf38afe 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 54c9ff17233..7faf29d07db 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 eff7c4074fc..1bf9553d1db 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 e0de5bfa84e..7b975dccb0a 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',