glsl: fix crash in loop analysis when some controls can't be determined
[mesa.git] / src / gallium / drivers / i965 / brw_vs.c
index 53a5560105d56b14a149336ee34b1b47722f31a1..ca8ee79550d3ea7efa9dfefb8f6ea337cb207ae1 100644 (file)
   * Authors:
   *   Keith Whitwell <keith@tungstengraphics.com>
   */
-           
+
+#include "tgsi/tgsi_dump.h"           
 
 #include "brw_context.h"
 #include "brw_vs.h"
-#include "brw_util.h"
 #include "brw_state.h"
-#include "shader/prog_print.h"
 
 
 
-static void do_vs_prog( struct brw_context *brw, 
-                       struct brw_vertex_program *vp,
-                       struct brw_vs_prog_key *key )
+static enum pipe_error do_vs_prog( struct brw_context *brw, 
+                                   struct brw_vertex_shader *vp,
+                                   struct brw_vs_prog_key *key,
+                                   struct brw_winsys_buffer **bo_out)
 {
+   enum pipe_error ret;
    GLuint program_size;
    const GLuint *program;
    struct brw_vs_compile c;
@@ -52,16 +53,11 @@ static void do_vs_prog( struct brw_context *brw,
    brw_init_compile(brw, &c.func);
    c.vp = vp;
 
-   c.prog_data.outputs_written = vp->program.Base.OutputsWritten;
-   c.prog_data.inputs_read = vp->program.Base.InputsRead;
-
-   if (c.key.copy_edgeflag) {
-      c.prog_data.outputs_written |= 1<<VERT_RESULT_EDGE;
-      c.prog_data.inputs_read |= 1<<VERT_ATTRIB_EDGEFLAG;
-   }
+   c.prog_data.nr_outputs = vp->info.num_outputs;
+   c.prog_data.nr_inputs = vp->info.num_inputs;
 
-   if (0)
-      tgsi_dump(&c.vp->tokens, 0);
+   if (1)
+      tgsi_dump(c.vp->tokens, 0);
 
    /* Emit GEN4 code.
     */
@@ -69,44 +65,53 @@ static void do_vs_prog( struct brw_context *brw,
 
    /* get the program
     */
-   program = brw_get_program(&c.func, &program_size);
-
-   dri_bo_unreference(brw->vs.prog_bo);
-   brw->vs.prog_bo = brw_upload_cache( &brw->cache, BRW_VS_PROG,
-                                      &c.key, sizeof(c.key),
-                                      NULL, 0,
-                                      program, program_size,
-                                      &c.prog_data,
-                                      &brw->vs.prog_data );
+   ret = brw_get_program(&c.func, &program, &program_size);
+   if (ret)
+      return ret;
+
+   ret = brw_upload_cache( &brw->cache, BRW_VS_PROG,
+                           &c.key, brw_vs_prog_key_size(&c.key),
+                           NULL, 0,
+                           program, program_size,
+                           &c.prog_data,
+                           &brw->vs.prog_data,
+                           bo_out);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
 }
 
 
-static void brw_upload_vs_prog(struct brw_context *brw)
+static enum pipe_error brw_upload_vs_prog(struct brw_context *brw)
 {
-   GLcontext *ctx = &brw->intel.ctx;
    struct brw_vs_prog_key key;
-   struct brw_vertex_program *vp = 
-      (struct brw_vertex_program *)brw->vertex_program;
+   struct brw_vertex_shader *vp = brw->curr.vertex_shader;
+   struct brw_fs_signature *sig = &brw->curr.fragment_shader->signature;
+   enum pipe_error ret;
 
    memset(&key, 0, sizeof(key));
 
-   /* Just upload the program verbatim for now.  Always send it all
-    * the inputs it asks for, whether they are varying or not.
-    */
    key.program_string_id = vp->id;
-   key.nr_userclip = brw->nr_userclip;
-   key.copy_edgeflag = (brw->rast->fill_ccw != PIPE_POLYGON_MODE_FILL ||
-                       brw->rast->fill_cw != PIPE_POLYGON_MODE_FILL);
+   key.nr_userclip = brw->curr.ucp.nr;
+
+   memcpy(&key.fs_signature, sig, brw_fs_signature_size(sig));
+
 
    /* Make an early check for the key.
     */
-   dri_bo_unreference(brw->vs.prog_bo);
-   brw->vs.prog_bo = brw_search_cache(&brw->cache, BRW_VS_PROG,
-                                     &key, sizeof(key),
-                                     NULL, 0,
-                                     &brw->vs.prog_data);
-   if (brw->vs.prog_bo == NULL)
-      do_vs_prog(brw, vp, &key);
+   if (brw_search_cache(&brw->cache, BRW_VS_PROG,
+                        &key, brw_vs_prog_key_size(&key),
+                        NULL, 0,
+                        &brw->vs.prog_data,
+                        &brw->vs.prog_bo))
+      return PIPE_OK;
+
+   ret = do_vs_prog(brw, vp, &key, &brw->vs.prog_bo);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
 }
 
 
@@ -114,7 +119,9 @@ static void brw_upload_vs_prog(struct brw_context *brw)
  */
 const struct brw_tracked_state brw_vs_prog = {
    .dirty = {
-      .mesa  = PIPE_NEW_UCP | PIPE_NEW_RAST,
+      .mesa  = (PIPE_NEW_CLIP | 
+                PIPE_NEW_RAST |
+                PIPE_NEW_FRAGMENT_SIGNATURE),
       .brw   = BRW_NEW_VERTEX_PROGRAM,
       .cache = 0
    },