示例#1
0
void
gen8_vec4_generator::generate_pull_constant_load(vec4_instruction *inst,
                                                 struct brw_reg dst,
                                                 struct brw_reg index,
                                                 struct brw_reg offset)
{
   assert(index.file == BRW_IMMEDIATE_VALUE &&
          index.type == BRW_REGISTER_TYPE_UD);
   uint32_t surf_index = index.dw1.ud;

   assert(offset.file == BRW_GENERAL_REGISTER_FILE);

   /* Each of the 8 channel enables is considered for whether each
    * dword is written.
    */
   gen8_instruction *send = next_inst(BRW_OPCODE_SEND);
   gen8_set_dst(brw, send, dst);
   gen8_set_src0(brw, send, offset);
   gen8_set_dp_message(brw, send, GEN7_SFID_DATAPORT_DATA_CACHE,
                       surf_index,
                       GEN6_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ,
                       0,      /* message control */
                       1,      /* mlen */
                       1,      /* rlen */
                       false,  /* no header */
                       false); /* EOT */

   mark_surface_used(surf_index);
}
示例#2
0
void
gen8_vec4_generator::generate_scratch_write(vec4_instruction *ir,
                                            struct brw_reg dst,
                                            struct brw_reg src,
                                            struct brw_reg index)
{
   struct brw_reg header = brw_vec8_grf(GEN7_MRF_HACK_START + ir->base_mrf, 0);

   MOV_RAW(header, brw_vec8_grf(0, 0));

   generate_oword_dual_block_offsets(brw_message_reg(ir->base_mrf + 1), index);

   MOV(retype(brw_message_reg(ir->base_mrf + 2), BRW_REGISTER_TYPE_D),
       retype(src, BRW_REGISTER_TYPE_D));

   /* Each of the 8 channel enables is considered for whether each
    * dword is written.
    */
   gen8_instruction *send = next_inst(BRW_OPCODE_SEND);
   gen8_set_dst(brw, send, dst);
   gen8_set_src0(brw, send, header);
   gen8_set_pred_control(send, ir->predicate);
   gen8_set_dp_message(brw, send, GEN7_SFID_DATAPORT_DATA_CACHE,
                       255, /* binding table index: stateless access */
                       GEN7_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE,
                       BRW_DATAPORT_OWORD_DUAL_BLOCK_1OWORD,
                       3,      /* mlen */
                       0,      /* rlen */
                       true,   /* header present */
                       false); /* EOT */
}
示例#3
0
void
gen8_vec4_generator::generate_urb_write(vec4_instruction *ir, bool vs)
{
   struct brw_reg header = brw_vec8_grf(GEN7_MRF_HACK_START + ir->base_mrf, 0);

   /* Copy g0. */
   if (vs)
      MOV_RAW(header, brw_vec8_grf(0, 0));

   gen8_instruction *inst;
   if (!(ir->urb_write_flags & BRW_URB_WRITE_USE_CHANNEL_MASKS)) {
      /* Enable Channel Masks in the URB_WRITE_OWORD message header */
      default_state.access_mode = BRW_ALIGN_1;
      inst = OR(retype(brw_vec1_grf(GEN7_MRF_HACK_START + ir->base_mrf, 5),
                       BRW_REGISTER_TYPE_UD),
                retype(brw_vec1_grf(0, 5), BRW_REGISTER_TYPE_UD),
                brw_imm_ud(0xff00));
      gen8_set_mask_control(inst, BRW_MASK_DISABLE);
      default_state.access_mode = BRW_ALIGN_16;
   }

   inst = next_inst(BRW_OPCODE_SEND);
   gen8_set_urb_message(brw, inst, ir->urb_write_flags, ir->mlen, 0, ir->offset,
                        true);
   gen8_set_dst(brw, inst, brw_null_reg());
   gen8_set_src0(brw, inst, header);
}
void
gen8_vec4_generator::generate_untyped_atomic(vec4_instruction *ir,
                                             struct brw_reg dst,
                                             struct brw_reg atomic_op,
                                             struct brw_reg surf_index)
{
   assert(atomic_op.file == BRW_IMMEDIATE_VALUE &&
          atomic_op.type == BRW_REGISTER_TYPE_UD &&
          surf_index.file == BRW_IMMEDIATE_VALUE &&
          surf_index.type == BRW_REGISTER_TYPE_UD);
   assert((atomic_op.dw1.ud & ~0xf) == 0);

