From fa772aa92baf659855f69829fa3f0d0f4fcbc2a6 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 14 Jan 2014 16:02:34 +0800 Subject: [PATCH] ilo: handle NULL renderbuffers correctly Renderbuffers may be NULL since 9baa45f78b8ca7d66280e36009b6a685055d7cd6. --- .../drivers/ilo/ilo_3d_pipeline_gen6.c | 14 +++---- src/gallium/drivers/ilo/ilo_blit.h | 7 +++- src/gallium/drivers/ilo/ilo_gpe.h | 7 ++-- src/gallium/drivers/ilo/ilo_gpe_gen6.c | 37 +++++++++++++------ src/gallium/drivers/ilo/ilo_gpe_gen6.h | 2 +- src/gallium/drivers/ilo/ilo_state.c | 5 ++- 6 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c index f3a5251a9a0..f7cd0d21192 100644 --- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c +++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c @@ -892,7 +892,11 @@ 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]; - if (fb->offset_to_layers) { + if (!surface) { + surface_state[i] = + gen6_emit_SURFACE_STATE(p->dev, &fb->null_rt, true, p->cp); + } + else if (fb->offset_to_layers) { struct ilo_view_surface layer; assert(surface->base.u.tex.first_layer == @@ -920,14 +924,8 @@ gen6_pipeline_state_surfaces_rt(struct ilo_3d_pipeline *p, * brw_update_renderbuffer_surfaces() does. I don't know why. */ if (i == 0) { - struct ilo_view_surface null_surface; - - ilo_gpe_init_view_surface_null(p->dev, - fb->state.width, fb->state.height, - 1, 0, &null_surface); - surface_state[i] = - gen6_emit_SURFACE_STATE(p->dev, &null_surface, true, p->cp); + gen6_emit_SURFACE_STATE(p->dev, &fb->null_rt, true, p->cp); i++; } diff --git a/src/gallium/drivers/ilo/ilo_blit.h b/src/gallium/drivers/ilo/ilo_blit.h index 61fa322c9f5..1e33824d4d7 100644 --- a/src/gallium/drivers/ilo/ilo_blit.h +++ b/src/gallium/drivers/ilo/ilo_blit.h @@ -179,8 +179,11 @@ ilo_blit_resolve_framebuffer(struct ilo_context *ilo) } } - for (i = 0; i < fb->nr_cbufs; i++) - ilo_blit_resolve_surface(ilo, fb->cbufs[i], ILO_TEXTURE_RENDER_WRITE); + for (i = 0; i < fb->nr_cbufs; i++) { + struct pipe_surface *surf = fb->cbufs[i]; + if (surf) + ilo_blit_resolve_surface(ilo, surf, ILO_TEXTURE_RENDER_WRITE); + } if (fb->zsbuf) ilo_blit_resolve_surface(ilo, fb->zsbuf, ILO_TEXTURE_RENDER_WRITE); diff --git a/src/gallium/drivers/ilo/ilo_gpe.h b/src/gallium/drivers/ilo/ilo_gpe.h index d8ddd06eed0..684626d8856 100644 --- a/src/gallium/drivers/ilo/ilo_gpe.h +++ b/src/gallium/drivers/ilo/ilo_gpe.h @@ -256,6 +256,7 @@ struct ilo_surface_cso { struct ilo_fb_state { struct pipe_framebuffer_state state; + struct ilo_view_surface null_rt; struct ilo_zs_surface null_zs; unsigned num_samples; @@ -528,8 +529,8 @@ 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); +ilo_gpe_set_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 b3957272cf0..c8ad38b7782 100644 --- a/src/gallium/drivers/ilo/ilo_gpe_gen6.c +++ b/src/gallium/drivers/ilo/ilo_gpe_gen6.c @@ -2458,21 +2458,30 @@ 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) +ilo_gpe_set_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; + unsigned num_surfaces, first_idx; 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; + ilo_gpe_init_view_surface_null(dev, + state->width, state->height, + 1, 0, &fb->null_rt); + + first = NULL; + for (first_idx = 0; first_idx < state->nr_cbufs; first_idx++) { + if (state->cbufs[first_idx]) { + first = state->cbufs[first_idx]; + break; + } + } + if (!first) + first = state->zsbuf; fb->num_samples = (first) ? first->texture->nr_samples : 1; if (!fb->num_samples) @@ -2484,6 +2493,8 @@ ilo_gpe_init_fb(const struct ilo_dev_info *dev, * The PRMs list several restrictions when the framebuffer has more than * one surface, but it seems they are lifted on GEN7+. */ + num_surfaces = state->nr_cbufs + !!state->zsbuf; + if (dev->gen < ILO_GEN(7) && num_surfaces > 1) { const unsigned first_depth = (first->texture->target == PIPE_TEXTURE_3D) ? @@ -2492,11 +2503,15 @@ ilo_gpe_init_fb(const struct ilo_dev_info *dev, bool has_3d_target = (first->texture->target == PIPE_TEXTURE_3D); unsigned i; - for (i = 1; i < num_surfaces; i++) { + for (i = first_idx + 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) ? + unsigned depth; + + if (!surf) + continue; + + depth = (surf->texture->target == PIPE_TEXTURE_3D) ? surf->texture->depth0 : surf->u.tex.last_layer - surf->u.tex.first_layer + 1; diff --git a/src/gallium/drivers/ilo/ilo_gpe_gen6.h b/src/gallium/drivers/ilo/ilo_gpe_gen6.h index 3c63a7108c9..7d9e93d50e1 100644 --- a/src/gallium/drivers/ilo/ilo_gpe_gen6.h +++ b/src/gallium/drivers/ilo/ilo_gpe_gen6.h @@ -2109,7 +2109,7 @@ gen6_emit_BLEND_STATE(const struct ilo_dev_info *dev, const struct ilo_blend_cso *cso = &blend->cso[idx]; const int num_samples = fb->num_samples; const struct util_format_description *format_desc = - (idx < fb->state.nr_cbufs) ? + (idx < fb->state.nr_cbufs && fb->state.cbufs[idx]) ? util_format_description(fb->state.cbufs[idx]->format) : NULL; bool rt_is_unorm, rt_is_pure_integer, rt_dst_alpha_forced_one; diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c index f9aa76d5382..43dc34756e9 100644 --- a/src/gallium/drivers/ilo/ilo_state.c +++ b/src/gallium/drivers/ilo/ilo_state.c @@ -644,7 +644,7 @@ ilo_set_framebuffer_state(struct pipe_context *pipe, { struct ilo_context *ilo = ilo_context(pipe); - ilo_gpe_init_fb(ilo->dev, state, &ilo->fb); + ilo_gpe_set_fb(ilo->dev, state, &ilo->fb); ilo->dirty |= ILO_DIRTY_FB; } @@ -1310,7 +1310,8 @@ ilo_mark_states_with_resource_dirty(struct ilo_context *ilo, /* for now? */ if (res->target != PIPE_BUFFER) { for (i = 0; i < ilo->fb.state.nr_cbufs; i++) { - if (ilo->fb.state.cbufs[i]->texture == res) { + const struct pipe_surface *surf = ilo->fb.state.cbufs[i]; + if (surf && surf->texture == res) { states |= ILO_DIRTY_FB; break; } -- 2.30.2