[Mesa-dev] [PATCHv3 2/3] i965: refactor texture instruction emission
Chia-I Wu
olvaffe at gmail.com
Wed Oct 16 08:58:10 CEST 2013
From: Chia-I Wu <olv at lunarg.com>
Add fs_visitor::emit_texture, which is used to emit the texture instruction
after the message payload has been set up.
v2: rebased because of texture gather changes
v3: rebased because of texture-from-GRF changes
Signed-off-by: Chia-I Wu <olv at lunarg.com>
---
src/mesa/drivers/dri/i965/brw_fs.h | 10 +-
src/mesa/drivers/dri/i965/brw_fs_fp.cpp | 13 ++-
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 154 +++++++++++++--------------
3 files changed, 85 insertions(+), 92 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index b5aed23..c2ba351 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -339,13 +339,17 @@ public:
fs_reg rescale_texcoord(ir_texture *ir, fs_reg coordinate,
bool is_rect, int sampler, int texunit);
fs_inst *emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
- fs_reg shadow_comp, fs_reg lod, fs_reg lod2);
+ fs_reg shadow_comp, fs_reg lod, fs_reg lod2,
+ int sampler);
fs_inst *emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
fs_reg shadow_comp, fs_reg lod, fs_reg lod2,
- fs_reg sample_index);
+ fs_reg sample_index, int sampler);
fs_inst *emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
fs_reg shadow_comp, fs_reg lod, fs_reg lod2,
- fs_reg sample_index);
+ fs_reg sample_index, int sampler);
+ fs_inst *emit_texture(ir_texture *ir, fs_reg dst, fs_reg payload, int mlen,
+ bool header_present, int regs_written, int sampler);
+
fs_reg fix_math_operand(fs_reg src);
fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0);
fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0, fs_reg src1);
diff --git a/src/mesa/drivers/dri/i965/brw_fs_fp.cpp b/src/mesa/drivers/dri/i965/brw_fs_fp.cpp
index 1ebaa4f..da9e99f 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_fp.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_fp.cpp
@@ -499,18 +499,17 @@ fs_visitor::emit_fragment_program_code()
fpi->TexSrcTarget == TEXTURE_RECT_INDEX,
fpi->TexSrcUnit, fpi->TexSrcUnit);
- fs_inst *inst;
if (brw->gen >= 7) {
- inst = emit_texture_gen7(ir, dst, coordinate, shadow_c, lod, dpdy, sample_index);
+ emit_texture_gen7(ir, dst, coordinate, shadow_c, lod, dpdy,
+ sample_index, fpi->TexSrcUnit);
} else if (brw->gen >= 5) {
- inst = emit_texture_gen5(ir, dst, coordinate, shadow_c, lod, dpdy, sample_index);
+ emit_texture_gen5(ir, dst, coordinate, shadow_c, lod, dpdy,
+ sample_index, fpi->TexSrcUnit);
} else {
- inst = emit_texture_gen4(ir, dst, coordinate, shadow_c, lod, dpdy);
+ emit_texture_gen4(ir, dst, coordinate, shadow_c, lod, dpdy,
+ fpi->TexSrcUnit);
}
- inst->sampler = fpi->TexSrcUnit;
- inst->shadow_compare = fpi->TexShadow;
-
/* Reuse the GLSL swizzle_result() handler. */
swizzle_result(ir, dst, fpi->TexSrcUnit);
dst = this->result;
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 9f37013..d164b04 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -901,8 +901,56 @@ fs_visitor::visit(ir_assignment *ir)
}
fs_inst *
+fs_visitor::emit_texture(ir_texture *ir, fs_reg dst, fs_reg payload, int mlen,
+ bool header_present, int regs_written, int sampler)
+{
+ int base_mrf;
+ fs_inst *inst;
+
+ if (payload.file == MRF) {
+ base_mrf = payload.reg;
+ payload = reg_undef;
+ } else {
+ base_mrf = -1;
+ }
+
+ switch (ir->op) {
+ case ir_tex: inst = emit(SHADER_OPCODE_TEX, dst, payload); break;
+ case ir_txb: inst = emit(FS_OPCODE_TXB, dst, payload); break;
+ case ir_txl: inst = emit(SHADER_OPCODE_TXL, dst, payload); break;
+ case ir_txd: inst = emit(SHADER_OPCODE_TXD, dst, payload); break;
+ case ir_txf: inst = emit(SHADER_OPCODE_TXF, dst, payload); break;
+ case ir_txf_ms: inst = emit(SHADER_OPCODE_TXF_MS, dst, payload); break;
+ case ir_txs: inst = emit(SHADER_OPCODE_TXS, dst, payload); break;
+ case ir_query_levels: inst = emit(SHADER_OPCODE_TXS, dst, payload); break;
+ case ir_lod: inst = emit(SHADER_OPCODE_LOD, dst, payload); break;
+ case ir_tg4: inst = emit(SHADER_OPCODE_TG4, dst, payload); break;
+ default: return NULL;
+ }
+
+ inst->base_mrf = base_mrf;
+ inst->mlen = mlen;
+ inst->header_present = header_present;
+ inst->regs_written = regs_written;
+
+ if (ir->offset != NULL && ir->op != ir_txf)
+ inst->texture_offset = brw_texture_offset(ir->offset->as_constant());
+
+ if (ir->op == ir_tg4)
+ inst->texture_offset |= gather_channel(ir, sampler) << 16; // M0.2:16-17
+
+ inst->sampler = sampler;
+
+ if (ir->shadow_comparitor)
+ inst->shadow_compare = true;
+
+ return inst;
+}
+
+fs_inst *
fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
- fs_reg shadow_c, fs_reg lod, fs_reg dPdy)
+ fs_reg shadow_c, fs_reg lod, fs_reg dPdy,
+ int sampler)
{
int mlen;
int base_mrf = 1;
@@ -1037,30 +1085,17 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
fs_inst *inst = NULL;
switch (ir->op) {
case ir_tex:
- inst = emit(SHADER_OPCODE_TEX, dst);
- break;
case ir_txb:
- inst = emit(FS_OPCODE_TXB, dst);
- break;
case ir_txl:
- inst = emit(SHADER_OPCODE_TXL, dst);
- break;
case ir_txd:
- inst = emit(SHADER_OPCODE_TXD, dst);
- break;
case ir_txs:
- inst = emit(SHADER_OPCODE_TXS, dst);
- break;
case ir_txf:
- inst = emit(SHADER_OPCODE_TXF, dst);
+ inst = emit_texture(ir, dst, fs_reg(MRF, base_mrf), mlen, true,
+ simd16 ? 8 : 4, sampler);
break;
default:
fail("unrecognized texture opcode");
}
- inst->base_mrf = base_mrf;
- inst->mlen = mlen;
- inst->header_present = true;
- inst->regs_written = simd16 ? 8 : 4;
if (simd16) {
for (int i = 0; i < 4; i++) {
@@ -1084,7 +1119,7 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
fs_inst *
fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
fs_reg shadow_c, fs_reg lod, fs_reg lod2,
- fs_reg sample_index)
+ fs_reg sample_index, int sampler)
{
int mlen = 0;
int base_mrf = 2;
@@ -1131,24 +1166,20 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
mlen += reg_width;
}
- fs_inst *inst = NULL;
switch (ir->op) {
case ir_tex:
- inst = emit(SHADER_OPCODE_TEX, dst);
+ case ir_lod:
+ case ir_tg4:
break;
case ir_txb:
mlen = MAX2(mlen, header_present + 4 * reg_width);
emit(MOV(fs_reg(MRF, base_mrf + mlen), lod));
mlen += reg_width;
-
- inst = emit(FS_OPCODE_TXB, dst);
break;
case ir_txl:
mlen = MAX2(mlen, header_present + 4 * reg_width);
emit(MOV(fs_reg(MRF, base_mrf + mlen), lod));
mlen += reg_width;
-
- inst = emit(SHADER_OPCODE_TXL, dst);
break;
case ir_txd: {
mlen = MAX2(mlen, header_present + 4 * reg_width); /* skip over 'ai' */
@@ -1171,24 +1202,19 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
lod2.reg_offset++;
mlen += reg_width;
}
-
- inst = emit(SHADER_OPCODE_TXD, dst);
break;
}
case ir_txs:
emit(MOV(fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), lod));
mlen += reg_width;
- inst = emit(SHADER_OPCODE_TXS, dst);
break;
case ir_query_levels:
emit(MOV(fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), fs_reg(0u)));
mlen += reg_width;
- inst = emit(SHADER_OPCODE_TXS, dst);
break;
case ir_txf:
mlen = header_present + 4 * reg_width;
emit(MOV(fs_reg(MRF, base_mrf + mlen - reg_width, BRW_REGISTER_TYPE_UD), lod));
- inst = emit(SHADER_OPCODE_TXF, dst);
break;
case ir_txf_ms:
mlen = header_present + 4 * reg_width;
@@ -1198,34 +1224,24 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
/* sample index */
emit(MOV(fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), sample_index));
mlen += reg_width;
- inst = emit(SHADER_OPCODE_TXF_MS, dst);
- break;
- case ir_lod:
- inst = emit(SHADER_OPCODE_LOD, dst);
- break;
- case ir_tg4:
- inst = emit(SHADER_OPCODE_TG4, dst);
break;
default:
fail("unrecognized texture opcode");
break;
}
- inst->base_mrf = base_mrf;
- inst->mlen = mlen;
- inst->header_present = header_present;
- inst->regs_written = 4;
if (mlen > 11) {
fail("Message length >11 disallowed by hardware\n");
}
- return inst;
+ return emit_texture(ir, dst, fs_reg(MRF, base_mrf),
+ mlen, header_present, 4, sampler);
}
fs_inst *
fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
fs_reg shadow_c, fs_reg lod, fs_reg lod2,
- fs_reg sample_index)
+ fs_reg sample_index, int sampler)
{
int reg_width = dispatch_width / 8;
bool header_present = false;
@@ -1349,6 +1365,9 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
next.reg_offset++;
}
break;
+ default:
+ fail("unrecognized texture opcode");
+ return NULL;
}
/* Set up the coordinate (except for cases where it was done above) */
@@ -1360,35 +1379,19 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
}
}
- /* Generate the SEND */
- fs_inst *inst = NULL;
- switch (ir->op) {
- case ir_tex: inst = emit(SHADER_OPCODE_TEX, dst, payload); break;
- case ir_txb: inst = emit(FS_OPCODE_TXB, dst, payload); break;
- case ir_txl: inst = emit(SHADER_OPCODE_TXL, dst, payload); break;
- case ir_txd: inst = emit(SHADER_OPCODE_TXD, dst, payload); break;
- case ir_txf: inst = emit(SHADER_OPCODE_TXF, dst, payload); break;
- case ir_txf_ms: inst = emit(SHADER_OPCODE_TXF_MS, dst, payload); break;
- case ir_txs: inst = emit(SHADER_OPCODE_TXS, dst, payload); break;
- case ir_query_levels: inst = emit(SHADER_OPCODE_TXS, dst, payload); break;
- case ir_lod: inst = emit(SHADER_OPCODE_LOD, dst, payload); break;
- case ir_tg4: inst = emit(SHADER_OPCODE_TG4, dst, payload); break;
- }
- inst->base_mrf = -1;
+ int mlen;
+
if (reg_width == 2)
- inst->mlen = next.reg_offset * reg_width - header_present;
+ mlen = next.reg_offset * reg_width - header_present;
else
- inst->mlen = next.reg_offset * reg_width;
-
- inst->header_present = header_present;
- inst->regs_written = 4;
+ mlen = next.reg_offset * reg_width;
virtual_grf_sizes[payload.reg] = next.reg_offset;
- if (inst->mlen > 11) {
+ if (mlen > 11) {
fail("Message length >11 disallowed by hardware\n");
}
- return inst;
+ return emit_texture(ir, dst, payload, mlen, header_present, 4, sampler);
}
fs_reg
@@ -1495,8 +1498,6 @@ fs_visitor::rescale_texcoord(ir_texture *ir, fs_reg coordinate,
void
fs_visitor::visit(ir_texture *ir)
{
- fs_inst *inst = NULL;
-
int sampler =
_mesa_get_sampler_uniform_value(ir->sampler, shader_prog, prog);
/* FINISHME: We're failing to recompile our programs when the sampler is
@@ -1585,27 +1586,16 @@ fs_visitor::visit(ir_texture *ir)
fs_reg dst = fs_reg(this, glsl_type::get_instance(ir->type->base_type, 4, 1));
if (brw->gen >= 7) {
- inst = emit_texture_gen7(ir, dst, coordinate, shadow_comparitor,
- lod, lod2, sample_index);
+ emit_texture_gen7(ir, dst, coordinate, shadow_comparitor,
+ lod, lod2, sample_index, sampler);
} else if (brw->gen >= 5) {
- inst = emit_texture_gen5(ir, dst, coordinate, shadow_comparitor,
- lod, lod2, sample_index);
+ emit_texture_gen5(ir, dst, coordinate, shadow_comparitor,
+ lod, lod2, sample_index, sampler);
} else {
- inst = emit_texture_gen4(ir, dst, coordinate, shadow_comparitor,
- lod, lod2);
+ emit_texture_gen4(ir, dst, coordinate, shadow_comparitor,
+ lod, lod2, sampler);
}
- if (ir->offset != NULL && ir->op != ir_txf)
- inst->texture_offset = brw_texture_offset(ir->offset->as_constant());
-
- if (ir->op == ir_tg4)
- inst->texture_offset |= gather_channel(ir, sampler) << 16; // M0.2:16-17
-
- inst->sampler = sampler;
-
- if (ir->shadow_comparitor)
- inst->shadow_compare = true;
-
/* fixup #layers for cube map arrays */
if (ir->op == ir_txs) {
glsl_type const *type = ir->sampler->type;
--
1.8.3.1
More information about the mesa-dev
mailing list