Three source instructions cannot directly source a packed vec4 (<0,4,1>
regioning) like vec4 uniforms, so we emit a MOV that expands the vec4 to
both halves of a register.
If these uniform values are used by multiple three-source instructions,
we'll emit multiple expansion moves, which we cannot combine in CSE
(because CSE emits moves itself).
So emit a virtual instruction that we can CSE.
Sometimes we demote a uniform to to a pull constant after emitting an
expansion move for it. In that case, recognize in opt_algebraic that if
the .file of the new instruction is GRF then it's just a real move that
we can copy propagate and such.
total instructions in shared programs:
5822418 ->
5812335 (-0.17%)
instructions in affected programs: 351841 -> 341758 (-2.87%)
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
SHADER_OPCODE_GEN7_SCRATCH_READ,
VEC4_OPCODE_PACK_BYTES,
+ VEC4_OPCODE_UNPACK_UNIFORM,
FS_OPCODE_DDX_COARSE,
FS_OPCODE_DDX_FINE,
case VEC4_OPCODE_PACK_BYTES:
return "pack_bytes";
+ case VEC4_OPCODE_UNPACK_UNIFORM:
+ return "unpack_uniform";
case FS_OPCODE_DDX_COARSE:
return "ddx_coarse";
foreach_block_and_inst(block, vec4_instruction, inst, cfg) {
switch (inst->opcode) {
+ case VEC4_OPCODE_UNPACK_UNIFORM:
+ if (inst->src[0].file != UNIFORM) {
+ inst->opcode = BRW_OPCODE_MOV;
+ progress = true;
+ }
+ break;
+
case BRW_OPCODE_ADD:
if (inst->src[1].is_zero()) {
inst->opcode = BRW_OPCODE_MOV;
case BRW_OPCODE_PLN:
case BRW_OPCODE_MAD:
case BRW_OPCODE_LRP:
+ case VEC4_OPCODE_UNPACK_UNIFORM:
return true;
case SHADER_OPCODE_RCP:
case SHADER_OPCODE_RSQ:
}
switch (inst->opcode) {
+ case VEC4_OPCODE_UNPACK_UNIFORM:
case BRW_OPCODE_MOV:
brw_MOV(p, dst, src[0]);
break;
dst_reg expanded = dst_reg(this, glsl_type::vec4_type);
expanded.type = src.type;
- emit(MOV(expanded, src));
+ emit(VEC4_OPCODE_UNPACK_UNIFORM, expanded, src);
return src_reg(expanded);
}