X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fintel%2Fcompiler%2Fbrw_fs_visitor.cpp;h=d8918858a8d6383c0beff67865f2a416133ace4c;hb=72dc06e07e3f8b9ed5bb46e3927b8f87dd24e42b;hp=6ced1b9db62dba3b373f9d927447142b8c0290ce;hpb=a5efb0eae85106bd89537ed755501a59a9cbbc92;p=mesa.git diff --git a/src/intel/compiler/brw_fs_visitor.cpp b/src/intel/compiler/brw_fs_visitor.cpp index 6ced1b9db62..d8918858a8d 100644 --- a/src/intel/compiler/brw_fs_visitor.cpp +++ b/src/intel/compiler/brw_fs_visitor.cpp @@ -122,6 +122,7 @@ fs_visitor::emit_dummy_fs() wm_prog_data->num_varying_inputs = devinfo->gen < 6 ? 1 : 0; memset(wm_prog_data->urb_setup, -1, sizeof(wm_prog_data->urb_setup[0]) * VARYING_SLOT_MAX); + brw_compute_urb_setup_index(wm_prog_data); /* We don't have any uniforms. */ stage_prog_data->nr_params = 0; @@ -176,12 +177,12 @@ fs_visitor::emit_interpolation_setup_gen4() const fs_reg xstart(negate(brw_vec1_grf(1, 0))); const fs_reg ystart(negate(brw_vec1_grf(1, 1))); - if (devinfo->has_pln && dispatch_width == 16) { - for (unsigned i = 0; i < 2; i++) { - abld.half(i).ADD(half(offset(delta_xy, abld, i), 0), - half(this->pixel_x, i), xstart); - abld.half(i).ADD(half(offset(delta_xy, abld, i), 1), - half(this->pixel_y, i), ystart); + if (devinfo->has_pln) { + for (unsigned i = 0; i < dispatch_width / 8; i++) { + abld.quarter(i).ADD(quarter(offset(delta_xy, abld, 0), i), + quarter(this->pixel_x, i), xstart); + abld.quarter(i).ADD(quarter(offset(delta_xy, abld, 1), i), + quarter(this->pixel_y, i), ystart); } } else { abld.ADD(offset(delta_xy, abld, 0), this->pixel_x, xstart); @@ -241,6 +242,9 @@ brw_rnd_mode_from_nir(unsigned mode, unsigned *mask) if (mode == FLOAT_CONTROLS_DEFAULT_FLOAT_CONTROL_MODE) *mask |= BRW_CR0_FP_MODE_MASK; + if (*mask != 0) + assert((*mask & brw_mode) == brw_mode); + return brw_mode; } @@ -252,8 +256,11 @@ fs_visitor::emit_shader_float_controls_execution_mode() return; fs_builder abld = bld.annotate("shader floats control execution mode"); - unsigned mask = 0; - unsigned mode = brw_rnd_mode_from_nir(execution_mode, &mask); + unsigned mask, mode = brw_rnd_mode_from_nir(execution_mode, &mask); + + if (mask == 0) + return; + abld.emit(SHADER_OPCODE_FLOAT_CONTROL_MODE, bld.null_reg_ud(), brw_imm_d(mode), brw_imm_d(mask)); } @@ -328,8 +335,8 @@ fs_visitor::emit_interpolation_setup_gen6() struct brw_wm_prog_data *wm_prog_data = brw_wm_prog_data(prog_data); for (int i = 0; i < BRW_BARYCENTRIC_MODE_COUNT; ++i) { - this->delta_xy[i] = fetch_payload_reg( - bld, payload.barycentric_coord_reg[i], BRW_REGISTER_TYPE_F, 2); + this->delta_xy[i] = fetch_barycentric_reg( + bld, payload.barycentric_coord_reg[i]); } uint32_t centroid_modes = wm_prog_data->barycentric_interp_modes & @@ -351,15 +358,18 @@ fs_visitor::emit_interpolation_setup_gen6() if (!(centroid_modes & (1 << i))) continue; + const fs_reg centroid_delta_xy = delta_xy[i]; const fs_reg &pixel_delta_xy = delta_xy[i - 1]; - for (unsigned q = 0; q < dispatch_width / 8; q++) { - for (unsigned c = 0; c < 2; c++) { - const unsigned idx = c + (q & 2) + (q & 1) * dispatch_width / 8; - set_predicate_inv( - BRW_PREDICATE_NORMAL, true, - bld.half(q).MOV(horiz_offset(delta_xy[i], idx * 8), - horiz_offset(pixel_delta_xy, idx * 8))); + delta_xy[i] = bld.vgrf(BRW_REGISTER_TYPE_F, 2); + + for (unsigned c = 0; c < 2; c++) { + for (unsigned q = 0; q < dispatch_width / 8; q++) { + set_predicate(BRW_PREDICATE_NORMAL, + bld.quarter(q).SEL( + quarter(offset(delta_xy[i], bld, c), q), + quarter(offset(centroid_delta_xy, bld, c), q), + quarter(offset(pixel_delta_xy, bld, c), q))); } } } @@ -453,88 +463,12 @@ fs_visitor::emit_single_fb_write(const fs_builder &bld, if (prog_data->uses_kill) { write->predicate = BRW_PREDICATE_NORMAL; - write->flag_subreg = 1; + write->flag_subreg = sample_mask_flag_subreg(this); } return write; } -void -fs_visitor::emit_alpha_to_coverage_workaround(const fs_reg &src0_alpha) -{ - /* We need to compute alpha to coverage dithering manually in shader - * and replace sample mask store with the bitwise-AND of sample mask and - * alpha to coverage dithering. - * - * The following formula is used to compute final sample mask: - * m = int(16.0 * clamp(src0_alpha, 0.0, 1.0)) - * dither_mask = 0x1111 * ((0xfea80 >> (m & ~3)) & 0xf) | - * 0x0808 * (m & 2) | 0x0100 * (m & 1) - * sample_mask = sample_mask & dither_mask - * - * It gives a number of ones proportional to the alpha for 2, 4, 8 or 16 - * least significant bits of the result: - * 0.0000 0000000000000000 - * 0.0625 0000000100000000 - * 0.1250 0001000000010000 - * 0.1875 0001000100010000 - * 0.2500 1000100010001000 - * 0.3125 1000100110001000 - * 0.3750 1001100010011000 - * 0.4375 1001100110011000 - * 0.5000 1010101010101010 - * 0.5625 1010101110101010 - * 0.6250 1011101010111010 - * 0.6875 1011101110111010 - * 0.7500 1110111011101110 - * 0.8125 1110111111101110 - * 0.8750 1111111011111110 - * 0.9375 1111111111111110 - * 1.0000 1111111111111111 - */ - const fs_builder abld = bld.annotate("compute alpha_to_coverage & " - "sample_mask"); - - /* clamp(src0_alpha, 0.f, 1.f) */ - const fs_reg float_tmp = abld.vgrf(BRW_REGISTER_TYPE_F); - set_saturate(true, abld.MOV(float_tmp, src0_alpha)); - - /* 16.0 * clamp(src0_alpha, 0.0, 1.0) */ - abld.MUL(float_tmp, float_tmp, brw_imm_f(16.0)); - - /* m = int(16.0 * clamp(src0_alpha, 0.0, 1.0)) */ - const fs_reg m = abld.vgrf(BRW_REGISTER_TYPE_UW); - abld.MOV(m, float_tmp); - - /* 0x1111 * ((0xfea80 >> (m & ~3)) & 0xf) */ - const fs_reg int_tmp_1 = abld.vgrf(BRW_REGISTER_TYPE_UW); - const fs_reg shift_const = abld.vgrf(BRW_REGISTER_TYPE_UD); - abld.MOV(shift_const, brw_imm_d(0xfea80)); - abld.AND(int_tmp_1, m, brw_imm_uw(~3)); - abld.SHR(int_tmp_1, shift_const, int_tmp_1); - abld.AND(int_tmp_1, int_tmp_1, brw_imm_uw(0xf)); - abld.MUL(int_tmp_1, int_tmp_1, brw_imm_uw(0x1111)); - - /* 0x0808 * (m & 2) */ - const fs_reg int_tmp_2 = abld.vgrf(BRW_REGISTER_TYPE_UW); - abld.AND(int_tmp_2, m, brw_imm_uw(2)); - abld.MUL(int_tmp_2, int_tmp_2, brw_imm_uw(0x0808)); - - abld.OR(int_tmp_1, int_tmp_1, int_tmp_2); - - /* 0x0100 * (m & 1) */ - const fs_reg int_tmp_3 = abld.vgrf(BRW_REGISTER_TYPE_UW); - abld.AND(int_tmp_3, m, brw_imm_uw(1)); - abld.MUL(int_tmp_3, int_tmp_3, brw_imm_uw(0x0100)); - - abld.OR(int_tmp_1, int_tmp_1, int_tmp_3); - - /* sample_mask = sample_mask & dither_mask */ - const fs_reg mask = abld.vgrf(BRW_REGISTER_TYPE_UD); - abld.AND(mask, sample_mask, int_tmp_1); - sample_mask = mask; -} - void fs_visitor::emit_fb_writes() { @@ -567,18 +501,10 @@ fs_visitor::emit_fb_writes() * so we compute if we need replicate alpha and emit alpha to coverage * workaround here. */ - prog_data->replicate_alpha = key->alpha_test_replicate_alpha || + const bool replicate_alpha = key->alpha_test_replicate_alpha || (key->nr_color_regions > 1 && key->alpha_to_coverage && (sample_mask.file == BAD_FILE || devinfo->gen == 6)); - /* From the SKL PRM, Volume 7, "Alpha Coverage": - * "If Pixel Shader outputs oMask, AlphaToCoverage is disabled in - * hardware, regardless of the state setting for this feature." - */ - if (devinfo->gen > 6 && key->alpha_to_coverage && - sample_mask.file != BAD_FILE && this->outputs[0].file != BAD_FILE) - emit_alpha_to_coverage_workaround(offset(this->outputs[0], bld, 3)); - for (int target = 0; target < key->nr_color_regions; target++) { /* Skip over outputs that weren't written. */ if (this->outputs[target].file == BAD_FILE) @@ -588,7 +514,7 @@ fs_visitor::emit_fb_writes() ralloc_asprintf(this->mem_ctx, "FB write target %d", target)); fs_reg src0_alpha; - if (devinfo->gen >= 6 && prog_data->replicate_alpha && target != 0) + if (devinfo->gen >= 6 && replicate_alpha && target != 0) src0_alpha = offset(outputs[0], bld, 3); inst = emit_single_fb_write(abld, this->outputs[target], @@ -619,6 +545,23 @@ fs_visitor::emit_fb_writes() inst->last_rt = true; inst->eot = true; + + if (devinfo->gen >= 11 && devinfo->gen <= 12 && + prog_data->dual_src_blend) { + /* The dual-source RT write messages fail to release the thread + * dependency on ICL and TGL with SIMD32 dispatch, leading to hangs. + * + * XXX - Emit an extra single-source NULL RT-write marked LastRT in + * order to release the thread dependency without disabling + * SIMD32. + * + * The dual-source RT write messages may lead to hangs with SIMD16 + * dispatch on ICL due some unknown reasons, see + * https://gitlab.freedesktop.org/mesa/mesa/-/issues/2183 + */ + limit_dispatch_width(8, "Dual source blending unsupported " + "in SIMD16 and SIMD32 modes.\n"); + } } void @@ -767,8 +710,18 @@ fs_visitor::emit_urb_writes(const fs_reg &gs_vertex_count) sources[length++] = reg; } } else { - for (unsigned i = 0; i < 4; i++) - sources[length++] = offset(this->outputs[varying], bld, i); + int slot_offset = 0; + + /* When using Primitive Replication, there may be multiple slots + * assigned to POS. + */ + if (varying == VARYING_SLOT_POS) + slot_offset = slot - vue_map->varying_to_slot[VARYING_SLOT_POS]; + + for (unsigned i = 0; i < 4; i++) { + sources[length++] = offset(this->outputs[varying], bld, + i + (slot_offset * 4)); + } } break; } @@ -892,7 +845,7 @@ fs_visitor::emit_cs_terminate() assert(devinfo->gen >= 7); /* We are getting the thread ID from the compute shader header */ - assert(stage == MESA_SHADER_COMPUTE); + assert(stage == MESA_SHADER_COMPUTE || stage == MESA_SHADER_KERNEL); /* We can't directly send from g0, since sends with EOT have to use * g112-127. So, copy it to a virtual register, The register allocator will @@ -927,7 +880,7 @@ fs_visitor::emit_barrier() } /* We are getting the barrier ID from the compute shader header */ - assert(stage == MESA_SHADER_COMPUTE); + assert(stage == MESA_SHADER_COMPUTE || stage == MESA_SHADER_KERNEL); fs_reg payload = fs_reg(VGRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD); @@ -956,6 +909,8 @@ fs_visitor::fs_visitor(const struct brw_compiler *compiler, void *log_data, : backend_shader(compiler, log_data, mem_ctx, shader, prog_data), key(key), gs_compile(NULL), prog_data(prog_data), input_vue_map(input_vue_map), + live_analysis(this), regpressure_analysis(this), + performance_analysis(this), dispatch_width(dispatch_width), shader_time_index(shader_time_index), bld(fs_builder(this, dispatch_width).at_end()) @@ -973,6 +928,8 @@ fs_visitor::fs_visitor(const struct brw_compiler *compiler, void *log_data, &prog_data->base.base), key(&c->key.base), gs_compile(c), prog_data(&prog_data->base.base), + live_analysis(this), regpressure_analysis(this), + performance_analysis(this), dispatch_width(8), shader_time_index(shader_time_index), bld(fs_builder(this, dispatch_width).at_end()) @@ -984,7 +941,10 @@ fs_visitor::fs_visitor(const struct brw_compiler *compiler, void *log_data, void fs_visitor::init() { - this->key_tex = &key->tex; + if (key) + this->key_tex = &key->tex; + else + this->key_tex = NULL; this->max_dispatch_width = 32; this->prog_data = this->stage_prog_data; @@ -1000,11 +960,6 @@ fs_visitor::init() this->first_non_payload_grf = 0; this->max_grf = devinfo->gen >= 7 ? GEN7_MRF_HACK_START : BRW_MAX_GRF; - this->virtual_grf_start = NULL; - this->virtual_grf_end = NULL; - this->live_intervals = NULL; - this->regs_live_at_ip = NULL; - this->uniforms = 0; this->last_scratch = 0; this->pull_constant_loc = NULL;