Merge remote branch 'origin/master' into lp-setup-llvm
[mesa.git] / src / mesa / drivers / dri / i965 / brw_program.c
index 1cdc8c6411b9775e30066951cf71a5fcbc489a30..1367d8146968ff0e72a12c055840fd21e9d7011b 100644 (file)
@@ -41,7 +41,7 @@
 #include "brw_context.h"
 #include "brw_wm.h"
 
-static void brwBindProgram( GLcontext *ctx,
+static void brwBindProgram( struct gl_context *ctx,
                            GLenum target, 
                            struct gl_program *prog )
 {
@@ -57,7 +57,7 @@ static void brwBindProgram( GLcontext *ctx,
    }
 }
 
-static struct gl_program *brwNewProgram( GLcontext *ctx,
+static struct gl_program *brwNewProgram( struct gl_context *ctx,
                                      GLenum target, 
                                      GLuint id )
 {
@@ -93,14 +93,14 @@ static struct gl_program *brwNewProgram( GLcontext *ctx,
    }
 }
 
-static void brwDeleteProgram( GLcontext *ctx,
+static void brwDeleteProgram( struct gl_context *ctx,
                              struct gl_program *prog )
 {
    _mesa_delete_program( ctx, prog );
 }
 
 
-static GLboolean brwIsProgramNative( GLcontext *ctx,
+static GLboolean brwIsProgramNative( struct gl_context *ctx,
                                     GLenum target, 
                                     struct gl_program *prog )
 {
@@ -108,7 +108,7 @@ static GLboolean brwIsProgramNative( GLcontext *ctx,
 }
 
 static void
-shader_error(GLcontext *ctx, struct gl_program *prog, const char *msg)
+shader_error(struct gl_context *ctx, struct gl_program *prog, const char *msg)
 {
    struct gl_shader_program *shader;
 
@@ -120,7 +120,7 @@ shader_error(GLcontext *ctx, struct gl_program *prog, const char *msg)
    }
 }
 
-static GLboolean brwProgramStringNotify( GLcontext *ctx,
+static GLboolean brwProgramStringNotify( struct gl_context *ctx,
                                          GLenum target,
                                          struct gl_program *prog )
 {
@@ -132,6 +132,7 @@ static GLboolean brwProgramStringNotify( GLcontext *ctx,
       struct brw_fragment_program *newFP = brw_fragment_program(fprog);
       const struct brw_fragment_program *curFP =
          brw_fragment_program_const(brw->fragment_program);
+      struct gl_shader_program *shader_program;
 
       if (fprog->FogOption) {
          _mesa_append_fog_code(ctx, fprog);
@@ -142,6 +143,15 @@ static GLboolean brwProgramStringNotify( GLcontext *ctx,
         brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
       newFP->id = brw->program_id++;      
       newFP->isGLSL = brw_wm_is_glsl(fprog);
+
+      /* Don't reject fragment shaders for their Mesa IR state when we're
+       * using the new FS backend.
+       */
+      shader_program = _mesa_lookup_shader_program(ctx, prog->Id);
+      if (shader_program
+         && shader_program->_LinkedShaders[MESA_SHADER_FRAGMENT]) {
+        return GL_TRUE;
+      }
    }
    else if (target == GL_VERTEX_PROGRAM_ARB) {
       struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog;
@@ -168,6 +178,9 @@ static GLboolean brwProgramStringNotify( GLcontext *ctx,
     * See piglit glsl-{vs,fs}-functions-[23] tests.
     */
    for (i = 0; i < prog->NumInstructions; i++) {
+      struct prog_instruction *inst = prog->Instructions + i;
+      int r;
+
       if (prog->Instructions[i].Opcode == OPCODE_CAL) {
         shader_error(ctx, prog,
                      "i965 driver doesn't yet support uninlined function "
@@ -183,16 +196,20 @@ static GLboolean brwProgramStringNotify( GLcontext *ctx,
         return GL_FALSE;
       }
 
-      if (prog->Instructions[i].DstReg.RelAddr &&
-         prog->Instructions[i].DstReg.File == PROGRAM_INPUT) {
-        shader_error(ctx, prog,
-                     "Variable indexing of shader inputs unsupported\n");
-        return GL_FALSE;
+      for (r = 0; r < _mesa_num_inst_src_regs(inst->Opcode); r++) {
+        if (prog->Instructions[i].SrcReg[r].RelAddr &&
+            prog->Instructions[i].SrcReg[r].File == PROGRAM_INPUT) {
+           shader_error(ctx, prog,
+                        "Variable indexing of shader inputs unsupported\n");
+           return GL_FALSE;
+        }
       }
-      if (prog->Instructions[i].DstReg.RelAddr &&
+
+      if (target == GL_FRAGMENT_PROGRAM_ARB &&
+         prog->Instructions[i].DstReg.RelAddr &&
          prog->Instructions[i].DstReg.File == PROGRAM_OUTPUT) {
         shader_error(ctx, prog,
-                     "Variable indexing of shader outputs unsupported\n");
+                     "Variable indexing of FS outputs unsupported\n");
         return GL_FALSE;
       }
       if (target == GL_FRAGMENT_PROGRAM_ARB) {
@@ -224,5 +241,10 @@ void brwInitFragProgFuncs( struct dd_function_table *functions )
    functions->DeleteProgram = brwDeleteProgram;
    functions->IsProgramNative = brwIsProgramNative;
    functions->ProgramStringNotify = brwProgramStringNotify;
+
+   functions->NewShader = brw_new_shader;
+   functions->NewShaderProgram = brw_new_shader_program;
+   functions->CompileShader = brw_compile_shader;
+   functions->LinkShader = brw_link_shader;
 }