i965/vs: Run the shader backend at link time and return compile failures.
authorEric Anholt <eric@anholt.net>
Thu, 11 Aug 2011 16:52:08 +0000 (09:52 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 16 Aug 2011 20:04:43 +0000 (13:04 -0700)
Link failure is something that shouldn't happen, but we sometimes want
it during development.  The precompile also allows analysis of shader
codegen with shader-db.

src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_shader.cpp
src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
src/mesa/drivers/dri/i965/brw_vs.c
src/mesa/drivers/dri/i965/brw_vs.h

index 693ef0ce31afc9a21c6d1000839a1cc947b91717..b19c6e72fa6bf0d877892aa3fb226d508f1d7a2f 100644 (file)
@@ -1781,7 +1781,7 @@ brw_wm_fs_emit(struct brw_context *brw, struct brw_wm_compile *c,
    fs_visitor v(c, prog, shader);
    if (!v.run()) {
       prog->LinkStatus = GL_FALSE;
-      prog->InfoLog = ralloc_strdup(prog, v.fail_msg);
+      ralloc_strcat(&prog->InfoLog, v.fail_msg);
 
       return false;
    }
index 2dc32c956108b8aa003f45a933e8be721df455b8..3ff6bbaed47eb555989bc4fb72c0327283f384b8 100644 (file)
@@ -24,6 +24,7 @@
 extern "C" {
 #include "main/macros.h"
 #include "brw_context.h"
+#include "brw_vs.h"
 }
 #include "brw_fs.h"
 #include "../glsl/ir_optimization.h"
@@ -67,6 +68,9 @@ brw_shader_precompile(struct gl_context *ctx, struct gl_shader_program *prog)
    if (!brw_fs_precompile(ctx, prog))
       return false;
 
+   if (!brw_vs_precompile(ctx, prog))
+      return false;
+
    return true;
 }
 
index 27160fb40d4913f3f074dc22a6944b0199b887f9..9ef6ab6de908a10ecafee4532e50ac3151c95f15 100644 (file)
@@ -809,14 +809,8 @@ vec4_visitor::generate_code()
 extern "C" {
 
 bool
-brw_vs_emit(struct brw_vs_compile *c)
+brw_vs_emit(struct gl_shader_program *prog, struct brw_vs_compile *c)
 {
-   struct brw_compile *p = &c->func;
-   struct brw_context *brw = p->brw;
-   struct intel_context *intel = &brw->intel;
-   struct gl_context *ctx = &intel->ctx;
-   struct gl_shader_program *prog = ctx->Shader.CurrentVertexProgram;
-
    if (!prog)
       return false;
 
@@ -833,8 +827,8 @@ brw_vs_emit(struct brw_vs_compile *c)
 
    vec4_visitor v(c, prog, shader);
    if (!v.run()) {
-      /* FINISHME: Cleanly fail, test at link time, etc. */
-      assert(!"not reached");
+      prog->LinkStatus = GL_FALSE;
+      ralloc_strcat(&prog->InfoLog, v.fail_msg);
       return false;
    }
 
index d188857959718fa3a7ece9fca0855fb45f4d3c59..b1792a8ee164feb9f521221cb7145633cd5e58f5 100644 (file)
@@ -2012,7 +2012,7 @@ vec4_visitor::vec4_visitor(struct brw_vs_compile *c,
    this->current_annotation = NULL;
 
    this->c = c;
-   this->vp = brw->vertex_program; /* FINISHME: change for precompile */
+   this->vp = prog->VertexProgram;
    this->prog_data = &c->prog_data;
 
    this->variable_ht = hash_table_ctor(0,
index d389f602fba3b106e26d4aab3afb5492b200c6c8..3373e707d98877aa38257cc865ec183a73bcdbf8 100644 (file)
 
 #include "../glsl/ralloc.h"
 
-static void do_vs_prog( struct brw_context *brw, 
-                       struct brw_vertex_program *vp,
-                       struct brw_vs_prog_key *key )
+static bool
+do_vs_prog(struct brw_context *brw,
+          struct gl_shader_program *prog,
+          struct brw_vertex_program *vp,
+          struct brw_vs_prog_key *key)
 {
    struct gl_context *ctx = &brw->intel.ctx;
    struct intel_context *intel = &brw->intel;
@@ -91,9 +93,11 @@ static void do_vs_prog( struct brw_context *brw,
    if (new_vs == -1)
       new_vs = getenv("INTEL_NEW_VS") != NULL;
 
-   if (new_vs) {
-      if (!brw_vs_emit(&c))
-        brw_old_vs_emit(&c);
+   if (new_vs && prog) {
+      if (!brw_vs_emit(prog, &c)) {
+        ralloc_free(mem_ctx);
+        return false;
+      }
    } else {
       brw_old_vs_emit(&c);
    }
@@ -130,6 +134,8 @@ static void do_vs_prog( struct brw_context *brw,
                    &c.prog_data, aux_size,
                    &brw->vs.prog_offset, &brw->vs.prog_data);
    ralloc_free(mem_ctx);
+
+   return true;
 }
 
 
@@ -174,13 +180,15 @@ static void brw_upload_vs_prog(struct brw_context *brw)
    if (!brw_search_cache(&brw->cache, BRW_VS_PROG,
                         &key, sizeof(key),
                         &brw->vs.prog_offset, &brw->vs.prog_data)) {
-      do_vs_prog(brw, vp, &key);
+      bool success = do_vs_prog(brw, ctx->Shader.CurrentVertexProgram,
+                               vp, &key);
+
+      assert(success);
    }
    brw->vs.constant_map = ((int8_t *)brw->vs.prog_data +
                           sizeof(*brw->vs.prog_data));
 }
 
-
 /* See brw_vs.c:
  */
 const struct brw_tracked_state brw_vs_prog = {
@@ -193,3 +201,30 @@ const struct brw_tracked_state brw_vs_prog = {
    },
    .prepare = brw_upload_vs_prog
 };
+
+bool
+brw_vs_precompile(struct gl_context *ctx, struct gl_shader_program *prog)
+{
+   struct brw_context *brw = brw_context(ctx);
+   struct brw_vs_prog_key key;
+   struct gl_vertex_program *vp = prog->VertexProgram;
+   struct brw_vertex_program *bvp = brw_vertex_program(vp);
+   uint32_t old_prog_offset = brw->vs.prog_offset;
+   struct brw_vs_prog_data *old_prog_data = brw->vs.prog_data;
+   bool success;
+
+   if (!vp)
+      return true;
+
+   memset(&key, 0, sizeof(key));
+
+   key.program_string_id = bvp->id;
+   key.clamp_vertex_color = true;
+
+   success = do_vs_prog(brw, prog, bvp, &key);
+
+   brw->vs.prog_offset = old_prog_offset;
+   brw->vs.prog_data = old_prog_data;
+
+   return success;
+}
index 83a37f5b800b7bfa84ef95e6b694028df1388ca7..beccb381ee267ab32a52414c663c9ea0ed9dcc6d 100644 (file)
@@ -93,7 +93,8 @@ struct brw_vs_compile {
    GLboolean needs_stack;
 };
 
-bool brw_vs_emit(struct brw_vs_compile *c);
+bool brw_vs_emit(struct gl_shader_program *prog, struct brw_vs_compile *c);
 void brw_old_vs_emit(struct brw_vs_compile *c);
+bool brw_vs_precompile(struct gl_context *ctx, struct gl_shader_program *prog);
 
 #endif