svga: Fix relative addressing translation for pixel shaders.
authorMichal Krol <michal@vmware.com>
Thu, 16 Sep 2010 16:48:00 +0000 (16:48 +0000)
committerJosé Fonseca <jfonseca@vmware.com>
Mon, 20 Sep 2010 08:26:17 +0000 (09:26 +0100)
Pixel shaders do not have address registers a#, only one
loop register aL. Our only hope is to assume the address
register is in fact a loop counter and replace it with aL.

Do not translate ARL instruction for pixel shaders -- MOVA
instruction is only valid for vertex saders.

Make it more explicit relative addressing of inputs is only valid
for pixel shaders and constants for vertex shaders.

src/gallium/drivers/svga/svga_tgsi_insn.c

index 72dccdf150291e6fa113db209a52f4867cebf829..ad7d27acbb0af8f8397811b7a249915e807e9364 100644 (file)
@@ -197,22 +197,37 @@ translate_src_register( const struct svga_shader_emitter *emit,
       break;
    }
 
-   /* Indirect addressing (for coninstant buffer lookups only)
+   /* Indirect addressing.
     */
-   if (reg->Register.Indirect)
-   {
-      /* we shift the offset towards the minimum */
-      if (svga_arl_needs_adjustment( emit )) {
-         src.base.num -= svga_arl_adjustment( emit );
+   if (reg->Register.Indirect) {
+      if (emit->unit == PIPE_SHADER_FRAGMENT) {
+         /* Pixel shaders have only loop registers for relative
+          * addressing into inputs. Ignore the redundant address
+          * register, the contents of aL should be in sync with it.
+          */
+         if (reg->Register.File == TGSI_FILE_INPUT) {
+            src.base.relAddr = 1;
+            src.indirect = src_token(SVGA3DREG_LOOP, 0);
+         }
+      }
+      else {
+         /* Constant buffers only.
+          */
+         if (reg->Register.File == TGSI_FILE_CONSTANT) {
+            /* we shift the offset towards the minimum */
+            if (svga_arl_needs_adjustment( emit )) {
+               src.base.num -= svga_arl_adjustment( emit );
+            }
+            src.base.relAddr = 1;
+
+            /* Not really sure what should go in the second token:
+             */
+            src.indirect = src_token( SVGA3DREG_ADDR,
+                                      reg->Indirect.Index );
+
+            src.indirect.swizzle = SWIZZLE_XXXX;
+         }
       }
-      src.base.relAddr = 1;
-
-      /* Not really sure what should go in the second token:
-       */
-      src.indirect = src_token( SVGA3DREG_ADDR,
-                                reg->Indirect.Index );
-
-      src.indirect.swizzle = SWIZZLE_XXXX;
    }
 
    src = swizzle( src,
@@ -1593,6 +1608,14 @@ static boolean emit_arl(struct svga_shader_emitter *emit,
                         const struct tgsi_full_instruction *insn)
 {
    ++emit->current_arl;
+   if (emit->unit == PIPE_SHADER_FRAGMENT) {
+      /* MOVA not present in pixel shader instruction set.
+       * Ignore this instruction altogether since it is
+       * only used for loop counters -- and for that
+       * we reference aL directly.
+       */
+      return TRUE;
+   }
    if (svga_arl_needs_adjustment( emit )) {
       return emit_fake_arl( emit, insn );
    } else {