tgsi: fix tgsi transform's epilog callback
[mesa.git] / src / gallium / auxiliary / tgsi / tgsi_transform.c
index ae875f29abfb23334a42fa5c55d42d6461909455..9d316ccb9e39d5ad89f33a96c1ebe87789a8f81c 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
  * 
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2008 VMware, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -18,7 +18,7 @@
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -109,6 +109,7 @@ tgsi_transform_shader(const struct tgsi_token *tokens_in,
                       struct tgsi_transform_context *ctx)
 {
    uint procType;
+   boolean first_instruction = TRUE;
 
    /* input shader */
    struct tgsi_parse_context parse;
@@ -166,10 +167,28 @@ tgsi_transform_shader(const struct tgsi_token *tokens_in,
             struct tgsi_full_instruction *fullinst
                = &parse.FullToken.FullInstruction;
 
-            if (ctx->transform_instruction)
-               ctx->transform_instruction(ctx, fullinst);
-            else
+            if (first_instruction && ctx->prolog) {
+               ctx->prolog(ctx);
+            }
+
+            /* XXX Note: we may also want to look for a main/top-level
+             * TGSI_OPCODE_RET instruction in the future.
+             */
+            if (fullinst->Instruction.Opcode == TGSI_OPCODE_END
+                && ctx->epilog) {
+               /* Emit caller's epilog */
+               ctx->epilog(ctx);
+               /* Emit END */
                ctx->emit_instruction(ctx, fullinst);
+            }
+            else {
+               if (ctx->transform_instruction)
+                  ctx->transform_instruction(ctx, fullinst);
+               else
+                  ctx->emit_instruction(ctx, fullinst);
+            }
+
+            first_instruction = FALSE;
          }
          break;
 
@@ -213,10 +232,6 @@ tgsi_transform_shader(const struct tgsi_token *tokens_in,
       }
    }
 
-   if (ctx->epilog) {
-      ctx->epilog(ctx);
-   }
-
    tgsi_parse_free (&parse);
 
    return ctx->ti;