i915g: implement early z
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Mon, 14 Mar 2011 21:13:01 +0000 (22:13 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 15 Mar 2011 17:36:25 +0000 (18:36 +0100)
v2: Make it actually work.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
src/gallium/drivers/i915/i915_reg.h
src/gallium/drivers/i915/i915_state.h
src/gallium/drivers/i915/i915_state_derived.c
src/gallium/drivers/i915/i915_state_static.c

index 5e4e80ddf6b2504a308bb298d5dd793ac9194294..6fe032cdb6eeb071d4bba0d46f9712cbda56b167 100644 (file)
 /* p161 */
 #define _3DSTATE_DST_BUF_VARS_CMD      (CMD_3D | (0x1d<<24) | (0x85<<16))
 /* Dword 1 */
+#define CLASSIC_EARLY_DEPTH             (1<<31)
 #define TEX_DEFAULT_COLOR_OGL           (0<<30)
 #define TEX_DEFAULT_COLOR_D3D           (1<<30)
 #define ZR_EARLY_DEPTH                  (1<<29)
index b4074dc35ba9d3964efc0487be0a89b3ae23c783..3f4e40294e63aacaeb57a1bcfd7febbc318b991d 100644 (file)
@@ -48,6 +48,7 @@ extern struct i915_tracked_state i915_hw_immediate;
 extern struct i915_tracked_state i915_hw_dynamic;
 extern struct i915_tracked_state i915_hw_fs;
 extern struct i915_tracked_state i915_hw_framebuffer;
+extern struct i915_tracked_state i915_hw_dst_buf_vars;
 extern struct i915_tracked_state i915_hw_constants;
 
 void i915_update_derived(struct i915_context *i915);
index 1d4026a214e9d9e6504d3e4432052a78efe82b09..59ac2f7292a207f84b6ff8987e11df2d1802834f 100644 (file)
@@ -165,6 +165,7 @@ static struct i915_tracked_state *atoms[] = {
    &i915_hw_dynamic,
    &i915_hw_fs,
    &i915_hw_framebuffer,
+   &i915_hw_dst_buf_vars,
    &i915_hw_constants,
    NULL,
 };
index 39d6a4c8b9657b883550edc26abbe3056fdb191e..44449bec0444f6917fa7daa25bb0536f7e6d3e3d 100644 (file)
@@ -28,6 +28,7 @@
 #include "i915_context.h"
 #include "i915_state.h"
 #include "i915_resource.h"
+#include "i915_screen.h"
 
 
 
@@ -82,10 +83,9 @@ static void update_framebuffer(struct i915_context *i915)
 {
    struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0];
    struct pipe_surface *depth_surface = i915->framebuffer.zsbuf;
-   unsigned cformat, zformat;
    unsigned x, y;
    int layer;
-   uint32_t draw_offset, draw_size, dst_buf_vars;
+   uint32_t draw_offset, draw_size;
 
    if (cbuf_surface) {
       struct i915_texture *tex = i915_texture(cbuf_surface->texture);
@@ -95,7 +95,6 @@ static void update_framebuffer(struct i915_context *i915)
       i915->current.cbuf_flags = BUF_3D_ID_COLOR_BACK |
                                  BUF_3D_PITCH(tex->stride) |  /* pitch in bytes */
                                  buf_3d_tiling_bits(tex->tiling);
-      cformat = cbuf_surface->format;
 
       layer = cbuf_surface->u.tex.first_layer;
 
@@ -103,10 +102,8 @@ static void update_framebuffer(struct i915_context *i915)
       y = tex->image_offset[cbuf_surface->u.tex.level][layer].nblocksy;
    } else {
       i915->current.cbuf_bo = NULL;
-      cformat = PIPE_FORMAT_B8G8R8A8_UNORM; /* arbitrary */
       x = y = 0;
    }
-   cformat = translate_format(cformat);
    i915->static_dirty |= I915_DST_BUF_COLOR;
 
    /* What happens if no zbuf??
@@ -122,24 +119,10 @@ static void update_framebuffer(struct i915_context *i915)
       i915->current.depth_flags = BUF_3D_ID_DEPTH |
                                   BUF_3D_PITCH(tex->stride) |  /* pitch in bytes */
                                   buf_3d_tiling_bits(tex->tiling);
-      zformat = translate_depth_format(depth_surface->format);
-   } else {
+   } else
       i915->current.depth_bo = NULL;
-      zformat = 0;
-   }
    i915->static_dirty |= I915_DST_BUF_DEPTH;
 
-   dst_buf_vars = DSTORG_HORT_BIAS(0x8) | /* .5 */
-                  DSTORG_VERT_BIAS(0x8) | /* .5 */
-                  LOD_PRECLAMP_OGL |
-                  TEX_DEFAULT_COLOR_OGL |
-                  cformat |
-                  zformat;
-   if (i915->current.dst_buf_vars != dst_buf_vars) {
-      i915->current.dst_buf_vars = dst_buf_vars;
-      i915->static_dirty |= I915_DST_VARS;
-   }
-
    /* drawing rect calculations */
    draw_offset = x | (y << 16);
    draw_size = (i915->framebuffer.width - 1 + x) |
@@ -164,3 +147,52 @@ struct i915_tracked_state i915_hw_framebuffer = {
    update_framebuffer,
    I915_NEW_FRAMEBUFFER
 };
+
+static void update_dst_buf_vars(struct i915_context *i915)
+{
+   struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0];
+   struct pipe_surface *depth_surface = i915->framebuffer.zsbuf;
+   uint32_t dst_buf_vars, cformat, zformat;
+   uint32_t early_z = 0;
+
+   if (cbuf_surface)
+      cformat = cbuf_surface->format;
+   else
+      cformat = PIPE_FORMAT_B8G8R8A8_UNORM; /* arbitrary */
+   cformat = translate_format(cformat);
+
+   if (depth_surface) {
+      struct i915_texture *tex = i915_texture(depth_surface->texture);
+      struct i915_screen *is = i915_screen(i915->base.screen);
+
+      zformat = translate_depth_format(depth_surface->format);
+
+      if (is->is_i945 && tex->tiling != I915_TILE_NONE
+            && !i915->fs->info.writes_z)
+         early_z = CLASSIC_EARLY_DEPTH;
+   } else
+      zformat = 0;
+
+   dst_buf_vars = DSTORG_HORT_BIAS(0x8) | /* .5 */
+                  DSTORG_VERT_BIAS(0x8) | /* .5 */
+                  LOD_PRECLAMP_OGL |
+                  TEX_DEFAULT_COLOR_OGL |
+                  cformat |
+                  zformat |
+                  early_z;
+
+   if (i915->current.dst_buf_vars != dst_buf_vars) {
+      if (early_z != (i915->current.dst_buf_vars & CLASSIC_EARLY_DEPTH))
+         i915_set_flush_dirty(i915, I915_PIPELINE_FLUSH);
+
+      i915->current.dst_buf_vars = dst_buf_vars;
+      i915->static_dirty |= I915_DST_VARS;
+      i915->hardware_dirty |= I915_HW_STATIC;
+   }
+}
+
+struct i915_tracked_state i915_hw_dst_buf_vars = {
+   "dst buf vars",
+   update_dst_buf_vars,
+   I915_NEW_FRAMEBUFFER | I915_NEW_FS
+};