From: Chia-I Wu Date: Fri, 20 Dec 2013 06:45:59 +0000 (+0800) Subject: ilo: offset to layers only when necessary X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=011fde4bf2b4337cb07ddc1af8b4398fef9b3648;p=mesa.git 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. --- 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 */ -#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;