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.
This commit is contained in:
Chia-I Wu 2013-12-20 14:45:59 +08:00
parent 0a2a221d01
commit 011fde4bf2
4 changed files with 137 additions and 20 deletions

View File

@ -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);
}
}
/*

View File

@ -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 */

View File

@ -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,

View File

@ -25,7 +25,6 @@
* Chia-I Wu <olv@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;