From 99725d2f8ae2e2d0dd1e80ac05b127c7f99778d3 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 30 May 2013 19:48:32 +0800 Subject: [PATCH] ilo: construct SCISSOR_RECT in set_scissor_states() This allows us to memcpy() the state in draw_vbo(). Add ilo_init_states() and ilo_cleanup_states() that are called when contexts are created and destroyed respectively, and properly set the initial scissor state in ilo_init_states(). --- .../drivers/ilo/ilo_3d_pipeline_gen6.c | 2 +- src/gallium/drivers/ilo/ilo_context.c | 4 ++ src/gallium/drivers/ilo/ilo_gpe.h | 14 +++- src/gallium/drivers/ilo/ilo_gpe_gen6.c | 72 ++++++++++++++----- src/gallium/drivers/ilo/ilo_gpe_gen6.h | 4 +- src/gallium/drivers/ilo/ilo_state.c | 16 ++++- src/gallium/drivers/ilo/ilo_state.h | 6 ++ 7 files changed, 92 insertions(+), 26 deletions(-) diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c index f2bdf371d60..43f0056522c 100644 --- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c +++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c @@ -839,7 +839,7 @@ gen6_pipeline_state_scissors(struct ilo_3d_pipeline *p, if (DIRTY(SCISSOR) || DIRTY(VIEWPORT)) { /* there should be as many scissors as there are viewports */ p->state.SCISSOR_RECT = p->gen6_SCISSOR_RECT(p->dev, - ilo->scissor.states, ilo->viewport.count, p->cp); + &ilo->scissor, ilo->viewport.count, p->cp); session->scissor_state_changed = true; } diff --git a/src/gallium/drivers/ilo/ilo_context.c b/src/gallium/drivers/ilo/ilo_context.c index 11e868f405d..a3b1c5e4d92 100644 --- a/src/gallium/drivers/ilo/ilo_context.c +++ b/src/gallium/drivers/ilo/ilo_context.c @@ -91,6 +91,8 @@ ilo_context_destroy(struct pipe_context *pipe) { struct ilo_context *ilo = ilo_context(pipe); + ilo_cleanup_states(ilo); + if (ilo->last_cp_bo) ilo->last_cp_bo->unreference(ilo->last_cp_bo); @@ -148,6 +150,8 @@ ilo_context_create(struct pipe_screen *screen, void *priv) ilo_init_video_functions(ilo); ilo_init_gpgpu_functions(ilo); + ilo_init_states(ilo); + /* this must be called last as u_blitter is a client of the pipe context */ ilo->blitter = util_blitter_create(&ilo->base); if (!ilo->blitter) { diff --git a/src/gallium/drivers/ilo/ilo_gpe.h b/src/gallium/drivers/ilo/ilo_gpe.h index 044076b522c..810a625730c 100644 --- a/src/gallium/drivers/ilo/ilo_gpe.h +++ b/src/gallium/drivers/ilo/ilo_gpe.h @@ -95,7 +95,8 @@ struct ilo_viewport_state { }; struct ilo_scissor_state { - struct pipe_scissor_state states[ILO_MAX_VIEWPORTS]; + /* SCISSOR_RECT */ + uint32_t payload[ILO_MAX_VIEWPORTS * 2]; }; struct ilo_rasterizer_state { @@ -163,4 +164,15 @@ ilo_gpe_set_viewport_cso(const struct ilo_dev_info *dev, const struct pipe_viewport_state *state, struct ilo_viewport_cso *vp); +void +ilo_gpe_set_scissor(const struct ilo_dev_info *dev, + unsigned start_slot, + unsigned num_states, + const struct pipe_scissor_state *states, + struct ilo_scissor_state *scissor); + +void +ilo_gpe_set_scissor_null(const struct ilo_dev_info *dev, + struct ilo_scissor_state *scissor); + #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 a2a24154be7..91dff27be72 100644 --- a/src/gallium/drivers/ilo/ilo_gpe_gen6.c +++ b/src/gallium/drivers/ilo/ilo_gpe_gen6.c @@ -3502,16 +3502,63 @@ gen6_emit_DEPTH_STENCIL_STATE(const struct ilo_dev_info *dev, return state_offset; } +void +ilo_gpe_set_scissor(const struct ilo_dev_info *dev, + unsigned start_slot, + unsigned num_states, + const struct pipe_scissor_state *states, + struct ilo_scissor_state *scissor) +{ + unsigned i; + + ILO_GPE_VALID_GEN(dev, 6, 7); + + for (i = 0; i < num_states; i++) { + uint16_t min_x, min_y, max_x, max_y; + + /* both max and min are inclusive in SCISSOR_RECT */ + if (states[i].minx < states[i].maxx && + states[i].miny < states[i].maxy) { + min_x = states[i].minx; + min_y = states[i].miny; + max_x = states[i].maxx - 1; + max_y = states[i].maxy - 1; + } + else { + /* we have to make min greater than max */ + min_x = 1; + min_y = 1; + max_x = 0; + max_y = 0; + } + + scissor->payload[start_slot * 2 + 0] = min_y << 16 | min_x; + scissor->payload[start_slot * 2 + 1] = max_y << 16 | max_x; + start_slot++; + } +} + +void +ilo_gpe_set_scissor_null(const struct ilo_dev_info *dev, + struct ilo_scissor_state *scissor) +{ + unsigned i; + + for (i = 0; i < Elements(scissor->payload); i += 2) { + scissor->payload[i + 0] = 1 << 16 | 1; + scissor->payload[i + 1] = 0; + } +} + static uint32_t gen6_emit_SCISSOR_RECT(const struct ilo_dev_info *dev, - const struct pipe_scissor_state *scissors, - int num_scissors, + const struct ilo_scissor_state *scissor, + unsigned num_viewports, struct ilo_cp *cp) { const int state_align = 32 / 4; - const int state_len = 2 * num_scissors; + const int state_len = 2 * num_viewports; uint32_t state_offset, *dw; - int i; ILO_GPE_VALID_GEN(dev, 6, 7); @@ -3521,25 +3568,12 @@ gen6_emit_SCISSOR_RECT(const struct ilo_dev_info *dev, * "The viewport-specific state used by the SF unit (SCISSOR_RECT) is * stored as an array of up to 16 elements..." */ - assert(num_scissors && num_scissors <= 16); + assert(num_viewports && num_viewports <= 16); dw = ilo_cp_steal_ptr(cp, "SCISSOR_RECT", state_len, state_align, &state_offset); - for (i = 0; i < num_scissors; i++) { - if (scissors[i].minx < scissors[i].maxx && - scissors[i].miny < scissors[i].maxy) { - dw[0] = scissors[i].miny << 16 | scissors[i].minx; - dw[1] = (scissors[i].maxy - 1) << 16 | (scissors[i].maxx - 1); - } - else { - /* we have to make min greater than max as they are both inclusive */ - dw[0] = 1 << 16 | 1; - dw[1] = 0; - } - - dw += 2; - } + memcpy(dw, scissor->payload, state_len * 4); return state_offset; } diff --git a/src/gallium/drivers/ilo/ilo_gpe_gen6.h b/src/gallium/drivers/ilo/ilo_gpe_gen6.h index 301ff8be502..a44e1ebf148 100644 --- a/src/gallium/drivers/ilo/ilo_gpe_gen6.h +++ b/src/gallium/drivers/ilo/ilo_gpe_gen6.h @@ -414,8 +414,8 @@ typedef uint32_t typedef uint32_t (*ilo_gpe_gen6_SCISSOR_RECT)(const struct ilo_dev_info *dev, - const struct pipe_scissor_state *scissors, - int num_scissors, + const struct ilo_scissor_state *scissor, + unsigned num_viewports, struct ilo_cp *cp); typedef uint32_t diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c index 205128e0993..cc74d03c49b 100644 --- a/src/gallium/drivers/ilo/ilo_state.c +++ b/src/gallium/drivers/ilo/ilo_state.c @@ -581,10 +581,9 @@ ilo_set_scissor_states(struct pipe_context *pipe, const struct pipe_scissor_state *scissors) { struct ilo_context *ilo = ilo_context(pipe); - unsigned i; - for (i = 0; i < num_scissors; i++) - ilo->scissor.states[start_slot + i] = scissors[i]; + ilo_gpe_set_scissor(ilo->dev, start_slot, num_scissors, + scissors, &ilo->scissor); ilo->dirty |= ILO_DIRTY_SCISSOR; } @@ -1056,3 +1055,14 @@ ilo_init_state_functions(struct ilo_context *ilo) ilo->base.set_compute_resources = ilo_set_compute_resources; ilo->base.set_global_binding = ilo_set_global_binding; } + +void +ilo_init_states(struct ilo_context *ilo) +{ + ilo_gpe_set_scissor_null(ilo->dev, &ilo->scissor); +} + +void +ilo_cleanup_states(struct ilo_context *ilo) +{ +} diff --git a/src/gallium/drivers/ilo/ilo_state.h b/src/gallium/drivers/ilo/ilo_state.h index e8db6cbc048..c73e8fb835b 100644 --- a/src/gallium/drivers/ilo/ilo_state.h +++ b/src/gallium/drivers/ilo/ilo_state.h @@ -118,6 +118,12 @@ struct ilo_context; void ilo_init_state_functions(struct ilo_context *ilo); +void +ilo_init_states(struct ilo_context *ilo); + +void +ilo_cleanup_states(struct ilo_context *ilo); + void ilo_finalize_states(struct ilo_context *ilo); -- 2.30.2