diff --git a/src/intel/compiler/brw_fs.cpp b/src/intel/compiler/brw_fs.cpp index 8d741a3611e..d2e40ef62bf 100644 --- a/src/intel/compiler/brw_fs.cpp +++ b/src/intel/compiler/brw_fs.cpp @@ -6910,25 +6910,7 @@ fs_visitor::run_task(bool allow_spilling) { assert(stage == MESA_SHADER_TASK); - /* Task Shader Payloads (SIMD8 and SIMD16) - * - * R0: Header - * R1: Local_ID.X[0-7 or 0-15] - * R2: Inline Parameter - * - * Task Shader Payloads (SIMD32) - * - * R0: Header - * R1: Local_ID.X[0-15] - * R2: Local_ID.X[16-31] - * R3: Inline Parameter - * - * Local_ID.X values are 16 bits. - * - * Inline parameter is optional but always present since we use it to pass - * the address to descriptors. - */ - payload().num_regs = dispatch_width == 32 ? 4 : 3; + payload_ = new task_mesh_thread_payload(*this); emit_nir_code(); @@ -6957,25 +6939,7 @@ fs_visitor::run_mesh(bool allow_spilling) { assert(stage == MESA_SHADER_MESH); - /* Mesh Shader Payloads (SIMD8 and SIMD16) - * - * R0: Header - * R1: Local_ID.X[0-7 or 0-15] - * R2: Inline Parameter - * - * Mesh Shader Payloads (SIMD32) - * - * R0: Header - * R1: Local_ID.X[0-15] - * R2: Local_ID.X[16-31] - * R3: Inline Parameter - * - * Local_ID.X values are 16 bits. - * - * Inline parameter is optional but always present since we use it to pass - * the address to descriptors. - */ - payload().num_regs = dispatch_width == 32 ? 4 : 3; + payload_ = new task_mesh_thread_payload(*this); emit_nir_code(); diff --git a/src/intel/compiler/brw_fs.h b/src/intel/compiler/brw_fs.h index 251251e0049..70cebae8a0e 100644 --- a/src/intel/compiler/brw_fs.h +++ b/src/intel/compiler/brw_fs.h @@ -133,6 +133,19 @@ struct fs_thread_payload : public thread_payload { uint8_t local_invocation_id_reg[2]; }; +struct task_mesh_thread_payload : public thread_payload { + task_mesh_thread_payload(const fs_visitor &v); + + fs_reg extended_parameter_0; + fs_reg local_index; + fs_reg inline_parameter; + + fs_reg urb_output; + + /* URB to read Task memory inputs. Only valid for MESH stage. */ + fs_reg task_urb_input; +}; + /** * The fragment shader front-end. * @@ -463,6 +476,11 @@ public: return *static_cast(this->payload_); }; + task_mesh_thread_payload &task_mesh_payload() { + assert(stage == MESA_SHADER_TASK || stage == MESA_SHADER_MESH); + return *static_cast(this->payload_); + } + bool source_depth_to_render_target; bool runtime_check_aads_emit; diff --git a/src/intel/compiler/brw_fs_thread_payload.cpp b/src/intel/compiler/brw_fs_thread_payload.cpp index d200ce90a44..e522f723897 100644 --- a/src/intel/compiler/brw_fs_thread_payload.cpp +++ b/src/intel/compiler/brw_fs_thread_payload.cpp @@ -318,3 +318,43 @@ fs_thread_payload::fs_thread_payload(const fs_visitor &v, setup_fs_payload_gfx4(*this, v, source_depth_to_render_target, runtime_check_aads_emit); } + +task_mesh_thread_payload::task_mesh_thread_payload(const fs_visitor &v) +{ + /* Task and Mesh Shader Payloads (SIMD8 and SIMD16) + * + * R0: Header + * R1: Local_ID.X[0-7 or 0-15] + * R2: Inline Parameter + * + * Task and Mesh Shader Payloads (SIMD32) + * + * R0: Header + * R1: Local_ID.X[0-15] + * R2: Local_ID.X[16-31] + * R3: Inline Parameter + * + * Local_ID.X values are 16 bits. + * + * Inline parameter is optional but always present since we use it to pass + * the address to descriptors. + */ + + unsigned r = 0; + extended_parameter_0 = retype(brw_vec1_grf(0, 3), BRW_REGISTER_TYPE_UD); + urb_output = retype(brw_vec1_grf(0, 6), BRW_REGISTER_TYPE_UD); + + if (v.stage == MESA_SHADER_MESH) + task_urb_input = retype(brw_vec1_grf(0, 7), BRW_REGISTER_TYPE_UD); + r++; + + local_index = retype(brw_vec8_grf(1, 0), BRW_REGISTER_TYPE_UW); + r++; + if (v.dispatch_width == 32) + r++; + + inline_parameter = retype(brw_vec1_grf(r, 0), BRW_REGISTER_TYPE_UD); + r++; + + num_regs = r; +} diff --git a/src/intel/compiler/brw_mesh.cpp b/src/intel/compiler/brw_mesh.cpp index 1ac7cb3965a..b2751a2d615 100644 --- a/src/intel/compiler/brw_mesh.cpp +++ b/src/intel/compiler/brw_mesh.cpp @@ -1147,18 +1147,17 @@ fs_visitor::nir_emit_task_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr) { assert(stage == MESA_SHADER_TASK); - - fs_reg urb_handle = retype(brw_vec1_grf(0, 6), BRW_REGISTER_TYPE_UD); + const task_mesh_thread_payload &payload = task_mesh_payload(); switch (instr->intrinsic) { case nir_intrinsic_store_output: case nir_intrinsic_store_task_payload: - emit_task_mesh_store(bld, instr, urb_handle); + emit_task_mesh_store(bld, instr, payload.urb_output); break; case nir_intrinsic_load_output: case nir_intrinsic_load_task_payload: - emit_task_mesh_load(bld, instr, urb_handle); + emit_task_mesh_load(bld, instr, payload.urb_output); break; default: @@ -1172,25 +1171,23 @@ fs_visitor::nir_emit_mesh_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr) { assert(stage == MESA_SHADER_MESH); - - unsigned subreg = instr->intrinsic == nir_intrinsic_load_task_payload ? 7 : 6; - fs_reg urb_handle = retype(brw_vec1_grf(0, subreg), BRW_REGISTER_TYPE_UD); + const task_mesh_thread_payload &payload = task_mesh_payload(); switch (instr->intrinsic) { case nir_intrinsic_store_per_primitive_output: case nir_intrinsic_store_per_vertex_output: case nir_intrinsic_store_output: - emit_task_mesh_store(bld, instr, urb_handle); + emit_task_mesh_store(bld, instr, payload.urb_output); break; case nir_intrinsic_load_per_vertex_output: case nir_intrinsic_load_per_primitive_output: case nir_intrinsic_load_output: - emit_task_mesh_load(bld, instr, urb_handle); + emit_task_mesh_load(bld, instr, payload.urb_output); break; case nir_intrinsic_load_task_payload: - emit_task_mesh_load(bld, instr, urb_handle); + emit_task_mesh_load(bld, instr, payload.task_urb_input); break; default: @@ -1204,30 +1201,27 @@ fs_visitor::nir_emit_task_mesh_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr) { assert(stage == MESA_SHADER_MESH || stage == MESA_SHADER_TASK); + const task_mesh_thread_payload &payload = task_mesh_payload(); fs_reg dest; if (nir_intrinsic_infos[instr->intrinsic].has_dest) dest = get_nir_dest(instr->dest); switch (instr->intrinsic) { - case nir_intrinsic_load_mesh_inline_data_intel: - assert(payload().num_regs == 3 || payload().num_regs == 4); - /* Inline Parameter is the last element of the payload. */ - bld.MOV(dest, retype(brw_vec1_grf(payload().num_regs - 1, - nir_intrinsic_align_offset(instr)), - dest.type)); + case nir_intrinsic_load_mesh_inline_data_intel: { + fs_reg data = offset(payload.inline_parameter, 1, nir_intrinsic_align_offset(instr)); + bld.MOV(dest, retype(data, dest.type)); break; + } case nir_intrinsic_load_draw_id: - /* DrawID comes from Extended Parameter 0 (XP0). */ - bld.MOV(dest, brw_vec1_grf(0, 3)); + bld.MOV(dest, payload.extended_parameter_0); break; case nir_intrinsic_load_local_invocation_index: case nir_intrinsic_load_local_invocation_id: - /* Local_ID.X is given by the HW in the shader payload. */ dest = retype(dest, BRW_REGISTER_TYPE_UD); - bld.MOV(dest, retype(brw_vec8_grf(1, 0), BRW_REGISTER_TYPE_UW)); + bld.MOV(dest, payload.local_index); /* Task/Mesh only use one dimension. */ if (instr->intrinsic == nir_intrinsic_load_local_invocation_id) { bld.MOV(offset(dest, bld, 1), brw_imm_uw(0));