--- src/mesa/drivers/dri/i965/brw_defines.h | 2 + src/mesa/drivers/dri/i965/brw_fs.cpp | 2 + src/mesa/drivers/dri/i965/brw_fs.h | 3 + src/mesa/drivers/dri/i965/brw_fs_generator.cpp | 142 +++++++++++++++++++++++++ src/mesa/drivers/dri/i965/brw_shader.cpp | 5 + 5 files changed, 154 insertions(+)
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index 16a72c4..1fd0b94 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -1063,6 +1063,8 @@ enum opcode { SHADER_OPCODE_GEN4_SCRATCH_READ, SHADER_OPCODE_GEN4_SCRATCH_WRITE, SHADER_OPCODE_GEN7_SCRATCH_READ, + SHADER_OPCODE_DWORD_SCATTERED_READ, + SHADER_OPCODE_DWORD_SCATTERED_WRITE, /** * Gen8+ SIMD8 URB Read messages. diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index c218f56..8d47638 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -792,6 +792,8 @@ fs_inst::size_read(int arg) const switch (opcode) { case FS_OPCODE_FB_WRITE: case FS_OPCODE_FB_READ: + case SHADER_OPCODE_DWORD_SCATTERED_READ: + case SHADER_OPCODE_DWORD_SCATTERED_WRITE: case SHADER_OPCODE_URB_WRITE_SIMD8: case SHADER_OPCODE_URB_WRITE_SIMD8_PER_SLOT: case SHADER_OPCODE_URB_WRITE_SIMD8_MASKED: diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 4ce0f56..d34428b 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -415,6 +415,9 @@ private: void generate_scratch_write(fs_inst *inst, struct brw_reg src); void generate_scratch_read(fs_inst *inst, struct brw_reg dst); void generate_scratch_read_gen7(fs_inst *inst, struct brw_reg dst); + void generate_dword_scattered_read(fs_inst *inst, struct brw_reg dst, + struct brw_reg payload); + void generate_dword_scattered_write(fs_inst *inst, struct brw_reg payload); void generate_uniform_pull_constant_load(fs_inst *inst, struct brw_reg dst, struct brw_reg index, struct brw_reg offset); diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp index 3ef2d5b..1f753c1 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp @@ -1122,6 +1122,140 @@ fs_generator::generate_scratch_read_gen7(fs_inst *inst, struct brw_reg dst) } void +fs_generator::generate_dword_scattered_read(fs_inst *inst, struct brw_reg dst, + struct brw_reg payload) +{ + assert(inst->mlen != 0); + + uint32_t msg_control; + int rlen; + + struct brw_reg mrf; + if (devinfo->gen >= 7) { + mrf = retype(payload, BRW_REGISTER_TYPE_UD); + } else { + mrf = retype(brw_message_reg(inst->base_mrf), BRW_REGISTER_TYPE_UD); + } + + if (inst->exec_size == 8) { + msg_control = BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS; + rlen = 1; + } else { + msg_control = BRW_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS; + rlen = 2; + } + + unsigned msg_type; + if (devinfo->gen >= 7) { + msg_type = GEN7_DATAPORT_DC_DWORD_SCATTERED_READ; + } else if (devinfo->gen > 4 || devinfo->is_g4x) { + msg_type = G45_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ; + } else { + msg_type = BRW_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ; + } + + brw_inst *insn = brw_next_insn(p, BRW_OPCODE_SEND); + + assert(brw_inst_pred_control(devinfo, insn) == 0); + brw_inst_set_qtr_control(devinfo, insn, BRW_COMPRESSION_NONE); + + brw_set_dest(p, insn, retype(dst, BRW_REGISTER_TYPE_UD)); /* UW? */ + if (devinfo->gen >= 6) { + brw_set_src0(p, insn, mrf); + } else { + brw_set_src0(p, insn, brw_null_reg()); + brw_inst_set_base_mrf(devinfo, insn, inst->base_mrf); + } + + const unsigned target_cache = devinfo->gen >= 7 ? + BRW_DATAPORT_READ_TARGET_DATA_CACHE : + BRW_DATAPORT_READ_TARGET_RENDER_CACHE; + + brw_set_dp_read_message(p, + insn, + brw_scratch_surface_idx(p), + msg_control, + msg_type, /* msg_type */ + target_cache, + inst->mlen, /* msg_length */ + true, /* header_present */ + rlen); +} + +void +fs_generator::generate_dword_scattered_write(fs_inst *inst, + struct brw_reg payload) +{ + assert(inst->mlen != 0); + + struct brw_reg mrf; + if (devinfo->gen >= 7) { + mrf = retype(payload, BRW_REGISTER_TYPE_UD); + } else { + mrf = retype(brw_message_reg(inst->base_mrf), BRW_REGISTER_TYPE_UD); + } + + uint32_t msg_control; + if (inst->exec_size == 8) { + msg_control = BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS; + } else { + msg_control = BRW_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS; + } + + unsigned msg_type; + if (devinfo->gen >= 6) { + msg_type = GEN6_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE; + } else { + msg_type = BRW_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE; + } + + brw_inst *insn = brw_next_insn(p, BRW_OPCODE_SEND); + + assert(brw_inst_pred_control(devinfo, insn) == 0); + brw_inst_set_qtr_control(devinfo, insn, BRW_COMPRESSION_NONE); + + /* Until gen6, writes followed by reads from the same location + * are not guaranteed to be ordered unless write_commit is set. + * If set, then a no-op write is issued to the destination + * register to set a dependency, and a read from the destination + * can be used to ensure the ordering. + * + * For gen6, only writes between different threads need ordering + * protection. Our use of DP writes is all about register + * spilling within a thread. + */ + int send_commit_msg; + struct brw_reg dest; + if (devinfo->gen >= 6) { + dest = vec16(brw_null_reg()); + send_commit_msg = 0; + } else { + dest = brw_vec16_grf(0, 0); + send_commit_msg = 1; + } + brw_set_dest(p, insn, retype(dest, BRW_REGISTER_TYPE_UW)); + + if (devinfo->gen >= 6) { + brw_set_src0(p, insn, mrf); + } else { + brw_set_src0(p, insn, brw_null_reg()); + brw_inst_set_base_mrf(devinfo, insn, inst->base_mrf); + } + + brw_set_dp_write_message(p, + insn, + brw_scratch_surface_idx(p), + msg_control, + msg_type, /* msg_type */ + inst->mlen, /* msg_length */ + true, /* header_present */ + 0, /* not a render target */ + send_commit_msg, /* rlen */ + 0, /* EOT */ + send_commit_msg); +} + +void fs_generator::generate_uniform_pull_constant_load(fs_inst *inst, struct brw_reg dst, struct brw_reg index, @@ -1967,6 +2101,14 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width) fill_count++; break; + case SHADER_OPCODE_DWORD_SCATTERED_READ: + generate_dword_scattered_read(inst, dst, src[0]); + break; + + case SHADER_OPCODE_DWORD_SCATTERED_WRITE: + generate_dword_scattered_write(inst, src[0]); + break; + case SHADER_OPCODE_MOV_INDIRECT: generate_mov_indirect(inst, dst, src[0], src[1]); break; diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp index 726bc7d..79fbb96 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.cpp +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp @@ -298,6 +298,10 @@ brw_instruction_name(const struct gen_device_info *devinfo, enum opcode op) return "gen4_scratch_write"; case SHADER_OPCODE_GEN7_SCRATCH_READ: return "gen7_scratch_read"; + case SHADER_OPCODE_DWORD_SCATTERED_READ: + return "dword_scattered_read"; + case SHADER_OPCODE_DWORD_SCATTERED_WRITE: + return "dword_scattered_write"; case SHADER_OPCODE_URB_WRITE_SIMD8: return "gen8_urb_write_simd8"; case SHADER_OPCODE_URB_WRITE_SIMD8_PER_SLOT: @@ -1005,6 +1009,7 @@ backend_instruction::has_side_effects() const case SHADER_OPCODE_UNTYPED_ATOMIC: case SHADER_OPCODE_UNTYPED_ATOMIC_LOGICAL: case SHADER_OPCODE_GEN4_SCRATCH_WRITE: + case SHADER_OPCODE_DWORD_SCATTERED_WRITE: case SHADER_OPCODE_UNTYPED_SURFACE_WRITE: case SHADER_OPCODE_UNTYPED_SURFACE_WRITE_LOGICAL: case SHADER_OPCODE_TYPED_ATOMIC: -- 2.5.0.400.gff86faf _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev