intel/blorp: Take a destination swizzle in blorp_blit
[mesa.git] / src / mesa / drivers / dri / i965 / brw_fs_generator.cpp
index 9d7ad5ba24f7af261a602c1ab381cc0b78e791a1..2f4ba7b55929c4a0e8f1fec1d4d75e26d0544fc9 100644 (file)
@@ -56,6 +56,7 @@ brw_file_from_reg(fs_reg *reg)
 static struct brw_reg
 brw_reg_from_fs_reg(fs_inst *inst, fs_reg *reg, unsigned gen, bool compressed)
 {
+   assert(reg->reg_offset == 0);
    struct brw_reg brw_reg;
 
    switch (reg->file) {
@@ -103,6 +104,7 @@ brw_reg_from_fs_reg(fs_inst *inst, fs_reg *reg, unsigned gen, bool compressed)
    case ARF:
    case FIXED_GRF:
    case IMM:
+      assert(reg->subreg_offset == 0);
       brw_reg = reg->as_brw_reg();
       break;
    case BAD_FILE:
@@ -212,7 +214,7 @@ fs_generator::fire_fb_write(fs_inst *inst,
    if (inst->opcode == FS_OPCODE_REP_FB_WRITE)
       msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE_REPLICATED;
    else if (prog_data->dual_src_blend) {
-      if (!inst->force_sechalf)
+      if (!inst->group)
          msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN01;
       else
          msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN23;
@@ -229,7 +231,6 @@ fs_generator::fire_fb_write(fs_inst *inst,
 
 
    brw_fb_WRITE(p,
-                dispatch_width,
                 payload,
                 implied_header,
                 msg_control,
@@ -352,6 +353,22 @@ fs_generator::generate_fb_write(fs_inst *inst, struct brw_reg payload)
    }
 }
 
+void
+fs_generator::generate_fb_read(fs_inst *inst, struct brw_reg dst,
+                               struct brw_reg payload)
+{
+   brw_wm_prog_data *prog_data =
+      reinterpret_cast<brw_wm_prog_data *>(this->prog_data);
+   const unsigned surf_index =
+      prog_data->binding_table.render_target_start + inst->target;
+
+   gen9_fb_READ(p, dst, payload, surf_index,
+                inst->header_size, inst->regs_written,
+                prog_data->persample_dispatch);
+
+   brw_mark_surface_used(&prog_data->base, surf_index);
+}
+
 void
 fs_generator::generate_mov_indirect(fs_inst *inst,
                                     struct brw_reg dst,
@@ -439,7 +456,7 @@ fs_generator::generate_urb_read(fs_inst *inst,
    assert(header.type == BRW_REGISTER_TYPE_UD);
 
    brw_inst *send = brw_next_insn(p, BRW_OPCODE_SEND);
-   brw_set_dest(p, send, dst);
+   brw_set_dest(p, send, retype(dst, BRW_REGISTER_TYPE_UD));
    brw_set_src0(p, send, header);
    brw_set_src1(p, send, brw_imm_ud(0u));
 
@@ -547,7 +564,7 @@ fs_generator::generate_linterp(fs_inst *inst,
     * See also: emit_interpolation_setup_gen4().
     */
    struct brw_reg delta_x = src[0];
-   struct brw_reg delta_y = offset(src[0], dispatch_width / 8);
+   struct brw_reg delta_y = offset(src[0], inst->exec_size / 8);
    struct brw_reg interp = src[1];
 
    if (devinfo->has_pln &&
@@ -1052,28 +1069,44 @@ fs_generator::generate_discard_jump(fs_inst *inst)
     * current block (or the program).
     */
    this->discard_halt_patches.push_tail(new(mem_ctx) ip_record(p->nr_insn));
-
-   brw_push_insn_state(p);
-   brw_set_default_mask_control(p, BRW_MASK_DISABLE);
    gen6_HALT(p);
-   brw_pop_insn_state(p);
 }
 
 void
 fs_generator::generate_scratch_write(fs_inst *inst, struct brw_reg src)
 {
+   /* The 32-wide messages only respect the first 16-wide half of the channel
+    * enable signals which are replicated identically for the second group of
+    * 16 channels, so we cannot use them unless the write is marked
+    * force_writemask_all.
+    */
+   const unsigned lower_size = inst->force_writemask_all ? inst->exec_size :
+                               MIN2(16, inst->exec_size);
+   const unsigned block_size = 4 * lower_size / REG_SIZE;
    assert(inst->mlen != 0);
 
-   brw_MOV(p,
-          brw_uvec_mrf(inst->exec_size, (inst->base_mrf + 1), 0),
-          retype(src, BRW_REGISTER_TYPE_UD));
-   brw_oword_block_write_scratch(p, brw_message_reg(inst->base_mrf),
-                                 inst->exec_size / 8, inst->offset);
+   brw_push_insn_state(p);
+   brw_set_default_exec_size(p, cvt(lower_size) - 1);
+   brw_set_default_compression(p, lower_size > 8);
+
+   for (unsigned i = 0; i < inst->exec_size / lower_size; i++) {
+      brw_set_default_group(p, inst->group + lower_size * i);
+
+      brw_MOV(p, brw_uvec_mrf(lower_size, inst->base_mrf + 1, 0),
+              retype(offset(src, block_size * i), BRW_REGISTER_TYPE_UD));
+
+      brw_oword_block_write_scratch(p, brw_message_reg(inst->base_mrf),
+                                    block_size,
+                                    inst->offset + block_size * REG_SIZE * i);
+   }
+
+   brw_pop_insn_state(p);
 }
 
 void
 fs_generator::generate_scratch_read(fs_inst *inst, struct brw_reg dst)
 {
+   assert(inst->exec_size <= 16 || inst->force_writemask_all);
    assert(inst->mlen != 0);
 
    brw_oword_block_read_scratch(p, dst, brw_message_reg(inst->base_mrf),
@@ -1083,6 +1116,8 @@ fs_generator::generate_scratch_read(fs_inst *inst, struct brw_reg dst)
 void
 fs_generator::generate_scratch_read_gen7(fs_inst *inst, struct brw_reg dst)
 {
+   assert(inst->exec_size <= 16 || inst->force_writemask_all);
+
    gen7_block_read_scratch(p, dst, inst->exec_size / 8, inst->offset);
 }
 
@@ -1154,7 +1189,7 @@ fs_generator::generate_uniform_pull_constant_load_gen7(fs_inst *inst,
       brw_inst_set_exec_size(devinfo, send, BRW_EXECUTE_4);
       brw_pop_insn_state(p);
 
-      brw_set_dest(p, send, dst);
+      brw_set_dest(p, send, retype(dst, BRW_REGISTER_TYPE_UD));
       brw_set_src0(p, send, src);
       brw_set_sampler_message(p, send,
                               surf_index,
@@ -1211,10 +1246,11 @@ fs_generator::generate_varying_pull_constant_load_gen4(fs_inst *inst,
    uint32_t surf_index = index.ud;
 
    uint32_t simd_mode, rlen, msg_type;
-   if (dispatch_width == 16) {
+   if (inst->exec_size == 16) {
       simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD16;
       rlen = 8;
    } else {
+      assert(inst->exec_size == 8);
       simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD8;
       rlen = 4;
    }
@@ -1272,11 +1308,12 @@ fs_generator::generate_varying_pull_constant_load_gen7(fs_inst *inst,
    assert(index.type == BRW_REGISTER_TYPE_UD);
 
    uint32_t simd_mode, rlen, mlen;
-   if (dispatch_width == 16) {
+   if (inst->exec_size == 16) {
       mlen = 2;
       rlen = 8;
       simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD16;
    } else {
+      assert(inst->exec_size == 8);
       mlen = 1;
       rlen = 4;
       simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD8;
@@ -1412,9 +1449,9 @@ fs_generator::generate_set_sample_id(fs_inst *inst,
           src0.type == BRW_REGISTER_TYPE_UD);
 
    struct brw_reg reg = stride(src1, 1, 4, 0);
-   if (devinfo->gen >= 8 || dispatch_width == 8) {
+   if (devinfo->gen >= 8 || inst->exec_size == 8) {
       brw_ADD(p, dst, src0, reg);
-   } else if (dispatch_width == 16) {
+   } else if (inst->exec_size == 16) {
       brw_push_insn_state(p);
       brw_set_default_exec_size(p, BRW_EXECUTE_8);
       brw_set_default_compression_control(p, BRW_COMPRESSION_NONE);
@@ -1597,7 +1634,7 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
       const bool compressed =
            inst->dst.component_size(inst->exec_size) > REG_SIZE;
       brw_set_default_compression(p, compressed);
-      brw_set_default_group(p, inst->force_sechalf ? 8 : 0);
+      brw_set_default_group(p, inst->group);
 
       for (unsigned int i = 0; i < inst->sources; i++) {
          src[i] = brw_reg_from_fs_reg(inst, &inst->src[i], devinfo->gen,
@@ -1624,7 +1661,8 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
       brw_set_default_acc_write_control(p, inst->writes_accumulator);
       brw_set_default_exec_size(p, cvt(inst->exec_size) - 1);
 
-      assert(inst->force_writemask_all || inst->exec_size >= 8);
+      assert(inst->force_writemask_all || inst->exec_size >= 4);
+      assert(inst->force_writemask_all || inst->group % inst->exec_size == 0);
       assert(inst->base_mrf + inst->mlen <= BRW_MAX_MRF(devinfo->gen));
       assert(inst->mlen <= BRW_MAX_MSG_LENGTH);
 
@@ -1735,6 +1773,9 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
          /* FBL only supports UD type for dst. */
          brw_FBL(p, retype(dst, BRW_REGISTER_TYPE_UD), src[0]);
          break;
+      case BRW_OPCODE_LZD:
+         brw_LZD(p, dst, src[0]);
+         break;
       case BRW_OPCODE_CBIT:
          assert(devinfo->gen >= 7);
          /* CBIT only supports UD type for dst. */
@@ -1940,6 +1981,10 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
         generate_fb_write(inst, src[0]);
         break;
 
+      case FS_OPCODE_FB_READ:
+         generate_fb_read(inst, dst, src[0]);
+         break;
+
       case FS_OPCODE_MOV_DISPATCH_TO_FLAGS:
          generate_mov_dispatch_to_flags(inst);
          break;
@@ -2000,6 +2045,7 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
          break;
 
       case SHADER_OPCODE_BROADCAST:
+         assert(inst->force_writemask_all);
          brw_broadcast(p, dst, src[0], src[1]);
          break;
 
@@ -2027,11 +2073,6 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
          }
          break;
 
-      case FS_OPCODE_INTERPOLATE_AT_CENTROID:
-         generate_pixel_interpolator_query(inst, dst, src[0], src[1],
-                                           GEN7_PIXEL_INTERPOLATOR_LOC_CENTROID);
-         break;
-
       case FS_OPCODE_INTERPOLATE_AT_SAMPLE:
          generate_pixel_interpolator_query(inst, dst, src[0], src[1],
                                            GEN7_PIXEL_INTERPOLATOR_LOC_SAMPLE);
@@ -2055,6 +2096,13 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
         generate_barrier(inst, src[0]);
         break;
 
+      case BRW_OPCODE_DIM:
+         assert(devinfo->is_haswell);
+         assert(src[0].type == BRW_REGISTER_TYPE_DF);
+         assert(dst.type == BRW_REGISTER_TYPE_DF);
+         brw_DIM(p, dst, retype(src[0], BRW_REGISTER_TYPE_F));
+         break;
+
       default:
          unreachable("Unsupported opcode");
 
@@ -2079,7 +2127,7 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
       }
    }
 
-   brw_set_uip_jip(p);
+   brw_set_uip_jip(p, start_offset);
    annotation_finalize(&annotation, p->next_insn_offset);
 
 #ifndef NDEBUG