mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 07:00:12 +01:00
i965/fs: Fix texelFetchOffset()
It appears that when using 'ld' with the offset bits, address bounds checking happens before the offset is applied, so parts of the drawing in piglit texelFetchOffset() with a negative texcoord go black.
This commit is contained in:
parent
587c221a29
commit
f41ecade7b
1 changed files with 21 additions and 6 deletions
|
|
@ -990,8 +990,9 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
|
||||||
int base_mrf = 2;
|
int base_mrf = 2;
|
||||||
int reg_width = c->dispatch_width / 8;
|
int reg_width = c->dispatch_width / 8;
|
||||||
bool header_present = false;
|
bool header_present = false;
|
||||||
|
int offsets[3];
|
||||||
|
|
||||||
if (ir->offset) {
|
if (ir->offset && ir->op != ir_txf) {
|
||||||
/* The offsets set up by the ir_texture visitor are in the
|
/* The offsets set up by the ir_texture visitor are in the
|
||||||
* m1 header, so we can't go headerless.
|
* m1 header, so we can't go headerless.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1054,9 +1055,23 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
|
||||||
mlen += reg_width;
|
mlen += reg_width;
|
||||||
break;
|
break;
|
||||||
case ir_txf:
|
case ir_txf:
|
||||||
|
/* It appears that the ld instruction used for txf does its
|
||||||
|
* address bounds check before adding in the offset. To work
|
||||||
|
* around this, just add the integer offset to the integer texel
|
||||||
|
* coordinate, and don't put the offset in the header.
|
||||||
|
*/
|
||||||
|
if (ir->offset) {
|
||||||
|
ir_constant *offset = ir->offset->as_constant();
|
||||||
|
offsets[0] = offset->value.i[0];
|
||||||
|
offsets[1] = offset->value.i[1];
|
||||||
|
offsets[2] = offset->value.i[2];
|
||||||
|
} else {
|
||||||
|
memset(offsets, 0, sizeof(offsets));
|
||||||
|
}
|
||||||
|
|
||||||
/* Unfortunately, the parameters for LD are intermixed: u, lod, v, r. */
|
/* Unfortunately, the parameters for LD are intermixed: u, lod, v, r. */
|
||||||
emit(BRW_OPCODE_MOV,
|
emit(BRW_OPCODE_ADD,
|
||||||
fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), coordinate);
|
fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), coordinate, offsets[0]);
|
||||||
coordinate.reg_offset++;
|
coordinate.reg_offset++;
|
||||||
mlen += reg_width;
|
mlen += reg_width;
|
||||||
|
|
||||||
|
|
@ -1065,8 +1080,8 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
|
||||||
mlen += reg_width;
|
mlen += reg_width;
|
||||||
|
|
||||||
for (int i = 1; i < ir->coordinate->type->vector_elements; i++) {
|
for (int i = 1; i < ir->coordinate->type->vector_elements; i++) {
|
||||||
emit(BRW_OPCODE_MOV,
|
emit(BRW_OPCODE_ADD,
|
||||||
fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), coordinate);
|
fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), coordinate, offsets[i]);
|
||||||
coordinate.reg_offset++;
|
coordinate.reg_offset++;
|
||||||
mlen += reg_width;
|
mlen += reg_width;
|
||||||
}
|
}
|
||||||
|
|
@ -1128,7 +1143,7 @@ fs_visitor::visit(ir_texture *ir)
|
||||||
ir->coordinate->accept(this);
|
ir->coordinate->accept(this);
|
||||||
fs_reg coordinate = this->result;
|
fs_reg coordinate = this->result;
|
||||||
|
|
||||||
if (ir->offset != NULL) {
|
if (ir->offset != NULL && !(intel->gen == 7 && ir->op == ir_txf)) {
|
||||||
uint32_t offset_bits = brw_texture_offset(ir->offset->as_constant());
|
uint32_t offset_bits = brw_texture_offset(ir->offset->as_constant());
|
||||||
|
|
||||||
/* Explicitly set up the message header by copying g0 to msg reg m1. */
|
/* Explicitly set up the message header by copying g0 to msg reg m1. */
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue