On Gen6, lower this to `ld` with lod=0 and an extra sample_index parameter.
On Gen7, use `ld2dms`. We don't support CMS yet for multisample textures, so we just hardcode MCS=0. This is ignored for IMS and UMS surfaces. Note: If we do end up emitting specialized shaders based on the MSAA layout, we can emit a slightly shorter message here in the UMS case. Note: According to the PRM, `ld2dms` takes one more parameter, lod. However, it's always zero, and including it would make the message too long for SIMD16, so we just omit it. V2: Reworked completely, added support for Gen7. V3: - Introduce sample_index parameter rather than reusing lod - Removed spurious whitespace change - Clarify commit message Signed-off-by: Chris Forbes <chr...@ijw.co.nz> --- src/mesa/drivers/dri/i965/brw_fs.h | 6 ++-- src/mesa/drivers/dri/i965/brw_fs_fp.cpp | 5 +-- src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 50 +++++++++++++++++++++++----- 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index d332502..266abb4 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -349,9 +349,11 @@ public: 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_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 shadow_comp, fs_reg lod, fs_reg lod2, + fs_reg sample_index); 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 shadow_comp, fs_reg lod, fs_reg lod2, + fs_reg sample_index); 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 5f5f6a9..bfaad62 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_fp.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_fp.cpp @@ -416,6 +416,7 @@ fs_visitor::emit_fragment_program_code() fs_reg dpdy; fs_reg coordinate = src[0]; fs_reg shadow_c; + fs_reg sample_index; switch (fpi->Opcode) { case OPCODE_TEX: @@ -504,9 +505,9 @@ fs_visitor::emit_fragment_program_code() fs_inst *inst; if (intel->gen >= 7) { - inst = emit_texture_gen7(ir, dst, coordinate, shadow_c, lod, dpdy); + inst = emit_texture_gen7(ir, dst, coordinate, shadow_c, lod, dpdy, sample_index); } else if (intel->gen >= 5) { - inst = emit_texture_gen5(ir, dst, coordinate, shadow_c, lod, dpdy); + inst = emit_texture_gen5(ir, dst, coordinate, shadow_c, lod, dpdy, sample_index); } else { inst = emit_texture_gen4(ir, dst, coordinate, shadow_c, lod, dpdy); } diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index d4f6fc9..a118be4 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -963,7 +963,8 @@ 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 shadow_c, fs_reg lod, fs_reg lod2, + fs_reg sample_index) { int mlen = 0; int base_mrf = 2; @@ -1061,9 +1062,17 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate, 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; - emit(MOV(fs_reg(MRF, base_mrf + mlen - reg_width, BRW_REGISTER_TYPE_UD), - lod)); + /* lod */ + emit(MOV(fs_reg(MRF, base_mrf + mlen - reg_width, BRW_REGISTER_TYPE_UD), fs_reg(0))); + /* sample index */ + emit(MOV(fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), sample_index)); + mlen += reg_width; inst = emit(SHADER_OPCODE_TXF, dst); break; } @@ -1080,7 +1089,8 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate, 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 shadow_c, fs_reg lod, fs_reg lod2, + fs_reg sample_index) { int mlen = 0; int base_mrf = 2; @@ -1176,10 +1186,29 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, mlen += reg_width; } break; + case ir_txf_ms: + emit(MOV(fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), sample_index)); + mlen += reg_width; + + /* constant zero MCS; we arrange to never actually have a compressed + * multisample surface here for now. TODO: issue ld_mcs to get this first, + * if we ever support texturing from compressed multisample surfaces */ + emit(MOV(fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), fs_reg(0u))); + mlen += reg_width; + + /* there is no offsetting for this message; just copy in the integer + * texture coordinates */ + for (int i=0; i < ir->coordinate->type->vector_elements; i++) { + emit(MOV(fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), + coordinate)); + coordinate.reg_offset++; + mlen += reg_width; + } + 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) { + if (ir->op != ir_txd && ir->op != ir_txs && ir->op != ir_txf && ir->op != ir_txf_ms) { for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { emit(MOV(fs_reg(MRF, base_mrf + mlen), coordinate)); coordinate.reg_offset++; @@ -1195,6 +1224,7 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, 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; } inst->base_mrf = base_mrf; @@ -1344,7 +1374,7 @@ fs_visitor::visit(ir_texture *ir) shadow_comparitor = this->result; } - fs_reg lod, lod2; + fs_reg lod, lod2, sample_index; switch (ir->op) { case ir_tex: break; @@ -1365,6 +1395,10 @@ fs_visitor::visit(ir_texture *ir) ir->lod_info.lod->accept(this); lod = this->result; break; + case ir_txf_ms: + ir->lod_info.sample_index->accept(this); + sample_index = this->result; + break; }; /* Writemasking doesn't eliminate channels on SIMD8 texture @@ -1374,10 +1408,10 @@ fs_visitor::visit(ir_texture *ir) if (intel->gen >= 7) { inst = emit_texture_gen7(ir, dst, coordinate, shadow_comparitor, - lod, lod2); + lod, lod2, sample_index); } else if (intel->gen >= 5) { inst = emit_texture_gen5(ir, dst, coordinate, shadow_comparitor, - lod, lod2); + lod, lod2, sample_index); } else { inst = emit_texture_gen4(ir, dst, coordinate, shadow_comparitor, lod, lod2); -- 1.8.1.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev