Implement gl_FrontFacing for fragment shaders.
authorBrian <brian@yutani.localnet.net>
Sat, 10 Mar 2007 18:30:19 +0000 (11:30 -0700)
committerBrian <brian@yutani.localnet.net>
Sat, 10 Mar 2007 18:30:19 +0000 (11:30 -0700)
For the time being, we put the gl_FrontFacing value in the FOGC.Y input
register.  Combining FOGC and FrontFacing in one register is a bit of a
hack and may need to be changed someday.

src/mesa/shader/slang/slang_codegen.c
src/mesa/swrast/s_fragprog.c
src/mesa/swrast_setup/ss_triangle.c
src/mesa/swrast_setup/ss_tritmp.h

index 64bb9141bc9281534234a44d70fe70217933a68b..640b87a34d30af29a97a946a3ea5aaef8a9925ac 100644 (file)
@@ -209,35 +209,37 @@ sampler_to_texture_index(const slang_type_specifier_type type)
  * XXX return size too
  */
 static GLint
-_slang_input_index(const char *name, GLenum target)
+_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut)
 {
    struct input_info {
       const char *Name;
       GLuint Attrib;
+      GLuint Swizzle;
    };
    static const struct input_info vertInputs[] = {
-      { "gl_Vertex", VERT_ATTRIB_POS },
-      { "gl_Normal", VERT_ATTRIB_NORMAL },
-      { "gl_Color", VERT_ATTRIB_COLOR0 },
-      { "gl_SecondaryColor", VERT_ATTRIB_COLOR1 },
-      { "gl_FogCoord", VERT_ATTRIB_FOG },
-      { "gl_MultiTexCoord0", VERT_ATTRIB_TEX0 },
-      { "gl_MultiTexCoord1", VERT_ATTRIB_TEX1 },
-      { "gl_MultiTexCoord2", VERT_ATTRIB_TEX2 },
-      { "gl_MultiTexCoord3", VERT_ATTRIB_TEX3 },
-      { "gl_MultiTexCoord4", VERT_ATTRIB_TEX4 },
-      { "gl_MultiTexCoord5", VERT_ATTRIB_TEX5 },
-      { "gl_MultiTexCoord6", VERT_ATTRIB_TEX6 },
-      { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7 },
-      { NULL, 0 }
+      { "gl_Vertex", VERT_ATTRIB_POS, SWIZZLE_NOOP },
+      { "gl_Normal", VERT_ATTRIB_NORMAL, SWIZZLE_NOOP },
+      { "gl_Color", VERT_ATTRIB_COLOR0, SWIZZLE_NOOP },
+      { "gl_SecondaryColor", VERT_ATTRIB_COLOR1, SWIZZLE_NOOP },
+      { "gl_FogCoord", VERT_ATTRIB_FOG, SWIZZLE_XXXX },
+      { "gl_MultiTexCoord0", VERT_ATTRIB_TEX0, SWIZZLE_NOOP },
+      { "gl_MultiTexCoord1", VERT_ATTRIB_TEX1, SWIZZLE_NOOP },
+      { "gl_MultiTexCoord2", VERT_ATTRIB_TEX2, SWIZZLE_NOOP },
+      { "gl_MultiTexCoord3", VERT_ATTRIB_TEX3, SWIZZLE_NOOP },
+      { "gl_MultiTexCoord4", VERT_ATTRIB_TEX4, SWIZZLE_NOOP },
+      { "gl_MultiTexCoord5", VERT_ATTRIB_TEX5, SWIZZLE_NOOP },
+      { "gl_MultiTexCoord6", VERT_ATTRIB_TEX6, SWIZZLE_NOOP },
+      { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7, SWIZZLE_NOOP },
+      { NULL, 0, SWIZZLE_NOOP }
    };
    static const struct input_info fragInputs[] = {
-      { "gl_FragCoord", FRAG_ATTRIB_WPOS },
-      { "gl_Color", FRAG_ATTRIB_COL0 },
-      { "gl_SecondaryColor", FRAG_ATTRIB_COL1 },
-      { "gl_FogFragCoord", FRAG_ATTRIB_FOGC },
-      { "gl_TexCoord", FRAG_ATTRIB_TEX0 },
-      { NULL, 0 }
+      { "gl_FragCoord", FRAG_ATTRIB_WPOS, SWIZZLE_NOOP },
+      { "gl_Color", FRAG_ATTRIB_COL0, SWIZZLE_NOOP },
+      { "gl_SecondaryColor", FRAG_ATTRIB_COL1, SWIZZLE_NOOP },
+      { "gl_FogFragCoord", FRAG_ATTRIB_FOGC, SWIZZLE_XXXX },
+      { "gl_TexCoord", FRAG_ATTRIB_TEX0, SWIZZLE_NOOP },
+      { "gl_FrontFacing", FRAG_ATTRIB_FOGC, SWIZZLE_YYYY }, /*XXX*/
+      { NULL, 0, SWIZZLE_NOOP }
    };
    GLuint i;
    const struct input_info *inputs
@@ -248,6 +250,7 @@ _slang_input_index(const char *name, GLenum target)
    for (i = 0; inputs[i].Name; i++) {
       if (strcmp(inputs[i].Name, name) == 0) {
          /* found */
+         *swizzleOut = inputs[i].Swizzle;
          return inputs[i].Attrib;
       }
    }
@@ -2571,9 +2574,12 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
       else {
          /* pre-defined varying, like gl_Color or gl_TexCoord */
          if (type == SLANG_UNIT_FRAGMENT_BUILTIN) {
-            GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB);
+            GLuint swizzle;
+            GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB,
+                                             &swizzle);
             assert(index >= 0);
             store = _slang_new_ir_storage(PROGRAM_INPUT, index, size);
+            store->Swizzle = swizzle;
             assert(index < FRAG_ATTRIB_MAX);
          }
          else {
@@ -2600,17 +2606,23 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
       }
       else {
          /* pre-defined vertex attrib */
-         GLint index = _slang_input_index(varName, GL_VERTEX_PROGRAM_ARB);
+         GLuint swizzle;
+         GLint index = _slang_input_index(varName, GL_VERTEX_PROGRAM_ARB,
+                                          &swizzle);
          GLint size = 4; /* XXX? */
          assert(index >= 0);
          store = _slang_new_ir_storage(PROGRAM_INPUT, index, size);
+         store->Swizzle = swizzle;
       }
       if (dbg) printf("ATTRIB ");
    }
    else if (var->type.qualifier == SLANG_QUAL_FIXEDINPUT) {
-      GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB);
+      GLuint swizzle;
+      GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB,
+                                       &swizzle);
       GLint size = 4; /* XXX? */
       store = _slang_new_ir_storage(PROGRAM_INPUT, index, size);
