i915_program.c revision 994d1db079b4947e6f10ab22a4b366a676382345
16b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell/**************************************************************************
26b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell *
36b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
46b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * All Rights Reserved.
56b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell *
66b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
76b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * copy of this software and associated documentation files (the
86b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * "Software"), to deal in the Software without restriction, including
96b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * without limitation the rights to use, copy, modify, merge, publish,
106b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * distribute, sub license, and/or sell copies of the Software, and to
116b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * permit persons to whom the Software is furnished to do so, subject to
126b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * the following conditions:
136b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell *
146b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * The above copyright notice and this permission notice (including the
156b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * next paragraph) shall be included in all copies or substantial portions
166b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * of the Software.
176b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell *
186b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
196b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
206b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
216b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
226b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
236b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
246b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
256b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell *
266b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell **************************************************************************/
276b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
286b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#include <strings.h>
296b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
30ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/glheader.h"
31ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/macros.h"
32ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/enums.h"
336b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
346b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#include "tnl/t_context.h"
356b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#include "intel_batchbuffer.h"
366b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
376b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#include "i915_reg.h"
386b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#include "i915_context.h"
396b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#include "i915_program.h"
406b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
416b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
426b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define A0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
436b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define D0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
446b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define T0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
456b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define A0_SRC0( reg ) (((reg)&UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT)
466b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define A1_SRC0( reg ) (((reg)&UREG_MASK)<<UREG_A1_SRC0_SHIFT_RIGHT)
476b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define A1_SRC1( reg ) (((reg)&UREG_MASK)>>UREG_A1_SRC1_SHIFT_LEFT)
486b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define A2_SRC1( reg ) (((reg)&UREG_MASK)<<UREG_A2_SRC1_SHIFT_RIGHT)
496b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define A2_SRC2( reg ) (((reg)&UREG_MASK)>>UREG_A2_SRC2_SHIFT_LEFT)
506b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
516b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell/* These are special, and don't have swizzle/negate bits.
526b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell */
536b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define T0_SAMPLER( reg )     (GET_UREG_NR(reg)<<T0_SAMPLER_NR_SHIFT)
546b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define T1_ADDRESS_REG( reg ) ((GET_UREG_NR(reg)<<T1_ADDRESS_REG_NR_SHIFT) | \
556b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell			       (GET_UREG_TYPE(reg)<<T1_ADDRESS_REG_TYPE_SHIFT))
566b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
576b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
586b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell/* Macros for translating UREG's into the various register fields used
596b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * by the I915 programmable unit.
606b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell */
616b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define UREG_A0_DEST_SHIFT_LEFT  (UREG_TYPE_SHIFT - A0_DEST_TYPE_SHIFT)
626b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define UREG_A0_SRC0_SHIFT_LEFT  (UREG_TYPE_SHIFT - A0_SRC0_TYPE_SHIFT)
636b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define UREG_A1_SRC0_SHIFT_RIGHT (A1_SRC0_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
646b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define UREG_A1_SRC1_SHIFT_LEFT  (UREG_TYPE_SHIFT - A1_SRC1_TYPE_SHIFT)
656b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define UREG_A2_SRC1_SHIFT_RIGHT (A2_SRC1_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
666b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define UREG_A2_SRC2_SHIFT_LEFT  (UREG_TYPE_SHIFT - A2_SRC2_TYPE_SHIFT)
676b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
686b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define UREG_MASK         0xffffff00
696b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define UREG_TYPE_NR_MASK ((REG_TYPE_MASK << UREG_TYPE_SHIFT) | \
706b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell  			   (REG_NR_MASK << UREG_NR_SHIFT))
716b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
726b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
736b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define I915_CONSTFLAG_PARAM 0x1f
746b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
756b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith WhitwellGLuint
766b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwelli915_get_temp(struct i915_fragment_program *p)
776b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
786b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   int bit = ffs(~p->temp_flag);
796b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (!bit) {
806b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      fprintf(stderr, "%s: out of temporaries\n", __FILE__);
816b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      exit(1);
826b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   }
836b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
846b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->temp_flag |= 1 << (bit - 1);
856b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   return UREG(REG_TYPE_R, (bit - 1));
866b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
876b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
886b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
896b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith WhitwellGLuint
906b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwelli915_get_utemp(struct i915_fragment_program * p)
916b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
926b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   int bit = ffs(~p->utemp_flag);
936b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (!bit) {
946b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      fprintf(stderr, "%s: out of temporaries\n", __FILE__);
956b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      exit(1);
966b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   }
976b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
986b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->utemp_flag |= 1 << (bit - 1);
996b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   return UREG(REG_TYPE_U, (bit - 1));
1006b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
1016b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1026b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwellvoid
1036b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwelli915_release_utemps(struct i915_fragment_program *p)
1046b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
1056b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->utemp_flag = ~0x7;
1066b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
1076b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1086b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1096b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith WhitwellGLuint
1106b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwelli915_emit_decl(struct i915_fragment_program *p,
1116b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell               GLuint type, GLuint nr, GLuint d0_flags)
1126b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
1136b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   GLuint reg = UREG(type, nr);
1146b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1156b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (type == REG_TYPE_T) {
1166b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      if (p->decl_t & (1 << nr))
1176b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         return reg;
1186b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1196b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      p->decl_t |= (1 << nr);
1206b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   }
1216b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   else if (type == REG_TYPE_S) {
1226b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      if (p->decl_s & (1 << nr))
1236b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         return reg;
1246b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1256b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      p->decl_s |= (1 << nr);
1266b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   }
1276b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   else
1286b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      return reg;
1296b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1306b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags);
1316b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   *(p->decl++) = D1_MBZ;
1326b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   *(p->decl++) = D2_MBZ;
1336b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1346b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->nr_decl_insn++;
1356b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   return reg;
1366b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
1376b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1386b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith WhitwellGLuint
1396b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwelli915_emit_arith(struct i915_fragment_program * p,
1406b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell                GLuint op,
1416b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell                GLuint dest,
1426b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell                GLuint mask,
1436b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell                GLuint saturate, GLuint src0, GLuint src1, GLuint src2)
1446b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
1456b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   GLuint c[3];
1466b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   GLuint nr_const = 0;
1476b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1486b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
1496b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
1506b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   assert(dest);
1516b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1526b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (GET_UREG_TYPE(src0) == REG_TYPE_CONST)
1536b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      c[nr_const++] = 0;
1546b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (GET_UREG_TYPE(src1) == REG_TYPE_CONST)
1556b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      c[nr_const++] = 1;
1566b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (GET_UREG_TYPE(src2) == REG_TYPE_CONST)
1576b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      c[nr_const++] = 2;
1586b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1596b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   /* Recursively call this function to MOV additional const values
1606b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell    * into temporary registers.  Use utemp registers for this -
1616b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell    * currently shouldn't be possible to run out, but keep an eye on
1626b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell    * this.
1636b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell    */
1646b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (nr_const > 1) {
1656b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      GLuint s[3], first, i, old_utemp_flag;
1666b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1676b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      s[0] = src0;
1686b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      s[1] = src1;
1696b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      s[2] = src2;
1706b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      old_utemp_flag = p->utemp_flag;
1716b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1726b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      first = GET_UREG_NR(s[c[0]]);
1736b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      for (i = 1; i < nr_const; i++) {
1746b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         if (GET_UREG_NR(s[c[i]]) != first) {
1756b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell            GLuint tmp = i915_get_utemp(p);
1766b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1776b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell            i915_emit_arith(p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0,
1786b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell                            s[c[i]], 0, 0);
1796b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell            s[c[i]] = tmp;
1806b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         }
1816b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      }
1826b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1836b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      src0 = s[0];
1846b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      src1 = s[1];
1856b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      src2 = s[2];
1866b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      p->utemp_flag = old_utemp_flag;   /* restore */
1876b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   }
1886b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1896b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
1906b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1));
1916b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2));
1926b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
19391d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt   if (GET_UREG_TYPE(dest) == REG_TYPE_R)
19491d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt      p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect;
19591d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt
1966b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->nr_alu_insn++;
1976b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   return dest;
1986b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
1996b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
2003369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihaostatic GLuint get_free_rreg (struct i915_fragment_program *p,
2013369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao                             GLuint live_regs)
2023369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao{
2033369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao    int bit = ffs(~live_regs);
2043369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao    if (!bit) {
2053369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao        i915_program_error(p, "Can't find free R reg");
2063369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao        return UREG_BAD;
2073369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao    }
2083369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao    return UREG(REG_TYPE_R, bit - 1);
2093369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao}
2103369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao
2116b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith WhitwellGLuint i915_emit_texld( struct i915_fragment_program *p,
2123369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao			GLuint live_regs,
2136b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell			GLuint dest,
2146b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell			GLuint destmask,
2156b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell			GLuint sampler,
2166b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell			GLuint coord,
2176b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell			GLuint op )
2186b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
2193369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao    if (coord != UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord))) {
2203369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao        /* With the help of the "needed registers" table created earlier, pick
2213369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao         * a register we can MOV the swizzled TC to (since TEX doesn't support
2223369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao         * swizzled sources) */
2233369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao        GLuint swizCoord = get_free_rreg(p, live_regs);
2243369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao        if (swizCoord == UREG_BAD)
2253369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao            return 0;
2263369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao
2273369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao        i915_emit_arith( p, A0_MOV, swizCoord, A0_DEST_CHANNEL_ALL, 0, coord, 0, 0 );
2283369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao        coord = swizCoord;
2293369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao    }
2303369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao
2313369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao   /* Don't worry about saturate as we only support texture formats
2323369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao    * that are always in the 0..1 range.
2336b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell    */
2346b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (destmask != A0_DEST_CHANNEL_ALL) {
2356b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      GLuint tmp = i915_get_utemp(p);
2363369cd9a6f943365242d7832e69788d4aede9a8fXiang, Haihao      i915_emit_texld( p, 0, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, op );
2376b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 );
2386b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      return dest;
2396b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   }
2406b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   else {
2416b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
2426b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)));
24391d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt      /* Can't use unsaved temps for coords, as the phase boundary would result
24491d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt       * in the contents becoming undefined.
24591d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt       */
24691d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt      assert(GET_UREG_TYPE(coord) != REG_TYPE_U);
24791d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt
248c238098bbcfb644ea01b33d3274b949d84822512Xiang, Haihao      if ((GET_UREG_TYPE(coord) != REG_TYPE_R) &&
249c238098bbcfb644ea01b33d3274b949d84822512Xiang, Haihao          (GET_UREG_TYPE(coord) != REG_TYPE_OC) &&
250c238098bbcfb644ea01b33d3274b949d84822512Xiang, Haihao          (GET_UREG_TYPE(coord) != REG_TYPE_OD) &&
251c238098bbcfb644ea01b33d3274b949d84822512Xiang, Haihao          (GET_UREG_TYPE(coord) != REG_TYPE_T)) {
252c238098bbcfb644ea01b33d3274b949d84822512Xiang, Haihao          GLuint  tmpCoord = get_free_rreg(p, live_regs);
253c238098bbcfb644ea01b33d3274b949d84822512Xiang, Haihao
254c238098bbcfb644ea01b33d3274b949d84822512Xiang, Haihao          if (tmpCoord == UREG_BAD)
255c238098bbcfb644ea01b33d3274b949d84822512Xiang, Haihao              return 0;
256c238098bbcfb644ea01b33d3274b949d84822512Xiang, Haihao
257c238098bbcfb644ea01b33d3274b949d84822512Xiang, Haihao          i915_emit_arith(p, A0_MOV, tmpCoord, A0_DEST_CHANNEL_ALL, 0, coord, 0, 0);
258c238098bbcfb644ea01b33d3274b949d84822512Xiang, Haihao          coord = tmpCoord;
259c238098bbcfb644ea01b33d3274b949d84822512Xiang, Haihao      }
260c238098bbcfb644ea01b33d3274b949d84822512Xiang, Haihao
26191d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt      /* Output register being oC or oD defines a phase boundary */
26291d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt      if (GET_UREG_TYPE(dest) == REG_TYPE_OC ||
26391d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt	  GET_UREG_TYPE(dest) == REG_TYPE_OD)
26491d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt	 p->nr_tex_indirect++;
2656b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
26691d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt      /* Reading from an r# register whose contents depend on output of the
26791d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt       * current phase defines a phase boundary.
26891d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt       */
26991d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt      if (GET_UREG_TYPE(coord) == REG_TYPE_R &&
27091d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt	  p->register_phases[GET_UREG_NR(coord)] == p->nr_tex_indirect)
2716b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell	 p->nr_tex_indirect++;
2726b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
2736b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      *(p->csr++) = (op |
2746b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell		     T0_DEST( dest ) |
2756b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell		     T0_SAMPLER( sampler ));
2766b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
2776b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      *(p->csr++) = T1_ADDRESS_REG( coord );
2786b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      *(p->csr++) = T2_MBZ;
2796b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
28091d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt      if (GET_UREG_TYPE(dest) == REG_TYPE_R)
28191d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt	 p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect;
28291d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt
2836b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      p->nr_tex_insn++;
2846b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      return dest;
2856b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   }
2866b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
2876b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
2886b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
2896b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith WhitwellGLuint
2906b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwelli915_emit_const1f(struct i915_fragment_program * p, GLfloat c0)
2916b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
2926b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   GLint reg, idx;
2936b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
2946b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (c0 == 0.0)
2956b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      return swizzle(UREG(REG_TYPE_R, 0), ZERO, ZERO, ZERO, ZERO);
2966b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (c0 == 1.0)
2976b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE);
2986b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
2996b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
3006b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      if (p->constant_flags[reg] == I915_CONSTFLAG_PARAM)
3016b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         continue;
3026b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      for (idx = 0; idx < 4; idx++) {
3036b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         if (!(p->constant_flags[reg] & (1 << idx)) ||
3046b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell             p->constant[reg][idx] == c0) {
3056b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell            p->constant[reg][idx] = c0;
3066b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell            p->constant_flags[reg] |= 1 << idx;
3076b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell            if (reg + 1 > p->nr_constants)
3086b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell               p->nr_constants = reg + 1;
3096b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell            return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE);
3106b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         }
3116b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      }
3126b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   }
3136b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
3146b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
3156b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->error = 1;
3166b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   return 0;
3176b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
3186b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
3196b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith WhitwellGLuint
3206b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwelli915_emit_const2f(struct i915_fragment_program * p, GLfloat c0, GLfloat c1)
3216b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
3226b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   GLint reg, idx;
3236b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
3246b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (c0 == 0.0)
3256b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      return swizzle(i915_emit_const1f(p, c1), ZERO, X, Z, W);
3266b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (c0 == 1.0)
3276b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      return swizzle(i915_emit_const1f(p, c1), ONE, X, Z, W);
3286b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
3296b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (c1 == 0.0)
3306b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      return swizzle(i915_emit_const1f(p, c0), X, ZERO, Z, W);
3316b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (c1 == 1.0)
3326b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W);
3336b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
3346b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
3356b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      if (p->constant_flags[reg] == 0xf ||
3366b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell          p->constant_flags[reg] == I915_CONSTFLAG_PARAM)
3376b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         continue;
3386b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      for (idx = 0; idx < 3; idx++) {
3396b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         if (!(p->constant_flags[reg] & (3 << idx))) {
3406b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell            p->constant[reg][idx] = c0;
3416b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell            p->constant[reg][idx + 1] = c1;
3426b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell            p->constant_flags[reg] |= 3 << idx;
3436b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell            if (reg + 1 > p->nr_constants)
3446b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell               p->nr_constants = reg + 1;
3456b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell            return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO,
3466b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell                           ONE);
3476b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         }
3486b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      }
3496b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   }
3506b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
3516b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
3526b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->error = 1;
3536b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   return 0;
3546b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
3556b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
3566b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
3576b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
3586b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith WhitwellGLuint
3596b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwelli915_emit_const4f(struct i915_fragment_program * p,
3606b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell                  GLfloat c0, GLfloat c1, GLfloat c2, GLfloat c3)
3616b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
3626b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   GLint reg;
3636b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
3646b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
3656b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      if (p->constant_flags[reg] == 0xf &&
3666b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell          p->constant[reg][0] == c0 &&
3676b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell          p->constant[reg][1] == c1 &&
3686b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell          p->constant[reg][2] == c2 && p->constant[reg][3] == c3) {
3696b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         return UREG(REG_TYPE_CONST, reg);
3706b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      }
3716b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      else if (p->constant_flags[reg] == 0) {
3726b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         p->constant[reg][0] = c0;
3736b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         p->constant[reg][1] = c1;
3746b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         p->constant[reg][2] = c2;
3756b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         p->constant[reg][3] = c3;
3766b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         p->constant_flags[reg] = 0xf;
3776b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         if (reg + 1 > p->nr_constants)
3786b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell            p->nr_constants = reg + 1;
3796b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         return UREG(REG_TYPE_CONST, reg);
3806b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      }
3816b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   }
3826b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
3836b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
3846b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->error = 1;
3856b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   return 0;
3866b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
3876b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
3886b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
3896b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith WhitwellGLuint
3906b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwelli915_emit_const4fv(struct i915_fragment_program * p, const GLfloat * c)
3916b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
3926b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   return i915_emit_const4f(p, c[0], c[1], c[2], c[3]);
3936b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
3946b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
3956b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
3966b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith WhitwellGLuint
3976b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwelli915_emit_param4fv(struct i915_fragment_program * p, const GLfloat * values)
3986b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
3996b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   GLint reg, i;
4006b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
4016b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   for (i = 0; i < p->nr_params; i++) {
4026b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      if (p->param[i].values == values)
4036b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         return UREG(REG_TYPE_CONST, p->param[i].reg);
4046b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   }
4056b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
4066b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
4076b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
4086b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      if (p->constant_flags[reg] == 0) {
4096b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         p->constant_flags[reg] = I915_CONSTFLAG_PARAM;
4106b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         i = p->nr_params++;
4116b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
4126b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         p->param[i].values = values;
4136b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         p->param[i].reg = reg;
4146b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         p->params_uptodate = 0;
4156b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
4166b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         if (reg + 1 > p->nr_constants)
4176b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell            p->nr_constants = reg + 1;
4186b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         return UREG(REG_TYPE_CONST, reg);
4196b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      }
4206b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   }
4216b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
4226b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
4236b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->error = 1;
4246b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   return 0;
4256b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
4266b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
427994d1db079b4947e6f10ab22a4b366a676382345Eric Anholt/* Warning the user about program errors seems to be quite valuable, from
428994d1db079b4947e6f10ab22a4b366a676382345Eric Anholt * our bug reports.  It unfortunately means piglit reporting errors
429994d1db079b4947e6f10ab22a4b366a676382345Eric Anholt * when we fall back to software due to an unsupportable program, though.
430994d1db079b4947e6f10ab22a4b366a676382345Eric Anholt */
4316b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwellvoid
432994d1db079b4947e6f10ab22a4b366a676382345Eric Anholti915_program_error(struct i915_fragment_program *p, const char *fmt, ...)
4336b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
434994d1db079b4947e6f10ab22a4b366a676382345Eric Anholt   va_list args;
435994d1db079b4947e6f10ab22a4b366a676382345Eric Anholt
436994d1db079b4947e6f10ab22a4b366a676382345Eric Anholt   fprintf(stderr, "i915_program_error: ");
437994d1db079b4947e6f10ab22a4b366a676382345Eric Anholt   va_start(args, fmt);
438994d1db079b4947e6f10ab22a4b366a676382345Eric Anholt   vfprintf(stderr, fmt, args);
439994d1db079b4947e6f10ab22a4b366a676382345Eric Anholt   va_end(args);
440994d1db079b4947e6f10ab22a4b366a676382345Eric Anholt
441994d1db079b4947e6f10ab22a4b366a676382345Eric Anholt   fprintf(stderr, "\n");
4426b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->error = 1;
4436b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
4446b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
44567a101759ec0b84e4f30fbb329e86ac5031cf7e7Brian Paul
4466b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwellvoid
4476b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwelli915_init_program(struct i915_context *i915, struct i915_fragment_program *p)
4486b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
4496b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   GLcontext *ctx = &i915->intel.ctx;
4506b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
4516b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->translated = 0;
4526b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->params_uptodate = 0;
4536b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->on_hardware = 0;
4546b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->error = 0;
4556b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
45691d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt   memset(&p->register_phases, 0, sizeof(p->register_phases));
45791d0020eecb78ef2984fd0afafc5d555c0e957d8Eric Anholt   p->nr_tex_indirect = 1;
4586b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->nr_tex_insn = 0;
4596b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->nr_alu_insn = 0;
4606b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->nr_decl_insn = 0;
4616b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
4626b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->ctx = ctx;
4636b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   memset(p->constant_flags, 0, sizeof(p->constant_flags));
4646b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
4656b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->nr_constants = 0;
4666b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->csr = p->program;
4676b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->decl = p->declarations;
4686b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->decl_s = 0;
4696b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->decl_t = 0;
4706b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->temp_flag = 0xffff000;
4716b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->utemp_flag = ~0x7;
4726b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->wpos_tex = -1;
4736b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->depth_written = 0;
4746b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->nr_params = 0;
4756b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
4766b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   *(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM;
4776b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
4786b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
4796b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
4806b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwellvoid
4816b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwelli915_fini_program(struct i915_fragment_program *p)
4826b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
4836b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   GLuint program_size = p->csr - p->program;
4846b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   GLuint decl_size = p->decl - p->declarations;
4856b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
4866b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (p->nr_tex_indirect > I915_MAX_TEX_INDIRECT)
4876b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      i915_program_error(p, "Exceeded max nr indirect texture lookups");
4886b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
4896b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (p->nr_tex_insn > I915_MAX_TEX_INSN)
4906b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      i915_program_error(p, "Exceeded max TEX instructions");
4916b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
4926b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (p->nr_alu_insn > I915_MAX_ALU_INSN)
4936b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      i915_program_error(p, "Exceeded max ALU instructions");
4946b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
4956b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (p->nr_decl_insn > I915_MAX_DECL_INSN)
4966b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      i915_program_error(p, "Exceeded max DECL instructions");
4976b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
4986b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (p->error) {
4996b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      p->FragProg.Base.NumNativeInstructions = 0;
500064ae479a770bf434958d673baf6f7530f642697Brian      p->FragProg.Base.NumNativeAluInstructions = 0;
501064ae479a770bf434958d673baf6f7530f642697Brian      p->FragProg.Base.NumNativeTexInstructions = 0;
502064ae479a770bf434958d673baf6f7530f642697Brian      p->FragProg.Base.NumNativeTexIndirections = 0;
5036b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   }
5046b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   else {
5056b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      p->FragProg.Base.NumNativeInstructions = (p->nr_alu_insn +
5066b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell                                                p->nr_tex_insn +
5076b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell                                                p->nr_decl_insn);
508064ae479a770bf434958d673baf6f7530f642697Brian      p->FragProg.Base.NumNativeAluInstructions = p->nr_alu_insn;
509064ae479a770bf434958d673baf6f7530f642697Brian      p->FragProg.Base.NumNativeTexInstructions = p->nr_tex_insn;
510064ae479a770bf434958d673baf6f7530f642697Brian      p->FragProg.Base.NumNativeTexIndirections = p->nr_tex_indirect;
5116b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   }
5126b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
5136b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->declarations[0] |= program_size + decl_size - 2;
5146b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
5156b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
5166b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwellvoid
5176b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwelli915_upload_program(struct i915_context *i915,
5186b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell                    struct i915_fragment_program *p)
5196b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
5206b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   GLuint program_size = p->csr - p->program;
5216b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   GLuint decl_size = p->decl - p->declarations;
5226b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
5236b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   FALLBACK(&i915->intel, I915_FALLBACK_PROGRAM, p->error);
5246b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
5256b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   /* Could just go straight to the batchbuffer from here:
5266b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell    */
5276b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (i915->state.ProgramSize != (program_size + decl_size) ||
5286b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell       memcmp(i915->state.Program + decl_size, p->program,
5296b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell              program_size * sizeof(int)) != 0) {
5306b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      I915_STATECHANGE(i915, I915_UPLOAD_PROGRAM);
5316b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      memcpy(i915->state.Program, p->declarations, decl_size * sizeof(int));
5326b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      memcpy(i915->state.Program + decl_size, p->program,
5336b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell             program_size * sizeof(int));
5346b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      i915->state.ProgramSize = decl_size + program_size;
5356b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   }
5366b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
5376b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   /* Always seemed to get a failure if I used memcmp() to
5386b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell    * shortcircuit this state upload.  Needs further investigation?
5396b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell    */
5406b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   if (p->nr_constants) {
5416b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      GLuint nr = p->nr_constants;
5426b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
5436b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 1);
5446b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      I915_STATECHANGE(i915, I915_UPLOAD_CONSTANTS);
5456b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
5466b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      i915->state.Constant[0] = _3DSTATE_PIXEL_SHADER_CONSTANTS | ((nr) * 4);
5476b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      i915->state.Constant[1] = (1 << (nr - 1)) | ((1 << (nr - 1)) - 1);
5486b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
5496b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      memcpy(&i915->state.Constant[2], p->constant, 4 * sizeof(int) * (nr));
5506b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      i915->state.ConstantSize = 2 + (nr) * 4;
5516b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
5526b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      if (0) {
5536b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         GLuint i;
5546b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         for (i = 0; i < nr; i++) {
5556b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell            fprintf(stderr, "const[%d]: %f %f %f %f\n", i,
5566b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell                    p->constant[i][0],
5576b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell                    p->constant[i][1], p->constant[i][2], p->constant[i][3]);
5586b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell         }
5596b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      }
5606b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   }
5616b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   else {
5626b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 0);
5636b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   }
5646b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
5656b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   p->on_hardware = 1;
5666b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
567