Added "passthrough" profile, which just sends the bytecode through unchanged; trunk
authorRyan C. Gordon <icculus@icculus.org>
Sun, 06 Apr 2008 04:45:06 -0400
branchtrunk
changeset 109 48e95cf41505
parent 108 b1b685bc63cb
child 110 c9e3d24f2e5a
Added "passthrough" profile, which just sends the bytecode through unchanged; this is useful if you want to actually pass the original shader to Direct3D, but want to parse out what attributes and uniforms it requires, or validate the bytecode, etc.
mojoshader.c
mojoshader.h
--- a/mojoshader.c	Sun Apr 06 04:20:39 2008 -0400
+++ b/mojoshader.c	Sun Apr 06 04:45:06 2008 -0400
@@ -40,6 +40,10 @@
 #define SUPPORT_PROFILE_D3D 1
 #endif
 
+#ifndef SUPPORT_PROFILE_PASSTHROUGH
+#define SUPPORT_PROFILE_PASSTHROUGH 1
+#endif
+
 #ifndef SUPPORT_PROFILE_GLSL
 #define SUPPORT_PROFILE_GLSL 1
 #endif
@@ -300,6 +304,7 @@
     OutputList mainline;
     OutputList ignore;
     OutputList *output_stack[2];
+    uint8 *output_bytes;  // can be used instead of the OutputLists.
     int indent_stack[2];
     int output_stack_len;
     int output_len; // total strlen; prevents walking the lists just to malloc.
@@ -1371,6 +1376,115 @@
 #endif  // SUPPORT_PROFILE_D3D
 
 
+#if !SUPPORT_PROFILE_PASSTHROUGH
+#define PROFILE_EMITTER_PASSTHROUGH(op)
+#else
+#undef AT_LEAST_ONE_PROFILE
+#define AT_LEAST_ONE_PROFILE 1
+#define PROFILE_EMITTER_PASSTHROUGH(op) emit_PASSTHROUGH_##op,
+
+static void emit_PASSTHROUGH_start(Context *ctx)
+{
+    // just copy the whole token stream and make all other emitters no-ops.
+    ctx->output_len = (ctx->tokencount * sizeof (uint32));
+    ctx->output_bytes = Malloc(ctx, ctx->output_len);
+    if (ctx->output_bytes == NULL)
+        out_of_memory(ctx);
+    else
+        memcpy(ctx->output_bytes, ctx->tokens, ctx->output_len);
+} // emit_PASSTHROUGH_start
+
+static void emit_PASSTHROUGH_RESERVED(Context *ctx) {}
+static void emit_PASSTHROUGH_NOP(Context *ctx) {}
+static void emit_PASSTHROUGH_MOV(Context *ctx) {}
+static void emit_PASSTHROUGH_ADD(Context *ctx) {}
+static void emit_PASSTHROUGH_SUB(Context *ctx) {}
+static void emit_PASSTHROUGH_MAD(Context *ctx) {}
+static void emit_PASSTHROUGH_MUL(Context *ctx) {}
+static void emit_PASSTHROUGH_RCP(Context *ctx) {}
+static void emit_PASSTHROUGH_RSQ(Context *ctx) {}
+static void emit_PASSTHROUGH_DP3(Context *ctx) {}
+static void emit_PASSTHROUGH_DP4(Context *ctx) {}
+static void emit_PASSTHROUGH_MIN(Context *ctx) {}
+static void emit_PASSTHROUGH_MAX(Context *ctx) {}
+static void emit_PASSTHROUGH_SLT(Context *ctx) {}
+static void emit_PASSTHROUGH_SGE(Context *ctx) {}
+static void emit_PASSTHROUGH_EXP(Context *ctx) {}
+static void emit_PASSTHROUGH_LOG(Context *ctx) {}
+static void emit_PASSTHROUGH_LIT(Context *ctx) {}
+static void emit_PASSTHROUGH_DST(Context *ctx) {}
+static void emit_PASSTHROUGH_LRP(Context *ctx) {}
+static void emit_PASSTHROUGH_FRC(Context *ctx) {}
+static void emit_PASSTHROUGH_M4X4(Context *ctx) {}
+static void emit_PASSTHROUGH_M4X3(Context *ctx) {}
+static void emit_PASSTHROUGH_M3X4(Context *ctx) {}
+static void emit_PASSTHROUGH_M3X3(Context *ctx) {}
+static void emit_PASSTHROUGH_M3X2(Context *ctx) {}
+static void emit_PASSTHROUGH_CALL(Context *ctx) {}
+static void emit_PASSTHROUGH_CALLNZ(Context *ctx) {}
+static void emit_PASSTHROUGH_LOOP(Context *ctx) {}
+static void emit_PASSTHROUGH_RET(Context *ctx) {}
+static void emit_PASSTHROUGH_ENDLOOP(Context *ctx) {}
+static void emit_PASSTHROUGH_LABEL(Context *ctx) {}
+static void emit_PASSTHROUGH_POW(Context *ctx) {}
+static void emit_PASSTHROUGH_CRS(Context *ctx) {}
+static void emit_PASSTHROUGH_SGN(Context *ctx) {}
+static void emit_PASSTHROUGH_ABS(Context *ctx) {}
+static void emit_PASSTHROUGH_NRM(Context *ctx) {}
+static void emit_PASSTHROUGH_SINCOS(Context *ctx) {}
+static void emit_PASSTHROUGH_REP(Context *ctx) {}
+static void emit_PASSTHROUGH_ENDREP(Context *ctx) {}
+static void emit_PASSTHROUGH_IF(Context *ctx) {}
+static void emit_PASSTHROUGH_ELSE(Context *ctx) {}
+static void emit_PASSTHROUGH_ENDIF(Context *ctx) {}
+static void emit_PASSTHROUGH_BREAK(Context *ctx) {}
+static void emit_PASSTHROUGH_MOVA(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXKILL(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXBEM(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXBEML(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXREG2AR(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXREG2GB(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXM3X2PAD(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXM3X2TEX(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXM3X3PAD(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXM3X3TEX(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXM3X3SPEC(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXM3X3VSPEC(Context *ctx) {}
+static void emit_PASSTHROUGH_EXPP(Context *ctx) {}
+static void emit_PASSTHROUGH_LOGP(Context *ctx) {}
+static void emit_PASSTHROUGH_CND(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXREG2RGB(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXDP3TEX(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXM3X2DEPTH(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXDP3(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXM3X3(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXDEPTH(Context *ctx) {}
+static void emit_PASSTHROUGH_CMP(Context *ctx) {}
+static void emit_PASSTHROUGH_BEM(Context *ctx) {}
+static void emit_PASSTHROUGH_DP2ADD(Context *ctx) {}
+static void emit_PASSTHROUGH_DSX(Context *ctx) {}
+static void emit_PASSTHROUGH_DSY(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXLDD(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXLDL(Context *ctx) {}
+static void emit_PASSTHROUGH_BREAKP(Context *ctx) {}
+static void emit_PASSTHROUGH_BREAKC(Context *ctx) {}
+static void emit_PASSTHROUGH_IFC(Context *ctx) {}
+static void emit_PASSTHROUGH_SETP(Context *ctx) {}
+static void emit_PASSTHROUGH_DEF(Context *ctx) {}
+static void emit_PASSTHROUGH_DEFI(Context *ctx) {}
+static void emit_PASSTHROUGH_DEFB(Context *ctx) {}
+static void emit_PASSTHROUGH_DCL(Context *ctx) {}
+static void emit_PASSTHROUGH_TEXCOORD(Context *ctx) {}
+static void emit_PASSTHROUGH_TEX(Context *ctx) {}
+static void emit_PASSTHROUGH_end(Context *ctx) {}
+static void emit_PASSTHROUGH_finalize(Context *ctx) {}
+static void emit_PASSTHROUGH_global(Context *ctx, RegisterType t, int n) {}
+static void emit_PASSTHROUGH_uniform(Context *ctx, RegisterType t, int n) {}
+static void emit_PASSTHROUGH_comment(Context *ctx, const char *str) {}
+static void emit_PASSTHROUGH_attribute(Context *ctx, RegisterType t, int n,
+                                       MOJOSHADER_usage u, int i, int w) {}
+#endif  // SUPPORT_PROFILE_PASSTHROUGH
+
 
 #if !SUPPORT_PROFILE_GLSL
 #define PROFILE_EMITTER_GLSL(op)
@@ -2568,6 +2682,9 @@
 #if SUPPORT_PROFILE_D3D
     DEFINE_PROFILE(D3D)
 #endif
+#if SUPPORT_PROFILE_PASSTHROUGH
+    DEFINE_PROFILE(PASSTHROUGH)
+#endif
 #if SUPPORT_PROFILE_GLSL
     DEFINE_PROFILE(GLSL)
 #endif
@@ -2578,6 +2695,7 @@
 // The PROFILE_EMITTER_* items MUST be in the same order as profiles[]!
 #define PROFILE_EMITTERS(op) { \
      PROFILE_EMITTER_D3D(op) \
+     PROFILE_EMITTER_PASSTHROUGH(op) \
      PROFILE_EMITTER_GLSL(op) \
 }
 
@@ -3643,6 +3761,8 @@
     {
         MOJOSHADER_free f = ((ctx->free != NULL) ? ctx->free : internal_free);
         void *d = ctx->malloc_data;
+        if (ctx->output_bytes != NULL)
+            f(d, ctx->output_bytes);
         free_output_list(f, d, ctx->globals.head.next);
         free_output_list(f, d, ctx->helpers.head.next);
         free_output_list(f, d, ctx->subroutines.head.next);
@@ -3679,7 +3799,9 @@
 
 static char *build_output(Context *ctx)
 {
-    char *retval = (char *) Malloc(ctx, ctx->output_len + 1);
+    // add a byte for the null terminator if we're doing text output.
+    const int plusbytes = (ctx->output_bytes == NULL) ? 1 : 0;
+    char *retval = (char *) Malloc(ctx, ctx->output_len + plusbytes);
     if (retval == NULL)
         out_of_memory(ctx);
     else
@@ -3687,11 +3809,16 @@
         const char *endl = ctx->endline;
         const size_t endllen = ctx->endline_len;
         char *wptr = retval;
-        append_list(&wptr, endl, endllen, ctx->globals.head.next);
-        append_list(&wptr, endl, endllen, ctx->helpers.head.next);
-        append_list(&wptr, endl, endllen, ctx->subroutines.head.next);
-        append_list(&wptr, endl, endllen, ctx->mainline.head.next);
-        // don't append ctx->ignore ... that's why it's called "ignore"
+        if (ctx->output_bytes != NULL)
+            memcpy(retval, ctx->output_bytes, ctx->output_len);
+        else
+        {
+            append_list(&wptr, endl, endllen, ctx->globals.head.next);
+            append_list(&wptr, endl, endllen, ctx->helpers.head.next);
+            append_list(&wptr, endl, endllen, ctx->subroutines.head.next);
+            append_list(&wptr, endl, endllen, ctx->mainline.head.next);
+            // don't append ctx->ignore ... that's why it's called "ignore"
+        } // else
     } // else
 
     return retval;
--- a/mojoshader.h	Sun Apr 06 04:20:39 2008 -0400
+++ b/mojoshader.h	Sun Apr 06 04:45:06 2008 -0400
@@ -207,6 +207,11 @@
 #define MOJOSHADER_PROFILE_D3D "d3d"
 
 /*
+ * Profile string for passthrough of the original bytecode, unchanged.
+ */
+#define MOJOSHADER_PROFILE_PASSTHROUGH "passthrough"
+
+/*
  * Profile string for GLSL: OpenGL high-level shader language output.
  */
 #define MOJOSHADER_PROFILE_GLSL "glsl"