   unsigned msg_control =
      atomic_op.dw1.ud | /* Atomic Operation Type: BRW_AOP_* */
      (1 << 5); /* Return data expected */

   gen8_instruction *inst = next_inst(BRW_OPCODE_SEND);
   gen8_set_dst(brw, inst, retype(dst, BRW_REGISTER_TYPE_UD));
   gen8_set_src0(brw, inst, brw_message_reg(ir->base_mrf));
   gen8_set_dp_message(brw, inst, HSW_SFID_DATAPORT_DATA_CACHE_1,
                       surf_index.dw1.ud,
                       HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP_SIMD4X2,
                       msg_control,
                       ir->mlen,
                       1,
                       ir->header_present,
                       false);

   brw_mark_surface_used(&prog_data->base, surf_index.dw1.ud);
}
示例#5
0
gen8_instruction *
gen8_generator::MOV_RAW(struct brw_reg dst, struct brw_reg src0)
{
   gen8_instruction *inst = next_inst(BRW_OPCODE_MOV);
   gen8_set_dst(brw, inst, retype(dst, BRW_REGISTER_TYPE_UD));
   gen8_set_src0(brw, inst, retype(src0, BRW_REGISTER_TYPE_UD));
   gen8_set_mask_control(inst, BRW_MASK_DISABLE);

   return inst;
}
示例#6
0
gen8_instruction *
gen8_generator::math(unsigned math_function,
                     struct brw_reg dst,
                     struct brw_reg src0)
{
   gen8_instruction *inst = next_inst(BRW_OPCODE_MATH);

   assert(src0.hstride == 0 || src0.hstride == dst.hstride);

   gen8_set_math_function(inst, math_function);
   gen8_set_dst(brw, inst, dst);
   gen8_set_src0(brw, inst, src0);
   return inst;
}
示例#7
0
gen8_instruction *
gen8_generator::CMP(struct brw_reg dst, unsigned conditional,
                    struct brw_reg src0, struct brw_reg src1)
{
   gen8_instruction *inst = next_inst(BRW_OPCODE_CMP);
   gen8_set_cond_modifier(inst, conditional);
   /* The CMP instruction appears to behave erratically for floating point
    * sources unless the destination type is also float.  Overriding it to
    * match src0 makes it work in all cases.
    */
   dst.type = src0.type;
   gen8_set_dst(brw, inst, dst);
   gen8_set_src0(brw, inst, src0);
   gen8_set_src1(brw, inst, src1);
   return inst;
}
示例#8
0
static int arch_xap_disasm(char *str, const unsigned char *buf, ut64 seek) {
	struct state *s = get_state();
	struct directive *d;
	memset(s, 0, sizeof(*s));
	s->s_buf = buf;
	s->s_off = seek;
	s->s_out = NULL;
	d = next_inst(s);
	if (d != NULL) {
		xap_decode(s, d);
		strcpy(str, d->d_asm);
		free(d);
	} else *str = '\0';
#if 0
	if (s->s_ff_quirk) {
		sprintf(d->d_asm, "DC\t0x%x", i2u16(&d->d_inst));
		s->s_ff_quirk = 0;
	}
#endif
	return 0;
}
示例#9
0
void
gen8_vec4_generator::generate_gs_thread_end(vec4_instruction *ir)
{
   struct brw_reg src = brw_vec8_grf(GEN7_MRF_HACK_START + ir->base_mrf, 0);
   gen8_instruction *inst;

   /* Enable Channel Masks in the URB_WRITE_HWORD message header */
   default_state.access_mode = BRW_ALIGN_1;
   inst = OR(retype(brw_vec1_grf(GEN7_MRF_HACK_START + ir->base_mrf, 5),
                    BRW_REGISTER_TYPE_UD),
             retype(brw_vec1_grf(0, 5), BRW_REGISTER_TYPE_UD),
             brw_imm_ud(0xff00)); /* could be 0x1100 but shouldn't matter */
   gen8_set_mask_control(inst, BRW_MASK_DISABLE);
   default_state.access_mode = BRW_ALIGN_16;

   /* mlen = 2: g0 header + vertex count */
   inst = next_inst(BRW_OPCODE_SEND);
   gen8_set_urb_message(brw, inst, BRW_URB_WRITE_EOT, 2, 0, 0, true);
   gen8_set_dst(brw, inst, brw_null_reg());
   gen8_set_src0(brw, inst, src);
}
示例#10
0
void
gen8_vec4_generator::generate_untyped_surface_read(vec4_instruction *ir,
                                                   struct brw_reg dst,
                                                   struct brw_reg surf_index)
{
   assert(surf_index.file == BRW_IMMEDIATE_VALUE &&
          surf_index.type == BRW_REGISTER_TYPE_UD);

