aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.h3
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_fp.cpp2
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_visitor.cpp46
3 files changed, 41 insertions, 10 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 2949c47118f..e516046686f 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -353,7 +353,8 @@ public:
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 sample_index);
+ fs_reg sample_index, fs_reg mcs);
+ fs_reg emit_mcs_fetch(ir_texture *ir, fs_reg coordinate, 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 1ebaa4f2c81..5aec757a9b1 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_fp.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_fp.cpp
@@ -501,7 +501,7 @@ fs_visitor::emit_fragment_program_code()
fs_inst *inst;
if (brw->gen >= 7) {
- inst = emit_texture_gen7(ir, dst, coordinate, shadow_c, lod, dpdy, sample_index);
+ inst = emit_texture_gen7(ir, dst, coordinate, shadow_c, lod, dpdy, sample_index, fs_reg(0u));
} else if (brw->gen >= 5) {
inst = emit_texture_gen5(ir, dst, coordinate, shadow_c, lod, dpdy, sample_index);
} else {
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index f81bc8ee095..a28dc6cdffe 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -1239,7 +1239,7 @@ 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 sample_index)
+ fs_reg sample_index, fs_reg mcs)
{
int reg_width = dispatch_width / 8;
bool header_present = false;
@@ -1338,11 +1338,8 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
emit(MOV(next.retype(BRW_REGISTER_TYPE_UD), sample_index));
next.reg_offset++;
- /* 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(next.retype(BRW_REGISTER_TYPE_UD), fs_reg(0u)));
+ /* data from the multisample control surface */
+ emit(MOV(next.retype(BRW_REGISTER_TYPE_UD), mcs));
next.reg_offset++;
/* there is no offsetting for this message; just copy in the integer
@@ -1533,6 +1530,34 @@ fs_visitor::rescale_texcoord(ir_texture *ir, fs_reg coordinate,
return coordinate;
}
+/* Sample from the MCS surface attached to this multisample texture. */
+fs_reg
+fs_visitor::emit_mcs_fetch(ir_texture *ir, fs_reg coordinate, int sampler)
+{
+ int reg_width = dispatch_width / 8;
+ fs_reg payload = fs_reg(this, glsl_type::float_type);
+ fs_reg dest = fs_reg(this, glsl_type::uvec4_type);
+ fs_reg next = payload;
+
+ /* parameters are: u, v, r, lod; missing parameters are treated as zero */
+ for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
+ emit(MOV(next.retype(BRW_REGISTER_TYPE_D), coordinate));
+ coordinate.reg_offset++;
+ next.reg_offset++;
+ }
+
+ fs_inst *inst = emit(SHADER_OPCODE_TXF_MCS, dest, payload);
+ inst->base_mrf = -1;
+ inst->mlen = next.reg_offset * reg_width;
+ inst->header_present = false;
+ inst->regs_written = 4 * reg_width; /* we only care about one reg of response,
+ * but the sampler always writes 4/8
+ */
+ inst->sampler = sampler;
+
+ return dest;
+}
+
void
fs_visitor::visit(ir_texture *ir)
{
@@ -1591,7 +1616,7 @@ fs_visitor::visit(ir_texture *ir)
shadow_comparitor = this->result;
}
- fs_reg lod, lod2, sample_index;
+ fs_reg lod, lod2, sample_index, mcs;
switch (ir->op) {
case ir_tex:
case ir_lod:
@@ -1618,6 +1643,11 @@ fs_visitor::visit(ir_texture *ir)
case ir_txf_ms:
ir->lod_info.sample_index->accept(this);
sample_index = this->result;
+
+ if (brw->gen >= 7 && c->key.tex.compressed_multisample_layout_mask & (1<<sampler))
+ mcs = emit_mcs_fetch(ir, coordinate, sampler);
+ else
+ mcs = fs_reg(0u);
break;
default:
assert(!"Unrecognized texture opcode");
@@ -1630,7 +1660,7 @@ fs_visitor::visit(ir_texture *ir)
if (brw->gen >= 7) {
inst = emit_texture_gen7(ir, dst, coordinate, shadow_comparitor,
- lod, lod2, sample_index);
+ lod, lod2, sample_index, mcs);
} else if (brw->gen >= 5) {
inst = emit_texture_gen5(ir, dst, coordinate, shadow_comparitor,
lod, lod2, sample_index);