[Mesa-dev] [PATCH] nv50/ir: avoid asserts when the state tracker feeds us bogus inputs
Samuel Pitoiset
samuel.pitoiset at gmail.com
Sat May 14 14:43:23 UTC 2016
On 05/13/2016 05:45 AM, Ilia Mirkin wrote:
> INTERP is defined (by me) to have to have a INPUT source. However the
> state tracker does not always obey this. This happens due to varying
> packing logic introducing additional mov's which can't always be undone.
> Instead of just giving up, we instead try harder to find the original
> input. This won't always be possible, for example with indirect
> accesses. There's not much we can (easily) do about that though.
>
> This fixes a bunch of dEQP interpolateAt* tests that happen to hit this.
Maybe you can just add:
dEQP-GLES31.functional.shaders.multisample_interpolation.interpolate_at_offset.*
dEQP-GLES31.functional.shaders.multisample_interpolation.interpolate_at_centroid.*
to be (a little) more precise?
Anyway, this patch is:
Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
>
> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
> ---
> .../drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp | 59 ++++++++++++++++++----
> 1 file changed, 48 insertions(+), 11 deletions(-)
>
> diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
> index 69e1a34..73c824c 100644
> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
> @@ -2733,24 +2733,61 @@ Converter::handleINTERP(Value *dst[4])
> // Check whether the input is linear. All other attributes ignored.
> Instruction *insn;
> Value *offset = NULL, *ptr = NULL, *w = NULL;
> + Symbol *sym[4] = { NULL };
> bool linear;
> operation op;
> int c, mode;
>
> tgsi::Instruction::SrcRegister src = tgsi.getSrc(0);
> - assert(src.getFile() == TGSI_FILE_INPUT);
>
> - if (src.isIndirect(0))
> + // In some odd cases, in large part due to varying packing, the source
> + // might not actually be an input. This is illegal TGSI, but it's easier to
> + // account for it here than it is to fix it where the TGSI is being
> + // generated. In that case, it's going to be a straight up mov (or sequence
> + // of mov's) from the input in question. We follow the mov chain to see
> + // which input we need to use.
> + FOR_EACH_DST_ENABLED_CHANNEL(0, c, tgsi) {
> + if (src.getFile() == TGSI_FILE_INPUT) {
> + sym[c] = srcToSym(src, c);
> + continue;
> + }
> + Value *val = fetchSrc(0, c);
> + assert(val->defs.size() == 1);
> + insn = val->getInsn();
> + while (insn->op == OP_MOV) {
> + assert(insn->getSrc(0)->defs.size() == 1);
> + insn = insn->getSrc(0)->getInsn();
> + assert(insn);
> + if (!insn) {
> + // This could happen if there's an indirect situation which caused
> + // us to move this temp array into local memory. Just bail.
> + WARN("Miscompiling shader due to unhandled INTERP\n");
> + return;
> + }
> + }
> + sym[c] = insn->getSrc(0)->asSym();
> + op = insn->op;
> + mode = insn->ipa;
> + }
> +
> + if (src.isIndirect(0)) {
> + // In the case where there's varying packing *and* indirect inputs going
> + // on, we're sunk.
> + assert(src.getFile() == TGSI_FILE_INPUT);
> ptr = fetchSrc(src.getIndirect(0), 0, NULL);
> + }
>
> - // XXX: no way to know interp mode if we don't know the index
> - linear = info->in[ptr ? 0 : src.getIndex(0)].linear;
> - if (linear) {
> - op = OP_LINTERP;
> - mode = NV50_IR_INTERP_LINEAR;
> - } else {
> - op = OP_PINTERP;
> - mode = NV50_IR_INTERP_PERSPECTIVE;
> + // We can assume that the fixed index will point to an input of the same
> + // interpolation type in case of an indirect.
> + if (src.getFile() == TGSI_FILE_INPUT) {
> + linear = info->in[src.getIndex(0)].linear;
> + if (linear) {
> + op = OP_LINTERP;
> + mode = NV50_IR_INTERP_LINEAR;
> + } else {
> + op = OP_PINTERP;
> + mode = NV50_IR_INTERP_PERSPECTIVE;
> + }
> }
>
> switch (tgsi.getOpcode()) {
> @@ -2793,7 +2830,7 @@ Converter::handleINTERP(Value *dst[4])
>
>
> FOR_EACH_DST_ENABLED_CHANNEL(0, c, tgsi) {
> - insn = mkOp1(op, TYPE_F32, dst[c], srcToSym(src, c));
> + insn = mkOp1(op, TYPE_F32, dst[c], sym[c]);
> if (op == OP_PINTERP)
> insn->setSrc(1, w);
> if (ptr)
>
More information about the mesa-dev
mailing list