   gen8_instruction *inst = next_inst(BRW_OPCODE_SEND);
   gen8_set_dst(brw, inst, retype(dst, BRW_REGISTER_TYPE_UD));
   gen8_set_src0(brw, inst, brw_message_reg(ir->base_mrf));
   gen8_set_dp_message(brw, inst, HSW_SFID_DATAPORT_DATA_CACHE_1,
                       surf_index.dw1.ud,
                       HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_READ,
                       0xe, /* enable only the R channel */
                       ir->mlen,
                       1,
                       ir->header_present,
                       false);

   brw_mark_surface_used(&prog_data->base, surf_index.dw1.ud);
}
示例#11
0
gen8_instruction *
gen8_generator::NOP()
{
   return next_inst(BRW_OPCODE_NOP);
}
示例#12
0
gen8_instruction *
gen8_generator::alu3(unsigned opcode,
                     struct brw_reg dst,
                     struct brw_reg src0,
                     struct brw_reg src1,
                     struct brw_reg src2)
{
   /* MRFs haven't existed since Gen7, so we better not be using them. */
   if (dst.file == BRW_MESSAGE_REGISTER_FILE) {
      dst.file = BRW_GENERAL_REGISTER_FILE;
      dst.nr += GEN7_MRF_HACK_START;
   }

   gen8_instruction *inst = next_inst(opcode);
   assert(gen8_access_mode(inst) == BRW_ALIGN_16);

   assert(dst.file == BRW_GENERAL_REGISTER_FILE);
   assert(dst.nr < 128);
   assert(dst.address_mode == BRW_ADDRESS_DIRECT);
   assert(dst.type == BRW_REGISTER_TYPE_F ||
          dst.type == BRW_REGISTER_TYPE_D ||
          dst.type == BRW_REGISTER_TYPE_UD);
   gen8_set_dst_3src_reg_nr(inst, dst.nr);
   gen8_set_dst_3src_subreg_nr(inst, dst.subnr / 16);
   gen8_set_dst_3src_writemask(inst, dst.dw1.bits.writemask);

   assert(src0.file == BRW_GENERAL_REGISTER_FILE);
   assert(src0.address_mode == BRW_ADDRESS_DIRECT);
   assert(src0.nr < 128);
   gen8_set_src0_3src_swizzle(inst, src0.dw1.bits.swizzle);
   gen8_set_src0_3src_subreg_nr(inst, get_3src_subreg_nr(src0));
   gen8_set_src0_3src_rep_ctrl(inst, src0.vstride == BRW_VERTICAL_STRIDE_0);
   gen8_set_src0_3src_reg_nr(inst, src0.nr);
   gen8_set_src0_3src_abs(inst, src0.abs);
   gen8_set_src0_3src_negate(inst, src0.negate);

   assert(src1.file == BRW_GENERAL_REGISTER_FILE);
   assert(src1.address_mode == BRW_ADDRESS_DIRECT);
   assert(src1.nr < 128);
   gen8_set_src1_3src_swizzle(inst, src1.dw1.bits.swizzle);
   gen8_set_src1_3src_subreg_nr(inst, get_3src_subreg_nr(src1));
   gen8_set_src1_3src_rep_ctrl(inst, src1.vstride == BRW_VERTICAL_STRIDE_0);
   gen8_set_src1_3src_reg_nr(inst, src1.nr);
   gen8_set_src1_3src_abs(inst, src1.abs);
   gen8_set_src1_3src_negate(inst, src1.negate);

   assert(src2.file == BRW_GENERAL_REGISTER_FILE);
   assert(src2.address_mode == BRW_ADDRESS_DIRECT);
   assert(src2.nr < 128);
   gen8_set_src2_3src_swizzle(inst, src2.dw1.bits.swizzle);
   gen8_set_src2_3src_subreg_nr(inst, get_3src_subreg_nr(src2));
   gen8_set_src2_3src_rep_ctrl(inst, src2.vstride == BRW_VERTICAL_STRIDE_0);
   gen8_set_src2_3src_reg_nr(inst, src2.nr);
   gen8_set_src2_3src_abs(inst, src2.abs);
   gen8_set_src2_3src_negate(inst, src2.negate);

