diff options
author | Kenneth Graunke <[email protected]> | 2011-06-08 16:08:07 -0700 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2011-06-18 17:53:47 -0700 |
commit | 3fa910fff9f72d1adf33f0f4dea3d790a9ce04ab (patch) | |
tree | a35efec8b77e68a2092a8f9efa7206940edd2d7f /src | |
parent | ad9481e12813d5f1dec95ce123927e132fa935fb (diff) |
i965/fs: Add support for non-shadow textureGrad (TXD) on Ivybridge.
This is somewhat ugly, but I couldn't think of a nicer way to handle the
interleaved coordinate/derivative parameter loading.
Ironlake and Sandybridge will still hit an assertion in visit().
Signed-off-by: Kenneth Graunke <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_emit.cpp | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 50 |
2 files changed, 43 insertions, 10 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp index 6b7c434949c..844b89b7dc3 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp @@ -273,7 +273,8 @@ fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src) } break; case FS_OPCODE_TXD: - assert(!"TXD isn't supported on gen5+ yet."); + assert(!inst->shadow_compare); + msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_DERIVS; break; } } else { diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index b4857871c78..72559465864 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -796,20 +796,52 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); mlen += reg_width; break; - case ir_txd: + case ir_txd: { + if (c->dispatch_width == 16) + fail("Gen7 does not support sample_d/sample_d_c in SIMD16 mode."); + + ir->lod_info.grad.dPdx->accept(this); + fs_reg dPdx = this->result; + + ir->lod_info.grad.dPdy->accept(this); + fs_reg dPdy = this->result; + + /* Load dPdx and the coordinate together: + * [hdr], [ref], x, dPdx.x, dPdy.x, y, dPdx.y, dPdy.y, z, dPdx.z, dPdy.z + */ + for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { + fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), + coordinate); + if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler)) + inst->saturate = true; + coordinate.reg_offset++; + mlen += reg_width; + + emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx); + dPdx.reg_offset++; + mlen += reg_width; + + emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy); + dPdy.reg_offset++; + mlen += reg_width; + } + break; + } case ir_txf: assert(!"GLSL 1.30 features unsupported"); break; } - /* Set up the coordinate */ - for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { - fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), - coordinate); - if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler)) - inst->saturate = true; - coordinate.reg_offset++; - mlen += reg_width; + /* Set up the coordinate (except for TXD where it was done earlier) */ + if (ir->op != ir_txd) { + for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { + fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), + coordinate); + if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler)) + inst->saturate = true; + coordinate.reg_offset++; + mlen += reg_width; + } } /* Generate the SEND */ |