Mesa (master): ilo: offset to layers only when necessary

Chia-I Wu olv at kemper.freedesktop.org
Wed Jan 8 10:13:10 UTC 2014


Module: Mesa
Branch: master
Commit: 011fde4bf2b4337cb07ddc1af8b4398fef9b3648
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=011fde4bf2b4337cb07ddc1af8b4398fef9b3648

Author: Chia-I Wu <olvaffe at gmail.com>
Date:   Fri Dec 20 14:45:59 2013 +0800

ilo: offset to layers only when necessary

GEN6 has several requirements regarding the LOD/Depth/Width/Height of the
render targets and the depth buffer.  We used to offset to the layers in
question unconditionally to meet the requirements.  With this commit,
offseting is done only when the requirements are not met.

---

 src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c |   42 +++++++++--
 src/gallium/drivers/ilo/ilo_gpe.h              |    7 ++
 src/gallium/drivers/ilo/ilo_gpe_gen6.c         |   89 ++++++++++++++++++++++++
 src/gallium/drivers/ilo/ilo_state.c            |   19 ++---
 4 files changed, 137 insertions(+), 20 deletions(-)

diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
index b585fd6..ce12dd4 100644
--- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
+++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
@@ -723,13 +723,27 @@ gen6_pipeline_wm_depth(struct ilo_3d_pipeline *p,
    /* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */
    if (DIRTY(FB) || session->batch_bo_changed) {
       const struct ilo_zs_surface *zs;
+      struct ilo_zs_surface layer;
 
       if (ilo->fb.state.zsbuf) {
          const struct ilo_surface_cso *surface =
             (const struct ilo_surface_cso *) ilo->fb.state.zsbuf;
 
-         assert(!surface->is_rt);
-         zs = &surface->u.zs;
+         if (ilo->fb.offset_to_layers) {
+            assert(surface->base.u.tex.first_layer ==
+                  surface->base.u.tex.last_layer);
+
+            ilo_gpe_init_zs_surface(ilo->dev,
+                  ilo_texture(surface->base.texture),
+                  surface->base.format, surface->base.u.tex.level,
+                  surface->base.u.tex.first_layer, 1, true, &layer);
+
+            zs = &layer;
+         }
+         else {
+            assert(!surface->is_rt);
+            zs = &surface->u.zs;
+         }
       }
       else {
          zs = &ilo->fb.null_zs;
@@ -875,9 +889,27 @@ gen6_pipeline_state_surfaces_rt(struct ilo_3d_pipeline *p,
          const struct ilo_surface_cso *surface =
             (const struct ilo_surface_cso *) fb->state.cbufs[i];
 
-         assert(surface && surface->is_rt);
-         surface_state[i] =
-            gen6_emit_SURFACE_STATE(p->dev, &surface->u.rt, true, p->cp);
+         if (fb->offset_to_layers) {
+            struct ilo_view_surface layer;
+
+            assert(surface->base.u.tex.first_layer ==
+                  surface->base.u.tex.last_layer);
+
+            ilo_gpe_init_view_surface_for_texture(ilo->dev,
+                  ilo_texture(surface->base.texture),
+                  surface->base.format,
+                  surface->base.u.tex.level, 1,
+                  surface->base.u.tex.first_layer, 1,
+                  true, true, &layer);
+
+            surface_state[i] =
+               gen6_emit_SURFACE_STATE(p->dev, &layer, true, p->cp);
+         }
+         else {
+            assert(surface && surface->is_rt);
+            surface_state[i] =
+               gen6_emit_SURFACE_STATE(p->dev, &surface->u.rt, true, p->cp);
+         }
       }
 
       /*
diff --git a/src/gallium/drivers/ilo/ilo_gpe.h b/src/gallium/drivers/ilo/ilo_gpe.h
index 9347d88..d8ddd06 100644
--- a/src/gallium/drivers/ilo/ilo_gpe.h
+++ b/src/gallium/drivers/ilo/ilo_gpe.h
@@ -257,7 +257,9 @@ struct ilo_fb_state {
    struct pipe_framebuffer_state state;
 
    struct ilo_zs_surface null_zs;
+
    unsigned num_samples;
+   bool offset_to_layers;
 };
 
 struct ilo_global_binding {
@@ -525,4 +527,9 @@ ilo_gpe_init_fs_cso(const struct ilo_dev_info *dev,
    }
 }
 
+void
+ilo_gpe_init_fb(const struct ilo_dev_info *dev,
+                const struct pipe_framebuffer_state *state,
+                struct ilo_fb_state *fb);
+
 #endif /* ILO_GPE_H */
diff --git a/src/gallium/drivers/ilo/ilo_gpe_gen6.c b/src/gallium/drivers/ilo/ilo_gpe_gen6.c
index a84cb4d..d4c0398 100644
--- a/src/gallium/drivers/ilo/ilo_gpe_gen6.c
+++ b/src/gallium/drivers/ilo/ilo_gpe_gen6.c
@@ -26,6 +26,7 @@
  */
 
 #include "util/u_dual_blend.h"
+#include "util/u_framebuffer.h"
 #include "util/u_half.h"
 #include "brw_defines.h"
 #include "intel_reg.h"
@@ -2454,6 +2455,94 @@ ilo_gpe_init_sampler_cso(const struct ilo_dev_info *dev,
    }
 }
 
+void
+ilo_gpe_init_fb(const struct ilo_dev_info *dev,
+                const struct pipe_framebuffer_state *state,
+                struct ilo_fb_state *fb)
+{
+   const struct pipe_surface *first;
+   unsigned num_surfaces;
+
+   ILO_GPE_VALID_GEN(dev, 6, 7.5);
+
+   util_copy_framebuffer_state(&fb->state, state);
+
+   first = (state->nr_cbufs) ? state->cbufs[0] :
+           (state->zsbuf) ? state->zsbuf :
+           NULL;
+   num_surfaces = state->nr_cbufs + !!state->zsbuf;
+
+   fb->num_samples = (first) ? first->texture->nr_samples : 1;
+   if (!fb->num_samples)
+      fb->num_samples = 1;
+
+   fb->offset_to_layers = false;
+
+   if (num_surfaces > 1) {
+      const unsigned first_depth =
+         (first->texture->target == PIPE_TEXTURE_3D) ?
+         first->texture->depth0 :
+         first->u.tex.last_layer - first->u.tex.first_layer + 1;
+      bool has_3d_target = (first->texture->target == PIPE_TEXTURE_3D);
+      unsigned i;
+
+      for (i = 1; i < num_surfaces; i++) {
+         const struct pipe_surface *surf =
+            (i < state->nr_cbufs) ? state->cbufs[i] : state->zsbuf;
+         const unsigned depth =
+            (surf->texture->target == PIPE_TEXTURE_3D) ?
+            surf->texture->depth0 :
+            surf->u.tex.last_layer - surf->u.tex.first_layer + 1;
+
+         has_3d_target |= (surf->texture->target == PIPE_TEXTURE_3D);
+
+         /*
+          * From the Sandy Bridge PRM, volume 4 part 1, page 79:
+          *
+          *     "The LOD of a render target must be the same as the LOD of the
+          *      other render target(s) and of the depth buffer (defined in
+          *      3DSTATE_DEPTH_BUFFER)."
+          *
+          * From the Sandy Bridge PRM, volume 4 part 1, page 81:
+          *
+          *     "The Depth of a render target must be the same as the Depth of
+          *      the other render target(s) and of the depth buffer (defined
+          *      in 3DSTATE_DEPTH_BUFFER)."
+          */
+         if (surf->u.tex.level != first->u.tex.level ||
+             depth != first_depth) {
+            fb->offset_to_layers = true;
+            break;
+         }
+
+         /*
+          * From the Sandy Bridge PRM, volume 4 part 1, page 77:
+          *
+          *     "The Height of a render target must be the same as the Height
+          *      of the other render targets and the depth buffer (defined in
+          *      3DSTATE_DEPTH_BUFFER), unless Surface Type is SURFTYPE_1D or
+          *      SURFTYPE_2D with Depth = 0 (non-array) and LOD = 0 (non-mip
+          *      mapped)."
+          *
+          * From the Sandy Bridge PRM, volume 4 part 1, page 78:
+          *
+          *     "The Width of a render target must be the same as the Width of
+          *      the other render target(s) and the depth buffer (defined in
+          *      3DSTATE_DEPTH_BUFFER), unless Surface Type is SURFTYPE_1D or
+          *      SURFTYPE_2D with Depth = 0 (non-array) and LOD = 0 (non-mip
+          *      mapped)."
+          */
+         if (surf->texture->width0 != first->texture->width0 ||
+             surf->texture->height0 != first->texture->height0) {
+            if (has_3d_target || first->u.tex.level || first_depth > 1) {
+               fb->offset_to_layers = true;
+               break;
+            }
+         }
+      }
+   }
+}
+
 int
 ilo_gpe_gen6_estimate_command_size(const struct ilo_dev_info *dev,
                                    enum ilo_gpe_gen6_command cmd,
diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c
index 4953e52..f9aa76d 100644
--- a/src/gallium/drivers/ilo/ilo_state.c
+++ b/src/gallium/drivers/ilo/ilo_state.c
@@ -25,7 +25,6 @@
  *    Chia-I Wu <olv at lunarg.com>
  */
 
-#include "util/u_framebuffer.h"
 #include "util/u_helpers.h"
 #include "util/u_upload_mgr.h"
 
@@ -645,17 +644,7 @@ ilo_set_framebuffer_state(struct pipe_context *pipe,
 {
    struct ilo_context *ilo = ilo_context(pipe);
 
-   util_copy_framebuffer_state(&ilo->fb.state, state);
-
-   if (state->nr_cbufs)
-      ilo->fb.num_samples = state->cbufs[0]->texture->nr_samples;
-   else if (state->zsbuf)
-      ilo->fb.num_samples = state->zsbuf->texture->nr_samples;
-   else
-      ilo->fb.num_samples = 1;
-
-   if (!ilo->fb.num_samples)
-      ilo->fb.num_samples = 1;
+   ilo_gpe_init_fb(ilo->dev, state, &ilo->fb);
 
    ilo->dirty |= ILO_DIRTY_FB;
 }
@@ -943,7 +932,7 @@ ilo_create_sampler_view(struct pipe_context *pipe,
             templ->u.tex.last_level - templ->u.tex.first_level + 1,
             templ->u.tex.first_layer,
             templ->u.tex.last_layer - templ->u.tex.first_layer + 1,
-            false, true, &view->surface);
+            false, false, &view->surface);
    }
 
    return &view->base;
@@ -991,7 +980,7 @@ ilo_create_surface(struct pipe_context *pipe,
             templ->format, templ->u.tex.level, 1,
             templ->u.tex.first_layer,
             templ->u.tex.last_layer - templ->u.tex.first_layer + 1,
-            true, true, &surf->u.rt);
+            true, false, &surf->u.rt);
    }
    else {
       assert(res->target != PIPE_BUFFER);
@@ -1000,7 +989,7 @@ ilo_create_surface(struct pipe_context *pipe,
             templ->format, templ->u.tex.level,
             templ->u.tex.first_layer,
             templ->u.tex.last_layer - templ->u.tex.first_layer + 1,
-            true, &surf->u.zs);
+            false, &surf->u.zs);
    }
 
    return &surf->base;




More information about the mesa-commit mailing list