aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h1
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp31
2 files changed, 30 insertions, 2 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h
index c885c8cf3fc..dc74cded2bd 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h
@@ -177,6 +177,7 @@ struct nv50_ir_prog_info
uint8_t vertexId; /* system value index of VertexID */
uint8_t edgeFlagIn;
uint8_t edgeFlagOut;
+ int8_t viewportId; /* output index of ViewportIndex */
uint8_t fragDepth; /* output index of FragDepth */
uint8_t sampleMask; /* output index of SampleMask */
boolean sampleInterp; /* perform sample interp on all fp inputs */
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 a0f1fe1c87d..2ba3c1c8e0f 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
@@ -790,6 +790,8 @@ bool Source::scanSource()
info->prop.gp.instanceCount = 1; // default value
}
+ info->io.viewportId = -1;
+
info->immd.data = (uint32_t *)MALLOC(scan.immediate_count * 16);
info->immd.type = (ubyte *)MALLOC(scan.immediate_count * sizeof(ubyte));
@@ -982,6 +984,9 @@ bool Source::scanDeclaration(const struct tgsi_full_declaration *decl)
case TGSI_SEMANTIC_SAMPLEMASK:
info->io.sampleMask = i;
break;
+ case TGSI_SEMANTIC_VIEWPORT_INDEX:
+ info->io.viewportId = i;
+ break;
default:
break;
}
@@ -1258,6 +1263,8 @@ private:
Stack joinBBs; // fork BB, for inserting join ops on ENDIF
Stack loopBBs; // loop headers
Stack breakBBs; // end of / after loop
+
+ Value *viewport;
};
Symbol *
@@ -1555,8 +1562,16 @@ Converter::storeDst(const tgsi::Instruction::DstRegister dst, int c,
mkOp2(OP_WRSV, TYPE_U32, NULL, dstToSym(dst, c), val);
} else
if (f == TGSI_FILE_OUTPUT && prog->getType() != Program::TYPE_FRAGMENT) {
- if (ptr || (info->out[idx].mask & (1 << c)))
- mkStore(OP_EXPORT, TYPE_U32, dstToSym(dst, c), ptr, val);
+
+ if (ptr || (info->out[idx].mask & (1 << c))) {
+ /* Save the viewport index into a scratch register so that it can be
+ exported at EMIT time */
+ if (info->out[idx].sn == TGSI_SEMANTIC_VIEWPORT_INDEX &&
+ viewport != NULL)
+ mkOp1(OP_MOV, TYPE_U32, viewport, val);
+ else
+ mkStore(OP_EXPORT, TYPE_U32, dstToSym(dst, c), ptr, val);
+ }
} else
if (f == TGSI_FILE_TEMPORARY ||
f == TGSI_FILE_PREDICATE ||
@@ -2523,6 +2538,13 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
mkCvt(OP_CVT, dstTy, dst0[c], srcTy, fetchSrc(0, c));
break;
case TGSI_OPCODE_EMIT:
+ /* export the saved viewport index */
+ if (viewport != NULL) {
+ Symbol *vpSym = mkSymbol(FILE_SHADER_OUTPUT, 0, TYPE_U32,
+ info->out[info->io.viewportId].slot[0] * 4);
+ mkStore(OP_EXPORT, TYPE_U32, vpSym, NULL, viewport);
+ }
+ /* fallthrough */
case TGSI_OPCODE_ENDPRIM:
// get vertex stream if specified (must be immediate)
src0 = tgsi.srcCount() ?
@@ -2952,6 +2974,11 @@ Converter::run()
mkOp1(OP_RCP, TYPE_F32, fragCoord[3], fragCoord[3]);
}
+ if (info->io.viewportId >= 0)
+ viewport = getScratch();
+ else
+ viewport = NULL;
+
for (ip = 0; ip < code->scan.num_instructions; ++ip) {
if (!handleInstruction(&code->insns[ip]))
return false;