diff options
-rw-r--r-- | src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c | 42 | ||||
-rw-r--r-- | src/gallium/drivers/ilo/ilo_gpe.h | 7 | ||||
-rw-r--r-- | src/gallium/drivers/ilo/ilo_gpe_gen6.c | 89 | ||||
-rw-r--r-- | 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 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; |