glsl: Optionally lower TES gl_PatchVerticesIn to a uniform.
[mesa.git] / src / mesa / program / arbprogparse.c
index ca63e72c0851bf599c6f637e8eb7a591495e5f9c..3ddaeca8a71f44711e85c9c5c6b3212b452dd216 100644 (file)
@@ -1,6 +1,5 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.1
  *
  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
  *
  * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL 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.
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
  */
 
 #define DEBUG_PARSING 0
@@ -60,6 +60,7 @@ having three separate program parameter arrays.
 #include "prog_parameter.h"
 #include "prog_statevars.h"
 #include "prog_instruction.h"
+#include "prog_optimize.h"
 #include "program_parser.h"
 
 
@@ -72,7 +73,7 @@ _mesa_parse_arb_fragment_program(struct gl_context* ctx, GLenum target,
    struct asm_parser_state state;
    GLuint i;
 
-   ASSERT(target == GL_FRAGMENT_PROGRAM_ARB);
+   assert(target == GL_FRAGMENT_PROGRAM_ARB);
 
    memset(&prog, 0, sizeof(prog));
    memset(&state, 0, sizeof(state));
@@ -84,8 +85,7 @@ _mesa_parse_arb_fragment_program(struct gl_context* ctx, GLenum target,
       return;
    }
 
-   if (program->Base.String != NULL)
-      free(program->Base.String);
+   free(program->Base.String);
 
    /* Copy the relevant contents of the arb_program struct into the
     * fragment_program struct.
@@ -116,22 +116,13 @@ _mesa_parse_arb_fragment_program(struct gl_context* ctx, GLenum target,
          program->Base.SamplersUsed |= (1 << i);
    }
    program->Base.ShadowSamplers = prog.ShadowSamplers;
-   switch (state.option.Fog) {
-   case OPTION_FOG_EXP:    program->FogOption = GL_EXP;    break;
-   case OPTION_FOG_EXP2:   program->FogOption = GL_EXP2;   break;
-   case OPTION_FOG_LINEAR: program->FogOption = GL_LINEAR; break;
-   default:                program->FogOption = GL_NONE;   break;
-   }
    program->OriginUpperLeft = state.option.OriginUpperLeft;
    program->PixelCenterInteger = state.option.PixelCenterInteger;
 
    program->UsesKill            = state.fragment.UsesKill;
+   program->UsesDFdy            = state.fragment.UsesDFdy;
 
-   if (program->FogOption)
-      program->Base.InputsRead |= FRAG_BIT_FOGC;
-
-   if (program->Base.Instructions)
-      free(program->Base.Instructions);
+   free(program->Base.Instructions);
    program->Base.Instructions = prog.Instructions;
 
    if (program->Base.Parameters)
@@ -143,9 +134,15 @@ _mesa_parse_arb_fragment_program(struct gl_context* ctx, GLenum target,
     * there's no hardware that wants to do fog in a discrete stage separate
     * from the fragment shader.
     */
-   if (program->FogOption != GL_NONE) {
-      _mesa_append_fog_code(ctx, program);
-      program->FogOption = GL_NONE;
+   if (state.option.Fog != OPTION_NONE) {
+      static const GLenum fog_modes[4] = {
+        GL_NONE, GL_EXP, GL_EXP2, GL_LINEAR
+      };
+
+      /* XXX: we should somehow recompile this to remove clamping if disabled
+       * On the ATI driver, this is unclampled if fragment clamping is disabled
+       */
+      _mesa_append_fog_code(ctx, program, fog_modes[state.option.Fog], GL_TRUE);
    }
 
 #if DEBUG_FP
@@ -169,7 +166,7 @@ _mesa_parse_arb_vertex_program(struct gl_context *ctx, GLenum target,
    struct gl_program prog;
    struct asm_parser_state state;
 
-   ASSERT(target == GL_VERTEX_PROGRAM_ARB);
+   assert(target == GL_VERTEX_PROGRAM_ARB);
 
    memset(&prog, 0, sizeof(prog));
    memset(&state, 0, sizeof(state));
@@ -181,8 +178,10 @@ _mesa_parse_arb_vertex_program(struct gl_context *ctx, GLenum target,
       return;
    }
 
-   if (program->Base.String != NULL)
-      free(program->Base.String);
+   if ((ctx->_Shader->Flags & GLSL_NO_OPT) == 0)
+      _mesa_optimize_program(ctx, &prog);
+
+   free(program->Base.String);
 
    /* Copy the relevant contents of the arb_program struct into the 
     * vertex_program struct.
@@ -204,8 +203,7 @@ _mesa_parse_arb_vertex_program(struct gl_context *ctx, GLenum target,
    program->IsPositionInvariant = (state.option.PositionInvariant)
       ? GL_TRUE : GL_FALSE;
 
-   if (program->Base.Instructions)
-      free(program->Base.Instructions);
+   free(program->Base.Instructions);
    program->Base.Instructions = prog.Instructions;
 
    if (program->Base.Parameters)