+      store->Swizzle = swizzle;
       if (dbg) printf("INPUT ");
    }
    else if (var->type.qualifier == SLANG_QUAL_FIXEDOUTPUT) {
index 698925cdba39af053328aef18b4e09b1082714ed..dbfc1b8c0cc00d8f35604a258d4b67e7c2c14857 100644 (file)
@@ -113,6 +113,10 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine,
 
    /* Setup pointer to input attributes */
    machine->Attribs = span->array->attribs;
+
+   /* Store front/back facing value in register FOGC.Y */
+   machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = (GLfloat) ctx->_Facing;
+
    machine->CurElement = col;
 
    /* init condition codes */
index 09244d9c4bc254a6a26723e997278210c3bdb69c..628e9288e8754352fe85b461f17c38a2b59c7f95 100644 (file)
@@ -290,8 +290,10 @@ void _swsetup_choose_trifuncs( GLcontext *ctx )
        ctx->Polygon.OffsetFill)
       ind |= SS_OFFSET_BIT;
 
+   /* Note: gl_FrontFacing lives in fragment input FOGC.Y at this time */
    if ((ctx->Light.Enabled && ctx->Light.Model.TwoSide) ||
-       (ctx->VertexProgram._Enabled && ctx->VertexProgram.TwoSideEnabled))
+       (ctx->VertexProgram._Enabled && ctx->VertexProgram.TwoSideEnabled) ||
+       (ctx->FragmentProgram._Current && ctx->FragmentProgram._Current->Base.InputsRead & (1 << FRAG_ATTRIB_FOGC)))
       ind |= SS_TWOSIDE_BIT;
 
    /* We piggyback the two-sided stencil front/back determination on the
index 61c9b2817e689f03508d2e6a62955402eeca72af..5b14b283f128fb9518fc9aa3e892d49214ae544f 100644 (file)
@@ -55,8 +55,7 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
       if (IND & (SS_TWOSIDE_BIT | SS_UNFILLED_BIT))
       {
         facing = (cc < 0.0) ^ ctx->Polygon._FrontBit;
-         if (ctx->Stencil.TestTwoSide)
-            ctx->_Facing = facing; /* for 2-sided stencil test */
+         ctx->_Facing = facing;
 
         if (IND & SS_UNFILLED_BIT)
            mode = facing ? ctx->Polygon.BackMode : ctx->Polygon.FrontMode;