X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fbrw_fs_visitor.cpp;h=c89f4d6a05ddc21081b2b8407de047e4affc2799;hb=cf40ebacb113a370c1b2445e881f8dc440a7d8f3;hp=70eb997944283a766070c6691c040349e8558865;hpb=e00b93a1f7b4bc7f5e887591c000524e13f80826;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index 70eb9979442..c89f4d6a05d 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -56,7 +56,7 @@ fs_visitor::visit(ir_variable *ir) if (variable_storage(ir)) return; - if (ir->mode == ir_var_shader_in) { + if (ir->data.mode == ir_var_shader_in) { if (!strcmp(ir->name, "gl_FragCoord")) { reg = emit_fragcoord_interpolation(ir); } else if (!strcmp(ir->name, "gl_FrontFacing")) { @@ -67,27 +67,27 @@ fs_visitor::visit(ir_variable *ir) assert(reg); hash_table_insert(this->variable_ht, reg, ir); return; - } else if (ir->mode == ir_var_shader_out) { + } else if (ir->data.mode == ir_var_shader_out) { reg = new(this->mem_ctx) fs_reg(this, ir->type); - if (ir->index > 0) { - assert(ir->location == FRAG_RESULT_DATA0); - assert(ir->index == 1); + if (ir->data.index > 0) { + assert(ir->data.location == FRAG_RESULT_DATA0); + assert(ir->data.index == 1); this->dual_src_output = *reg; - } else if (ir->location == FRAG_RESULT_COLOR) { + } else if (ir->data.location == FRAG_RESULT_COLOR) { /* Writing gl_FragColor outputs to all color regions. */ for (unsigned int i = 0; i < MAX2(c->key.nr_color_regions, 1); i++) { this->outputs[i] = *reg; this->output_components[i] = 4; } - } else if (ir->location == FRAG_RESULT_DEPTH) { + } else if (ir->data.location == FRAG_RESULT_DEPTH) { this->frag_depth = *reg; - } else if (ir->location == FRAG_RESULT_SAMPLE_MASK) { + } else if (ir->data.location == FRAG_RESULT_SAMPLE_MASK) { this->sample_mask = *reg; } else { /* gl_FragData or a user-defined FS output */ - assert(ir->location >= FRAG_RESULT_DATA0 && - ir->location < FRAG_RESULT_DATA0 + BRW_MAX_DRAW_BUFFERS); + assert(ir->data.location >= FRAG_RESULT_DATA0 && + ir->data.location < FRAG_RESULT_DATA0 + BRW_MAX_DRAW_BUFFERS); int vector_elements = ir->type->is_array() ? ir->type->fields.array->vector_elements @@ -95,14 +95,14 @@ fs_visitor::visit(ir_variable *ir) /* General color output. */ for (unsigned int i = 0; i < MAX2(1, ir->type->length); i++) { - int output = ir->location - FRAG_RESULT_DATA0 + i; + int output = ir->data.location - FRAG_RESULT_DATA0 + i; this->outputs[output] = *reg; this->outputs[output].reg_offset += vector_elements * i; this->output_components[output] = vector_elements; } } - } else if (ir->mode == ir_var_uniform) { - int param_index = c->prog_data.nr_params; + } else if (ir->data.mode == ir_var_uniform) { + int param_index = uniforms; /* Thanks to the lower_ubo_reference pass, we will see only * ir_binop_ubo_load expressions and not ir_dereference_variable for UBO @@ -116,7 +116,7 @@ fs_visitor::visit(ir_variable *ir) if (dispatch_width == 16) { if (!variable_storage(ir)) { - fail("Failed to find uniform '%s' in 16-wide\n", ir->name); + fail("Failed to find uniform '%s' in SIMD16\n", ir->name); } return; } @@ -131,11 +131,13 @@ fs_visitor::visit(ir_variable *ir) reg = new(this->mem_ctx) fs_reg(UNIFORM, param_index); reg->type = brw_type_for_base_type(ir->type); - } else if (ir->mode == ir_var_system_value) { - if (ir->location == SYSTEM_VALUE_SAMPLE_POS) { + } else if (ir->data.mode == ir_var_system_value) { + if (ir->data.location == SYSTEM_VALUE_SAMPLE_POS) { reg = emit_samplepos_setup(ir); - } else if (ir->location == SYSTEM_VALUE_SAMPLE_ID) { + } else if (ir->data.location == SYSTEM_VALUE_SAMPLE_ID) { reg = emit_sampleid_setup(ir); + } else if (ir->data.location == SYSTEM_VALUE_SAMPLE_MASK_IN) { + reg = emit_samplemaskin_setup(ir); } } @@ -210,7 +212,8 @@ fs_visitor::visit(ir_dereference_array *ir) } void -fs_visitor::emit_lrp(fs_reg dst, fs_reg x, fs_reg y, fs_reg a) +fs_visitor::emit_lrp(const fs_reg &dst, const fs_reg &x, const fs_reg &y, + const fs_reg &a) { if (brw->gen < 6 || !x.is_valid_3src() || @@ -223,8 +226,9 @@ fs_visitor::emit_lrp(fs_reg dst, fs_reg x, fs_reg y, fs_reg a) emit(MUL(y_times_a, y, a)); - a.negate = !a.negate; - emit(ADD(one_minus_a, a, fs_reg(1.0f))); + fs_reg negative_a = a; + negative_a.negate = !a.negate; + emit(ADD(one_minus_a, negative_a, fs_reg(1.0f))); emit(MUL(x_times_one_minus_a, x, one_minus_a)); emit(ADD(dst, x_times_one_minus_a, y_times_a)); @@ -237,8 +241,8 @@ fs_visitor::emit_lrp(fs_reg dst, fs_reg x, fs_reg y, fs_reg a) } void -fs_visitor::emit_minmax(uint32_t conditionalmod, fs_reg dst, - fs_reg src0, fs_reg src1) +fs_visitor::emit_minmax(uint32_t conditionalmod, const fs_reg &dst, + const fs_reg &src0, const fs_reg &src1) { fs_inst *inst; @@ -345,8 +349,8 @@ fs_visitor::visit(ir_expression *ir) ir->operands[operand]->accept(this); if (this->result.file == BAD_FILE) { fail("Failed to get tree for expression operand:\n"); - ir->operands[operand]->print(); - printf("\n"); + ir->operands[operand]->fprint(stderr); + fprintf(stderr, "\n"); } assert(this->result.is_valid_3src()); op[operand] = this->result; @@ -454,25 +458,34 @@ fs_visitor::visit(ir_expression *ir) * of one of the operands (src0 on gen6, src1 on gen7). The * MACH accumulates in the contribution of the upper 16 bits * of that operand. - * - * FINISHME: Emit just the MUL if we know an operand is small - * enough. - */ - if (brw->gen >= 7 && dispatch_width == 16) - fail("16-wide explicit accumulator operands unsupported\n"); - - struct brw_reg acc = retype(brw_acc_reg(), this->result.type); - - emit(MUL(acc, op[0], op[1])); - emit(MACH(reg_null_d, op[0], op[1])); - emit(MOV(this->result, fs_reg(acc))); + */ + if (ir->operands[0]->is_uint16_constant()) { + if (brw->gen < 7) + emit(MUL(this->result, op[0], op[1])); + else + emit(MUL(this->result, op[1], op[0])); + } else if (ir->operands[1]->is_uint16_constant()) { + if (brw->gen < 7) + emit(MUL(this->result, op[1], op[0])); + else + emit(MUL(this->result, op[0], op[1])); + } else { + if (brw->gen >= 7) + no16("SIMD16 explicit accumulator operands unsupported\n"); + + struct brw_reg acc = retype(brw_acc_reg(), this->result.type); + + emit(MUL(acc, op[0], op[1])); + emit(MACH(reg_null_d, op[0], op[1])); + emit(MOV(this->result, fs_reg(acc))); + } } else { emit(MUL(this->result, op[0], op[1])); } break; case ir_binop_imul_high: { - if (brw->gen >= 7 && dispatch_width == 16) - fail("16-wide explicit accumulator operands unsupported\n"); + if (brw->gen >= 7) + no16("SIMD16 explicit accumulator operands unsupported\n"); struct brw_reg acc = retype(brw_acc_reg(), this->result.type); @@ -486,8 +499,8 @@ fs_visitor::visit(ir_expression *ir) emit_math(SHADER_OPCODE_INT_QUOTIENT, this->result, op[0], op[1]); break; case ir_binop_carry: { - if (brw->gen >= 7 && dispatch_width == 16) - fail("16-wide explicit accumulator operands unsupported\n"); + if (brw->gen >= 7) + no16("SIMD16 explicit accumulator operands unsupported\n"); struct brw_reg acc = retype(brw_acc_reg(), BRW_REGISTER_TYPE_UD); @@ -496,8 +509,8 @@ fs_visitor::visit(ir_expression *ir) break; } case ir_binop_borrow: { - if (brw->gen >= 7 && dispatch_width == 16) - fail("16-wide explicit accumulator operands unsupported\n"); + if (brw->gen >= 7) + no16("SIMD16 explicit accumulator operands unsupported\n"); struct brw_reg acc = retype(brw_acc_reg(), BRW_REGISTER_TYPE_UD); @@ -739,11 +752,17 @@ fs_visitor::visit(ir_expression *ir) packed_consts.type = result.type; fs_reg const_offset_reg = fs_reg(const_offset->value.u[0] & ~15); - emit(fs_inst(FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD, - packed_consts, surf_index, const_offset_reg)); + emit(new(mem_ctx) fs_inst(FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD, + packed_consts, surf_index, const_offset_reg)); - packed_consts.smear = const_offset->value.u[0] % 16 / 4; for (int i = 0; i < ir->type->vector_elements; i++) { + packed_consts.set_smear(const_offset->value.u[0] % 16 / 4 + i); + + /* The std140 packing rules don't allow vectors to cross 16-byte + * boundaries, and a reg is 32 bytes. + */ + assert(packed_consts.subreg_offset < 32); + /* UBO bools are any nonzero value. We consider bools to be * values with the low bit set to 1. Convert them using CMP. */ @@ -753,13 +772,7 @@ fs_visitor::visit(ir_expression *ir) emit(MOV(result, packed_consts)); } - packed_consts.smear++; result.reg_offset++; - - /* The std140 packing rules don't allow vectors to cross 16-byte - * boundaries, and a reg is 32 bytes. - */ - assert(packed_consts.smear < 8); } } else { /* Turn the byte offset into a dword offset. */ @@ -836,6 +849,7 @@ fs_visitor::emit_assignment_writes(fs_reg &l, fs_reg &r, break; case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_IMAGE: case GLSL_TYPE_ATOMIC_UINT: break; @@ -1212,7 +1226,7 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate, /* sample index */ emit(MOV(fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), sample_index)); mlen += reg_width; - inst = emit(SHADER_OPCODE_TXF_MS, dst); + inst = emit(SHADER_OPCODE_TXF_CMS, dst); break; case ir_lod: inst = emit(SHADER_OPCODE_LOD, dst); @@ -1229,8 +1243,9 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate, inst->header_present = header_present; inst->regs_written = 4; - if (mlen > 11) { - fail("Message length >11 disallowed by hardware\n"); + if (mlen > MAX_SAMPLER_MESSAGE_SIZE) { + fail("Message length >" STRINGIFY(MAX_SAMPLER_MESSAGE_SIZE) + " disallowed by hardware\n"); } return inst; @@ -1239,7 +1254,7 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate, fs_inst * fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, fs_reg shadow_c, fs_reg lod, fs_reg lod2, - fs_reg sample_index, fs_reg mcs) + fs_reg sample_index, fs_reg mcs, int sampler) { int reg_width = dispatch_width / 8; bool header_present = false; @@ -1247,13 +1262,16 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, fs_reg payload = fs_reg(this, glsl_type::float_type); fs_reg next = payload; - if (ir->op == ir_tg4 || (ir->offset && ir->op != ir_txf)) { + if (ir->op == ir_tg4 || (ir->offset && ir->op != ir_txf) || sampler >= 16) { /* For general texture offsets (no txf workaround), we need a header to - * put them in. Note that for 16-wide we're making space for two actual + * put them in. Note that for SIMD16 we're making space for two actual * hardware registers here, so the emit will have to fix up for this. * * * ir4_tg4 needs to place its channel select in the header, * for interaction with ARB_texture_swizzle + * + * The sampler index is only 4-bits, so for larger sampler numbers we + * need to offset the Sampler State Pointer in the header. */ header_present = true; next.reg_offset++; @@ -1281,8 +1299,7 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, next.reg_offset++; break; case ir_txd: { - if (dispatch_width == 16) - fail("Gen7 does not support sample_d/sample_d_c in SIMD16 mode."); + no16("Gen7 does not support sample_d/sample_d_c in SIMD16 mode."); /* Load dPdx and the coordinate together: * [hdr], [ref], x, dPdx.x, dPdy.x, y, dPdx.y, dPdy.y, z, dPdx.z, dPdy.z @@ -1310,24 +1327,24 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, break; } case ir_txs: - emit(MOV(next.retype(BRW_REGISTER_TYPE_UD), lod)); + emit(MOV(retype(next, BRW_REGISTER_TYPE_UD), lod)); next.reg_offset++; break; case ir_query_levels: - emit(MOV(next.retype(BRW_REGISTER_TYPE_UD), fs_reg(0u))); + emit(MOV(retype(next, BRW_REGISTER_TYPE_UD), fs_reg(0u))); next.reg_offset++; break; case ir_txf: /* Unfortunately, the parameters for LD are intermixed: u, lod, v, r. */ - emit(MOV(next.retype(BRW_REGISTER_TYPE_D), coordinate)); + emit(MOV(retype(next, BRW_REGISTER_TYPE_D), coordinate)); coordinate.reg_offset++; next.reg_offset++; - emit(MOV(next.retype(BRW_REGISTER_TYPE_D), lod)); + emit(MOV(retype(next, BRW_REGISTER_TYPE_D), lod)); next.reg_offset++; for (int i = 1; i < ir->coordinate->type->vector_elements; i++) { - emit(MOV(next.retype(BRW_REGISTER_TYPE_D), coordinate)); + emit(MOV(retype(next, BRW_REGISTER_TYPE_D), coordinate)); coordinate.reg_offset++; next.reg_offset++; } @@ -1335,18 +1352,18 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, coordinate_done = true; break; case ir_txf_ms: - emit(MOV(next.retype(BRW_REGISTER_TYPE_UD), sample_index)); + emit(MOV(retype(next, BRW_REGISTER_TYPE_UD), sample_index)); next.reg_offset++; /* data from the multisample control surface */ - emit(MOV(next.retype(BRW_REGISTER_TYPE_UD), mcs)); + emit(MOV(retype(next, BRW_REGISTER_TYPE_UD), mcs)); next.reg_offset++; /* there is no offsetting for this message; just copy in the integer * texture coordinates */ for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { - emit(MOV(next.retype(BRW_REGISTER_TYPE_D), coordinate)); + emit(MOV(retype(next, BRW_REGISTER_TYPE_D), coordinate)); coordinate.reg_offset++; next.reg_offset++; } @@ -1355,8 +1372,8 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, break; case ir_tg4: if (has_nonconstant_offset) { - if (ir->shadow_comparitor && dispatch_width == 16) - fail("Gen7 does not support gather4_po_c in SIMD16 mode."); + if (ir->shadow_comparitor) + no16("Gen7 does not support gather4_po_c in SIMD16 mode."); /* More crazy intermixing */ ir->offset->accept(this); @@ -1369,7 +1386,7 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, } for (int i = 0; i < 2; i++) { /* offu, offv */ - emit(MOV(next.retype(BRW_REGISTER_TYPE_D), offset_value)); + emit(MOV(retype(next, BRW_REGISTER_TYPE_D), offset_value)); offset_value.reg_offset++; next.reg_offset++; } @@ -1402,7 +1419,7 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, case ir_txl: inst = emit(SHADER_OPCODE_TXL, dst, payload); break; case ir_txd: inst = emit(SHADER_OPCODE_TXD, dst, payload); break; case ir_txf: inst = emit(SHADER_OPCODE_TXF, dst, payload); break; - case ir_txf_ms: inst = emit(SHADER_OPCODE_TXF_MS, dst, payload); break; + case ir_txf_ms: inst = emit(SHADER_OPCODE_TXF_CMS, dst, payload); break; case ir_txs: inst = emit(SHADER_OPCODE_TXS, dst, payload); break; case ir_query_levels: inst = emit(SHADER_OPCODE_TXS, dst, payload); break; case ir_lod: inst = emit(SHADER_OPCODE_LOD, dst, payload); break; @@ -1422,8 +1439,9 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, inst->regs_written = 4; virtual_grf_sizes[payload.reg] = next.reg_offset; - if (inst->mlen > 11) { - fail("Message length >11 disallowed by hardware\n"); + if (inst->mlen > MAX_SAMPLER_MESSAGE_SIZE) { + fail("Message length >" STRINGIFY(MAX_SAMPLER_MESSAGE_SIZE) + " disallowed by hardware\n"); } return inst; @@ -1454,19 +1472,19 @@ fs_visitor::rescale_texcoord(ir_texture *ir, fs_reg coordinate, 0 }; + no16("rectangle scale uniform setup not supported on SIMD16\n"); if (dispatch_width == 16) { - fail("rectangle scale uniform setup not supported on 16-wide\n"); return coordinate; } - scale_x = fs_reg(UNIFORM, c->prog_data.nr_params); - scale_y = fs_reg(UNIFORM, c->prog_data.nr_params + 1); + scale_x = fs_reg(UNIFORM, uniforms); + scale_y = fs_reg(UNIFORM, uniforms + 1); GLuint index = _mesa_add_state_reference(params, (gl_state_index *)tokens); - c->prog_data.param[c->prog_data.nr_params++] = + stage_prog_data->param[uniforms++] = &prog->Parameters->ParameterValues[index][0].f; - c->prog_data.param[c->prog_data.nr_params++] = + stage_prog_data->param[uniforms++] = &prog->Parameters->ParameterValues[index][1].f; } @@ -1541,12 +1559,13 @@ fs_visitor::emit_mcs_fetch(ir_texture *ir, fs_reg coordinate, int sampler) /* parameters are: u, v, r, lod; missing parameters are treated as zero */ for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { - emit(MOV(next.retype(BRW_REGISTER_TYPE_D), coordinate)); + emit(MOV(retype(next, BRW_REGISTER_TYPE_D), coordinate)); coordinate.reg_offset++; next.reg_offset++; } fs_inst *inst = emit(SHADER_OPCODE_TXF_MCS, dest, payload); + virtual_grf_sizes[payload.reg] = next.reg_offset; inst->base_mrf = -1; inst->mlen = next.reg_offset * reg_width; inst->header_present = false; @@ -1660,7 +1679,7 @@ fs_visitor::visit(ir_texture *ir) if (brw->gen >= 7) { inst = emit_texture_gen7(ir, dst, coordinate, shadow_comparitor, - lod, lod2, sample_index, mcs); + lod, lod2, sample_index, mcs, sampler); } else if (brw->gen >= 5) { inst = emit_texture_gen5(ir, dst, coordinate, shadow_comparitor, lod, lod2, sample_index); @@ -1691,9 +1710,43 @@ fs_visitor::visit(ir_texture *ir) } } + if (brw->gen == 6 && ir->op == ir_tg4) { + emit_gen6_gather_wa(c->key.tex.gen6_gather_wa[sampler], dst); + } + swizzle_result(ir, dst, sampler); } +/** + * Apply workarounds for Gen6 gather with UINT/SINT + */ +void +fs_visitor::emit_gen6_gather_wa(uint8_t wa, fs_reg dst) +{ + if (!wa) + return; + + int width = (wa & WA_8BIT) ? 8 : 16; + + for (int i = 0; i < 4; i++) { + fs_reg dst_f = retype(dst, BRW_REGISTER_TYPE_F); + /* Convert from UNORM to UINT */ + emit(MUL(dst_f, dst_f, fs_reg((float)((1 << width) - 1)))); + emit(MOV(dst, dst_f)); + + if (wa & WA_SIGN) { + /* Reinterpret the UINT value as a signed INT value by + * shifting the sign bit into place, then shifting back + * preserving sign. + */ + emit(SHL(dst, dst, fs_reg(32 - width))); + emit(ASR(dst, dst, fs_reg(32 - width))); + } + + dst.reg_offset++; + } +} + /** * Set up the gather channel based on the swizzle, for gather4. */ @@ -2138,8 +2191,8 @@ fs_visitor::try_replace_with_sel() void fs_visitor::visit(ir_if *ir) { - if (brw->gen < 6 && dispatch_width == 16) { - fail("Can't support (non-uniform) control flow on 16-wide\n"); + if (brw->gen < 6) { + no16("Can't support (non-uniform) control flow on SIMD16\n"); } /* Don't point the annotation at the if statement, because then it plus @@ -2181,13 +2234,8 @@ fs_visitor::visit(ir_if *ir) void fs_visitor::visit(ir_loop *ir) { - /* Any normative loop bounds should have been lowered by - * lower_bounded_loops(). - */ - assert(ir->normative_bound < 0); - - if (brw->gen < 6 && dispatch_width == 16) { - fail("Can't support (non-uniform) control flow on 16-wide\n"); + if (brw->gen < 6) { + no16("Can't support (non-uniform) control flow on SIMD16\n"); } this->base_ir = NULL; @@ -2224,7 +2272,7 @@ fs_visitor::visit_atomic_counter_intrinsic(ir_call *ir) ir->actual_parameters.get_head()); ir_variable *location = deref->variable_referenced(); unsigned surf_index = (c->prog_data.base.binding_table.abo_start + - location->atomic.buffer_index); + location->data.atomic.buffer_index); /* Calculate the surface offset */ fs_reg offset(this, glsl_type::uint_type); @@ -2235,9 +2283,9 @@ fs_visitor::visit_atomic_counter_intrinsic(ir_call *ir) fs_reg tmp(this, glsl_type::uint_type); emit(MUL(tmp, this->result, ATOMIC_COUNTER_SIZE)); - emit(ADD(offset, tmp, location->atomic.offset)); + emit(ADD(offset, tmp, location->data.atomic.offset)); } else { - offset = location->atomic.offset; + offset = location->data.atomic.offset; } /* Emit the appropriate machine instruction */ @@ -2359,9 +2407,10 @@ fs_visitor::emit_untyped_atomic(unsigned atomic_op, unsigned surf_index, } /* Emit the instruction. */ - fs_inst inst(SHADER_OPCODE_UNTYPED_ATOMIC, dst, atomic_op, surf_index); - inst.base_mrf = 0; - inst.mlen = mlen; + fs_inst *inst = new(mem_ctx) fs_inst(SHADER_OPCODE_UNTYPED_ATOMIC, dst, + atomic_op, surf_index); + inst->base_mrf = 0; + inst->mlen = mlen; emit(inst); } @@ -2392,21 +2441,13 @@ fs_visitor::emit_untyped_surface_read(unsigned surf_index, fs_reg dst, mlen += operand_len; /* Emit the instruction. */ - fs_inst inst(SHADER_OPCODE_UNTYPED_SURFACE_READ, dst, surf_index); - inst.base_mrf = 0; - inst.mlen = mlen; + fs_inst *inst = new(mem_ctx) + fs_inst(SHADER_OPCODE_UNTYPED_SURFACE_READ, dst, surf_index); + inst->base_mrf = 0; + inst->mlen = mlen; emit(inst); } -fs_inst * -fs_visitor::emit(fs_inst inst) -{ - fs_inst *list_inst = new(mem_ctx) fs_inst; - *list_inst = inst; - emit(list_inst); - return list_inst; -} - fs_inst * fs_visitor::emit(fs_inst *inst) { @@ -2616,12 +2657,10 @@ fs_visitor::emit_color_write(int target, int index, int first_color_mrf) inst->saturate = c->key.clamp_fragment_color; pop_force_uncompressed(); - color.sechalf = true; inst = emit(MOV(fs_reg(MRF, first_color_mrf + index + 4, color.type), - color)); + half(color, 1))); inst->force_sechalf = true; inst->saturate = c->key.clamp_fragment_color; - color.sechalf = false; } } } @@ -2694,9 +2733,10 @@ fs_visitor::emit_fb_writes() bool do_dual_src = this->dual_src_output.file != BAD_FILE; bool src0_alpha_to_render_target = false; - if (dispatch_width == 16 && do_dual_src) { - fail("GL_ARB_blend_func_extended not yet supported in 16-wide."); - do_dual_src = false; + if (do_dual_src) { + no16("GL_ARB_blend_func_extended not yet supported in SIMD16."); + if (dispatch_width == 16) + do_dual_src = false; } /* From the Sandy Bridge PRM, volume 4, page 198: @@ -2707,7 +2747,7 @@ fs_visitor::emit_fb_writes() * thread message and on all dual-source messages." */ if (brw->gen >= 6 && - !this->fp->UsesKill && + (brw->is_haswell || brw->gen >= 8 || !this->fp->UsesKill) && !do_dual_src && c->key.nr_color_regions == 1) { header_present = false; @@ -2747,13 +2787,13 @@ fs_visitor::emit_fb_writes() nr += reg_width; if (c->source_depth_to_render_target) { - if (brw->gen == 6 && dispatch_width == 16) { + if (brw->gen == 6) { /* For outputting oDepth on gen6, SIMD8 writes have to be - * used. This would require 8-wide moves of each half to + * used. This would require SIMD8 moves of each half to * message regs, kind of like pre-gen5 SIMD16 FB writes. * Just bail on doing so for now. */ - fail("Missing support for simd16 depth writes on gen6\n"); + no16("Missing support for simd16 depth writes on gen6\n"); } if (prog->OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) { @@ -2804,6 +2844,10 @@ fs_visitor::emit_fb_writes() inst->mlen = nr - base_mrf; inst->eot = true; inst->header_present = header_present; + if ((brw->gen >= 8 || brw->is_haswell) && fp->UsesKill) { + inst->predicate = BRW_PREDICATE_NORMAL; + inst->flag_subreg = 1; + } c->prog_data.dual_src_blend = true; this->current_annotation = NULL; @@ -2849,6 +2893,10 @@ fs_visitor::emit_fb_writes() inst->mlen = nr - base_mrf; inst->eot = eot; inst->header_present = header_present; + if ((brw->gen >= 8 || brw->is_haswell) && fp->UsesKill) { + inst->predicate = BRW_PREDICATE_NORMAL; + inst->flag_subreg = 1; + } } if (c->key.nr_color_regions == 0) { @@ -2866,6 +2914,10 @@ fs_visitor::emit_fb_writes() inst->mlen = nr - base_mrf; inst->eot = true; inst->header_present = header_present; + if ((brw->gen >= 8 || brw->is_haswell) && fp->UsesKill) { + inst->predicate = BRW_PREDICATE_NORMAL; + inst->flag_subreg = 1; + } } this->current_annotation = NULL; @@ -2899,23 +2951,16 @@ fs_visitor::fs_visitor(struct brw_context *brw, struct gl_shader_program *shader_prog, struct gl_fragment_program *fp, unsigned dispatch_width) - : dispatch_width(dispatch_width) + : backend_visitor(brw, shader_prog, &fp->Base, &c->prog_data.base, + MESA_SHADER_FRAGMENT), + dispatch_width(dispatch_width) { this->c = c; - this->brw = brw; this->fp = fp; - this->prog = &fp->Base; - this->shader_prog = shader_prog; - this->prog = &fp->Base; - this->stage_prog_data = &c->prog_data.base; - this->ctx = &brw->ctx; this->mem_ctx = ralloc_context(NULL); - if (shader_prog) - shader = (struct brw_shader *) - shader_prog->_LinkedShaders[MESA_SHADER_FRAGMENT]; - else - shader = NULL; this->failed = false; + this->simd16_unsupported = false; + this->no16_msg = NULL; this->variable_ht = hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare); @@ -2934,15 +2979,18 @@ fs_visitor::fs_visitor(struct brw_context *brw, this->virtual_grf_start = NULL; this->virtual_grf_end = NULL; this->live_intervals = NULL; + this->regs_live_at_ip = NULL; - this->params_remap = NULL; - this->nr_params_remap = 0; + this->uniforms = 0; + this->pull_constant_loc = NULL; + this->push_constant_loc = NULL; this->force_uncompressed_stack = 0; this->spilled_any_registers = false; - memset(&this->param_size, 0, sizeof(this->param_size)); + if (dispatch_width == 8) + this->param_size = rzalloc_array(mem_ctx, int, stage_prog_data->nr_params); } fs_visitor::~fs_visitor()