diff --git a/src/intel/compiler/brw_compile_mesh.cpp b/src/intel/compiler/brw_compile_mesh.cpp index 1147cb7e16c..8cfac02617a 100644 --- a/src/intel/compiler/brw_compile_mesh.cpp +++ b/src/intel/compiler/brw_compile_mesh.cpp @@ -36,51 +36,6 @@ using namespace brw; -static bool -brw_nir_lower_load_uniforms_filter(const nir_instr *instr, - UNUSED const void *data) -{ - if (instr->type != nir_instr_type_intrinsic) - return false; - nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); - return intrin->intrinsic == nir_intrinsic_load_uniform; -} - -static nir_def * -brw_nir_lower_load_uniforms_impl(nir_builder *b, nir_instr *instr, - void *data) -{ - assert(instr->type == nir_instr_type_intrinsic); - nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); - assert(intrin->intrinsic == nir_intrinsic_load_uniform); - - /* Use the first few bytes of InlineData as push constants. */ - if (nir_src_is_const(intrin->src[0])) { - int offset = - BRW_TASK_MESH_PUSH_CONSTANTS_START_DW * 4 + - nir_intrinsic_base(intrin) + nir_src_as_uint(intrin->src[0]); - int range = intrin->def.num_components * intrin->def.bit_size / 8; - if ((offset + range) <= (int)(BRW_TASK_MESH_INLINE_DATA_SIZE_DW * 4)) { - return nir_load_inline_data_intel(b, - intrin->def.num_components, - intrin->def.bit_size, - .base = offset); - } - } - - return brw_nir_load_global_const(b, intrin, - nir_load_inline_data_intel(b, 1, 64, 0), 0); -} - -static bool -brw_nir_lower_load_uniforms(nir_shader *nir, - const struct intel_device_info *devinfo) -{ - return nir_shader_lower_instructions(nir, brw_nir_lower_load_uniforms_filter, - brw_nir_lower_load_uniforms_impl, - (void *)devinfo); -} - static inline int type_size_scalar_dwords(const struct glsl_type *type, bool bindless) { @@ -431,7 +386,6 @@ brw_compile_task(const struct brw_compiler *compiler, prog_data->uses_drawid = BITSET_TEST(nir->info.system_values_read, SYSTEM_VALUE_DRAW_ID); - NIR_PASS(_, nir, brw_nir_lower_load_uniforms, compiler->devinfo); prog_data->base.uses_inline_data = brw_nir_uses_inline_data(nir); brw_simd_selection_state simd_state{ @@ -1742,7 +1696,6 @@ brw_compile_mesh(const struct brw_compiler *compiler, prog_data->autostrip_enable = brw_mesh_autostrip_enable(compiler, nir, &prog_data->map); - NIR_PASS(_, nir, brw_nir_lower_load_uniforms, compiler->devinfo); prog_data->base.uses_inline_data = brw_nir_uses_inline_data(nir); brw_simd_selection_state simd_state{ diff --git a/src/intel/compiler/brw_fs.cpp b/src/intel/compiler/brw_fs.cpp index 98785c2af5f..d773dfa3bd6 100644 --- a/src/intel/compiler/brw_fs.cpp +++ b/src/intel/compiler/brw_fs.cpp @@ -205,9 +205,10 @@ fs_visitor::assign_curb_setup() prog_data->curb_read_length = MAX2(1, prog_data->curb_read_length); uint64_t used = 0; - bool is_compute = gl_shader_stage_is_compute(stage); + const bool shader_pulls_constants = devinfo->verx10 >= 125 && + (gl_shader_stage_is_compute(stage) || gl_shader_stage_is_mesh(stage)); - if (is_compute && devinfo->verx10 >= 125 && uniform_push_length > 0) { + if (shader_pulls_constants && uniform_push_length > 0) { assert(devinfo->has_lsc); brw_builder ubld = brw_builder(this, 1).exec_all().at( cfg->first_block(), cfg->first_block()->start()); diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c index b5a9a0b3dd7..e18609f23db 100644 --- a/src/intel/vulkan/anv_cmd_buffer.c +++ b/src/intel/vulkan/anv_cmd_buffer.c @@ -1208,10 +1208,24 @@ anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer, struct anv_state anv_cmd_buffer_gfx_push_constants(struct anv_cmd_buffer *cmd_buffer) { + const struct intel_device_info *devinfo = cmd_buffer->device->info; const struct anv_push_constants *data = &cmd_buffer->state.gfx.base.push_constants; + /* For Mesh/Task shaders the 3DSTATE_(MESH|TASK)_SHADER_DATA require a 64B + * alignment. + * + * ATMS PRMs Volume 2d: Command Reference: Structures, + * 3DSTATE_MESH_SHADER_DATA_BODY::Indirect Data Start Address: + * + * "This pointer is relative to the General State Base Address. It is + * the 64-byte aligned address of the indirect data." + */ struct anv_state state = + devinfo->verx10 >= 125 ? + anv_cmd_buffer_alloc_general_state(cmd_buffer, + align(sizeof(struct anv_push_constants), 64), + 64) : anv_cmd_buffer_alloc_temporary_state(cmd_buffer, sizeof(struct anv_push_constants), 32 /* bottom 5 bits MBZ */); diff --git a/src/intel/vulkan/anv_nir_compute_push_layout.c b/src/intel/vulkan/anv_nir_compute_push_layout.c index 00c72b4885e..61b1786d824 100644 --- a/src/intel/vulkan/anv_nir_compute_push_layout.c +++ b/src/intel/vulkan/anv_nir_compute_push_layout.c @@ -124,11 +124,34 @@ anv_nir_compute_push_layout(nir_shader *nir, push_end = anv_drv_const_offset(cs.subgroup_id); } - /* Align push_start down to a 32B boundary and make it no larger than + /* Align push_start down to a 32B (for 3DSTATE_CONSTANT) or 64B (for + * 3DSTATE_(MESH|TASK)_SHADER_DATA) boundary and make it no larger than * push_end (no push constants is indicated by push_start = UINT_MAX). + * + * SKL PRMs, Volume 2d: Command Reference: Structures, + * 3DSTATE_CONSTANT::Constant Buffer 0 Read Length: + * + * "This field specifies the length of the constant data to be loaded + * from memory in 256-bit units." + * + * ATS-M PRMs, Volume 2d: Command Reference: Structures, + * 3DSTATE_MESH_SHADER_DATA_BODY::Indirect Data Start Address: + * + * "This pointer is relative to the General State Base Address. It is + * the 64-byte aligned address of the indirect data." + * + * COMPUTE_WALKER::Indirect Data Start Address has the same requirements as + * 3DSTATE_MESH_SHADER_DATA_BODY::Indirect Data Start Address but the push + * constant allocation for compute shader is not shared with other stages + * (unlike all Gfx stages) and so we can bound+align the allocation there + * (see anv_cmd_buffer_cs_push_constants). */ + const unsigned push_alignment = + devinfo->verx10 >= 125 && (nir->info.stage == MESA_SHADER_TASK || + nir->info.stage == MESA_SHADER_MESH) ? + 64 : 32; push_start = MIN2(push_start, push_end); - push_start = ROUND_DOWN_TO(push_start, 32); + push_start = ROUND_DOWN_TO(push_start, push_alignment); /* For scalar, push data size needs to be aligned to a DWORD. */ const unsigned alignment = 4; @@ -159,7 +182,7 @@ anv_nir_compute_push_layout(nir_shader *nir, * brw_nir_lower_rt_intrinsics.c). */ unsigned base_offset = - brw_shader_stage_requires_bindless_resources(nir->info.stage) ? 0 : push_start; + brw_shader_stage_is_bindless(nir->info.stage) ? 0 : push_start; intrin->intrinsic = nir_intrinsic_load_uniform; nir_intrinsic_set_base(intrin, nir_intrinsic_base(intrin) - diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 0be2e720ee4..7ac64495691 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -4508,6 +4508,8 @@ anv_cmd_buffer_gfx_push_constants_state_address(struct anv_cmd_buffer *cmd_buffe struct anv_state state) { return anv_state_pool_state_address( + cmd_buffer->device->info->verx10 >= 125 ? + &cmd_buffer->device->general_state_pool : &cmd_buffer->device->dynamic_state_pool, state); } diff --git a/src/intel/vulkan/genX_cmd_draw.c b/src/intel/vulkan/genX_cmd_draw.c index 265156c4c54..fa8a8986593 100644 --- a/src/intel/vulkan/genX_cmd_draw.c +++ b/src/intel/vulkan/genX_cmd_draw.c @@ -562,6 +562,20 @@ cmd_buffer_flush_gfx_push_constants(struct anv_cmd_buffer *cmd_buffer, } #if GFX_VERx10 >= 125 +static inline uint32_t +get_mesh_task_push_offset(struct anv_cmd_buffer *cmd_buffer, + const struct anv_push_range *range) +{ + struct anv_cmd_graphics_state *gfx_state = &cmd_buffer->state.gfx; + + if (gfx_state->base.push_constants_state.alloc_size == 0) { + gfx_state->base.push_constants_state = + anv_cmd_buffer_gfx_push_constants(cmd_buffer); + } + + return gfx_state->base.push_constants_state.offset + range->start * 32; +} + static void cmd_buffer_flush_mesh_inline_data(struct anv_cmd_buffer *cmd_buffer, VkShaderStageFlags dirty_stages) @@ -572,47 +586,23 @@ cmd_buffer_flush_mesh_inline_data(struct anv_cmd_buffer *cmd_buffer, if (dirty_stages & VK_SHADER_STAGE_TASK_BIT_EXT && anv_pipeline_has_stage(pipeline, MESA_SHADER_TASK)) { - const struct anv_shader_bin *shader = pipeline->base.shaders[MESA_SHADER_TASK]; - const struct anv_pipeline_bind_map *bind_map = &shader->bind_map; + const struct anv_push_range *range = &shader->bind_map.push_ranges[0]; anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_TASK_SHADER_DATA), data) { - const struct anv_push_range *range = &bind_map->push_ranges[0]; - if (range->length > 0) { - struct anv_address buffer = - get_push_range_address(cmd_buffer, shader, range); - - uint64_t addr = anv_address_physical(buffer); - data.InlineData[0] = addr & 0xffffffff; - data.InlineData[1] = addr >> 32; - - memcpy(&data.InlineData[BRW_TASK_MESH_PUSH_CONSTANTS_START_DW], - cmd_buffer->state.gfx.base.push_constants.client_data, - BRW_TASK_MESH_PUSH_CONSTANTS_SIZE_DW * 4); - } + if (range->length > 0) + data.IndirectDataStartAddress = get_mesh_task_push_offset(cmd_buffer, range); } } if (dirty_stages & VK_SHADER_STAGE_MESH_BIT_EXT && anv_pipeline_has_stage(pipeline, MESA_SHADER_MESH)) { - const struct anv_shader_bin *shader = pipeline->base.shaders[MESA_SHADER_MESH]; - const struct anv_pipeline_bind_map *bind_map = &shader->bind_map; + const struct anv_push_range *range = &shader->bind_map.push_ranges[0]; anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_MESH_SHADER_DATA), data) { - const struct anv_push_range *range = &bind_map->push_ranges[0]; - if (range->length > 0) { - struct anv_address buffer = - get_push_range_address(cmd_buffer, shader, range); - - uint64_t addr = anv_address_physical(buffer); - data.InlineData[0] = addr & 0xffffffff; - data.InlineData[1] = addr >> 32; - - memcpy(&data.InlineData[BRW_TASK_MESH_PUSH_CONSTANTS_START_DW], - cmd_buffer->state.gfx.base.push_constants.client_data, - BRW_TASK_MESH_PUSH_CONSTANTS_SIZE_DW * 4); - } + if (range->length > 0) + data.IndirectDataStartAddress = get_mesh_task_push_offset(cmd_buffer, range); } } diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c index f0a98abbf9f..2ccb02b5362 100644 --- a/src/intel/vulkan/genX_pipeline.c +++ b/src/intel/vulkan/genX_pipeline.c @@ -1809,12 +1809,8 @@ emit_task_state(struct anv_graphics_pipeline *pipeline) task_dispatch.group_size, task_dispatch.simd_size); - /* - * 3DSTATE_TASK_SHADER_DATA.InlineData[0:1] will be used for an address - * of a buffer with push constants and descriptor set table and - * InlineData[2:7] will be used for first few push constants. - */ - task.EmitInlineParameter = true; + task.EmitInlineParameter = task_prog_data->base.uses_inline_data; + task.IndirectDataLength = align(task_bin->bind_map.push_ranges[0].length * 32, 64); task.XP0Required = task_prog_data->uses_drawid; @@ -1912,12 +1908,8 @@ emit_mesh_state(struct anv_graphics_pipeline *pipeline) mesh_dispatch.group_size, mesh_dispatch.simd_size); - /* - * 3DSTATE_MESH_SHADER_DATA.InlineData[0:1] will be used for an address - * of a buffer with push constants and descriptor set table and - * InlineData[2:7] will be used for first few push constants. - */ - mesh.EmitInlineParameter = true; + mesh.EmitInlineParameter = mesh_prog_data->base.uses_inline_data; + mesh.IndirectDataLength = align(mesh_bin->bind_map.push_ranges[0].length * 32, 64); mesh.XP0Required = mesh_prog_data->uses_drawid;