mesa/st: Generates TGSI that always recognizes INSTANCEID/VERTEXID as integers.
authorJosé Fonseca <jfonseca@vmware.com>
Thu, 12 Jul 2012 19:44:02 +0000 (20:44 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Fri, 13 Jul 2012 12:01:52 +0000 (13:01 +0100)
Tested by running piglit draw-instanced, and by forcing llvmpipe advertise no native
integer support, which now produces:

VERT
DCL IN[0]
DCL SV[0], INSTANCEID
DCL OUT[0], POSITION
DCL OUT[1], COLOR
DCL CONST[0..19]
DCL TEMP[0], LOCAL
DCL TEMP[1], LOCAL
DCL TEMP[2], LOCAL
DCL ADDR[0]
  0: U2F TEMP[0].x, SV[0]
  1: ARL ADDR[0].x, TEMP[0].xxxx
  2: MOV TEMP[1].xy, CONST[ADDR[0].x+8].xyxx
  3: ADD TEMP[2].x, IN[0].xxxx, TEMP[1].xxxx
  4: ADD TEMP[1].x, IN[0].yyyy, TEMP[1].yyyy
  5: MUL TEMP[2], CONST[16], TEMP[2].xxxx
  6: MAD TEMP[2], CONST[17], TEMP[1].xxxx, TEMP[2]
  7: MAD TEMP[2], CONST[18], IN[0].zzzz, TEMP[2]
  8: MAD TEMP[2], CONST[19], IN[0].wwww, TEMP[2]
  9: ARL ADDR[0].x, TEMP[0].xxxx
 10: MOV TEMP[1], CONST[ADDR[0].x]
 11: MOV OUT[0], TEMP[2]
 12: MOV OUT[1], TEMP[1]
 13: END

src/mesa/state_tracker/st_glsl_to_tgsi.cpp
src/mesa/state_tracker/st_mesa_to_tgsi.c

index b6abe84..1d91e36 100644 (file)
@@ -4615,6 +4615,25 @@ st_translate_program(
          if (sysInputs & (1 << i)) {
             unsigned semName = mesa_sysval_to_semantic[i];
             t->systemValues[i] = ureg_DECL_system_value(ureg, numSys, semName, 0);
+            if (semName == TGSI_SEMANTIC_INSTANCEID ||
+                semName == TGSI_SEMANTIC_VERTEXID) {
+               /* From Gallium perspective, these system values are always
+                * integer, and require native integer support.  However, if
+                * native integer is supported on the vertex stage but not the
+                * pixel stage (e.g, i915g + draw), Mesa will generate IR that
+                * assumes these system values are floats. To resolve the
+                * inconsistency, we insert a U2F.
+                */
+               struct st_context *st = st_context(ctx);
+               struct pipe_screen *pscreen = st->pipe->screen;
+               assert(procType == TGSI_PROCESSOR_VERTEX);
+               assert(pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_INTEGERS));
+               if (!ctx->Const.NativeIntegers) {
+                  struct ureg_dst temp = ureg_DECL_local_temporary(t->ureg);
+                  ureg_U2F( t->ureg, ureg_writemask(temp, TGSI_WRITEMASK_X), t->systemValues[i]);
+                  t->systemValues[i] = ureg_scalar(ureg_src(temp), 0);
+               }
+            }
             numSys++;
             sysInputs &= ~(1 << i);
          }
index e414ed8..90af1b0 100644 (file)
@@ -1159,6 +1159,25 @@ st_translate_mesa_program(
          if (sysInputs & (1 << i)) {
             unsigned semName = mesa_sysval_to_semantic[i];
             t->systemValues[i] = ureg_DECL_system_value(ureg, numSys, semName, 0);
+            if (semName == TGSI_SEMANTIC_INSTANCEID ||
+                semName == TGSI_SEMANTIC_VERTEXID) {
+               /* From Gallium perspective, these system values are always
+                * integer, and require native integer support.  However, if
+                * native integer is supported on the vertex stage but not the
+                * pixel stage (e.g, i915g + draw), Mesa will generate IR that
+                * assumes these system values are floats. To resolve the
+                * inconsistency, we insert a U2F.
+                */
+               struct st_context *st = st_context(ctx);
+               struct pipe_screen *pscreen = st->pipe->screen;
+               assert(procType == TGSI_PROCESSOR_VERTEX);
+               assert(pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_INTEGERS));
+               if (!ctx->Const.NativeIntegers) {
+                  struct ureg_dst temp = ureg_DECL_local_temporary(t->ureg);
+                  ureg_U2F( t->ureg, ureg_writemask(temp, TGSI_WRITEMASK_X), t->systemValues[i]);
+                  t->systemValues[i] = ureg_scalar(ureg_src(temp), 0);
+               }
+            }
             numSys++;
             sysInputs &= ~(1 << i);
          }