+/**
+ * Find an unused temporary in the tempsUsed array.
+ */
+static int
+find_free_temporary(GLboolean tempsUsed[MAX_PROGRAM_TEMPS])
+{
+ int i;
+ for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
+ if (!tempsUsed[i]) {
+ tempsUsed[i] = GL_TRUE;
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+/** helper for building simple TGSI instruction, one src register */
+static void
+build_tgsi_instruction1(struct tgsi_full_instruction *inst,
+ int opcode,
+ int dstFile, int dstIndex, int writemask,
+ int srcFile1, int srcIndex1)
+{
+ *inst = tgsi_default_full_instruction();
+
+ inst->Instruction.Opcode = opcode;
+
+ inst->Instruction.NumDstRegs = 1;
+ inst->FullDstRegisters[0].DstRegister.File = dstFile;
+ inst->FullDstRegisters[0].DstRegister.Index = dstIndex;
+ inst->FullDstRegisters[0].DstRegister.WriteMask = writemask;
+
+ inst->Instruction.NumSrcRegs = 1;
+ inst->FullSrcRegisters[0].SrcRegister.File = srcFile1;
+ inst->FullSrcRegisters[0].SrcRegister.Index = srcIndex1;
+}
+
+
+/** helper for building simple TGSI instruction, two src registers */
+static void
+build_tgsi_instruction2(struct tgsi_full_instruction *inst,
+ int opcode,
+ int dstFile, int dstIndex, int writemask,
+ int srcFile1, int srcIndex1,
+ int srcFile2, int srcIndex2)
+{
+ *inst = tgsi_default_full_instruction();
+
+ inst->Instruction.Opcode = opcode;
+
+ inst->Instruction.NumDstRegs = 1;
+ inst->FullDstRegisters[0].DstRegister.File = dstFile;
+ inst->FullDstRegisters[0].DstRegister.Index = dstIndex;
+ inst->FullDstRegisters[0].DstRegister.WriteMask = writemask;
+
+ inst->Instruction.NumSrcRegs = 2;
+ inst->FullSrcRegisters[0].SrcRegister.File = srcFile1;
+ inst->FullSrcRegisters[0].SrcRegister.Index = srcIndex1;
+ inst->FullSrcRegisters[1].SrcRegister.File = srcFile2;
+ inst->FullSrcRegisters[1].SrcRegister.Index = srcIndex2;
+}
+
+
+
+/**
+ * Emit the TGSI instructions for inverting the WPOS y coordinate.
+ */
+static int
+emit_inverted_wpos(struct tgsi_token *tokens,
+ int wpos_temp,
+ int winsize_const,
+ int wpos_input,
+ struct tgsi_header *header, int maxTokens)
+{
+ struct tgsi_full_instruction fullinst;
+ int ti = 0;
+
+ /* MOV wpos_temp.xzw, input[wpos]; */
+ build_tgsi_instruction1(&fullinst,
+ TGSI_OPCODE_MOV,
+ TGSI_FILE_TEMPORARY, wpos_temp, WRITEMASK_XZW,
+ TGSI_FILE_INPUT, 0);
+
+ ti += tgsi_build_full_instruction(&fullinst,
+ &tokens[ti],
+ header,
+ maxTokens - ti);
+
+ /* SUB wpos_temp.y, const[winsize_const] - input[wpos_input]; */
+ build_tgsi_instruction2(&fullinst,
+ TGSI_OPCODE_SUB,
+ TGSI_FILE_TEMPORARY, wpos_temp, WRITEMASK_Y,
+ TGSI_FILE_CONSTANT, winsize_const,
+ TGSI_FILE_INPUT, wpos_input);
+
+ ti += tgsi_build_full_instruction(&fullinst,
+ &tokens[ti],
+ header,
+ maxTokens - ti);
+
+ return ti;
+}
+
+