[Mesa-dev] [PATCH RFC 5/6] i965: refactor texture instruction emission
Chia-I Wu
olvaffe at gmail.com
Mon Sep 30 01:27:49 PDT 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.
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 | 129 ++++++++++++---------------
3 files changed, 70 insertions(+), 82 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index b2aa041..c161e7d 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -327,13 +327,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, int base_mrf, 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 0594948..46ff03d 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 72c379a..6435a17 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -870,8 +870,46 @@ fs_visitor::visit(ir_assignment *ir)
}
fs_inst *
+fs_visitor::emit_texture(ir_texture *ir, fs_reg dst, int base_mrf, int mlen,
+ bool header_present, int regs_written, int sampler)
+{
+ fs_inst *inst;
+
+ 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_txf: inst = emit(SHADER_OPCODE_TXF, dst); break;
+ case ir_txf_ms: inst = emit(SHADER_OPCODE_TXF_MS, dst); break;
+ case ir_txs: inst = emit(SHADER_OPCODE_TXS, dst); break;
+ case ir_lod: inst = emit(SHADER_OPCODE_LOD, dst); break;
+ default: return NULL;
+ }
+
+ inst->base_mrf = base_mrf;
+ inst->mlen = mlen;
+ inst->header_present = header_present;
+ inst->regs_written = regs_written;
+
+ /* The header is set up by generate_tex() when necessary. */
+ inst->src[0] = reg_undef;
+
+ if (ir->offset != NULL && ir->op != ir_txf)
+ inst->texture_offset = brw_texture_offset(ir->offset->as_constant());
+
+ 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;
@@ -1006,30 +1044,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, 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++) {
@@ -1053,7 +1078,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;
@@ -1100,24 +1125,18 @@ 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);
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' */
@@ -1140,19 +1159,15 @@ 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_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;
@@ -1162,28 +1177,25 @@ 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;
+ default:
+ fail("unrecognized texture opcode");
+ return NULL;
}
- 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, 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 mlen = 0;
int base_mrf = 2;
@@ -1301,6 +1313,9 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
mlen += reg_width;
}
break;
+ default:
+ fail("unrecognized texture opcode");
+ return NULL;
}
/* Set up the coordinate (except for cases where it was done above) */
@@ -1312,28 +1327,11 @@ 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); 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_txf: inst = emit(SHADER_OPCODE_TXF, dst); break;
- case ir_txf_ms: inst = emit(SHADER_OPCODE_TXF_MS, dst); break;
- case ir_txs: inst = emit(SHADER_OPCODE_TXS, dst); break;
- case ir_lod: inst = emit(SHADER_OPCODE_LOD, dst); 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, base_mrf, mlen, header_present, 4, sampler);
}
fs_reg
@@ -1440,8 +1438,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, &fp->Base);
/* FINISHME: We're failing to recompile our programs when the sampler is
@@ -1507,27 +1503,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);
}
- /* The header is set up by generate_tex() when necessary. */
- inst->src[0] = reg_undef;
-
- if (ir->offset != NULL && ir->op != ir_txf)
- inst->texture_offset = brw_texture_offset(ir->offset->as_constant());
-
- 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