intel/elk: Remove stages not used in Gfx8-

OpenCL, Mesh and RayTracing stages are not supported, so removing them
and related code.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27563>
This commit is contained in:
Caio Oliveira
2024-01-19 12:06:08 -08:00
committed by Marge Bot
parent 8a57012ff4
commit b743ab7acc
18 changed files with 13 additions and 2072 deletions
-31
View File
@@ -136,9 +136,6 @@ brw_compiler_create(void *mem_ctx, const struct intel_device_info *devinfo)
i == MESA_SHADER_FRAGMENT || i == MESA_SHADER_COMPUTE;
}
for (int i = MESA_SHADER_TASK; i < MESA_VULKAN_SHADER_STAGES; i++)
compiler->scalar_stage[i] = true;
nir_lower_int64_options int64_options =
nir_lower_imul64 |
nir_lower_isign64 |
@@ -233,11 +230,6 @@ brw_compiler_create(void *mem_ctx, const struct intel_device_info *devinfo)
compiler->nir_options[i] = nir_options;
}
compiler->mesh.mue_header_packing =
(unsigned)debug_get_num_option("INTEL_MESH_HEADER_PACKING", 3);
compiler->mesh.mue_compaction =
debug_get_bool_option("INTEL_MESH_COMPACTION", true);
return compiler;
}
@@ -257,8 +249,6 @@ brw_get_compiler_config_value(const struct brw_compiler *compiler)
bits++;
insert_u64_bit(&config, compiler->lower_dpas);
bits++;
insert_u64_bit(&config, compiler->mesh.mue_compaction);
bits++;
uint64_t mask = DEBUG_DISK_CACHE_MASK;
bits += util_bitcount64(mask);
@@ -275,9 +265,6 @@ brw_get_compiler_config_value(const struct brw_compiler *compiler)
mask = 3;
bits += util_bitcount64(mask);
u_foreach_bit64(bit, mask)
insert_u64_bit(&config, (compiler->mesh.mue_header_packing & (1ULL << bit)) != 0);
assert(bits <= util_bitcount64(UINT64_MAX));
return config;
@@ -293,15 +280,6 @@ brw_prog_data_size(gl_shader_stage stage)
[MESA_SHADER_GEOMETRY] = sizeof(struct brw_gs_prog_data),
[MESA_SHADER_FRAGMENT] = sizeof(struct brw_wm_prog_data),
[MESA_SHADER_COMPUTE] = sizeof(struct brw_cs_prog_data),
[MESA_SHADER_TASK] = sizeof(struct brw_task_prog_data),
[MESA_SHADER_MESH] = sizeof(struct brw_mesh_prog_data),
[MESA_SHADER_RAYGEN] = sizeof(struct brw_bs_prog_data),
[MESA_SHADER_ANY_HIT] = sizeof(struct brw_bs_prog_data),
[MESA_SHADER_CLOSEST_HIT] = sizeof(struct brw_bs_prog_data),
[MESA_SHADER_MISS] = sizeof(struct brw_bs_prog_data),
[MESA_SHADER_INTERSECTION] = sizeof(struct brw_bs_prog_data),
[MESA_SHADER_CALLABLE] = sizeof(struct brw_bs_prog_data),
[MESA_SHADER_KERNEL] = sizeof(struct brw_cs_prog_data),
};
assert((int)stage >= 0 && stage < ARRAY_SIZE(stage_sizes));
return stage_sizes[stage];
@@ -317,15 +295,6 @@ brw_prog_key_size(gl_shader_stage stage)
[MESA_SHADER_GEOMETRY] = sizeof(struct brw_gs_prog_key),
[MESA_SHADER_FRAGMENT] = sizeof(struct brw_wm_prog_key),
[MESA_SHADER_COMPUTE] = sizeof(struct brw_cs_prog_key),
[MESA_SHADER_TASK] = sizeof(struct brw_task_prog_key),
[MESA_SHADER_MESH] = sizeof(struct brw_mesh_prog_key),
[MESA_SHADER_RAYGEN] = sizeof(struct brw_bs_prog_key),
[MESA_SHADER_ANY_HIT] = sizeof(struct brw_bs_prog_key),
[MESA_SHADER_CLOSEST_HIT] = sizeof(struct brw_bs_prog_key),
[MESA_SHADER_MISS] = sizeof(struct brw_bs_prog_key),
[MESA_SHADER_INTERSECTION] = sizeof(struct brw_bs_prog_key),
[MESA_SHADER_CALLABLE] = sizeof(struct brw_bs_prog_key),
[MESA_SHADER_KERNEL] = sizeof(struct brw_cs_prog_key),
};
assert((int)stage >= 0 && stage < ARRAY_SIZE(stage_sizes));
return stage_sizes[stage];
+1 -181
View File
@@ -149,11 +149,6 @@ struct brw_compiler {
int spilling_rate;
struct nir_shader *clc_shader;
struct {
unsigned mue_header_packing;
bool mue_compaction;
} mesh;
};
#define brw_shader_debug_log(compiler, data, fmt, ... ) do { \
@@ -175,19 +170,6 @@ struct brw_compiler {
*/
#define BRW_SUBGROUP_SIZE 32
static inline bool
brw_shader_stage_is_bindless(gl_shader_stage stage)
{
return stage >= MESA_SHADER_RAYGEN &&
stage <= MESA_SHADER_CALLABLE;
}
static inline bool
brw_shader_stage_requires_bindless_resources(gl_shader_stage stage)
{
return brw_shader_stage_is_bindless(stage) || gl_shader_stage_is_mesh(stage);
}
/**
* Program key structures.
*
@@ -429,19 +411,6 @@ struct brw_gs_prog_key
unsigned padding:27;
};
struct brw_task_prog_key
{
struct brw_base_prog_key base;
};
struct brw_mesh_prog_key
{
struct brw_base_prog_key base;
bool compact_mue:1;
unsigned padding:31;
};
enum brw_sf_primitive {
BRW_SF_PRIM_POINTS = 0,
BRW_SF_PRIM_LINES = 1,
@@ -568,30 +537,17 @@ struct brw_wm_prog_key {
enum brw_sometimes line_aa:2;
/* Whether the preceding shader stage is mesh */
enum brw_sometimes mesh_input:2;
bool coherent_fb_fetch:1;
bool ignore_sample_mask_out:1;
bool coarse_pixel:1;
uint64_t padding:53;
uint64_t padding:55;
};
struct brw_cs_prog_key {
struct brw_base_prog_key base;
};
struct brw_bs_prog_key {
struct brw_base_prog_key base;
/* Represents enum enum brw_rt_ray_flags values given at pipeline creation
* to be combined with ray_flags handed to the traceRayEXT() calls by the
* shader.
*/
uint32_t pipeline_ray_flags;
};
struct brw_ff_gs_prog_key {
uint64_t attrs;
@@ -633,9 +589,6 @@ union brw_any_prog_key {
struct brw_gs_prog_key gs;
struct brw_wm_prog_key wm;
struct brw_cs_prog_key cs;
struct brw_bs_prog_key bs;
struct brw_task_prog_key task;
struct brw_mesh_prog_key mesh;
};
PRAGMA_DIAGNOSTIC_POP
@@ -732,8 +685,6 @@ enum brw_shader_reloc_id {
BRW_SHADER_RELOC_CONST_DATA_ADDR_LOW,
BRW_SHADER_RELOC_CONST_DATA_ADDR_HIGH,
BRW_SHADER_RELOC_SHADER_START_OFFSET,
BRW_SHADER_RELOC_RESUME_SBT_ADDR_LOW,
BRW_SHADER_RELOC_RESUME_SBT_ADDR_HIGH,
BRW_SHADER_RELOC_DESCRIPTORS_ADDR_HIGH,
};
@@ -1298,22 +1249,6 @@ brw_cs_prog_data_prog_offset(const struct brw_cs_prog_data *prog_data,
return prog_data->prog_offset[index];
}
struct brw_bs_prog_data {
struct brw_stage_prog_data base;
/** SIMD size of the root shader */
uint8_t simd_size;
/** Maximum stack size of all shaders */
uint32_t max_stack_size;
/** Offset into the shader where the resume SBT is located */
uint32_t resume_sbt_offset;
/** Number of resume shaders */
uint32_t num_resume_shaders;
};
struct brw_ff_gs_prog_data {
unsigned urb_read_length;
unsigned total_grf;
@@ -1541,58 +1476,6 @@ struct brw_clip_prog_data {
uint32_t total_grf;
};
struct brw_tue_map {
uint32_t size_dw;
uint32_t per_task_data_start_dw;
};
struct brw_mue_map {
int32_t start_dw[VARYING_SLOT_MAX];
uint32_t len_dw[VARYING_SLOT_MAX];
uint32_t per_primitive_indices_dw;
uint32_t size_dw;
uint32_t max_primitives;
uint32_t per_primitive_start_dw;
uint32_t per_primitive_header_size_dw;
uint32_t per_primitive_data_size_dw;
uint32_t per_primitive_pitch_dw;
bool user_data_in_primitive_header;
uint32_t max_vertices;
uint32_t per_vertex_start_dw;
uint32_t per_vertex_header_size_dw;
uint32_t per_vertex_data_size_dw;
uint32_t per_vertex_pitch_dw;
bool user_data_in_vertex_header;
};
struct brw_task_prog_data {
struct brw_cs_prog_data base;
struct brw_tue_map map;
bool uses_drawid;
};
enum brw_mesh_index_format {
BRW_INDEX_FORMAT_U32,
BRW_INDEX_FORMAT_U888X,
};
struct brw_mesh_prog_data {
struct brw_cs_prog_data base;
struct brw_mue_map map;
uint32_t clip_distance_mask;
uint32_t cull_distance_mask;
uint16_t primitive_type;
enum brw_mesh_index_format index_format;
bool uses_drawid;
};
/* brw_any_prog_data is prog_data for any stage that maps to an API stage */
union brw_any_prog_data {
struct brw_stage_prog_data base;
@@ -1603,9 +1486,6 @@ union brw_any_prog_data {
struct brw_gs_prog_data gs;
struct brw_wm_prog_data wm;
struct brw_cs_prog_data cs;
struct brw_bs_prog_data bs;
struct brw_task_prog_data task;
struct brw_mesh_prog_data mesh;
};
#define DEFINE_PROG_DATA_DOWNCAST(STAGE, CHECK) \
@@ -1630,16 +1510,12 @@ DEFINE_PROG_DATA_DOWNCAST(tes, prog_data->stage == MESA_SHADER_TESS_EVAL)
DEFINE_PROG_DATA_DOWNCAST(gs, prog_data->stage == MESA_SHADER_GEOMETRY)
DEFINE_PROG_DATA_DOWNCAST(wm, prog_data->stage == MESA_SHADER_FRAGMENT)
DEFINE_PROG_DATA_DOWNCAST(cs, gl_shader_stage_uses_workgroup(prog_data->stage))
DEFINE_PROG_DATA_DOWNCAST(bs, brw_shader_stage_is_bindless(prog_data->stage))
DEFINE_PROG_DATA_DOWNCAST(vue, prog_data->stage == MESA_SHADER_VERTEX ||
prog_data->stage == MESA_SHADER_TESS_CTRL ||
prog_data->stage == MESA_SHADER_TESS_EVAL ||
prog_data->stage == MESA_SHADER_GEOMETRY)
DEFINE_PROG_DATA_DOWNCAST(task, prog_data->stage == MESA_SHADER_TASK)
DEFINE_PROG_DATA_DOWNCAST(mesh, prog_data->stage == MESA_SHADER_MESH)
/* These are not really brw_stage_prog_data. */
DEFINE_PROG_DATA_DOWNCAST(ff_gs, true)
DEFINE_PROG_DATA_DOWNCAST(clip, true)
@@ -1817,29 +1693,6 @@ brw_compile_clip(const struct brw_compiler *compiler,
struct intel_vue_map *vue_map,
unsigned *final_assembly_size);
struct brw_compile_task_params {
struct brw_compile_params base;
const struct brw_task_prog_key *key;
struct brw_task_prog_data *prog_data;
};
const unsigned *
brw_compile_task(const struct brw_compiler *compiler,
struct brw_compile_task_params *params);
struct brw_compile_mesh_params {
struct brw_compile_params base;
const struct brw_mesh_prog_key *key;
struct brw_mesh_prog_data *prog_data;
const struct brw_tue_map *tue_map;
};
const unsigned *
brw_compile_mesh(const struct brw_compiler *compiler,
struct brw_compile_mesh_params *params);
/**
* Parameters for compiling a fragment shader.
*
@@ -1889,30 +1742,6 @@ const unsigned *
brw_compile_cs(const struct brw_compiler *compiler,
struct brw_compile_cs_params *params);
/**
* Parameters for compiling a Bindless shader.
*
* Some of these will be modified during the shader compilation.
*/
struct brw_compile_bs_params {
struct brw_compile_params base;
const struct brw_bs_prog_key *key;
struct brw_bs_prog_data *prog_data;
unsigned num_resume_shaders;
struct nir_shader **resume_shaders;
};
/**
* Compile a Bindless shader.
*
* Returns the final assembly and updates the parameters structure.
*/
const unsigned *
brw_compile_bs(const struct brw_compiler *compiler,
struct brw_compile_bs_params *params);
/**
* Compile a fixed function geometry shader.
*
@@ -2083,15 +1912,6 @@ brw_compute_first_urb_slot_required(uint64_t inputs_read,
return 0;
}
/* From InlineData in 3DSTATE_TASK_SHADER_DATA and 3DSTATE_MESH_SHADER_DATA. */
#define BRW_TASK_MESH_INLINE_DATA_SIZE_DW 8
/* InlineData[0-1] is used for Vulkan descriptor. */
#define BRW_TASK_MESH_PUSH_CONSTANTS_START_DW 2
#define BRW_TASK_MESH_PUSH_CONSTANTS_SIZE_DW \
(BRW_TASK_MESH_INLINE_DATA_SIZE_DW - BRW_TASK_MESH_PUSH_CONSTANTS_START_DW)
/**
* This enum is used as the base indice of the nir_load_topology_id_intel
* intrinsic. This is used to return different values based on some aspect of
-10
View File
@@ -325,7 +325,6 @@ static const char *const gfx6_sfid[16] = {
[GFX7_SFID_PIXEL_INTERPOLATOR] = "pixel interp",
[HSW_SFID_DATAPORT_DATA_CACHE_1] = "dp data 1",
[HSW_SFID_CRE] = "cre",
[GEN_RT_SFID_RAY_TRACE_ACCELERATOR] = "rt accel",
[GFX12_SFID_SLM] = "slm",
[GFX12_SFID_TGM] = "tgm",
[GFX12_SFID_UGM] = "ugm",
@@ -2713,15 +2712,6 @@ brw_disassemble_inst(FILE *file, const struct brw_isa_info *isa,
}
break;
case GEN_RT_SFID_RAY_TRACE_ACCELERATOR:
if (devinfo->has_ray_tracing) {
format(file, " SIMD%d,",
brw_rt_trace_ray_desc_exec_size(devinfo, imm_desc));
} else {
unsupported = true;
}
break;
default:
unsupported = true;
break;
-7
View File
@@ -1686,13 +1686,6 @@ brw_rt_trace_ray_desc(ASSERTED const struct intel_device_info *devinfo,
SET_BITS(brw_mdc_sm2(exec_size), 8, 8);
}
static inline uint32_t
brw_rt_trace_ray_desc_exec_size(UNUSED const struct intel_device_info *devinfo,
uint32_t desc)
{
return brw_mdc_sm2_exec_size(GET_BITS(desc, 8, 8));
}
/**
* Construct a message descriptor immediate with the specified pixel
* interpolator function controls.
+2 -3
View File
@@ -2907,9 +2907,8 @@ brw_compact_instructions(struct brw_codegen *p, int start_offset,
if (try_compact_instruction(&c, dst, &inst)) {
compacted_count++;
if (INTEL_DEBUG(DEBUG_VS | DEBUG_GS | DEBUG_TCS | DEBUG_TASK |
DEBUG_WM | DEBUG_CS | DEBUG_TES | DEBUG_MESH |
DEBUG_RT)) {
if (INTEL_DEBUG(DEBUG_VS | DEBUG_GS | DEBUG_TCS |
DEBUG_WM | DEBUG_CS | DEBUG_TES)) {
brw_inst uncompacted;
uncompact_instruction(&c, &uncompacted, dst);
if (memcmp(&saved, &uncompacted, sizeof(uncompacted))) {
-15
View File
@@ -1435,9 +1435,6 @@ enum brw_message_target {
GFX12_SFID_TGM = 13, /* Typed Global Memory */
GFX12_SFID_SLM = 14, /* Shared Local Memory */
GFX12_SFID_UGM = 15, /* Untyped Global Memory */
GEN_RT_SFID_BINDLESS_THREAD_DISPATCH = 7,
GEN_RT_SFID_RAY_TRACE_ACCELERATOR = 8,
};
#define GFX7_MESSAGE_TARGET_DP_DATA_CACHE 10
@@ -1863,18 +1860,6 @@ enum ENUM_PACKED brw_rnd_mode {
#define GFX7_BYTE_SCATTERED_DATA_ELEMENT_WORD 1
#define GFX7_BYTE_SCATTERED_DATA_ELEMENT_DWORD 2
#define GEN_RT_BTD_MESSAGE_SPAWN 1
#define GEN_RT_TRACE_RAY_INITAL 0
#define GEN_RT_TRACE_RAY_INSTANCE 1
#define GEN_RT_TRACE_RAY_COMMIT 2
#define GEN_RT_TRACE_RAY_CONTINUE 3
#define GEN_RT_BTD_SHADER_TYPE_ANY_HIT 0
#define GEN_RT_BTD_SHADER_TYPE_CLOSEST_HIT 1
#define GEN_RT_BTD_SHADER_TYPE_MISS 2
#define GEN_RT_BTD_SHADER_TYPE_INTERSECTION 3
/* Starting with Xe-HPG, the old dataport was massively reworked dataport.
* The new thing, called Load/Store Cache or LSC, has a significantly improved
* interface. Instead of bespoke messages for every case, there's basically
+5 -422
View File
@@ -1475,10 +1475,6 @@ fs_visitor::assign_curb_setup()
void
brw_compute_urb_setup_index(struct brw_wm_prog_data *wm_prog_data)
{
/* TODO(mesh): Review usage of this in the context of Mesh, we may want to
* skip per-primitive attributes here.
*/
/* Make sure uint8_t is sufficient */
STATIC_ASSERT(VARYING_SLOT_MAX <= 0xff);
uint8_t index = 0;
@@ -1494,8 +1490,7 @@ static void
calculate_urb_setup(const struct intel_device_info *devinfo,
const struct brw_wm_prog_key *key,
struct brw_wm_prog_data *prog_data,
const nir_shader *nir,
const struct brw_mue_map *mue_map)
const nir_shader *nir)
{
memset(prog_data->urb_setup, -1, sizeof(prog_data->urb_setup));
memset(prog_data->urb_setup_channel, 0, sizeof(prog_data->urb_setup_channel));
@@ -1506,153 +1501,7 @@ calculate_urb_setup(const struct intel_device_info *devinfo,
nir->info.inputs_read & ~nir->info.per_primitive_inputs;
/* Figure out where each of the incoming setup attributes lands. */
if (key->mesh_input != BRW_NEVER) {
/* Per-Primitive Attributes are laid out by Hardware before the regular
* attributes, so order them like this to make easy later to map setup
* into real HW registers.
*/
if (nir->info.per_primitive_inputs) {
uint64_t per_prim_inputs_read =
nir->info.inputs_read & nir->info.per_primitive_inputs;
/* In Mesh, PRIMITIVE_SHADING_RATE, VIEWPORT and LAYER slots
* are always at the beginning, because they come from MUE
* Primitive Header, not Per-Primitive Attributes.
*/
const uint64_t primitive_header_bits = VARYING_BIT_VIEWPORT |
VARYING_BIT_LAYER |
VARYING_BIT_PRIMITIVE_SHADING_RATE;
if (mue_map) {
unsigned per_prim_start_dw = mue_map->per_primitive_start_dw;
unsigned per_prim_size_dw = mue_map->per_primitive_pitch_dw;
bool reads_header = (per_prim_inputs_read & primitive_header_bits) != 0;
if (reads_header || mue_map->user_data_in_primitive_header) {
/* Primitive Shading Rate, Layer and Viewport live in the same
* 4-dwords slot (psr is dword 0, layer is dword 1, and viewport
* is dword 2).
*/
if (per_prim_inputs_read & VARYING_BIT_PRIMITIVE_SHADING_RATE)
prog_data->urb_setup[VARYING_SLOT_PRIMITIVE_SHADING_RATE] = 0;
if (per_prim_inputs_read & VARYING_BIT_LAYER)
prog_data->urb_setup[VARYING_SLOT_LAYER] = 0;
if (per_prim_inputs_read & VARYING_BIT_VIEWPORT)
prog_data->urb_setup[VARYING_SLOT_VIEWPORT] = 0;
per_prim_inputs_read &= ~primitive_header_bits;
} else {
/* If fs doesn't need primitive header, then it won't be made
* available through SBE_MESH, so we have to skip them when
* calculating offset from start of per-prim data.
*/
per_prim_start_dw += mue_map->per_primitive_header_size_dw;
per_prim_size_dw -= mue_map->per_primitive_header_size_dw;
}
u_foreach_bit64(i, per_prim_inputs_read) {
int start = mue_map->start_dw[i];
assert(start >= 0);
assert(mue_map->len_dw[i] > 0);
assert(unsigned(start) >= per_prim_start_dw);
unsigned pos_dw = unsigned(start) - per_prim_start_dw;
prog_data->urb_setup[i] = urb_next + pos_dw / 4;
prog_data->urb_setup_channel[i] = pos_dw % 4;
}
urb_next = per_prim_size_dw / 4;
} else {
/* With no MUE map, we never read the primitive header, and
* per-primitive attributes won't be packed either, so just lay
* them in varying order.
*/
per_prim_inputs_read &= ~primitive_header_bits;
for (unsigned i = 0; i < VARYING_SLOT_MAX; i++) {
if (per_prim_inputs_read & BITFIELD64_BIT(i)) {
prog_data->urb_setup[i] = urb_next++;
}
}
/* The actual setup attributes later must be aligned to a full GRF. */
urb_next = ALIGN(urb_next, 2);
}
prog_data->num_per_primitive_inputs = urb_next;
}
const uint64_t clip_dist_bits = VARYING_BIT_CLIP_DIST0 |
VARYING_BIT_CLIP_DIST1;
uint64_t unique_fs_attrs = inputs_read & BRW_FS_VARYING_INPUT_MASK;
if (inputs_read & clip_dist_bits) {
assert(!mue_map || mue_map->per_vertex_header_size_dw > 8);
unique_fs_attrs &= ~clip_dist_bits;
}
if (mue_map) {
unsigned per_vertex_start_dw = mue_map->per_vertex_start_dw;
unsigned per_vertex_size_dw = mue_map->per_vertex_pitch_dw;
/* Per-Vertex header is available to fragment shader only if there's
* user data there.
*/
if (!mue_map->user_data_in_vertex_header) {
per_vertex_start_dw += 8;
per_vertex_size_dw -= 8;
}
/* In Mesh, CLIP_DIST slots are always at the beginning, because
* they come from MUE Vertex Header, not Per-Vertex Attributes.
*/
if (inputs_read & clip_dist_bits) {
prog_data->urb_setup[VARYING_SLOT_CLIP_DIST0] = urb_next;
prog_data->urb_setup[VARYING_SLOT_CLIP_DIST1] = urb_next + 1;
} else if (mue_map && mue_map->per_vertex_header_size_dw > 8) {
/* Clip distances are in MUE, but we are not reading them in FS. */
per_vertex_start_dw += 8;
per_vertex_size_dw -= 8;
}
/* Per-Vertex attributes are laid out ordered. Because we always link
* Mesh and Fragment shaders, the which slots are written and read by
* each of them will match. */
u_foreach_bit64(i, unique_fs_attrs) {
int start = mue_map->start_dw[i];
assert(start >= 0);
assert(mue_map->len_dw[i] > 0);
assert(unsigned(start) >= per_vertex_start_dw);
unsigned pos_dw = unsigned(start) - per_vertex_start_dw;
prog_data->urb_setup[i] = urb_next + pos_dw / 4;
prog_data->urb_setup_channel[i] = pos_dw % 4;
}
urb_next += per_vertex_size_dw / 4;
} else {
/* If we don't have an MUE map, just lay down the inputs the FS reads
* in varying order, as we do for the legacy pipeline.
*/
if (inputs_read & clip_dist_bits) {
prog_data->urb_setup[VARYING_SLOT_CLIP_DIST0] = urb_next++;
prog_data->urb_setup[VARYING_SLOT_CLIP_DIST1] = urb_next++;
}
for (unsigned int i = 0; i < VARYING_SLOT_MAX; i++) {
if (unique_fs_attrs & BITFIELD64_BIT(i))
prog_data->urb_setup[i] = urb_next++;
}
}
} else if (devinfo->ver >= 6) {
if (devinfo->ver >= 6) {
assert(!nir->info.per_primitive_inputs);
uint64_t vue_header_bits =
@@ -7215,104 +7064,6 @@ fs_visitor::run_cs(bool allow_spilling)
return !failed;
}
bool
fs_visitor::run_bs(bool allow_spilling)
{
assert(stage >= MESA_SHADER_RAYGEN && stage <= MESA_SHADER_CALLABLE);
payload_ = new bs_thread_payload(*this);
nir_to_brw(this);
if (failed)
return false;
/* TODO(RT): Perhaps rename this? */
emit_cs_terminate();
calculate_cfg();
optimize();
assign_curb_setup();
fixup_3src_null_dest();
emit_dummy_memory_fence_before_eot();
/* Wa_14015360517 */
emit_dummy_mov_instruction();
allocate_registers(allow_spilling);
return !failed;
}
bool
fs_visitor::run_task(bool allow_spilling)
{
assert(stage == MESA_SHADER_TASK);
payload_ = new task_mesh_thread_payload(*this);
nir_to_brw(this);
if (failed)
return false;
emit_urb_fence();
emit_cs_terminate();
calculate_cfg();
optimize();
assign_curb_setup();
fixup_3src_null_dest();
emit_dummy_memory_fence_before_eot();
/* Wa_14015360517 */
emit_dummy_mov_instruction();
allocate_registers(allow_spilling);
return !failed;
}
bool
fs_visitor::run_mesh(bool allow_spilling)
{
assert(stage == MESA_SHADER_MESH);
payload_ = new task_mesh_thread_payload(*this);
nir_to_brw(this);
if (failed)
return false;
emit_urb_fence();
emit_cs_terminate();
calculate_cfg();
optimize();
assign_curb_setup();
fixup_3src_null_dest();
emit_dummy_memory_fence_before_eot();
/* Wa_14015360517 */
emit_dummy_mov_instruction();
allocate_registers(allow_spilling);
return !failed;
}
static bool
is_used_in_not_interp_frag_coord(nir_def *def)
{
@@ -7510,8 +7261,7 @@ static void
brw_nir_populate_wm_prog_data(nir_shader *shader,
const struct intel_device_info *devinfo,
const struct brw_wm_prog_key *key,
struct brw_wm_prog_data *prog_data,
const struct brw_mue_map *mue_map)
struct brw_wm_prog_data *prog_data)
{
/* key->alpha_test_func means simulating alpha testing via discards,
* so the shader definitely kills pixels.
@@ -7663,7 +7413,7 @@ brw_nir_populate_wm_prog_data(nir_shader *shader,
BITSET_TEST(shader->info.system_values_read, SYSTEM_VALUE_FRAG_COORD) &&
prog_data->coarse_pixel_dispatch != BRW_NEVER;
calculate_urb_setup(devinfo, key, prog_data, shader, mue_map);
calculate_urb_setup(devinfo, key, prog_data, shader);
brw_compute_flat_inputs(prog_data, shader);
}
@@ -7721,8 +7471,7 @@ brw_compile_fs(const struct brw_compiler *compiler,
brw_postprocess_nir(nir, compiler, debug_enabled,
key->base.robust_flags);
brw_nir_populate_wm_prog_data(nir, compiler->devinfo, key, prog_data,
params->mue_map);
brw_nir_populate_wm_prog_data(nir, compiler->devinfo, key, prog_data);
std::unique_ptr<fs_visitor> v8, v16, v32, vmulti;
cfg_t *simd8_cfg = NULL, *simd16_cfg = NULL, *simd32_cfg = NULL,
@@ -8263,95 +8012,6 @@ brw_cs_get_dispatch_info(const struct intel_device_info *devinfo,
return info;
}
static uint8_t
compile_single_bs(const struct brw_compiler *compiler,
struct brw_compile_bs_params *params,
const struct brw_bs_prog_key *key,
struct brw_bs_prog_data *prog_data,
nir_shader *shader,
fs_generator *g,
struct brw_compile_stats *stats,
int *prog_offset)
{
const bool debug_enabled = brw_should_print_shader(shader, DEBUG_RT);
prog_data->base.stage = shader->info.stage;
prog_data->max_stack_size = MAX2(prog_data->max_stack_size,
shader->scratch_size);
const unsigned max_dispatch_width = 16;
brw_nir_apply_key(shader, compiler, &key->base, max_dispatch_width);
brw_postprocess_nir(shader, compiler, debug_enabled,
key->base.robust_flags);
brw_simd_selection_state simd_state{
.devinfo = compiler->devinfo,
.prog_data = prog_data,
/* Since divergence is a lot more likely in RT than compute, it makes
* sense to limit ourselves to the smallest available SIMD for now.
*/
.required_width = compiler->devinfo->ver >= 20 ? 16u : 8u,
};
std::unique_ptr<fs_visitor> v[2];
for (unsigned simd = 0; simd < ARRAY_SIZE(v); simd++) {
if (!brw_simd_should_compile(simd_state, simd))
continue;
const unsigned dispatch_width = 8u << simd;
if (dispatch_width == 8 && compiler->devinfo->ver >= 20)
continue;
v[simd] = std::make_unique<fs_visitor>(compiler, &params->base,
&key->base,
&prog_data->base, shader,
dispatch_width,
stats != NULL,
debug_enabled);
const bool allow_spilling = !brw_simd_any_compiled(simd_state);
if (v[simd]->run_bs(allow_spilling)) {
brw_simd_mark_compiled(simd_state, simd, v[simd]->spilled_any_registers);
} else {
simd_state.error[simd] = ralloc_strdup(params->base.mem_ctx,
v[simd]->fail_msg);
if (simd > 0) {
brw_shader_perf_log(compiler, params->base.log_data,
"SIMD%u shader failed to compile: %s",
dispatch_width, v[simd]->fail_msg);
}
}
}
const int selected_simd = brw_simd_select(simd_state);
if (selected_simd < 0) {
params->base.error_str =
ralloc_asprintf(params->base.mem_ctx,
"Can't compile shader: "
"SIMD8 '%s' and SIMD16 '%s'.\n",
simd_state.error[0], simd_state.error[1]);
return 0;
}
assert(selected_simd < int(ARRAY_SIZE(v)));
fs_visitor *selected = v[selected_simd].get();
assert(selected);
const unsigned dispatch_width = selected->dispatch_width;
int offset = g->generate_code(selected->cfg, dispatch_width, selected->shader_stats,
selected->performance_analysis.require(), stats);
if (prog_offset)
*prog_offset = offset;
else
assert(offset == 0);
return dispatch_width;
}
uint64_t
brw_bsr(const struct intel_device_info *devinfo,
uint32_t offset, uint8_t simd_size, uint8_t local_arg_offset)
@@ -8365,83 +8025,6 @@ brw_bsr(const struct intel_device_info *devinfo,
SET_BITS(local_arg_offset / 8, 2, 0);
}
const unsigned *
brw_compile_bs(const struct brw_compiler *compiler,
struct brw_compile_bs_params *params)
{
nir_shader *shader = params->base.nir;
struct brw_bs_prog_data *prog_data = params->prog_data;
unsigned num_resume_shaders = params->num_resume_shaders;
nir_shader **resume_shaders = params->resume_shaders;
const bool debug_enabled = brw_should_print_shader(shader, DEBUG_RT);
prog_data->base.stage = shader->info.stage;
prog_data->base.ray_queries = shader->info.ray_queries;
prog_data->base.total_scratch = 0;
prog_data->max_stack_size = 0;
prog_data->num_resume_shaders = num_resume_shaders;
fs_generator g(compiler, &params->base, &prog_data->base,
false, shader->info.stage);
if (unlikely(debug_enabled)) {
char *name = ralloc_asprintf(params->base.mem_ctx,
"%s %s shader %s",
shader->info.label ?
shader->info.label : "unnamed",
gl_shader_stage_name(shader->info.stage),
shader->info.name);
g.enable_debug(name);
}
prog_data->simd_size =
compile_single_bs(compiler, params, params->key, prog_data,
shader, &g, params->base.stats, NULL);
if (prog_data->simd_size == 0)
return NULL;
uint64_t *resume_sbt = ralloc_array(params->base.mem_ctx,
uint64_t, num_resume_shaders);
for (unsigned i = 0; i < num_resume_shaders; i++) {
if (INTEL_DEBUG(DEBUG_RT)) {
char *name = ralloc_asprintf(params->base.mem_ctx,
"%s %s resume(%u) shader %s",
shader->info.label ?
shader->info.label : "unnamed",
gl_shader_stage_name(shader->info.stage),
i, shader->info.name);
g.enable_debug(name);
}
/* TODO: Figure out shader stats etc. for resume shaders */
int offset = 0;
uint8_t simd_size =
compile_single_bs(compiler, params, params->key,
prog_data, resume_shaders[i], &g, NULL, &offset);
if (simd_size == 0)
return NULL;
assert(offset > 0);
resume_sbt[i] = brw_bsr(compiler->devinfo, offset, simd_size, 0);
}
/* We only have one constant data so we want to make sure they're all the
* same.
*/
for (unsigned i = 0; i < num_resume_shaders; i++) {
assert(resume_shaders[i]->constant_data_size ==
shader->constant_data_size);
assert(memcmp(resume_shaders[i]->constant_data,
shader->constant_data,
shader->constant_data_size) == 0);
}
g.add_const_data(shader->constant_data, shader->constant_data_size);
g.add_resume_sbt(num_resume_shaders, resume_sbt);
return g.get_assembly();
}
/**
* Test the dispatch mask packing assumptions of
* brw_stage_has_packed_dispatch(). Call this from e.g. the top of
-36
View File
@@ -153,28 +153,6 @@ protected:
fs_reg subgroup_id_;
};
struct task_mesh_thread_payload : public cs_thread_payload {
task_mesh_thread_payload(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;
};
struct bs_thread_payload : public thread_payload {
bs_thread_payload(const fs_visitor &v);
fs_reg global_arg_ptr;
fs_reg local_arg_ptr;
void load_shader_type(const brw::fs_builder &bld, fs_reg &dest) const;
};
class fs_instruction_scheduler;
/**
@@ -231,9 +209,6 @@ public:
bool run_tes();
bool run_gs();
bool run_cs(bool allow_spilling);
bool run_bs(bool allow_spilling);
bool run_task(bool allow_spilling);
bool run_mesh(bool allow_spilling);
void optimize();
void allocate_registers(bool allow_spilling);
uint32_t compute_max_register_pressure();
@@ -413,16 +388,6 @@ public:
return *static_cast<cs_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_);
}
bs_thread_payload &bs_payload() {
assert(stage >= MESA_SHADER_RAYGEN && stage <= MESA_SHADER_CALLABLE);
return *static_cast<bs_thread_payload *>(this->payload_);
}
bool source_depth_to_render_target;
bool runtime_check_aads_emit;
@@ -495,7 +460,6 @@ public:
struct brw_compile_stats *stats,
unsigned max_polygons = 0);
void add_const_data(void *data, unsigned size);
void add_resume_sbt(unsigned num_resume_shaders, uint64_t *sbt);
const unsigned *get_assembly();
private:
@@ -2517,24 +2517,6 @@ fs_generator::add_const_data(void *data, unsigned size)
}
}
void
fs_generator::add_resume_sbt(unsigned num_resume_shaders, uint64_t *sbt)
{
assert(brw_shader_stage_is_bindless(stage));
struct brw_bs_prog_data *bs_prog_data = brw_bs_prog_data(prog_data);
if (num_resume_shaders > 0) {
bs_prog_data->resume_sbt_offset =
brw_append_data(p, sbt, num_resume_shaders * sizeof(uint64_t), 32);
for (unsigned i = 0; i < num_resume_shaders; i++) {
size_t offset = bs_prog_data->resume_sbt_offset + i * sizeof(*sbt);
assert(offset <= UINT32_MAX);
brw_add_reloc(p, BRW_SHADER_RELOC_SHADER_START_OFFSET,
BRW_SHADER_RELOC_TYPE_U32,
(uint32_t)offset, (uint32_t)sbt[i]);
}
}
}
const unsigned *
fs_generator::get_assembly()
{
+1 -907
View File
@@ -93,8 +93,6 @@ fs_nir_setup_outputs(nir_to_brw_state &ntb)
fs_visitor &s = ntb.s;
if (s.stage == MESA_SHADER_TESS_CTRL ||
s.stage == MESA_SHADER_TASK ||
s.stage == MESA_SHADER_MESH ||
s.stage == MESA_SHADER_FRAGMENT)
return;
@@ -207,11 +205,7 @@ emit_system_values_block(nir_to_brw_state &ntb, nir_block *block)
break;
case nir_intrinsic_load_draw_id:
/* For Task/Mesh, draw_id will be handled later in
* nir_emit_mesh_task_intrinsic().
*/
if (!gl_shader_stage_is_mesh(s.stage))
unreachable("should be lowered by brw_nir_lower_vs_inputs().");
unreachable("should be lowered by brw_nir_lower_vs_inputs().");
break;
case nir_intrinsic_load_invocation_id:
@@ -249,8 +243,6 @@ emit_system_values_block(nir_to_brw_state &ntb, nir_block *block)
case nir_intrinsic_load_workgroup_id:
case nir_intrinsic_load_workgroup_id_zero_base:
if (gl_shader_stage_is_mesh(s.stage))
unreachable("should be lowered by nir_lower_compute_system_values().");
assert(gl_shader_stage_is_compute(s.stage));
reg = &ntb.system_values[SYSTEM_VALUE_WORKGROUP_ID];
if (reg->file == BAD_FILE)
@@ -4190,47 +4182,6 @@ fs_nir_emit_fs_intrinsic(nir_to_brw_state &ntb,
unsigned comp = nir_intrinsic_component(instr);
unsigned num_components = instr->num_components;
const struct brw_wm_prog_key *wm_key = (brw_wm_prog_key*) s.key;
if (wm_key->mesh_input == BRW_SOMETIMES) {
assert(devinfo->verx10 >= 125);
/* The FS payload gives us the viewport and layer clamped to valid
* ranges, but the spec for gl_ViewportIndex and gl_Layer includes
* the language:
* the fragment stage will read the same value written by the
* geometry stage, even if that value is out of range.
*
* Which is why these are normally passed as regular attributes.
* This isn't tested anywhere except some GL-only piglit tests
* though, so for the case where the FS may be used against either a
* traditional pipeline or a mesh one, where the position of these
* will change depending on the previous stage, read them from the
* payload to simplify things until the requisite magic is in place.
*/
if (base == VARYING_SLOT_LAYER || base == VARYING_SLOT_VIEWPORT) {
assert(num_components == 1);
fs_reg g1(retype(brw_vec1_grf(1, 1), BRW_REGISTER_TYPE_UD));
unsigned mask, shift_count;
if (base == VARYING_SLOT_LAYER) {
shift_count = 16;
mask = 0x7ff << shift_count;
} else {
shift_count = 27;
mask = 0xf << shift_count;
}
fs_reg vp_or_layer = bld.vgrf(BRW_REGISTER_TYPE_UD);
bld.AND(vp_or_layer, g1, brw_imm_ud(mask));
fs_reg shifted_value = bld.vgrf(BRW_REGISTER_TYPE_UD);
bld.SHR(shifted_value, vp_or_layer, brw_imm_ud(shift_count));
bld.MOV(offset(dest, bld, 0), retype(shifted_value, dest.type));
break;
}
}
/* TODO(mesh): Multiview. Verify and handle these special cases for Mesh. */
/* Special case fields in the VUE header */
if (base == VARYING_SLOT_LAYER)
comp = 1;
@@ -4661,64 +4612,6 @@ fs_nir_emit_cs_intrinsic(nir_to_brw_state &ntb,
}
}
static void
emit_rt_lsc_fence(const fs_builder &bld,
enum lsc_fence_scope scope,
enum lsc_flush_type flush_type)
{
const intel_device_info *devinfo = bld.shader->devinfo;
const fs_builder ubld = bld.exec_all().group(8, 0);
fs_reg tmp = ubld.vgrf(BRW_REGISTER_TYPE_UD);
fs_inst *send = ubld.emit(SHADER_OPCODE_SEND, tmp,
brw_imm_ud(0) /* desc */,
brw_imm_ud(0) /* ex_desc */,
brw_vec8_grf(0, 0) /* payload */);
send->sfid = GFX12_SFID_UGM;
send->desc = lsc_fence_msg_desc(devinfo, scope, flush_type, true);
send->mlen = reg_unit(devinfo); /* g0 header */
send->ex_mlen = 0;
/* Temp write for scheduling */
send->size_written = REG_SIZE * reg_unit(devinfo);
send->send_has_side_effects = true;
ubld.emit(FS_OPCODE_SCHEDULING_FENCE, ubld.null_reg_ud(), tmp);
}
static void
fs_nir_emit_bs_intrinsic(nir_to_brw_state &ntb,
nir_intrinsic_instr *instr)
{
const fs_builder &bld = ntb.bld;
fs_visitor &s = ntb.s;
assert(brw_shader_stage_is_bindless(s.stage));
const bs_thread_payload &payload = s.bs_payload();
fs_reg dest;
if (nir_intrinsic_infos[instr->intrinsic].has_dest)
dest = get_nir_def(ntb, instr->def);
switch (instr->intrinsic) {
case nir_intrinsic_load_btd_global_arg_addr_intel:
bld.MOV(dest, retype(payload.global_arg_ptr, dest.type));
break;
case nir_intrinsic_load_btd_local_arg_addr_intel:
bld.MOV(dest, retype(payload.local_arg_ptr, dest.type));
break;
case nir_intrinsic_load_btd_shader_type_intel:
payload.load_shader_type(bld, dest);
break;
default:
fs_nir_emit_intrinsic(ntb, bld, instr);
break;
}
}
static fs_reg
brw_nir_reduction_op_identity(const fs_builder &bld,
nir_op op, brw_reg_type type)
@@ -5172,713 +5065,6 @@ get_timestamp(const fs_builder &bld)
return dst;
}
static unsigned
component_from_intrinsic(nir_intrinsic_instr *instr)
{
if (nir_intrinsic_has_component(instr))
return nir_intrinsic_component(instr);
else
return 0;
}
static void
adjust_handle_and_offset(const fs_builder &bld,
fs_reg &urb_handle,
unsigned &urb_global_offset)
{
/* Make sure that URB global offset is below 2048 (2^11), because
* that's the maximum possible value encoded in Message Descriptor.
*/
unsigned adjustment = (urb_global_offset >> 11) << 11;
if (adjustment) {
fs_builder ubld8 = bld.group(8, 0).exec_all();
/* Allocate new register to not overwrite the shared URB handle. */
fs_reg new_handle = ubld8.vgrf(BRW_REGISTER_TYPE_UD);
ubld8.ADD(new_handle, urb_handle, brw_imm_ud(adjustment));
urb_handle = new_handle;
urb_global_offset -= adjustment;
}
}
static void
emit_urb_direct_vec4_write(const fs_builder &bld,
unsigned urb_global_offset,
const fs_reg &src,
fs_reg urb_handle,
unsigned dst_comp_offset,
unsigned comps,
unsigned mask)
{
for (unsigned q = 0; q < bld.dispatch_width() / 8; q++) {
fs_builder bld8 = bld.group(8, q);
fs_reg payload_srcs[8];
unsigned length = 0;
for (unsigned i = 0; i < dst_comp_offset; i++)
payload_srcs[length++] = reg_undef;
for (unsigned c = 0; c < comps; c++)
payload_srcs[length++] = quarter(offset(src, bld, c), q);
fs_reg srcs[URB_LOGICAL_NUM_SRCS];
srcs[URB_LOGICAL_SRC_HANDLE] = urb_handle;
srcs[URB_LOGICAL_SRC_CHANNEL_MASK] = brw_imm_ud(mask << 16);
srcs[URB_LOGICAL_SRC_DATA] = fs_reg(VGRF, bld.shader->alloc.allocate(length),
BRW_REGISTER_TYPE_F);
srcs[URB_LOGICAL_SRC_COMPONENTS] = brw_imm_ud(length);
bld8.LOAD_PAYLOAD(srcs[URB_LOGICAL_SRC_DATA], payload_srcs, length, 0);
fs_inst *inst = bld8.emit(SHADER_OPCODE_URB_WRITE_LOGICAL,
reg_undef, srcs, ARRAY_SIZE(srcs));
inst->offset = urb_global_offset;
assert(inst->offset < 2048);
}
}
static void
emit_urb_direct_writes(const fs_builder &bld, nir_intrinsic_instr *instr,
const fs_reg &src, fs_reg urb_handle)
{
assert(nir_src_bit_size(instr->src[0]) == 32);
nir_src *offset_nir_src = nir_get_io_offset_src(instr);
assert(nir_src_is_const(*offset_nir_src));
const unsigned comps = nir_src_num_components(instr->src[0]);
assert(comps <= 4);
const unsigned offset_in_dwords = nir_intrinsic_base(instr) +
nir_src_as_uint(*offset_nir_src) +
component_from_intrinsic(instr);
/* URB writes are vec4 aligned but the intrinsic offsets are in dwords.
* We can write up to 8 dwords, so single vec4 write is enough.
*/
const unsigned comp_shift = offset_in_dwords % 4;
const unsigned mask = nir_intrinsic_write_mask(instr) << comp_shift;
unsigned urb_global_offset = offset_in_dwords / 4;
adjust_handle_and_offset(bld, urb_handle, urb_global_offset);
emit_urb_direct_vec4_write(bld, urb_global_offset, src, urb_handle,
comp_shift, comps, mask);
}
static void
emit_urb_direct_vec4_write_xe2(const fs_builder &bld,
unsigned offset_in_bytes,
const fs_reg &src,
fs_reg urb_handle,
unsigned comps,
unsigned mask)
{
const struct intel_device_info *devinfo = bld.shader->devinfo;
const unsigned runit = reg_unit(devinfo);
const unsigned write_size = 8 * runit;
if (offset_in_bytes > 0) {
fs_builder bldall = bld.group(write_size, 0).exec_all();
fs_reg new_handle = bldall.vgrf(BRW_REGISTER_TYPE_UD);
bldall.ADD(new_handle, urb_handle, brw_imm_ud(offset_in_bytes));
urb_handle = new_handle;
}
for (unsigned q = 0; q < bld.dispatch_width() / write_size; q++) {
fs_builder hbld = bld.group(write_size, q);
fs_reg payload_srcs[comps];
for (unsigned c = 0; c < comps; c++)
payload_srcs[c] = horiz_offset(offset(src, bld, c), write_size * q);
fs_reg srcs[URB_LOGICAL_NUM_SRCS];
srcs[URB_LOGICAL_SRC_HANDLE] = urb_handle;
srcs[URB_LOGICAL_SRC_CHANNEL_MASK] = brw_imm_ud(mask << 16);
int nr = bld.shader->alloc.allocate(comps * runit);
srcs[URB_LOGICAL_SRC_DATA] = fs_reg(VGRF, nr, BRW_REGISTER_TYPE_F);
srcs[URB_LOGICAL_SRC_COMPONENTS] = brw_imm_ud(comps);
hbld.LOAD_PAYLOAD(srcs[URB_LOGICAL_SRC_DATA], payload_srcs, comps, 0);
hbld.emit(SHADER_OPCODE_URB_WRITE_LOGICAL,
reg_undef, srcs, ARRAY_SIZE(srcs));
}
}
static void
emit_urb_direct_writes_xe2(const fs_builder &bld, nir_intrinsic_instr *instr,
const fs_reg &src, fs_reg urb_handle)
{
assert(nir_src_bit_size(instr->src[0]) == 32);
nir_src *offset_nir_src = nir_get_io_offset_src(instr);
assert(nir_src_is_const(*offset_nir_src));
const unsigned comps = nir_src_num_components(instr->src[0]);
assert(comps <= 4);
const unsigned offset_in_dwords = nir_intrinsic_base(instr) +
nir_src_as_uint(*offset_nir_src) +
component_from_intrinsic(instr);
const unsigned mask = nir_intrinsic_write_mask(instr);
emit_urb_direct_vec4_write_xe2(bld, offset_in_dwords * 4, src,
urb_handle, comps, mask);
}
static void
emit_urb_indirect_vec4_write(const fs_builder &bld,
const fs_reg &offset_src,
unsigned base,
const fs_reg &src,
fs_reg urb_handle,
unsigned dst_comp_offset,
unsigned comps,
unsigned mask)
{
for (unsigned q = 0; q < bld.dispatch_width() / 8; q++) {
fs_builder bld8 = bld.group(8, q);
/* offset is always positive, so signedness doesn't matter */
assert(offset_src.type == BRW_REGISTER_TYPE_D ||
offset_src.type == BRW_REGISTER_TYPE_UD);
fs_reg off = bld8.vgrf(offset_src.type, 1);
bld8.MOV(off, quarter(offset_src, q));
bld8.ADD(off, off, brw_imm_ud(base));
bld8.SHR(off, off, brw_imm_ud(2));
fs_reg payload_srcs[8];
unsigned length = 0;
for (unsigned i = 0; i < dst_comp_offset; i++)
payload_srcs[length++] = reg_undef;
for (unsigned c = 0; c < comps; c++)
payload_srcs[length++] = quarter(offset(src, bld, c), q);
fs_reg srcs[URB_LOGICAL_NUM_SRCS];
srcs[URB_LOGICAL_SRC_HANDLE] = urb_handle;
srcs[URB_LOGICAL_SRC_PER_SLOT_OFFSETS] = off;
srcs[URB_LOGICAL_SRC_CHANNEL_MASK] = brw_imm_ud(mask << 16);
srcs[URB_LOGICAL_SRC_DATA] = fs_reg(VGRF, bld.shader->alloc.allocate(length),
BRW_REGISTER_TYPE_F);
srcs[URB_LOGICAL_SRC_COMPONENTS] = brw_imm_ud(length);
bld8.LOAD_PAYLOAD(srcs[URB_LOGICAL_SRC_DATA], payload_srcs, length, 0);
fs_inst *inst = bld8.emit(SHADER_OPCODE_URB_WRITE_LOGICAL,
reg_undef, srcs, ARRAY_SIZE(srcs));
inst->offset = 0;
}
}
static void
emit_urb_indirect_writes_mod(const fs_builder &bld, nir_intrinsic_instr *instr,
const fs_reg &src, const fs_reg &offset_src,
fs_reg urb_handle, unsigned mod)
{
assert(nir_src_bit_size(instr->src[0]) == 32);
const unsigned comps = nir_src_num_components(instr->src[0]);
assert(comps <= 4);
const unsigned base_in_dwords = nir_intrinsic_base(instr) +
component_from_intrinsic(instr);
const unsigned comp_shift = mod;
const unsigned mask = nir_intrinsic_write_mask(instr) << comp_shift;
emit_urb_indirect_vec4_write(bld, offset_src, base_in_dwords, src,
urb_handle, comp_shift, comps, mask);
}
static void
emit_urb_indirect_writes_xe2(const fs_builder &bld, nir_intrinsic_instr *instr,
const fs_reg &src, const fs_reg &offset_src,
fs_reg urb_handle)
{
assert(nir_src_bit_size(instr->src[0]) == 32);
const struct intel_device_info *devinfo = bld.shader->devinfo;
const unsigned runit = reg_unit(devinfo);
const unsigned write_size = 8 * runit;
const unsigned comps = nir_src_num_components(instr->src[0]);
assert(comps <= 4);
const unsigned base_in_dwords = nir_intrinsic_base(instr) +
component_from_intrinsic(instr);
if (base_in_dwords > 0) {
fs_builder bldall = bld.group(write_size, 0).exec_all();
fs_reg new_handle = bldall.vgrf(BRW_REGISTER_TYPE_UD);
bldall.ADD(new_handle, urb_handle, brw_imm_ud(base_in_dwords * 4));
urb_handle = new_handle;
}
const unsigned mask = nir_intrinsic_write_mask(instr);
for (unsigned q = 0; q < bld.dispatch_width() / write_size; q++) {
fs_builder wbld = bld.group(write_size, q);
fs_reg payload_srcs[comps];
for (unsigned c = 0; c < comps; c++)
payload_srcs[c] = horiz_offset(offset(src, bld, c), write_size * q);
fs_reg addr = wbld.vgrf(BRW_REGISTER_TYPE_UD);
wbld.SHL(addr, horiz_offset(offset_src, write_size * q), brw_imm_ud(2));
wbld.ADD(addr, addr, urb_handle);
fs_reg srcs[URB_LOGICAL_NUM_SRCS];
srcs[URB_LOGICAL_SRC_HANDLE] = addr;
srcs[URB_LOGICAL_SRC_CHANNEL_MASK] = brw_imm_ud(mask << 16);
int nr = bld.shader->alloc.allocate(comps * runit);
srcs[URB_LOGICAL_SRC_DATA] = fs_reg(VGRF, nr, BRW_REGISTER_TYPE_F);
srcs[URB_LOGICAL_SRC_COMPONENTS] = brw_imm_ud(comps);
wbld.LOAD_PAYLOAD(srcs[URB_LOGICAL_SRC_DATA], payload_srcs, comps, 0);
wbld.emit(SHADER_OPCODE_URB_WRITE_LOGICAL,
reg_undef, srcs, ARRAY_SIZE(srcs));
}
}
static void
emit_urb_indirect_writes(const fs_builder &bld, nir_intrinsic_instr *instr,
const fs_reg &src, const fs_reg &offset_src,
fs_reg urb_handle)
{
assert(nir_src_bit_size(instr->src[0]) == 32);
const unsigned comps = nir_src_num_components(instr->src[0]);
assert(comps <= 4);
const unsigned base_in_dwords = nir_intrinsic_base(instr) +
component_from_intrinsic(instr);
/* Use URB write message that allow different offsets per-slot. The offset
* is in units of vec4s (128 bits), so we use a write for each component,
* replicating it in the sources and applying the appropriate mask based on
* the dword offset.
*/
for (unsigned c = 0; c < comps; c++) {
if (((1 << c) & nir_intrinsic_write_mask(instr)) == 0)
continue;
fs_reg src_comp = offset(src, bld, c);
for (unsigned q = 0; q < bld.dispatch_width() / 8; q++) {
fs_builder bld8 = bld.group(8, q);
/* offset is always positive, so signedness doesn't matter */
assert(offset_src.type == BRW_REGISTER_TYPE_D ||
offset_src.type == BRW_REGISTER_TYPE_UD);
fs_reg off = bld8.vgrf(offset_src.type, 1);
bld8.MOV(off, quarter(offset_src, q));
bld8.ADD(off, off, brw_imm_ud(c + base_in_dwords));
fs_reg mask = bld8.vgrf(BRW_REGISTER_TYPE_UD, 1);
bld8.AND(mask, off, brw_imm_ud(0x3));
fs_reg one = bld8.vgrf(BRW_REGISTER_TYPE_UD, 1);
bld8.MOV(one, brw_imm_ud(1));
bld8.SHL(mask, one, mask);
bld8.SHL(mask, mask, brw_imm_ud(16));
bld8.SHR(off, off, brw_imm_ud(2));
fs_reg payload_srcs[4];
unsigned length = 0;
for (unsigned j = 0; j < 4; j++)
payload_srcs[length++] = quarter(src_comp, q);
fs_reg srcs[URB_LOGICAL_NUM_SRCS];
srcs[URB_LOGICAL_SRC_HANDLE] = urb_handle;
srcs[URB_LOGICAL_SRC_PER_SLOT_OFFSETS] = off;
srcs[URB_LOGICAL_SRC_CHANNEL_MASK] = mask;
srcs[URB_LOGICAL_SRC_DATA] = fs_reg(VGRF, bld.shader->alloc.allocate(length),
BRW_REGISTER_TYPE_F);
srcs[URB_LOGICAL_SRC_COMPONENTS] = brw_imm_ud(length);
bld8.LOAD_PAYLOAD(srcs[URB_LOGICAL_SRC_DATA], payload_srcs, length, 0);
fs_inst *inst = bld8.emit(SHADER_OPCODE_URB_WRITE_LOGICAL,
reg_undef, srcs, ARRAY_SIZE(srcs));
inst->offset = 0;
}
}
}
static void
emit_urb_direct_reads(const fs_builder &bld, nir_intrinsic_instr *instr,
const fs_reg &dest, fs_reg urb_handle)
{
assert(instr->def.bit_size == 32);
unsigned comps = instr->def.num_components;
if (comps == 0)
return;
nir_src *offset_nir_src = nir_get_io_offset_src(instr);
assert(nir_src_is_const(*offset_nir_src));
const unsigned offset_in_dwords = nir_intrinsic_base(instr) +
nir_src_as_uint(*offset_nir_src) +
component_from_intrinsic(instr);
unsigned urb_global_offset = offset_in_dwords / 4;
adjust_handle_and_offset(bld, urb_handle, urb_global_offset);
const unsigned comp_offset = offset_in_dwords % 4;
const unsigned num_regs = comp_offset + comps;
fs_builder ubld8 = bld.group(8, 0).exec_all();
fs_reg data = ubld8.vgrf(BRW_REGISTER_TYPE_UD, num_regs);
fs_reg srcs[URB_LOGICAL_NUM_SRCS];
srcs[URB_LOGICAL_SRC_HANDLE] = urb_handle;
fs_inst *inst = ubld8.emit(SHADER_OPCODE_URB_READ_LOGICAL, data,
srcs, ARRAY_SIZE(srcs));
inst->offset = urb_global_offset;
assert(inst->offset < 2048);
inst->size_written = num_regs * REG_SIZE;
for (unsigned c = 0; c < comps; c++) {
fs_reg dest_comp = offset(dest, bld, c);
fs_reg data_comp = horiz_stride(offset(data, ubld8, comp_offset + c), 0);
bld.MOV(retype(dest_comp, BRW_REGISTER_TYPE_UD), data_comp);
}
}
static void
emit_urb_direct_reads_xe2(const fs_builder &bld, nir_intrinsic_instr *instr,
const fs_reg &dest, fs_reg urb_handle)
{
assert(instr->def.bit_size == 32);
unsigned comps = instr->def.num_components;
if (comps == 0)
return;
nir_src *offset_nir_src = nir_get_io_offset_src(instr);
assert(nir_src_is_const(*offset_nir_src));
fs_builder ubld16 = bld.group(16, 0).exec_all();
const unsigned offset_in_dwords = nir_intrinsic_base(instr) +
nir_src_as_uint(*offset_nir_src) +
component_from_intrinsic(instr);
if (offset_in_dwords > 0) {
fs_reg new_handle = ubld16.vgrf(BRW_REGISTER_TYPE_UD);
ubld16.ADD(new_handle, urb_handle, brw_imm_ud(offset_in_dwords * 4));
urb_handle = new_handle;
}
fs_reg data = ubld16.vgrf(BRW_REGISTER_TYPE_UD, comps);
fs_reg srcs[URB_LOGICAL_NUM_SRCS];
srcs[URB_LOGICAL_SRC_HANDLE] = urb_handle;
fs_inst *inst = ubld16.emit(SHADER_OPCODE_URB_READ_LOGICAL,
data, srcs, ARRAY_SIZE(srcs));
inst->size_written = 2 * comps * REG_SIZE;
for (unsigned c = 0; c < comps; c++) {
fs_reg dest_comp = offset(dest, bld, c);
fs_reg data_comp = horiz_stride(offset(data, ubld16, c), 0);
bld.MOV(retype(dest_comp, BRW_REGISTER_TYPE_UD), data_comp);
}
}
static void
emit_urb_indirect_reads(const fs_builder &bld, nir_intrinsic_instr *instr,
const fs_reg &dest, const fs_reg &offset_src, fs_reg urb_handle)
{
assert(instr->def.bit_size == 32);
unsigned comps = instr->def.num_components;
if (comps == 0)
return;
fs_reg seq_ud;
{
fs_builder ubld8 = bld.group(8, 0).exec_all();
seq_ud = ubld8.vgrf(BRW_REGISTER_TYPE_UD, 1);
fs_reg seq_uw = ubld8.vgrf(BRW_REGISTER_TYPE_UW, 1);
ubld8.MOV(seq_uw, fs_reg(brw_imm_v(0x76543210)));
ubld8.MOV(seq_ud, seq_uw);
ubld8.SHL(seq_ud, seq_ud, brw_imm_ud(2));
}
const unsigned base_in_dwords = nir_intrinsic_base(instr) +
component_from_intrinsic(instr);
for (unsigned c = 0; c < comps; c++) {
for (unsigned q = 0; q < bld.dispatch_width() / 8; q++) {
fs_builder bld8 = bld.group(8, q);
/* offset is always positive, so signedness doesn't matter */
assert(offset_src.type == BRW_REGISTER_TYPE_D ||
offset_src.type == BRW_REGISTER_TYPE_UD);
fs_reg off = bld8.vgrf(offset_src.type, 1);
bld8.MOV(off, quarter(offset_src, q));
bld8.ADD(off, off, brw_imm_ud(base_in_dwords + c));
STATIC_ASSERT(IS_POT(REG_SIZE) && REG_SIZE > 1);
fs_reg comp = bld8.vgrf(BRW_REGISTER_TYPE_UD, 1);
bld8.AND(comp, off, brw_imm_ud(0x3));
bld8.SHL(comp, comp, brw_imm_ud(ffs(REG_SIZE) - 1));
bld8.ADD(comp, comp, seq_ud);
bld8.SHR(off, off, brw_imm_ud(2));
fs_reg srcs[URB_LOGICAL_NUM_SRCS];
srcs[URB_LOGICAL_SRC_HANDLE] = urb_handle;
srcs[URB_LOGICAL_SRC_PER_SLOT_OFFSETS] = off;
fs_reg data = bld8.vgrf(BRW_REGISTER_TYPE_UD, 4);
fs_inst *inst = bld8.emit(SHADER_OPCODE_URB_READ_LOGICAL,
data, srcs, ARRAY_SIZE(srcs));
inst->offset = 0;
inst->size_written = 4 * REG_SIZE;
fs_reg dest_comp = offset(dest, bld, c);
bld8.emit(SHADER_OPCODE_MOV_INDIRECT,
retype(quarter(dest_comp, q), BRW_REGISTER_TYPE_UD),
data,
comp,
brw_imm_ud(4 * REG_SIZE));
}
}
}
static void
emit_urb_indirect_reads_xe2(const fs_builder &bld, nir_intrinsic_instr *instr,
const fs_reg &dest, const fs_reg &offset_src,
fs_reg urb_handle)
{
assert(instr->def.bit_size == 32);
unsigned comps = instr->def.num_components;
if (comps == 0)
return;
fs_builder ubld16 = bld.group(16, 0).exec_all();
const unsigned offset_in_dwords = nir_intrinsic_base(instr) +
component_from_intrinsic(instr);
if (offset_in_dwords > 0) {
fs_reg new_handle = ubld16.vgrf(BRW_REGISTER_TYPE_UD);
ubld16.ADD(new_handle, urb_handle, brw_imm_ud(offset_in_dwords * 4));
urb_handle = new_handle;
}
fs_reg data = ubld16.vgrf(BRW_REGISTER_TYPE_UD, comps);
for (unsigned q = 0; q < bld.dispatch_width() / 16; q++) {
fs_builder wbld = bld.group(16, q);
fs_reg addr = wbld.vgrf(BRW_REGISTER_TYPE_UD);
wbld.SHL(addr, horiz_offset(offset_src, 16 * q), brw_imm_ud(2));
wbld.ADD(addr, addr, urb_handle);
fs_reg srcs[URB_LOGICAL_NUM_SRCS];
srcs[URB_LOGICAL_SRC_HANDLE] = addr;
fs_inst *inst = wbld.emit(SHADER_OPCODE_URB_READ_LOGICAL,
data, srcs, ARRAY_SIZE(srcs));
inst->size_written = 2 * comps * REG_SIZE;
for (unsigned c = 0; c < comps; c++) {
fs_reg dest_comp = horiz_offset(offset(dest, bld, c), 16 * q);
fs_reg data_comp = offset(data, wbld, c);
wbld.MOV(retype(dest_comp, BRW_REGISTER_TYPE_UD), data_comp);
}
}
}
static void
emit_task_mesh_store(nir_to_brw_state &ntb,
const fs_builder &bld, nir_intrinsic_instr *instr,
const fs_reg &urb_handle)
{
fs_reg src = get_nir_src(ntb, instr->src[0]);
nir_src *offset_nir_src = nir_get_io_offset_src(instr);
if (nir_src_is_const(*offset_nir_src)) {
if (bld.shader->devinfo->ver >= 20)
emit_urb_direct_writes_xe2(bld, instr, src, urb_handle);
else
emit_urb_direct_writes(bld, instr, src, urb_handle);
} else {
if (bld.shader->devinfo->ver >= 20) {
emit_urb_indirect_writes_xe2(bld, instr, src, get_nir_src(ntb, *offset_nir_src), urb_handle);
return;
}
bool use_mod = false;
unsigned mod;
/* Try to calculate the value of (offset + base) % 4. If we can do
* this, then we can do indirect writes using only 1 URB write.
*/
use_mod = nir_mod_analysis(nir_get_scalar(offset_nir_src->ssa, 0), nir_type_uint, 4, &mod);
if (use_mod) {
mod += nir_intrinsic_base(instr) + component_from_intrinsic(instr);
mod %= 4;
}
if (use_mod) {
emit_urb_indirect_writes_mod(bld, instr, src, get_nir_src(ntb, *offset_nir_src), urb_handle, mod);
} else {
emit_urb_indirect_writes(bld, instr, src, get_nir_src(ntb, *offset_nir_src), urb_handle);
}
}
}
static void
emit_task_mesh_load(nir_to_brw_state &ntb,
const fs_builder &bld, nir_intrinsic_instr *instr,
const fs_reg &urb_handle)
{
fs_reg dest = get_nir_def(ntb, instr->def);
nir_src *offset_nir_src = nir_get_io_offset_src(instr);
/* TODO(mesh): for per_vertex and per_primitive, if we could keep around
* the non-array-index offset, we could use to decide if we can perform
* a single large aligned read instead one per component.
*/
if (nir_src_is_const(*offset_nir_src)) {
if (bld.shader->devinfo->ver >= 20)
emit_urb_direct_reads_xe2(bld, instr, dest, urb_handle);
else
emit_urb_direct_reads(bld, instr, dest, urb_handle);
} else {
if (bld.shader->devinfo->ver >= 20)
emit_urb_indirect_reads_xe2(bld, instr, dest, get_nir_src(ntb, *offset_nir_src), urb_handle);
else
emit_urb_indirect_reads(bld, instr, dest, get_nir_src(ntb, *offset_nir_src), urb_handle);
}
}
static void
fs_nir_emit_task_mesh_intrinsic(nir_to_brw_state &ntb, const fs_builder &bld,
nir_intrinsic_instr *instr)
{
fs_visitor &s = ntb.s;
assert(s.stage == MESA_SHADER_MESH || s.stage == MESA_SHADER_TASK);
const task_mesh_thread_payload &payload = s.task_mesh_payload();
fs_reg dest;
if (nir_intrinsic_infos[instr->intrinsic].has_dest)
dest = get_nir_def(ntb, instr->def);
switch (instr->intrinsic) {
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:
dest = retype(dest, BRW_REGISTER_TYPE_UD);
bld.MOV(dest, payload.extended_parameter_0);
break;
case nir_intrinsic_load_local_invocation_id:
unreachable("local invocation id should have been lowered earlier");
break;
case nir_intrinsic_load_local_invocation_index:
dest = retype(dest, BRW_REGISTER_TYPE_UD);
bld.MOV(dest, payload.local_index);
break;
case nir_intrinsic_load_num_workgroups:
dest = retype(dest, BRW_REGISTER_TYPE_UD);
bld.MOV(offset(dest, bld, 0), brw_uw1_grf(0, 13)); /* g0.6 >> 16 */
bld.MOV(offset(dest, bld, 1), brw_uw1_grf(0, 8)); /* g0.4 & 0xffff */
bld.MOV(offset(dest, bld, 2), brw_uw1_grf(0, 9)); /* g0.4 >> 16 */
break;
case nir_intrinsic_load_workgroup_index:
dest = retype(dest, BRW_REGISTER_TYPE_UD);
bld.MOV(dest, retype(brw_vec1_grf(0, 1), BRW_REGISTER_TYPE_UD));
break;
default:
fs_nir_emit_cs_intrinsic(ntb, instr);
break;
}
}
static void
fs_nir_emit_task_intrinsic(nir_to_brw_state &ntb,
nir_intrinsic_instr *instr)
{
const fs_builder &bld = ntb.bld;
fs_visitor &s = ntb.s;
assert(s.stage == MESA_SHADER_TASK);
const task_mesh_thread_payload &payload = s.task_mesh_payload();
switch (instr->intrinsic) {
case nir_intrinsic_store_output:
case nir_intrinsic_store_task_payload:
emit_task_mesh_store(ntb, bld, instr, payload.urb_output);
break;
case nir_intrinsic_load_output:
case nir_intrinsic_load_task_payload:
emit_task_mesh_load(ntb, bld, instr, payload.urb_output);
break;
default:
fs_nir_emit_task_mesh_intrinsic(ntb, bld, instr);
break;
}
}
static void
fs_nir_emit_mesh_intrinsic(nir_to_brw_state &ntb,
nir_intrinsic_instr *instr)
{
const fs_builder &bld = ntb.bld;
fs_visitor &s = ntb.s;
assert(s.stage == MESA_SHADER_MESH);
const task_mesh_thread_payload &payload = s.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(ntb, 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(ntb, bld, instr, payload.urb_output);
break;
case nir_intrinsic_load_task_payload:
emit_task_mesh_load(ntb, bld, instr, payload.task_urb_input);
break;
default:
fs_nir_emit_task_mesh_intrinsic(ntb, bld, instr);
break;
}
}
static void
fs_nir_emit_intrinsic(nir_to_brw_state &ntb,
const fs_builder &bld, nir_intrinsic_instr *instr)
@@ -6164,8 +5350,6 @@ fs_nir_emit_intrinsic(nir_to_brw_state &ntb,
switch (s.stage) {
case MESA_SHADER_TESS_CTRL:
case MESA_SHADER_TASK:
case MESA_SHADER_MESH:
break;
default:
urb_fence = false;
@@ -7819,81 +7003,6 @@ fs_nir_emit_intrinsic(nir_to_brw_state &ntb,
break;
}
case nir_intrinsic_load_btd_stack_id_intel:
if (s.stage == MESA_SHADER_COMPUTE) {
assert(brw_cs_prog_data(s.prog_data)->uses_btd_stack_ids);
} else {
assert(brw_shader_stage_is_bindless(s.stage));
}
/* Stack IDs are always in R1 regardless of whether we're coming from a
* bindless shader or a regular compute shader.
*/
bld.MOV(retype(dest, BRW_REGISTER_TYPE_UD),
retype(brw_vec8_grf(1 * reg_unit(devinfo), 0), BRW_REGISTER_TYPE_UW));
break;
case nir_intrinsic_btd_spawn_intel:
if (s.stage == MESA_SHADER_COMPUTE) {
assert(brw_cs_prog_data(s.prog_data)->uses_btd_stack_ids);
} else {
assert(brw_shader_stage_is_bindless(s.stage));
}
/* Make sure all the pointers to resume shaders have landed where other
* threads can see them.
*/
emit_rt_lsc_fence(bld, LSC_FENCE_LOCAL, LSC_FLUSH_TYPE_NONE);
bld.emit(SHADER_OPCODE_BTD_SPAWN_LOGICAL, bld.null_reg_ud(),
bld.emit_uniformize(get_nir_src(ntb, instr->src[0])),
get_nir_src(ntb, instr->src[1]));
break;
case nir_intrinsic_btd_retire_intel:
if (s.stage == MESA_SHADER_COMPUTE) {
assert(brw_cs_prog_data(s.prog_data)->uses_btd_stack_ids);
} else {
assert(brw_shader_stage_is_bindless(s.stage));
}
/* Make sure all the pointers to resume shaders have landed where other
* threads can see them.
*/
emit_rt_lsc_fence(bld, LSC_FENCE_LOCAL, LSC_FLUSH_TYPE_NONE);
bld.emit(SHADER_OPCODE_BTD_RETIRE_LOGICAL);
break;
case nir_intrinsic_trace_ray_intel: {
const bool synchronous = nir_intrinsic_synchronous(instr);
assert(brw_shader_stage_is_bindless(s.stage) || synchronous);
/* Make sure all the previous RT structure writes are visible to the RT
* fixed function within the DSS, as well as stack pointers to resume
* shaders.
*/
emit_rt_lsc_fence(bld, LSC_FENCE_LOCAL, LSC_FLUSH_TYPE_NONE);
fs_reg srcs[RT_LOGICAL_NUM_SRCS];
fs_reg globals = get_nir_src(ntb, instr->src[0]);
srcs[RT_LOGICAL_SRC_GLOBALS] = bld.emit_uniformize(globals);
srcs[RT_LOGICAL_SRC_BVH_LEVEL] = get_nir_src(ntb, instr->src[1]);
srcs[RT_LOGICAL_SRC_TRACE_RAY_CONTROL] = get_nir_src(ntb, instr->src[2]);
srcs[RT_LOGICAL_SRC_SYNCHRONOUS] = brw_imm_ud(synchronous);
bld.emit(RT_OPCODE_TRACE_RAY_LOGICAL, bld.null_reg_ud(),
srcs, RT_LOGICAL_NUM_SRCS);
/* There is no actual value to use in the destination register of the
* synchronous trace instruction. All of the communication with the HW
* unit happens through memory reads/writes. So to ensure that the
* operation has completed before we go read the results in memory, we
* need a barrier followed by an invalidate before accessing memory.
*/
if (synchronous) {
bld.emit(BRW_OPCODE_SYNC, bld.null_reg_ud(), brw_imm_ud(TGL_SYNC_ALLWR));
emit_rt_lsc_fence(bld, LSC_FENCE_LOCAL, LSC_FLUSH_TYPE_INVALIDATE);
}
break;
}
default:
#ifndef NDEBUG
assert(instr->intrinsic < nir_num_intrinsics);
@@ -8660,23 +7769,8 @@ fs_nir_emit_instr(nir_to_brw_state &ntb, nir_instr *instr)
fs_nir_emit_fs_intrinsic(ntb, nir_instr_as_intrinsic(instr));
break;
case MESA_SHADER_COMPUTE:
case MESA_SHADER_KERNEL:
fs_nir_emit_cs_intrinsic(ntb, nir_instr_as_intrinsic(instr));
break;
case MESA_SHADER_RAYGEN:
case MESA_SHADER_ANY_HIT:
case MESA_SHADER_CLOSEST_HIT:
case MESA_SHADER_MISS:
case MESA_SHADER_INTERSECTION:
case MESA_SHADER_CALLABLE:
fs_nir_emit_bs_intrinsic(ntb, nir_instr_as_intrinsic(instr));
break;
case MESA_SHADER_TASK:
fs_nir_emit_task_intrinsic(ntb, nir_instr_as_intrinsic(instr));
break;
case MESA_SHADER_MESH:
fs_nir_emit_mesh_intrinsic(ntb, nir_instr_as_intrinsic(instr));
break;
default:
unreachable("unsupported shader stage");
}
@@ -517,89 +517,3 @@ cs_thread_payload::load_subgroup_id(const fs_builder &bld,
}
}
task_mesh_thread_payload::task_mesh_thread_payload(fs_visitor &v)
: cs_thread_payload(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.
*/
const fs_builder bld = fs_builder(&v).at_end();
unsigned r = 0;
assert(subgroup_id_.file != BAD_FILE);
extended_parameter_0 = retype(brw_vec1_grf(0, 3), BRW_REGISTER_TYPE_UD);
if (v.devinfo->ver >= 20) {
urb_output = brw_ud1_grf(1, 0);
} else {
urb_output = bld.vgrf(BRW_REGISTER_TYPE_UD);
/* In both mesh and task shader payload, lower 16 bits of g0.6 is
* an offset within Slice's Local URB, which says where shader is
* supposed to output its data.
*/
bld.AND(urb_output, brw_ud1_grf(0, 6), brw_imm_ud(0xFFFF));
}
if (v.stage == MESA_SHADER_MESH) {
/* g0.7 is Task Shader URB Entry Offset, which contains both an offset
* within Slice's Local USB (bits 0:15) and a slice selector
* (bits 16:24). Slice selector can be non zero when mesh shader
* is spawned on slice other than the one where task shader was run.
* Bit 24 says that Slice ID is present and bits 16:23 is the Slice ID.
*/
task_urb_input = brw_ud1_grf(0, 7);
}
r += reg_unit(v.devinfo);
local_index = brw_uw8_grf(r, 0);
r += reg_unit(v.devinfo);
if (v.devinfo->ver < 20 && v.dispatch_width == 32)
r += reg_unit(v.devinfo);
inline_parameter = brw_ud1_grf(r, 0);
r += reg_unit(v.devinfo);
num_regs = r;
}
bs_thread_payload::bs_thread_payload(const fs_visitor &v)
{
unsigned r = 0;
/* R0: Thread header. */
r += reg_unit(v.devinfo);
/* R1: Stack IDs. */
r += reg_unit(v.devinfo);
/* R2: Inline Parameter. Used for argument addresses. */
global_arg_ptr = brw_ud1_grf(r, 0);
local_arg_ptr = brw_ud1_grf(r, 2);
r += reg_unit(v.devinfo);
num_regs = r;
}
void
bs_thread_payload::load_shader_type(const fs_builder &bld, fs_reg &dest) const
{
fs_reg ud_dest = retype(dest, BRW_REGISTER_TYPE_UD);
bld.MOV(ud_dest, retype(brw_vec1_grf(0, 3), ud_dest.type));
bld.AND(ud_dest, ud_dest, brw_imm_ud(0xf));
}
-1
View File
@@ -1133,7 +1133,6 @@ sharedfunction:
| CRE { $$ = HSW_SFID_CRE; }
| SAMPLER { $$ = BRW_SFID_SAMPLER; }
| DP_SAMPLER { $$ = GFX6_SFID_DATAPORT_SAMPLER_CACHE; }
| RT_ACCEL { $$ = GEN_RT_SFID_RAY_TRACE_ACCELERATOR; }
| SLM { $$ = GFX12_SFID_SLM; }
| TGM { $$ = GFX12_SFID_TGM; }
| UGM { $$ = GFX12_SFID_UGM; }
@@ -1185,11 +1185,6 @@ namespace {
abort();
}
case GEN_RT_SFID_BINDLESS_THREAD_DISPATCH:
case GEN_RT_SFID_RAY_TRACE_ACCELERATOR:
return calculate_desc(info, EU_UNIT_SPAWNER, 2, 0, 0, 0 /* XXX */, 0,
10 /* XXX */, 0, 0, 0, 0, 0);
case BRW_SFID_URB:
return calculate_desc(info, EU_UNIT_URB, 2, 0, 0, 0, 6 /* XXX */,
32 /* XXX */, 200 /* XXX */, 0, 0, 0, 0);
@@ -2890,155 +2890,6 @@ lower_interpolator_logical_send(const fs_builder &bld, fs_inst *inst,
inst->src[2] = payload;
}
static void
lower_btd_logical_send(const fs_builder &bld, fs_inst *inst)
{
const intel_device_info *devinfo = bld.shader->devinfo;
fs_reg global_addr = inst->src[0];
const fs_reg btd_record = inst->src[1];
const unsigned unit = reg_unit(devinfo);
const unsigned mlen = 2 * unit;
const fs_builder ubld = bld.exec_all();
fs_reg header = ubld.vgrf(BRW_REGISTER_TYPE_UD, 2 * unit);
ubld.MOV(header, brw_imm_ud(0));
switch (inst->opcode) {
case SHADER_OPCODE_BTD_SPAWN_LOGICAL:
assert(type_sz(global_addr.type) == 8 && global_addr.stride == 0);
global_addr.type = BRW_REGISTER_TYPE_UD;
global_addr.stride = 1;
ubld.group(2, 0).MOV(header, global_addr);
break;
case SHADER_OPCODE_BTD_RETIRE_LOGICAL:
/* The bottom bit is the Stack ID release bit */
ubld.group(1, 0).MOV(header, brw_imm_ud(1));
break;
default:
unreachable("Invalid BTD message");
}
/* Stack IDs are always in R1 regardless of whether we're coming from a
* bindless shader or a regular compute shader.
*/
fs_reg stack_ids = retype(offset(header, bld, 1), BRW_REGISTER_TYPE_UW);
bld.exec_all().MOV(stack_ids, retype(brw_vec8_grf(1 * unit, 0),
BRW_REGISTER_TYPE_UW));
unsigned ex_mlen = 0;
fs_reg payload;
if (inst->opcode == SHADER_OPCODE_BTD_SPAWN_LOGICAL) {
ex_mlen = 2 * (inst->exec_size / 8);
payload = bld.move_to_vgrf(btd_record, 1);
} else {
assert(inst->opcode == SHADER_OPCODE_BTD_RETIRE_LOGICAL);
/* All these messages take a BTD and things complain if we don't provide
* one for RETIRE. However, it shouldn't ever actually get used so fill
* it with zero.
*/
ex_mlen = 2 * (inst->exec_size / 8);
payload = bld.move_to_vgrf(brw_imm_uq(0), 1);
}
/* Update the original instruction. */
inst->opcode = SHADER_OPCODE_SEND;
inst->mlen = mlen;
inst->ex_mlen = ex_mlen;
inst->header_size = 0; /* HW docs require has_header = false */
inst->send_has_side_effects = true;
inst->send_is_volatile = false;
/* Set up SFID and descriptors */
inst->sfid = GEN_RT_SFID_BINDLESS_THREAD_DISPATCH;
inst->desc = brw_btd_spawn_desc(devinfo, inst->exec_size,
GEN_RT_BTD_MESSAGE_SPAWN);
inst->resize_sources(4);
inst->src[0] = brw_imm_ud(0); /* desc */
inst->src[1] = brw_imm_ud(0); /* ex_desc */
inst->src[2] = header;
inst->src[3] = payload;
}
static void
lower_trace_ray_logical_send(const fs_builder &bld, fs_inst *inst)
{
const intel_device_info *devinfo = bld.shader->devinfo;
/* The emit_uniformize() in brw_fs_nir.cpp will generate an horizontal
* stride of 0. Below we're doing a MOV() in SIMD2. Since we can't use UQ/Q
* types in on Gfx12.5, we need to tweak the stride with a value of 1 dword
* so that the MOV operates on 2 components rather than twice the same
* component.
*/
fs_reg globals_addr = retype(inst->src[RT_LOGICAL_SRC_GLOBALS], BRW_REGISTER_TYPE_UD);
globals_addr.stride = 1;
const fs_reg bvh_level =
inst->src[RT_LOGICAL_SRC_BVH_LEVEL].file == BRW_IMMEDIATE_VALUE ?
inst->src[RT_LOGICAL_SRC_BVH_LEVEL] :
bld.move_to_vgrf(inst->src[RT_LOGICAL_SRC_BVH_LEVEL],
inst->components_read(RT_LOGICAL_SRC_BVH_LEVEL));
const fs_reg trace_ray_control =
inst->src[RT_LOGICAL_SRC_TRACE_RAY_CONTROL].file == BRW_IMMEDIATE_VALUE ?
inst->src[RT_LOGICAL_SRC_TRACE_RAY_CONTROL] :
bld.move_to_vgrf(inst->src[RT_LOGICAL_SRC_TRACE_RAY_CONTROL],
inst->components_read(RT_LOGICAL_SRC_TRACE_RAY_CONTROL));
const fs_reg synchronous_src = inst->src[RT_LOGICAL_SRC_SYNCHRONOUS];
assert(synchronous_src.file == BRW_IMMEDIATE_VALUE);
const bool synchronous = synchronous_src.ud;
const unsigned unit = reg_unit(devinfo);
const unsigned mlen = unit;
const fs_builder ubld = bld.exec_all();
fs_reg header = ubld.vgrf(BRW_REGISTER_TYPE_UD);
ubld.MOV(header, brw_imm_ud(0));
ubld.group(2, 0).MOV(header, globals_addr);
if (synchronous)
ubld.group(1, 0).MOV(byte_offset(header, 16), brw_imm_ud(synchronous));
const unsigned ex_mlen = inst->exec_size / 8;
fs_reg payload = bld.vgrf(BRW_REGISTER_TYPE_UD);
if (bvh_level.file == BRW_IMMEDIATE_VALUE &&
trace_ray_control.file == BRW_IMMEDIATE_VALUE) {
bld.MOV(payload, brw_imm_ud(SET_BITS(trace_ray_control.ud, 9, 8) |
(bvh_level.ud & 0x7)));
} else {
bld.SHL(payload, trace_ray_control, brw_imm_ud(8));
bld.OR(payload, payload, bvh_level);
}
/* When doing synchronous traversal, the HW implicitly computes the
* stack_id using the following formula :
*
* EUID[3:0] & THREAD_ID[2:0] & SIMD_LANE_ID[3:0]
*
* Only in the asynchronous case we need to set the stack_id given from the
* payload register.
*/
if (!synchronous) {
bld.AND(subscript(payload, BRW_REGISTER_TYPE_UW, 1),
retype(brw_vec8_grf(1 * unit, 0), BRW_REGISTER_TYPE_UW),
brw_imm_uw(0x7ff));
}
/* Update the original instruction. */
inst->opcode = SHADER_OPCODE_SEND;
inst->mlen = mlen;
inst->ex_mlen = ex_mlen;
inst->header_size = 0; /* HW docs require has_header = false */
inst->send_has_side_effects = true;
inst->send_is_volatile = false;
/* Set up SFID and descriptors */
inst->sfid = GEN_RT_SFID_RAY_TRACE_ACCELERATOR;
inst->desc = brw_rt_trace_ray_desc(devinfo, inst->exec_size);
inst->resize_sources(4);
inst->src[0] = brw_imm_ud(0); /* desc */
inst->src[1] = brw_imm_ud(0); /* ex_desc */
inst->src[2] = header;
inst->src[3] = payload;
}
static void
lower_get_buffer_size(const fs_builder &bld, fs_inst *inst)
{
@@ -3243,15 +3094,6 @@ fs_visitor::lower_logical_sends()
brw_wm_prog_data(prog_data));
break;
case SHADER_OPCODE_BTD_SPAWN_LOGICAL:
case SHADER_OPCODE_BTD_RETIRE_LOGICAL:
lower_btd_logical_send(ibld, inst);
break;
case RT_OPCODE_TRACE_RAY_LOGICAL:
lower_trace_ray_logical_send(ibld, inst);
break;
case SHADER_OPCODE_URB_READ_LOGICAL:
if (devinfo->ver < 20)
lower_urb_read_logical_send(ibld, inst);
+3 -163
View File
@@ -613,14 +613,6 @@ brw_nir_optimize(nir_shader *nir, bool is_scalar,
do {
progress = false;
/* This pass is causing problems with types used by OpenCL :
* https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13955
*
* Running with it disabled made no difference in the resulting assembly
* code.
*/
if (nir->info.stage != MESA_SHADER_KERNEL)
OPT(nir_split_array_vars, nir_var_function_temp);
OPT(nir_shrink_vec_array_vars, nir_var_function_temp);
OPT(nir_opt_deref);
if (OPT(nir_opt_memcpy))
@@ -1087,116 +1079,12 @@ brw_nir_zero_inputs(nir_shader *shader, uint64_t *zero_inputs)
zero_inputs);
}
/* Code for Wa_18019110168 may have created input/output variables beyond
* VARYING_SLOT_MAX and removed uses of variables below VARYING_SLOT_MAX.
* Clean it up, so they all stay below VARYING_SLOT_MAX.
*/
static void
brw_mesh_compact_io(nir_shader *mesh, nir_shader *frag)
{
gl_varying_slot mapping[VARYING_SLOT_MAX] = {0, };
gl_varying_slot cur = VARYING_SLOT_VAR0;
bool compact = false;
nir_foreach_shader_out_variable(var, mesh) {
gl_varying_slot location = var->data.location;
if (location < VARYING_SLOT_VAR0)
continue;
assert(location < ARRAY_SIZE(mapping));
const struct glsl_type *type = var->type;
if (nir_is_arrayed_io(var, MESA_SHADER_MESH) || var->data.per_view) {
assert(glsl_type_is_array(type));
type = glsl_get_array_element(type);
}
if (mapping[location])
continue;
unsigned num_slots = glsl_count_attribute_slots(type, false);
compact |= location + num_slots > VARYING_SLOT_MAX;
mapping[location] = cur;
cur += num_slots;
}
if (!compact)
return;
/* The rest of this function should be hit only for Wa_18019110168. */
nir_foreach_shader_out_variable(var, mesh) {
gl_varying_slot location = var->data.location;
if (location < VARYING_SLOT_VAR0)
continue;
location = mapping[location];
if (location == 0)
continue;
var->data.location = location;
}
nir_foreach_shader_in_variable(var, frag) {
gl_varying_slot location = var->data.location;
if (location < VARYING_SLOT_VAR0)
continue;
location = mapping[location];
if (location == 0)
continue;
var->data.location = location;
}
nir_shader_gather_info(mesh, nir_shader_get_entrypoint(mesh));
nir_shader_gather_info(frag, nir_shader_get_entrypoint(frag));
if (should_print_nir(mesh)) {
printf("%s\n", __func__);
nir_print_shader(mesh, stdout);
}
if (should_print_nir(frag)) {
printf("%s\n", __func__);
nir_print_shader(frag, stdout);
}
}
void
brw_nir_link_shaders(const struct brw_compiler *compiler,
nir_shader *producer, nir_shader *consumer)
{
const struct intel_device_info *devinfo = compiler->devinfo;
if (producer->info.stage == MESA_SHADER_MESH &&
consumer->info.stage == MESA_SHADER_FRAGMENT) {
uint64_t fs_inputs = 0, ms_outputs = 0;
/* gl_MeshPerPrimitiveEXT[].gl_ViewportIndex, gl_PrimitiveID and gl_Layer
* are per primitive, but fragment shader does not have them marked as
* such. Add the annotation here.
*/
nir_foreach_shader_in_variable(var, consumer) {
fs_inputs |= BITFIELD64_BIT(var->data.location);
switch (var->data.location) {
case VARYING_SLOT_LAYER:
case VARYING_SLOT_PRIMITIVE_ID:
case VARYING_SLOT_VIEWPORT:
var->data.per_primitive = 1;
break;
default:
continue;
}
}
nir_foreach_shader_out_variable(var, producer)
ms_outputs |= BITFIELD64_BIT(var->data.location);
uint64_t zero_inputs = ~ms_outputs & fs_inputs;
zero_inputs &= BITFIELD64_BIT(VARYING_SLOT_LAYER) |
BITFIELD64_BIT(VARYING_SLOT_VIEWPORT);
if (zero_inputs)
NIR_PASS(_, consumer, brw_nir_zero_inputs, &zero_inputs);
}
nir_lower_io_arrays_to_elements(producer, consumer);
nir_validate_shader(producer, "after nir_lower_io_arrays_to_elements");
nir_validate_shader(consumer, "after nir_lower_io_arrays_to_elements");
@@ -1243,11 +1131,6 @@ brw_nir_link_shaders(const struct brw_compiler *compiler,
brw_nir_optimize(producer, p_is_scalar, devinfo);
brw_nir_optimize(consumer, c_is_scalar, devinfo);
if (producer->info.stage == MESA_SHADER_MESH &&
consumer->info.stage == MESA_SHADER_FRAGMENT) {
brw_mesh_compact_io(producer, consumer);
}
}
NIR_PASS(_, producer, nir_lower_io_to_vector, nir_var_shader_out);
@@ -1259,18 +1142,12 @@ brw_nir_link_shaders(const struct brw_compiler *compiler,
NIR_PASS(_, producer, nir_opt_combine_stores, nir_var_shader_out);
NIR_PASS(_, consumer, nir_lower_io_to_vector, nir_var_shader_in);
if (producer->info.stage != MESA_SHADER_TESS_CTRL &&
producer->info.stage != MESA_SHADER_MESH &&
producer->info.stage != MESA_SHADER_TASK) {
if (producer->info.stage != MESA_SHADER_TESS_CTRL) {
/* Calling lower_io_to_vector creates output variable writes with
* write-masks. On non-TCS outputs, the back-end can't handle it and we
* need to call nir_lower_io_to_temporaries to get rid of them. This,
* in turn, creates temporary variables and extra copy_deref intrinsics
* that we need to clean up.
*
* Note Mesh/Task don't support I/O as temporaries (I/O is shared
* between whole workgroup, possibly using multiple HW threads). For
* those write-mask in output is handled by I/O lowering.
*/
NIR_PASS_V(producer, nir_lower_io_to_temporaries,
nir_shader_get_entrypoint(producer), true, false);
@@ -1278,24 +1155,6 @@ brw_nir_link_shaders(const struct brw_compiler *compiler,
NIR_PASS(_, producer, nir_split_var_copies);
NIR_PASS(_, producer, nir_lower_var_copies);
}
if (producer->info.stage == MESA_SHADER_TASK &&
consumer->info.stage == MESA_SHADER_MESH) {
for (unsigned i = 0; i < 3; ++i)
assert(producer->info.mesh.ts_mesh_dispatch_dimensions[i] <= UINT16_MAX);
nir_lower_compute_system_values_options options = {
.lower_workgroup_id_to_index = true,
.num_workgroups[0] = producer->info.mesh.ts_mesh_dispatch_dimensions[0],
.num_workgroups[1] = producer->info.mesh.ts_mesh_dispatch_dimensions[1],
.num_workgroups[2] = producer->info.mesh.ts_mesh_dispatch_dimensions[2],
/* nir_lower_idiv generates expensive code */
.shortcut_1d_workgroup_id = compiler->devinfo->verx10 >= 125,
};
NIR_PASS(_, consumer, nir_lower_compute_system_values, &options);
}
}
bool
@@ -1412,16 +1271,6 @@ get_mem_access_size_align(nir_intrinsic_op intrin, uint8_t bytes,
}
break;
case nir_intrinsic_load_task_payload:
if (bytes < 4 || align < 4) {
return (nir_mem_access_size_align) {
.bit_size = 32,
.num_components = 1,
.align = 4,
};
}
break;
default:
break;
}
@@ -1476,8 +1325,7 @@ brw_vectorize_lower_mem_access(nir_shader *nir,
if (is_scalar) {
nir_load_store_vectorize_options options = {
.modes = nir_var_mem_ubo | nir_var_mem_ssbo |
nir_var_mem_global | nir_var_mem_shared |
nir_var_mem_task_payload,
nir_var_mem_global | nir_var_mem_shared,
.callback = brw_nir_should_vectorize_mem,
.robust_modes = (nir_variable_mode)0,
};
@@ -1518,7 +1366,6 @@ brw_vectorize_lower_mem_access(nir_shader *nir,
nir_lower_mem_access_bit_sizes_options mem_access_options = {
.modes = nir_var_mem_ssbo |
nir_var_mem_constant |
nir_var_mem_task_payload |
nir_var_shader_temp |
nir_var_function_temp |
nir_var_mem_global |
@@ -1692,15 +1539,8 @@ brw_postprocess_nir(nir_shader *nir, const struct brw_compiler *compiler,
/* TODO: Enable nir_opt_uniform_atomics on Gfx7.x too.
* It currently fails Vulkan tests on Haswell for an unknown reason.
*
* TODO: Using this optimization on RT/OpenCL kernels also seems to cause
* issues. Until we can understand those issues, disable it.
*/
bool opt_uniform_atomic_stage_allowed =
devinfo->ver >= 8 &&
nir->info.stage != MESA_SHADER_KERNEL &&
nir->info.stage != MESA_SHADER_RAYGEN &&
!gl_shader_stage_is_callable(nir->info.stage);
bool opt_uniform_atomic_stage_allowed = devinfo->ver >= 8;
if (opt_uniform_atomic_stage_allowed && OPT(nir_opt_uniform_atomics)) {
const nir_lower_subgroups_options subgroups_options = {
@@ -608,16 +608,6 @@ schedule_node::set_latency_gfx7(const struct brw_isa_info *isa)
}
break;
case GEN_RT_SFID_BINDLESS_THREAD_DISPATCH:
case GEN_RT_SFID_RAY_TRACE_ACCELERATOR:
/* TODO.
*
* We'll assume for the moment that this is pretty quick as it
* doesn't actually return any data.
*/
latency = 200;
break;
case BRW_SFID_URB:
latency = 200;
break;
+1 -3
View File
@@ -153,9 +153,7 @@ brw_nir_no_indirect_mask(const struct brw_compiler *compiler,
break;
}
if (is_scalar && stage != MESA_SHADER_TESS_CTRL &&
stage != MESA_SHADER_TASK &&
stage != MESA_SHADER_MESH)
if (is_scalar && stage != MESA_SHADER_TESS_CTRL)
indirect_mask |= nir_var_shader_out;
/* On HSW+, we allow indirects in scalar shaders. They get implemented
@@ -62,8 +62,6 @@ get_prog_data(brw_simd_selection_state &state)
{
if (std::holds_alternative<struct brw_cs_prog_data *>(state.prog_data))
return &std::get<struct brw_cs_prog_data *>(state.prog_data)->base;
else if (std::holds_alternative<struct brw_bs_prog_data *>(state.prog_data))
return &std::get<struct brw_bs_prog_data *>(state.prog_data)->base;
else
return nullptr;
}
@@ -149,20 +147,6 @@ brw_simd_should_compile(brw_simd_selection_state &state, unsigned simd)
case MESA_SHADER_COMPUTE:
start = DEBUG_CS_SIMD8;
break;
case MESA_SHADER_TASK:
start = DEBUG_TS_SIMD8;
break;
case MESA_SHADER_MESH:
start = DEBUG_MS_SIMD8;
break;
case MESA_SHADER_RAYGEN:
case MESA_SHADER_ANY_HIT:
case MESA_SHADER_CLOSEST_HIT:
case MESA_SHADER_MISS:
case MESA_SHADER_INTERSECTION:
case MESA_SHADER_CALLABLE:
start = DEBUG_RT_SIMD8;
break;
default:
unreachable("unknown shader stage in brw_simd_should_compile");
}