X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fbrw_nir.c;h=fb7fa23586101a77d07bd00240ecf9a01e642710;hb=b63a98b1211d22f759ae9c80b2270fe2d3b2639e;hp=46b5116357917cffa2a607789ecc0ad917f7f4ab;hpb=74f956c416d5b0b37b4c2d6b957167bb203502c3;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/brw_nir.c b/src/mesa/drivers/dri/i965/brw_nir.c index 46b51163579..fb7fa235861 100644 --- a/src/mesa/drivers/dri/i965/brw_nir.c +++ b/src/mesa/drivers/dri/i965/brw_nir.c @@ -77,7 +77,7 @@ add_const_offset_to_base_block(nir_block *block, void *closure) nir_const_value *const_offset = nir_src_as_const_value(*offset); if (const_offset) { - intrin->const_index[0] += const_offset->u[0]; + intrin->const_index[0] += const_offset->u32[0]; b->cursor = nir_before_instr(&intrin->instr); nir_instr_rewrite_src(&intrin->instr, offset, nir_src_for_ssa(nir_imm_int(b, 0))); @@ -149,7 +149,7 @@ remap_inputs_with_vue_map(nir_block *block, void *closure) struct remap_patch_urb_offsets_state { nir_builder b; - struct brw_vue_map vue_map; + const struct brw_vue_map *vue_map; }; static bool @@ -167,7 +167,7 @@ remap_patch_urb_offsets(nir_block *block, void *closure) if ((stage == MESA_SHADER_TESS_CTRL && is_output(intrin)) || (stage == MESA_SHADER_TESS_EVAL && is_input(intrin))) { - int vue_slot = state->vue_map.varying_to_slot[intrin->const_index[0]]; + int vue_slot = state->vue_map->varying_to_slot[intrin->const_index[0]]; assert(vue_slot != -1); intrin->const_index[0] = vue_slot; @@ -175,8 +175,8 @@ remap_patch_urb_offsets(nir_block *block, void *closure) if (vertex) { nir_const_value *const_vertex = nir_src_as_const_value(*vertex); if (const_vertex) { - intrin->const_index[0] += const_vertex->u[0] * - state->vue_map.num_per_vertex_slots; + intrin->const_index[0] += const_vertex->u32[0] * + state->vue_map->num_per_vertex_slots; } else { state->b.cursor = nir_before_instr(&intrin->instr); @@ -185,7 +185,7 @@ remap_patch_urb_offsets(nir_block *block, void *closure) nir_imul(&state->b, nir_ssa_for_src(&state->b, *vertex, 1), nir_imm_int(&state->b, - state->vue_map.num_per_vertex_slots)); + state->vue_map->num_per_vertex_slots)); /* Add it to the existing offset */ nir_src *offset = nir_get_io_offset_src(intrin); @@ -202,105 +202,61 @@ remap_patch_urb_offsets(nir_block *block, void *closure) return true; } -static void -brw_nir_lower_inputs(nir_shader *nir, - const struct brw_device_info *devinfo, - bool is_scalar) +void +brw_nir_lower_vs_inputs(nir_shader *nir, + const struct brw_device_info *devinfo, + bool is_scalar, + bool use_legacy_snorm_formula, + const uint8_t *vs_attrib_wa_flags) { - switch (nir->stage) { - case MESA_SHADER_VERTEX: - /* Start with the location of the variable's base. */ - foreach_list_typed(nir_variable, var, node, &nir->inputs) { - var->data.driver_location = var->data.location; - } - - /* Now use nir_lower_io to walk dereference chains. Attribute arrays - * are loaded as one vec4 per element (or matrix column), so we use - * type_size_vec4 here. - */ - nir_lower_io(nir, nir_var_shader_in, type_size_vec4); - - /* This pass needs actual constants */ - nir_opt_constant_folding(nir); - - add_const_offset_to_base(nir, nir_var_shader_in); + /* Start with the location of the variable's base. */ + foreach_list_typed(nir_variable, var, node, &nir->inputs) { + var->data.driver_location = var->data.location; + } - if (is_scalar) { - /* Finally, translate VERT_ATTRIB_* values into the actual registers. - * - * Note that we can use nir->info.inputs_read instead of - * key->inputs_read since the two are identical aside from Gen4-5 - * edge flag differences. - */ - GLbitfield64 inputs_read = nir->info.inputs_read; + /* Now use nir_lower_io to walk dereference chains. Attribute arrays + * are loaded as one vec4 per element (or matrix column), so we use + * type_size_vec4 here. + */ + nir_lower_io(nir, nir_var_shader_in, type_size_vec4); - nir_foreach_function(nir, function) { - if (function->impl) { - nir_foreach_block(function->impl, remap_vs_attrs, &inputs_read); - } - } - } - break; - case MESA_SHADER_TESS_CTRL: - case MESA_SHADER_GEOMETRY: { - if (!is_scalar && nir->stage == MESA_SHADER_GEOMETRY) { - foreach_list_typed(nir_variable, var, node, &nir->inputs) { - var->data.driver_location = var->data.location; - } - } else { - /* The GLSL linker will have already matched up GS inputs and - * the outputs of prior stages. The driver does extend VS outputs - * in some cases, but only for legacy OpenGL or Gen4-5 hardware, - * neither of which offer geometry shader support. So we can - * safely ignore that. - * - * For SSO pipelines, we use a fixed VUE map layout based on variable - * locations, so we can rely on rendezvous-by-location to make this - * work. - * - * However, we need to ignore VARYING_SLOT_PRIMITIVE_ID, as it's not - * written by previous stages and shows up via payload magic. - */ - struct brw_vue_map input_vue_map; - GLbitfield64 inputs_read = - nir->info.inputs_read & ~VARYING_BIT_PRIMITIVE_ID; - brw_compute_vue_map(devinfo, &input_vue_map, inputs_read, - nir->info.separate_shader || - nir->stage == MESA_SHADER_TESS_CTRL); - - foreach_list_typed(nir_variable, var, node, &nir->inputs) { - var->data.driver_location = var->data.location; - } + /* This pass needs actual constants */ + nir_opt_constant_folding(nir); - /* Inputs are stored in vec4 slots, so use type_size_vec4(). */ - nir_lower_io(nir, nir_var_shader_in, type_size_vec4); + add_const_offset_to_base(nir, nir_var_shader_in); - /* This pass needs actual constants */ - nir_opt_constant_folding(nir); + brw_nir_apply_attribute_workarounds(nir, use_legacy_snorm_formula, + vs_attrib_wa_flags); - add_const_offset_to_base(nir, nir_var_shader_in); + if (is_scalar) { + /* Finally, translate VERT_ATTRIB_* values into the actual registers. + * + * Note that we can use nir->info.inputs_read instead of + * key->inputs_read since the two are identical aside from Gen4-5 + * edge flag differences. + */ + GLbitfield64 inputs_read = nir->info.inputs_read; - nir_foreach_function(nir, function) { - if (function->impl) { - nir_foreach_block(function->impl, remap_inputs_with_vue_map, - &input_vue_map); - } + nir_foreach_function(nir, function) { + if (function->impl) { + nir_foreach_block(function->impl, remap_vs_attrs, &inputs_read); } } - break; } - case MESA_SHADER_TESS_EVAL: { - struct remap_patch_urb_offsets_state state; - brw_compute_tess_vue_map(&state.vue_map, - nir->info.inputs_read & ~VARYING_BIT_PRIMITIVE_ID, - nir->info.patch_inputs_read); +} - foreach_list_typed(nir_variable, var, node, &nir->inputs) { - var->data.driver_location = var->data.location; - } +void +brw_nir_lower_vue_inputs(nir_shader *nir, bool is_scalar, + const struct brw_vue_map *vue_map) +{ + foreach_list_typed(nir_variable, var, node, &nir->inputs) { + var->data.driver_location = var->data.location; + } - nir_lower_io(nir, nir_var_shader_in, type_size_vec4); + /* Inputs are stored in vec4 slots, so use type_size_vec4(). */ + nir_lower_io(nir, nir_var_shader_in, type_size_vec4); + if (is_scalar || nir->stage != MESA_SHADER_GEOMETRY) { /* This pass needs actual constants */ nir_opt_constant_folding(nir); @@ -308,81 +264,93 @@ brw_nir_lower_inputs(nir_shader *nir, nir_foreach_function(nir, function) { if (function->impl) { - nir_builder_init(&state.b, function->impl); - nir_foreach_block(function->impl, remap_patch_urb_offsets, &state); + nir_foreach_block(function->impl, remap_inputs_with_vue_map, + (void *) vue_map); } } - break; - } - case MESA_SHADER_FRAGMENT: - assert(is_scalar); - nir_assign_var_locations(&nir->inputs, &nir->num_inputs, - type_size_scalar); - break; - case MESA_SHADER_COMPUTE: - /* Compute shaders have no inputs. */ - assert(exec_list_is_empty(&nir->inputs)); - break; - default: - unreachable("unsupported shader stage"); } } -static void -brw_nir_lower_outputs(nir_shader *nir, - const struct brw_device_info *devinfo, - bool is_scalar) +void +brw_nir_lower_tes_inputs(nir_shader *nir, const struct brw_vue_map *vue_map) { - switch (nir->stage) { - case MESA_SHADER_VERTEX: - case MESA_SHADER_TESS_EVAL: - case MESA_SHADER_GEOMETRY: - if (is_scalar) { - nir_assign_var_locations(&nir->outputs, &nir->num_outputs, - type_size_vec4_times_4); - nir_lower_io(nir, nir_var_shader_out, type_size_vec4_times_4); - } else { - nir_foreach_variable(var, &nir->outputs) - var->data.driver_location = var->data.location; - } - break; - case MESA_SHADER_TESS_CTRL: { - struct remap_patch_urb_offsets_state state; - brw_compute_tess_vue_map(&state.vue_map, nir->info.outputs_written, - nir->info.patch_outputs_written); + struct remap_patch_urb_offsets_state state; + state.vue_map = vue_map; - nir_foreach_variable(var, &nir->outputs) { - var->data.driver_location = var->data.location; - } + foreach_list_typed(nir_variable, var, node, &nir->inputs) { + var->data.driver_location = var->data.location; + } - nir_lower_io(nir, nir_var_shader_out, type_size_vec4); + nir_lower_io(nir, nir_var_shader_in, type_size_vec4); - /* This pass needs actual constants */ - nir_opt_constant_folding(nir); + /* This pass needs actual constants */ + nir_opt_constant_folding(nir); - add_const_offset_to_base(nir, nir_var_shader_out); + add_const_offset_to_base(nir, nir_var_shader_in); - nir_foreach_function(nir, function) { - if (function->impl) { - nir_builder_init(&state.b, function->impl); - nir_foreach_block(function->impl, remap_patch_urb_offsets, &state); - } + nir_foreach_function(nir, function) { + if (function->impl) { + nir_builder_init(&state.b, function->impl); + nir_foreach_block(function->impl, remap_patch_urb_offsets, &state); } - break; } - case MESA_SHADER_FRAGMENT: +} + +void +brw_nir_lower_fs_inputs(nir_shader *nir) +{ + nir_assign_var_locations(&nir->inputs, &nir->num_inputs, type_size_scalar); + nir_lower_io(nir, nir_var_shader_in, type_size_scalar); +} + +void +brw_nir_lower_vue_outputs(nir_shader *nir, + bool is_scalar) +{ + if (is_scalar) { nir_assign_var_locations(&nir->outputs, &nir->num_outputs, - type_size_scalar); - break; - case MESA_SHADER_COMPUTE: - /* Compute shaders have no outputs. */ - assert(exec_list_is_empty(&nir->outputs)); - break; - default: - unreachable("unsupported shader stage"); + type_size_vec4_times_4); + nir_lower_io(nir, nir_var_shader_out, type_size_vec4_times_4); + } else { + nir_foreach_variable(var, &nir->outputs) + var->data.driver_location = var->data.location; + nir_lower_io(nir, nir_var_shader_out, type_size_vec4); + } +} + +void +brw_nir_lower_tcs_outputs(nir_shader *nir, const struct brw_vue_map *vue_map) +{ + struct remap_patch_urb_offsets_state state; + state.vue_map = vue_map; + + nir_foreach_variable(var, &nir->outputs) { + var->data.driver_location = var->data.location; + } + + nir_lower_io(nir, nir_var_shader_out, type_size_vec4); + + /* This pass needs actual constants */ + nir_opt_constant_folding(nir); + + add_const_offset_to_base(nir, nir_var_shader_out); + + nir_foreach_function(nir, function) { + if (function->impl) { + nir_builder_init(&state.b, function->impl); + nir_foreach_block(function->impl, remap_patch_urb_offsets, &state); + } } } +void +brw_nir_lower_fs_outputs(nir_shader *nir) +{ + nir_assign_var_locations(&nir->outputs, &nir->num_outputs, + type_size_scalar); + nir_lower_io(nir, nir_var_shader_out, type_size_scalar); +} + static int type_size_scalar_bytes(const struct glsl_type *type) { @@ -409,6 +377,14 @@ brw_nir_lower_uniforms(nir_shader *nir, bool is_scalar) } } +void +brw_nir_lower_cs_shared(nir_shader *nir) +{ + nir_assign_var_locations(&nir->shared, &nir->num_shared, + type_size_scalar_bytes); + nir_lower_io(nir, nir_var_shared, type_size_scalar_bytes); +} + #define OPT(pass, ...) ({ \ bool this_progress = false; \ NIR_PASS(this_progress, nir, pass, ##__VA_ARGS__); \ @@ -461,14 +437,19 @@ nir_optimize(nir_shader *nir, bool is_scalar) * is_scalar = true to scalarize everything prior to code gen. */ nir_shader * -brw_preprocess_nir(nir_shader *nir, bool is_scalar) +brw_preprocess_nir(const struct brw_compiler *compiler, nir_shader *nir) { bool progress; /* Written by OPT and OPT_V */ (void)progress; + const bool is_scalar = compiler->scalar_stage[nir->stage]; + if (nir->stage == MESA_SHADER_GEOMETRY) OPT(nir_lower_gs_intrinsics); + if (compiler->precise_trig) + OPT(brw_nir_apply_trig_workarounds); + static const nir_lower_tex_options tex_options = { .lower_txp = ~0, }; @@ -492,27 +473,11 @@ brw_preprocess_nir(nir_shader *nir, bool is_scalar) /* Get rid of split copies */ nir = nir_optimize(nir, is_scalar); - OPT(nir_remove_dead_variables); + OPT(nir_remove_dead_variables, nir_var_local); return nir; } -/** Lower input and output loads and stores for i965. */ -nir_shader * -brw_nir_lower_io(nir_shader *nir, - const struct brw_device_info *devinfo, - bool is_scalar) -{ - bool progress; /* Written by OPT and OPT_V */ - (void)progress; - - OPT_V(brw_nir_lower_inputs, devinfo, is_scalar); - OPT_V(brw_nir_lower_outputs, devinfo, is_scalar); - OPT_V(nir_lower_io, nir_var_all, is_scalar ? type_size_scalar : type_size_vec4); - - return nir_optimize(nir, is_scalar); -} - /* Prepare the given shader for codegen * * This function is intended to be called right before going into the actual @@ -531,6 +496,8 @@ brw_postprocess_nir(nir_shader *nir, bool progress; /* Written by OPT and OPT_V */ (void)progress; + nir = nir_optimize(nir, is_scalar); + if (devinfo->gen >= 6) { /* Try and fuse multiply-adds */ OPT(brw_nir_opt_peephole_ffma); @@ -590,7 +557,6 @@ brw_create_nir(struct brw_context *brw, bool is_scalar) { struct gl_context *ctx = &brw->ctx; - const struct brw_device_info *devinfo = brw->intelScreen->devinfo; const nir_shader_compiler_options *options = ctx->Const.ShaderCompilerOptions[stage].NirOptions; bool progress; @@ -607,7 +573,7 @@ brw_create_nir(struct brw_context *brw, (void)progress; - nir = brw_preprocess_nir(nir, is_scalar); + nir = brw_preprocess_nir(brw->intelScreen->compiler, nir); OPT(nir_lower_system_values); OPT_V(brw_nir_lower_uniforms, is_scalar); @@ -617,11 +583,6 @@ brw_create_nir(struct brw_context *brw, OPT_V(nir_lower_atomics, shader_prog); } - if (nir->stage != MESA_SHADER_TESS_CTRL && - nir->stage != MESA_SHADER_TESS_EVAL) { - nir = brw_nir_lower_io(nir, devinfo, is_scalar); - } - return nir; } @@ -667,12 +628,24 @@ brw_type_for_nir_type(nir_alu_type type) { switch (type) { case nir_type_uint: + case nir_type_uint32: return BRW_REGISTER_TYPE_UD; case nir_type_bool: case nir_type_int: + case nir_type_bool32: + case nir_type_int32: return BRW_REGISTER_TYPE_D; case nir_type_float: + case nir_type_float32: return BRW_REGISTER_TYPE_F; + case nir_type_float64: + return BRW_REGISTER_TYPE_DF; + case nir_type_int64: + case nir_type_uint64: + /* TODO we should only see these in moves, so for now it's ok, but when + * we add actual 64-bit integer support we should fix this. + */ + return BRW_REGISTER_TYPE_DF; default: unreachable("unknown type"); } @@ -688,12 +661,18 @@ brw_glsl_base_type_for_nir_type(nir_alu_type type) { switch (type) { case nir_type_float: + case nir_type_float32: return GLSL_TYPE_FLOAT; + case nir_type_float64: + return GLSL_TYPE_DOUBLE; + case nir_type_int: + case nir_type_int32: return GLSL_TYPE_INT; case nir_type_uint: + case nir_type_uint32: return GLSL_TYPE_UINT; default: