[Mesa-dev] [RFC 4/7] i965/fs: Add DWord scattered read/write opcodes
Jason Ekstrand
jason at jlekstrand.net
Mon Dec 5 19:59:55 UTC 2016
---
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
More information about the mesa-dev
mailing list