summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri')
-rw-r--r--src/mesa/drivers/dri/i965/brw_defines.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_shader.cpp3
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.cpp12
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_generator.cpp35
4 files changed, 52 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index ed94bcc5bbf..fa473d08ef6 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -908,6 +908,8 @@ enum opcode {
SHADER_OPCODE_GEN4_SCRATCH_WRITE,
SHADER_OPCODE_GEN7_SCRATCH_READ,
+ VEC4_OPCODE_PACK_BYTES,
+
FS_OPCODE_DDX,
FS_OPCODE_DDY,
FS_OPCODE_PIXEL_X,
diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
index b694b6d0d17..61ea2079140 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.cpp
+++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
@@ -447,6 +447,9 @@ brw_instruction_name(enum opcode op)
case SHADER_OPCODE_GEN7_SCRATCH_READ:
return "gen7_scratch_read";
+ case VEC4_OPCODE_PACK_BYTES:
+ return "pack_bytes";
+
case FS_OPCODE_DDX:
return "ddx";
case FS_OPCODE_DDY:
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index db6f6a38ffa..534b4b0668f 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -352,6 +352,12 @@ vec4_visitor::opt_reduce_swizzle()
/* Determine which channels of the sources are read. */
switch (inst->opcode) {
+ case VEC4_OPCODE_PACK_BYTES:
+ swizzle[0] = 0;
+ swizzle[1] = 1;
+ swizzle[2] = 2;
+ swizzle[3] = 3;
+ break;
case BRW_OPCODE_DP4:
case BRW_OPCODE_DPH: /* FINISHME: DPH reads only three channels of src0,
* but all four of src1.
@@ -1018,6 +1024,12 @@ vec4_instruction::reswizzle(int dst_writemask, int swizzle)
if (src[i].file == BAD_FILE || src[i].file == IMM)
continue;
+ /* Destination write mask doesn't correspond to source swizzle for the
+ * pack_bytes instruction.
+ */
+ if (opcode == VEC4_OPCODE_PACK_BYTES)
+ continue;
+
for (int c = 0; c < 4; c++) {
new_swizzle[c] = BRW_GET_SWZ(src[i].swizzle, BRW_GET_SWZ(swizzle, c));
}
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
index 058b2baa098..22db81323e7 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
@@ -1495,6 +1495,41 @@ vec4_generator::generate_code(const cfg_t *cfg)
generate_unpack_flags(inst, dst);
break;
+ case VEC4_OPCODE_PACK_BYTES: {
+ /* Is effectively:
+ *
+ * mov(8) dst<16,4,1>:UB src<4,1,0>:UB
+ *
+ * but destinations' only regioning is horizontal stride, so instead we
+ * have to use two instructions:
+ *
+ * mov(4) dst<1>:UB src<4,1,0>:UB
+ * mov(4) dst.16<1>:UB src.16<4,1,0>:UB
+ *
+ * where they pack the four bytes from the low and high four DW.
+ */
+ dst.type = BRW_REGISTER_TYPE_UB;
+
+ brw_set_default_access_mode(p, BRW_ALIGN_1);
+
+ src[0].type = BRW_REGISTER_TYPE_UB;
+ src[0].vstride = BRW_VERTICAL_STRIDE_4;
+ src[0].width = BRW_WIDTH_1;
+ src[0].hstride = BRW_HORIZONTAL_STRIDE_0;
+ struct brw_inst *insn = brw_MOV(p, dst, src[0]);
+ brw_inst_set_exec_size(brw, insn, BRW_EXECUTE_4);
+ brw_inst_set_no_dd_clear(brw, insn, true);
+
+ src[0].subnr = 16;
+ dst.subnr = 16;
+ insn = brw_MOV(p, dst, src[0]);
+ brw_inst_set_exec_size(brw, insn, BRW_EXECUTE_4);
+ brw_inst_set_no_dd_check(brw, insn, true);
+
+ brw_set_default_access_mode(p, BRW_ALIGN_16);
+ break;
+ }
+
default:
if (inst->opcode < (int) ARRAY_SIZE(opcode_descs)) {
_mesa_problem(&brw->ctx, "Unsupported opcode in `%s' in vec4\n",