i965: Perform program state upload outside of atom handling
[mesa.git] / src / mesa / drivers / dri / i965 / brw_wm.c
index fe36dd422850695d695c83546f6cc737def6010c..a0eda3a8b94537247abc54f4caf26e9f5bf1cd7d 100644 (file)
@@ -116,6 +116,25 @@ brw_compute_barycentric_interp_modes(struct brw_context *brw,
    return barycentric_interp_modes;
 }
 
+static uint8_t
+computed_depth_mode(struct gl_fragment_program *fp)
+{
+   if (fp->Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
+      switch (fp->FragDepthLayout) {
+      case FRAG_DEPTH_LAYOUT_NONE:
+      case FRAG_DEPTH_LAYOUT_ANY:
+         return BRW_PSCDEPTH_ON;
+      case FRAG_DEPTH_LAYOUT_GREATER:
+         return BRW_PSCDEPTH_ON_GE;
+      case FRAG_DEPTH_LAYOUT_LESS:
+         return BRW_PSCDEPTH_ON_LE;
+      case FRAG_DEPTH_LAYOUT_UNCHANGED:
+         return BRW_PSCDEPTH_OFF;
+      }
+   }
+   return BRW_PSCDEPTH_OFF;
+}
+
 bool
 brw_wm_prog_data_compare(const void *in_a, const void *in_b)
 {
@@ -161,6 +180,12 @@ bool do_wm_prog(struct brw_context *brw,
     */
    prog_data.uses_kill = fp->program.UsesKill || key->alpha_test_func;
 
+   prog_data.computed_depth_mode = computed_depth_mode(&fp->program);
+
+   /* Use ALT floating point mode for ARB programs so that 0^0 == 1. */
+   if (!prog)
+      prog_data.base.use_alt_mode = true;
+
    /* Allocate the references to the uniforms that will end up in the
     * prog_data associated with the compiled program, and which will be freed
     * by the state cache.
@@ -557,8 +582,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
    key->program_string_id = fp->id;
 }
 
-
-static void
+void
 brw_upload_wm_prog(struct brw_context *brw)
 {
    struct gl_context *ctx = &brw->ctx;
@@ -566,6 +590,24 @@ brw_upload_wm_prog(struct brw_context *brw)
    struct brw_fragment_program *fp = (struct brw_fragment_program *)
       brw->fragment_program;
 
+   if (!brw_state_dirty(brw,
+                        _NEW_BUFFERS |
+                        _NEW_COLOR |
+                        _NEW_DEPTH |
+                        _NEW_FRAG_CLAMP |
+                        _NEW_HINT |
+                        _NEW_LIGHT |
+                        _NEW_LINE |
+                        _NEW_MULTISAMPLE |
+                        _NEW_POLYGON |
+                        _NEW_STENCIL |
+                        _NEW_TEXTURE,
+                        BRW_NEW_FRAGMENT_PROGRAM |
+                        BRW_NEW_REDUCED_PRIMITIVE |
+                        BRW_NEW_STATS_WM |
+                        BRW_NEW_VUE_MAP_GEOM_OUT))
+      return;
+
    brw_wm_populate_key(brw, &key);
 
    if (!brw_search_cache(&brw->cache, BRW_CACHE_FS_PROG,
@@ -578,26 +620,3 @@ brw_upload_wm_prog(struct brw_context *brw)
    }
    brw->wm.base.prog_data = &brw->wm.prog_data->base;
 }
-
-
-const struct brw_tracked_state brw_wm_prog = {
-   .dirty = {
-      .mesa  = _NEW_BUFFERS |
-               _NEW_COLOR |
-               _NEW_DEPTH |
-               _NEW_FRAG_CLAMP |
-               _NEW_HINT |
-               _NEW_LIGHT |
-               _NEW_LINE |
-               _NEW_MULTISAMPLE |
-               _NEW_POLYGON |
-               _NEW_STENCIL |
-               _NEW_TEXTURE,
-      .brw   = BRW_NEW_FRAGMENT_PROGRAM |
-               BRW_NEW_REDUCED_PRIMITIVE |
-               BRW_NEW_STATS_WM |
-               BRW_NEW_VUE_MAP_GEOM_OUT,
-   },
-   .emit = brw_upload_wm_prog
-};
-