summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c42
-rw-r--r--src/gallium/drivers/ilo/ilo_gpe.h7
-rw-r--r--src/gallium/drivers/ilo/ilo_gpe_gen6.c89
-rw-r--r--src/gallium/drivers/ilo/ilo_state.c19
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 b585fd6052d..ce12dd46e51 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 9347d889d83..d8ddd06eed0 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 a84cb4d565e..d4c0398a1f2 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 4953e52ec68..f9aa76d5382 100644
--- a/src/gallium/drivers/ilo/ilo_state.c
+++ b/src/gallium/drivers/ilo/ilo_state.c
@@ -25,7 +25,6 @@
* Chia-I Wu <[email protected]>
*/
-#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;