Exemplo n.º 1
0
void
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;

   if (intel->gen == 7) {
      gen6_resolve_implied_move(p, &offset, inst->base_mrf);
      brw_instruction *insn = brw_next_insn(p, BRW_OPCODE_SEND);
      brw_set_dest(p, insn, dst);
      brw_set_src0(p, insn, offset);
      brw_set_sampler_message(p, insn,
                              surf_index,
                              0, /* LD message ignores sampler unit */
                              GEN5_SAMPLER_MESSAGE_SAMPLE_LD,
                              1, /* rlen */
                              1, /* mlen */
                              false, /* no header */
                              BRW_SAMPLER_SIMD_MODE_SIMD4X2,
                              0);
      return;
   }

   struct brw_reg header = brw_vec8_grf(0, 0);

   gen6_resolve_implied_move(p, &header, inst->base_mrf);

   brw_MOV(p, retype(brw_message_reg(inst->base_mrf + 1), BRW_REGISTER_TYPE_D),
	   offset);

   uint32_t msg_type;

   if (intel->gen >= 6)
      msg_type = GEN6_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ;
   else if (intel->gen == 5 || intel->is_g4x)
      msg_type = G45_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ;
   else
      msg_type = BRW_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ;

   /* Each of the 8 channel enables is considered for whether each
    * dword is written.
    */
   struct brw_instruction *send = brw_next_insn(p, BRW_OPCODE_SEND);
   brw_set_dest(p, send, dst);
   brw_set_src0(p, send, header);
   if (intel->gen < 6)
      send->header.destreg__conditionalmod = inst->base_mrf;
   brw_set_dp_read_message(p, send,
			   surf_index,
			   BRW_DATAPORT_OWORD_DUAL_BLOCK_1OWORD,
			   msg_type,
			   BRW_DATAPORT_READ_TARGET_DATA_CACHE,
			   2, /* mlen */
			   1 /* rlen */);
}
Exemplo n.º 2
0
void
vec4_generator::generate_pull_constant_load(vec4_instruction *inst,
        struct brw_reg dst,
        struct brw_reg index,
        struct brw_reg offset)
{
    assert(brw->gen <= 7);
    assert(index.file == BRW_IMMEDIATE_VALUE &&
           index.type == BRW_REGISTER_TYPE_UD);
    uint32_t surf_index = index.dw1.ud;

    struct brw_reg header = brw_vec8_grf(0, 0);

    gen6_resolve_implied_move(p, &header, inst->base_mrf);

    brw_MOV(p, retype(brw_message_reg(inst->base_mrf + 1), BRW_REGISTER_TYPE_D),
            offset);

    uint32_t msg_type;

    if (brw->gen >= 6)
        msg_type = GEN6_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ;
    else if (brw->gen == 5 || brw->is_g4x)
        msg_type = G45_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ;
    else
        msg_type = BRW_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ;

    /* Each of the 8 channel enables is considered for whether each
     * dword is written.
     */
    struct brw_instruction *send = brw_next_insn(p, BRW_OPCODE_SEND);
    brw_set_dest(p, send, dst);
    brw_set_src0(p, send, header);
    if (brw->gen < 6)
        send->header.destreg__conditionalmod = inst->base_mrf;
    brw_set_dp_read_message(p, send,
                            surf_index,
                            BRW_DATAPORT_OWORD_DUAL_BLOCK_1OWORD,
                            msg_type,
                            BRW_DATAPORT_READ_TARGET_DATA_CACHE,
                            2, /* mlen */
                            true, /* header_present */
                            1 /* rlen */);

    brw_mark_surface_used(&prog_data->base, surf_index);
}
Exemplo n.º 3
0
void
vec4_generator::generate_scratch_read(vec4_instruction *inst,
                                      struct brw_reg dst,
                                      struct brw_reg index)
{
    struct brw_reg header = brw_vec8_grf(0, 0);

    gen6_resolve_implied_move(p, &header, inst->base_mrf);

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

    uint32_t msg_type;

    if (brw->gen >= 6)
        msg_type = GEN6_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ;
    else if (brw->gen == 5 || brw->is_g4x)
        msg_type = G45_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ;
    else
        msg_type = BRW_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ;

    /* Each of the 8 channel enables is considered for whether each
     * dword is written.
     */
    struct brw_instruction *send = brw_next_insn(p, BRW_OPCODE_SEND);
    brw_set_dest(p, send, dst);
    brw_set_src0(p, send, header);
    if (brw->gen < 6)
        send->header.destreg__conditionalmod = inst->base_mrf;
    brw_set_dp_read_message(p, send,
                            255, /* binding table index: stateless access */
                            BRW_DATAPORT_OWORD_DUAL_BLOCK_1OWORD,
                            msg_type,
                            BRW_DATAPORT_READ_TARGET_RENDER_CACHE,
                            2, /* mlen */
                            true, /* header_present */
                            1 /* rlen */);
}
Exemplo n.º 4
0
void
vec4_generator::generate_scratch_write(vec4_instruction *inst,
                                       struct brw_reg dst,
                                       struct brw_reg src,
                                       struct brw_reg index)
{
    struct brw_reg header = brw_vec8_grf(0, 0);
    bool write_commit;

    /* If the instruction is predicated, we'll predicate the send, not
     * the header setup.
     */
    brw_set_predicate_control(p, false);

    gen6_resolve_implied_move(p, &header, inst->base_mrf);

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

    brw_MOV(p,
            retype(brw_message_reg(inst->base_mrf + 2), BRW_REGISTER_TYPE_D),
            retype(src, BRW_REGISTER_TYPE_D));

    uint32_t msg_type;

    if (brw->gen >= 7)
        msg_type = GEN7_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE;
    else if (brw->gen == 6)
        msg_type = GEN6_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE;
    else
        msg_type = BRW_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE;

    brw_set_predicate_control(p, inst->predicate);

    /* Pre-gen6, we have to specify write commits to ensure ordering
     * between reads and writes within a thread.  Afterwards, that's
     * guaranteed and write commits only matter for inter-thread
     * synchronization.
     */
    if (brw->gen >= 6) {
        write_commit = false;
    } else {
        /* The visitor set up our destination register to be g0.  This
         * means that when the next read comes along, we will end up
         * reading from g0 and causing a block on the write commit.  For
         * write-after-read, we are relying on the value of the previous
         * read being used (and thus blocking on completion) before our
         * write is executed.  This means we have to be careful in
         * instruction scheduling to not violate this assumption.
         */
        write_commit = true;
    }

    /* Each of the 8 channel enables is considered for whether each
     * dword is written.
     */
    struct brw_instruction *send = brw_next_insn(p, BRW_OPCODE_SEND);
    brw_set_dest(p, send, dst);
    brw_set_src0(p, send, header);
    if (brw->gen < 6)
        send->header.destreg__conditionalmod = inst->base_mrf;
    brw_set_dp_write_message(p, send,
                             255, /* binding table index: stateless access */
                             BRW_DATAPORT_OWORD_DUAL_BLOCK_1OWORD,
                             msg_type,
                             3, /* mlen */
                             true, /* header present */
                             false, /* not a render target write */
                             write_commit, /* rlen */
                             false, /* eot */
                             write_commit);
}