intel/compiler: Create and use struct for TASK and MESH thread payloads
Acked-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Reviewed-by: Marcin Ślusarz <marcin.slusarz@intel.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Acked-by: Ian Romanick <ian.d.romanick@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18176>
This commit is contained in:
@@ -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();
|
||||
|
||||
|
@@ -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<fs_thread_payload *>(this->payload_);
|
||||
};
|
||||
|
||||
task_mesh_thread_payload &task_mesh_payload() {
|
||||
assert(stage == MESA_SHADER_TASK || stage == MESA_SHADER_MESH);
|
||||
return *static_cast<task_mesh_thread_payload *>(this->payload_);
|
||||
}
|
||||
|
||||
bool source_depth_to_render_target;
|
||||
bool runtime_check_aads_emit;
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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));
|
||||
|
Reference in New Issue
Block a user