   /* Set both the source and destination types based on dst.type, ignoring
    * the source register types.  The MAD and LRP emitters both ensure that
    * all register types are float.  The BFE and BFI2 emitters, however, may
    * send us mixed D and UD source types and want us to ignore that.
    */
   switch (dst.type) {
   case BRW_REGISTER_TYPE_F:
      gen8_set_src_3src_type(inst, BRW_3SRC_TYPE_F);
      gen8_set_dst_3src_type(inst, BRW_3SRC_TYPE_F);
      break;
   case BRW_REGISTER_TYPE_D:
      gen8_set_src_3src_type(inst, BRW_3SRC_TYPE_D);
      gen8_set_dst_3src_type(inst, BRW_3SRC_TYPE_D);
      break;
   case BRW_REGISTER_TYPE_UD:
      gen8_set_src_3src_type(inst, BRW_3SRC_TYPE_UD);
      gen8_set_dst_3src_type(inst, BRW_3SRC_TYPE_UD);
      break;
   }

   return inst;
}
示例#13
0
void
gen8_vec4_generator::generate_tex(vec4_instruction *ir, struct brw_reg dst)
{
   int msg_type = 0;

   switch (ir->opcode) {
   case SHADER_OPCODE_TEX:
   case SHADER_OPCODE_TXL:
      if (ir->shadow_compare) {
         msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_LOD_COMPARE;
      } else {
         msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_LOD;
      }
      break;
   case SHADER_OPCODE_TXD:
      if (ir->shadow_compare) {
         msg_type = HSW_SAMPLER_MESSAGE_SAMPLE_DERIV_COMPARE;
      } else {
         msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_DERIVS;
      }
      break;
   case SHADER_OPCODE_TXF:
      msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_LD;
      break;
   case SHADER_OPCODE_TXF_CMS:
      msg_type = GEN7_SAMPLER_MESSAGE_SAMPLE_LD2DMS;
      break;
   case SHADER_OPCODE_TXF_MCS:
      msg_type = GEN7_SAMPLER_MESSAGE_SAMPLE_LD_MCS;
      break;
   case SHADER_OPCODE_TXS:
      msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_RESINFO;
      break;
   case SHADER_OPCODE_TG4:
      if (ir->shadow_compare) {
         msg_type = GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4_C;
      } else {
         msg_type = GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4;
      }
      break;
   case SHADER_OPCODE_TG4_OFFSET:
      if (ir->shadow_compare) {
         msg_type = GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO_C;
      } else {
         msg_type = GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO;
      }
      break;
   default:
      assert(!"should not get here: invalid VS texture opcode");
      break;
   }

   if (ir->header_present) {
      MOV_RAW(retype(brw_message_reg(ir->base_mrf), BRW_REGISTER_TYPE_UD),
              retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD));

      default_state.access_mode = BRW_ALIGN_1;

      if (ir->texture_offset) {
         /* Set the offset bits in DWord 2. */
         MOV_RAW(retype(brw_vec1_reg(MRF, ir->base_mrf, 2),
                        BRW_REGISTER_TYPE_UD),
                 brw_imm_ud(ir->texture_offset));
      }

      if (ir->sampler >= 16) {
         /* The "Sampler Index" field can only store values between 0 and 15.
          * However, we can add an offset to the "Sampler State Pointer"
          * field, effectively selecting a different set of 16 samplers.
          *
          * The "Sampler State Pointer" needs to be aligned to a 32-byte
          * offset, and each sampler state is only 16-bytes, so we can't
          * exclusively use the offset - we have to use both.
          */
         gen8_instruction *add =
            ADD(get_element_ud(brw_message_reg(ir->base_mrf), 3),
                get_element_ud(brw_vec8_grf(0, 0), 3),
                brw_imm_ud(16 * (ir->sampler / 16) *
                           sizeof(gen7_sampler_state)));
         gen8_set_mask_control(add, BRW_MASK_DISABLE);
      }

      default_state.access_mode = BRW_ALIGN_16;
   }

   uint32_t surf_index =
      prog_data->base.binding_table.texture_start + ir->sampler;

   gen8_instruction *inst = next_inst(BRW_OPCODE_SEND);
   gen8_set_dst(brw, inst, dst);
   gen8_set_src0(brw, inst, brw_message_reg(ir->base_mrf));
   gen8_set_sampler_message(brw, inst,
                            surf_index,
                            ir->sampler % 16,
                            msg_type,
                            1,
                            ir->mlen,
                            ir->header_present,
                            BRW_SAMPLER_SIMD_MODE_SIMD4X2);

   mark_surface_used(surf_index);
}