diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index 7dabc4767dc..314fe2ab519 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -1251,11 +1251,13 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, next.reg_offset++; } + bool has_nonconstant_offset = ir->offset && !ir->offset->as_constant(); + bool coordinate_done = false; + /* Set up the LOD info */ switch (ir->op) { case ir_tex: case ir_lod: - case ir_tg4: break; case ir_txb: emit(MOV(next, lod)); @@ -1290,6 +1292,8 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, next.reg_offset++; } } + + coordinate_done = true; break; } case ir_txs: @@ -1328,6 +1332,8 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, coordinate.reg_offset++; next.reg_offset++; } + + coordinate_done = true; break; case ir_txf_ms: emit(MOV(next.retype(BRW_REGISTER_TYPE_UD), sample_index)); @@ -1348,15 +1354,44 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, coordinate.reg_offset++; next.reg_offset++; } + + coordinate_done = true; + break; + case ir_tg4: + if (has_nonconstant_offset) { + /* More crazy intermixing */ + ir->offset->accept(this); + fs_reg offset_value = this->result; + + for (int i = 0; i < 2; i++) { /* u, v */ + emit(MOV(next, coordinate)); + coordinate.reg_offset++; + next.reg_offset++; + } + + for (int i = 0; i < 2; i++) { /* offu, offv */ + emit(MOV(next.retype(BRW_REGISTER_TYPE_D), offset_value)); + offset_value.reg_offset++; + next.reg_offset++; + } + + if (ir->coordinate->type->vector_elements == 3) { /* r if present */ + emit(MOV(next, coordinate)); + coordinate.reg_offset++; + next.reg_offset++; + } + + coordinate_done = true; + } break; } /* Set up the coordinate (except for cases where it was done above) */ - if (ir->op != ir_txd && ir->op != ir_txs && ir->op != ir_txf && ir->op != ir_txf_ms && ir->op != ir_query_levels) { + if (ir->coordinate && !coordinate_done) { for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { - emit(MOV(next, coordinate)); - coordinate.reg_offset++; - next.reg_offset++; + emit(MOV(next, coordinate)); + coordinate.reg_offset++; + next.reg_offset++; } } @@ -1372,14 +1407,18 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, 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; + case ir_tg4: + if (has_nonconstant_offset) + inst = emit(SHADER_OPCODE_TG4_OFFSET, dst, payload); + else + inst = emit(SHADER_OPCODE_TG4, dst, payload); + break; } inst->base_mrf = -1; if (reg_width == 2) inst->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; |