From 6f3219a8f34296cfd21c165ca4d41d7e62bb4cf5 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sat, 11 Jan 2014 19:42:04 -0500 Subject: nv50/ir: add support for gl_PrimitiveIDIn Note that the primitive id is stored in a[0x18], while usually the geometry instructions are of the form a[$a1 + 0x4] which gets mapped to p[] space. We need to avoid the change from a[] to p[] here, so it's keyed on whether the access is indirect or not. Note that there's also a use-case for accessing e.g. a[$r1], however that's not supported for now. (Could be added by checking the register file of the indirect parameter.) Signed-off-by: Ilia Mirkin --- src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp | 6 +++--- src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp | 7 +++++-- src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp | 3 +++ 3 files changed, 11 insertions(+), 5 deletions(-) (limited to 'src/gallium/drivers/nouveau') diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp index 173497723c2..c73508c67c1 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp @@ -381,7 +381,7 @@ CodeEmitterNV50::setSrcFileBits(const Instruction *i, int enc) case 0x00: // rrr break; case 0x01: // arr/grr - if (progType == Program::TYPE_GEOMETRY) { + if (progType == Program::TYPE_GEOMETRY && i->src(0).isIndirect(0)) { code[0] |= 0x01800000; if (enc == NV50_OP_ENC_LONG || enc == NV50_OP_ENC_LONG_ALT) code[1] |= 0x00200000; @@ -412,7 +412,7 @@ CodeEmitterNV50::setSrcFileBits(const Instruction *i, int enc) code[1] |= (i->getSrc(1)->reg.fileIndex << 22); break; case 0x09: // acr/gcr - if (progType == Program::TYPE_GEOMETRY) { + if (progType == Program::TYPE_GEOMETRY && i->src(0).isIndirect(0)) { code[0] |= 0x01800000; } else { code[0] |= (enc == NV50_OP_ENC_LONG_ALT) ? 0x01000000 : 0x00800000; @@ -617,7 +617,7 @@ CodeEmitterNV50::emitLOAD(const Instruction *i) switch (sf) { case FILE_SHADER_INPUT: - if (progType == Program::TYPE_GEOMETRY) + if (progType == Program::TYPE_GEOMETRY && i->src(0).isIndirect(0)) code[0] = 0x11800001; else // use 'mov' where we can 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 3c790cfe77f..321410e4d45 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp @@ -1434,13 +1434,16 @@ Converter::fetchSrc(tgsi::Instruction::SrcRegister src, int c, Value *ptr) return mkOp1v(OP_RDSV, TYPE_F32, getSSA(), mkSysVal(SV_FACE, 0)); return interpolate(src, c, shiftAddress(ptr)); } else - if (ptr && prog->getType() == Program::TYPE_GEOMETRY) { + if (prog->getType() == Program::TYPE_GEOMETRY) { + if (!ptr && info->in[idx].sn == TGSI_SEMANTIC_PRIMID) + return mkOp1v(OP_RDSV, TYPE_U32, getSSA(), mkSysVal(SV_PRIMITIVE_ID, 0)); // XXX: This is going to be a problem with scalar arrays, i.e. when // we cannot assume that the address is given in units of vec4. // // nv50 and nvc0 need different things here, so let the lowering // passes decide what to do with the address - return mkLoadv(TYPE_U32, srcToSym(src, c), ptr); + if (ptr) + return mkLoadv(TYPE_U32, srcToSym(src, c), ptr); } return mkLoadv(TYPE_U32, srcToSym(src, c), shiftAddress(ptr)); case TGSI_FILE_OUTPUT: diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp index 1dc50c44b96..636ef9ee252 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp @@ -238,6 +238,9 @@ TargetNV50::getSVAddress(DataFile shaderFile, const Symbol *sym) const addr += 4; return addr; } + case SV_PRIMITIVE_ID: + return shaderFile == FILE_SHADER_INPUT ? 0x18 : + sysvalLocation[sym->reg.data.sv.sv]; case SV_NCTAID: return 0x8 + 2 * sym->reg.data.sv.index; case SV_CTAID: -- cgit v1.2.3