From: Chia-I Wu Date: Sun, 17 May 2015 16:00:37 +0000 (+0800) Subject: ilo: embed ilo_state_viewport in ilo_viewport_state X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ded7d412d04cf702596e91f36ba586b18f1933a2;p=mesa.git ilo: embed ilo_state_viewport in ilo_viewport_state --- diff --git a/src/gallium/drivers/ilo/core/ilo_builder_3d_bottom.h b/src/gallium/drivers/ilo/core/ilo_builder_3d_bottom.h index c49f4e470e7..0c0403fb73f 100644 --- a/src/gallium/drivers/ilo/core/ilo_builder_3d_bottom.h +++ b/src/gallium/drivers/ilo/core/ilo_builder_3d_bottom.h @@ -35,6 +35,7 @@ #include "ilo_core.h" #include "ilo_dev.h" #include "ilo_format.h" +#include "ilo_state_viewport.h" #include "ilo_builder.h" #include "ilo_builder_3d_top.h" @@ -1452,34 +1453,24 @@ gen7_3DSTATE_BLEND_STATE_POINTERS(struct ilo_builder *builder, static inline uint32_t gen6_CLIP_VIEWPORT(struct ilo_builder *builder, - const struct ilo_viewport_cso *viewports, - unsigned num_viewports) + const struct ilo_state_viewport *vp) { const int state_align = 32; - const int state_len = 4 * num_viewports; + const int state_len = 4 * vp->count; uint32_t state_offset, *dw; - unsigned i; + int i; ILO_DEV_ASSERT(builder->dev, 6, 6); - /* - * From the Sandy Bridge PRM, volume 2 part 1, page 193: - * - * "The viewport-related state is stored as an array of up to 16 - * elements..." - */ - assert(num_viewports && num_viewports <= 16); - state_offset = ilo_builder_dynamic_pointer(builder, ILO_BUILDER_ITEM_CLIP_VIEWPORT, state_align, state_len, &dw); - for (i = 0; i < num_viewports; i++) { - const struct ilo_viewport_cso *vp = &viewports[i]; - - dw[0] = fui(vp->min_gbx); - dw[1] = fui(vp->max_gbx); - dw[2] = fui(vp->min_gby); - dw[3] = fui(vp->max_gby); + for (i = 0; i < vp->count; i++) { + /* see viewport_matrix_set_gen7_SF_CLIP_VIEWPORT() */ + dw[0] = vp->sf_clip[i][8]; + dw[1] = vp->sf_clip[i][9]; + dw[2] = vp->sf_clip[i][10]; + dw[3] = vp->sf_clip[i][11]; dw += 4; } @@ -1489,38 +1480,21 @@ gen6_CLIP_VIEWPORT(struct ilo_builder *builder, static inline uint32_t gen6_SF_VIEWPORT(struct ilo_builder *builder, - const struct ilo_viewport_cso *viewports, - unsigned num_viewports) + const struct ilo_state_viewport *vp) { const int state_align = 32; - const int state_len = 8 * num_viewports; + const int state_len = 8 * vp->count; uint32_t state_offset, *dw; - unsigned i; + int i; ILO_DEV_ASSERT(builder->dev, 6, 6); - /* - * From the Sandy Bridge PRM, volume 2 part 1, page 262: - * - * "The viewport-specific state used by the SF unit (SF_VIEWPORT) is - * stored as an array of up to 16 elements..." - */ - assert(num_viewports && num_viewports <= 16); - state_offset = ilo_builder_dynamic_pointer(builder, ILO_BUILDER_ITEM_SF_VIEWPORT, state_align, state_len, &dw); - for (i = 0; i < num_viewports; i++) { - const struct ilo_viewport_cso *vp = &viewports[i]; - - dw[0] = fui(vp->m00); - dw[1] = fui(vp->m11); - dw[2] = fui(vp->m22); - dw[3] = fui(vp->m30); - dw[4] = fui(vp->m31); - dw[5] = fui(vp->m32); - dw[6] = 0; - dw[7] = 0; + for (i = 0; i < vp->count; i++) { + /* see viewport_matrix_set_gen7_SF_CLIP_VIEWPORT() */ + memcpy(dw, vp->sf_clip[i], sizeof(*dw) * 8); dw += 8; } @@ -1530,121 +1504,44 @@ gen6_SF_VIEWPORT(struct ilo_builder *builder, static inline uint32_t gen7_SF_CLIP_VIEWPORT(struct ilo_builder *builder, - const struct ilo_viewport_cso *viewports, - unsigned num_viewports) + const struct ilo_state_viewport *vp) { const int state_align = 64; - const int state_len = 16 * num_viewports; - uint32_t state_offset, *dw; - unsigned i; + const int state_len = 16 * vp->count; ILO_DEV_ASSERT(builder->dev, 7, 8); - /* - * From the Ivy Bridge PRM, volume 2 part 1, page 270: - * - * "The viewport-specific state used by both the SF and CL units - * (SF_CLIP_VIEWPORT) is stored as an array of up to 16 elements, each - * of which contains the DWords described below. The start of each - * element is spaced 16 DWords apart. The location of first element of - * the array, as specified by both Pointer to SF_VIEWPORT and Pointer - * to CLIP_VIEWPORT, is aligned to a 64-byte boundary." - */ - assert(num_viewports && num_viewports <= 16); - - state_offset = ilo_builder_dynamic_pointer(builder, - ILO_BUILDER_ITEM_SF_VIEWPORT, state_align, state_len, &dw); - - for (i = 0; i < num_viewports; i++) { - const struct ilo_viewport_cso *vp = &viewports[i]; - - dw[0] = fui(vp->m00); - dw[1] = fui(vp->m11); - dw[2] = fui(vp->m22); - dw[3] = fui(vp->m30); - dw[4] = fui(vp->m31); - dw[5] = fui(vp->m32); - dw[6] = 0; - dw[7] = 0; - - dw[8] = fui(vp->min_gbx); - dw[9] = fui(vp->max_gbx); - dw[10] = fui(vp->min_gby); - dw[11] = fui(vp->max_gby); - - if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) { - dw[12] = fui(vp->min_x); - dw[13] = fui(vp->max_x - 1.0f); - dw[14] = fui(vp->min_y); - dw[15] = fui(vp->max_y - 1.0f); - } else { - dw[12] = 0; - dw[13] = 0; - dw[14] = 0; - dw[15] = 0; - } - - dw += 16; - } - - return state_offset; + /* see viewport_matrix_set_gen7_SF_CLIP_VIEWPORT() */ + return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_SF_VIEWPORT, + state_align, state_len, (const uint32_t *) vp->sf_clip); } static inline uint32_t gen6_CC_VIEWPORT(struct ilo_builder *builder, - const struct ilo_viewport_cso *viewports, - unsigned num_viewports) + const struct ilo_state_viewport *vp) { const int state_align = 32; - const int state_len = 2 * num_viewports; - uint32_t state_offset, *dw; - unsigned i; + const int state_len = 2 * vp->count; ILO_DEV_ASSERT(builder->dev, 6, 8); - /* - * From the Sandy Bridge PRM, volume 2 part 1, page 385: - * - * "The viewport state is stored as an array of up to 16 elements..." - */ - assert(num_viewports && num_viewports <= 16); - - state_offset = ilo_builder_dynamic_pointer(builder, - ILO_BUILDER_ITEM_CC_VIEWPORT, state_align, state_len, &dw); - - for (i = 0; i < num_viewports; i++) { - const struct ilo_viewport_cso *vp = &viewports[i]; - - dw[0] = fui(vp->min_z); - dw[1] = fui(vp->max_z); - - dw += 2; - } - - return state_offset; + /* see viewport_matrix_set_gen6_CC_VIEWPORT() */ + return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_CC_VIEWPORT, + state_align, state_len, (const uint32_t *) vp->cc); } static inline uint32_t gen6_SCISSOR_RECT(struct ilo_builder *builder, - const struct ilo_scissor_state *scissor, - unsigned num_viewports) + const struct ilo_state_viewport *vp) { const int state_align = 32; - const int state_len = 2 * num_viewports; + const int state_len = 2 * vp->count; ILO_DEV_ASSERT(builder->dev, 6, 8); - /* - * From the Sandy Bridge PRM, volume 2 part 1, page 263: - * - * "The viewport-specific state used by the SF unit (SCISSOR_RECT) is - * stored as an array of up to 16 elements..." - */ - assert(num_viewports && num_viewports <= 16); - assert(Elements(scissor->payload) >= state_len); - + /* see viewport_scissor_set_gen6_SCISSOR_RECT() */ return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_SCISSOR_RECT, - state_align, state_len, scissor->payload); + state_align, state_len, (const uint32_t *) vp->scissor); } static inline uint32_t diff --git a/src/gallium/drivers/ilo/core/ilo_state_3d.h b/src/gallium/drivers/ilo/core/ilo_state_3d.h index 260f94bf766..9d9dd29831f 100644 --- a/src/gallium/drivers/ilo/core/ilo_state_3d.h +++ b/src/gallium/drivers/ilo/core/ilo_state_3d.h @@ -101,32 +101,6 @@ struct ilo_so_state { bool enabled; }; -struct ilo_viewport_cso { - /* matrix form */ - float m00, m11, m22, m30, m31, m32; - - /* guardband in NDC space */ - float min_gbx, min_gby, max_gbx, max_gby; - - /* viewport in screen space */ - float min_x, min_y, min_z; - float max_x, max_y, max_z; -}; - -struct ilo_viewport_state { - struct ilo_viewport_cso cso[ILO_MAX_VIEWPORTS]; - unsigned count; - - struct pipe_viewport_state viewport0; -}; - -struct ilo_scissor_state { - /* SCISSOR_RECT */ - uint32_t payload[ILO_MAX_VIEWPORTS * 2]; - - struct pipe_scissor_state scissor0; -}; - struct ilo_rasterizer_clip { /* 3DSTATE_CLIP */ uint32_t payload[3]; @@ -240,22 +214,6 @@ ilo_gpe_init_ve_nosrc(const struct ilo_dev *dev, int comp0, int comp1, int comp2, int comp3, struct ilo_ve_cso *cso); -void -ilo_gpe_set_viewport_cso(const struct ilo_dev *dev, - const struct pipe_viewport_state *state, - struct ilo_viewport_cso *vp); - -void -ilo_gpe_set_scissor(const struct ilo_dev *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 *dev, - struct ilo_scissor_state *scissor); - void ilo_gpe_init_rasterizer(const struct ilo_dev *dev, const struct pipe_rasterizer_state *state, diff --git a/src/gallium/drivers/ilo/core/ilo_state_3d_bottom.c b/src/gallium/drivers/ilo/core/ilo_state_3d_bottom.c index 31d9a203c5a..67233cf3d07 100644 --- a/src/gallium/drivers/ilo/core/ilo_state_3d_bottom.c +++ b/src/gallium/drivers/ilo/core/ilo_state_3d_bottom.c @@ -900,105 +900,6 @@ ilo_gpe_init_fs_cso(const struct ilo_dev *dev, fs_init_cso_gen6(dev, fs, cso); } -static void -viewport_get_guardband(const struct ilo_dev *dev, - int center_x, int center_y, - int *min_gbx, int *max_gbx, - int *min_gby, int *max_gby) -{ - /* - * From the Sandy Bridge PRM, volume 2 part 1, page 234: - * - * "Per-Device Guardband Extents - * - * - Supported X,Y ScreenSpace "Guardband" Extent: [-16K,16K-1] - * - Maximum Post-Clamp Delta (X or Y): 16K" - * - * "In addition, in order to be correctly rendered, objects must have a - * screenspace bounding box not exceeding 8K in the X or Y direction. - * This additional restriction must also be comprehended by software, - * i.e., enforced by use of clipping." - * - * From the Ivy Bridge PRM, volume 2 part 1, page 248: - * - * "Per-Device Guardband Extents - * - * - Supported X,Y ScreenSpace "Guardband" Extent: [-32K,32K-1] - * - Maximum Post-Clamp Delta (X or Y): N/A" - * - * "In addition, in order to be correctly rendered, objects must have a - * screenspace bounding box not exceeding 8K in the X or Y direction. - * This additional restriction must also be comprehended by software, - * i.e., enforced by use of clipping." - * - * Combined, the bounding box of any object can not exceed 8K in both - * width and height. - * - * Below we set the guardband as a squre of length 8K, centered at where - * the viewport is. This makes sure all objects passing the GB test are - * valid to the renderer, and those failing the XY clipping have a - * better chance of passing the GB test. - */ - const int max_extent = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 32768 : 16384; - const int half_len = 8192 / 2; - - /* make sure the guardband is within the valid range */ - if (center_x - half_len < -max_extent) - center_x = -max_extent + half_len; - else if (center_x + half_len > max_extent - 1) - center_x = max_extent - half_len; - - if (center_y - half_len < -max_extent) - center_y = -max_extent + half_len; - else if (center_y + half_len > max_extent - 1) - center_y = max_extent - half_len; - - *min_gbx = (float) (center_x - half_len); - *max_gbx = (float) (center_x + half_len); - *min_gby = (float) (center_y - half_len); - *max_gby = (float) (center_y + half_len); -} - -void -ilo_gpe_set_viewport_cso(const struct ilo_dev *dev, - const struct pipe_viewport_state *state, - struct ilo_viewport_cso *vp) -{ - const float scale_x = fabs(state->scale[0]); - const float scale_y = fabs(state->scale[1]); - const float scale_z = fabs(state->scale[2]); - int min_gbx, max_gbx, min_gby, max_gby; - - ILO_DEV_ASSERT(dev, 6, 8); - - viewport_get_guardband(dev, - (int) state->translate[0], - (int) state->translate[1], - &min_gbx, &max_gbx, &min_gby, &max_gby); - - /* matrix form */ - vp->m00 = state->scale[0]; - vp->m11 = state->scale[1]; - vp->m22 = state->scale[2]; - vp->m30 = state->translate[0]; - vp->m31 = state->translate[1]; - vp->m32 = state->translate[2]; - - /* guardband in NDC space */ - vp->min_gbx = ((float) min_gbx - state->translate[0]) / scale_x; - vp->max_gbx = ((float) max_gbx - state->translate[0]) / scale_x; - vp->min_gby = ((float) min_gby - state->translate[1]) / scale_y; - vp->max_gby = ((float) max_gby - state->translate[1]) / scale_y; - - /* viewport in screen space */ - vp->min_x = scale_x * -1.0f + state->translate[0]; - vp->max_x = scale_x * 1.0f + state->translate[0]; - vp->min_y = scale_y * -1.0f + state->translate[1]; - vp->max_y = scale_y * 1.0f + state->translate[1]; - vp->min_z = scale_z * -1.0f + state->translate[2]; - vp->max_z = scale_z * 1.0f + state->translate[2]; -} - /** * Translate a pipe logicop to the matching hardware logicop. */ @@ -1674,56 +1575,6 @@ ilo_gpe_init_dsa(const struct ilo_dev *dev, dsa->alpha_ref = float_to_ubyte(state->alpha.ref_value); } -void -ilo_gpe_set_scissor(const struct ilo_dev *dev, - unsigned start_slot, - unsigned num_states, - const struct pipe_scissor_state *states, - struct ilo_scissor_state *scissor) -{ - unsigned i; - - ILO_DEV_ASSERT(dev, 6, 8); - - 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 + i) * 2 + 0] = min_y << 16 | min_x; - scissor->payload[(start_slot + i) * 2 + 1] = max_y << 16 | max_x; - } - - if (!start_slot && num_states) - scissor->scissor0 = states[0]; -} - -void -ilo_gpe_set_scissor_null(const struct ilo_dev *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 void fb_set_blend_caps(const struct ilo_dev *dev, enum pipe_format format, diff --git a/src/gallium/drivers/ilo/ilo_blitter.h b/src/gallium/drivers/ilo/ilo_blitter.h index 4284f415c1c..1967c485ca5 100644 --- a/src/gallium/drivers/ilo/ilo_blitter.h +++ b/src/gallium/drivers/ilo/ilo_blitter.h @@ -66,7 +66,9 @@ struct ilo_blitter { struct ilo_ve_state ve; struct pipe_draw_info draw; - struct ilo_viewport_cso viewport; + struct ilo_state_viewport vp; + uint32_t vp_data[20]; + struct ilo_dsa_state dsa; struct { diff --git a/src/gallium/drivers/ilo/ilo_blitter_pipe.c b/src/gallium/drivers/ilo/ilo_blitter_pipe.c index c4c02bd3e53..0bfe7827f11 100644 --- a/src/gallium/drivers/ilo/ilo_blitter_pipe.c +++ b/src/gallium/drivers/ilo/ilo_blitter_pipe.c @@ -63,7 +63,7 @@ ilo_blitter_pipe_begin(struct ilo_blitter *blitter, util_blitter_save_viewport(b, &vec->viewport.viewport0); if (scissor_enable) - util_blitter_save_scissor(b, &vec->scissor.scissor0); + util_blitter_save_scissor(b, &vec->viewport.scissor0); switch (op) { case ILO_BLITTER_PIPE_BLIT: diff --git a/src/gallium/drivers/ilo/ilo_blitter_rectlist.c b/src/gallium/drivers/ilo/ilo_blitter_rectlist.c index 6d8afed9dca..84100c0f3c7 100644 --- a/src/gallium/drivers/ilo/ilo_blitter_rectlist.c +++ b/src/gallium/drivers/ilo/ilo_blitter_rectlist.c @@ -41,7 +41,6 @@ static bool ilo_blitter_set_invariants(struct ilo_blitter *blitter) { struct pipe_vertex_element velem; - struct pipe_viewport_state vp; if (blitter->initialized) return true; @@ -69,16 +68,13 @@ ilo_blitter_set_invariants(struct ilo_blitter *blitter) * From the Haswell PRM, volume 7, page 615: * * "The clear value must be between the min and max depth values - * (inclusive) defined in the CC_VIEWPORT." + * (inclusive) defined in the CC_VIEWPORT." * * Even though clipping and viewport transformation will be disabled, we * still need to set up the viewport states. */ - memset(&vp, 0, sizeof(vp)); - vp.scale[0] = 1.0f; - vp.scale[1] = 1.0f; - vp.scale[2] = 1.0f; - ilo_gpe_set_viewport_cso(blitter->ilo->dev, &vp, &blitter->viewport); + ilo_state_viewport_init_for_rectlist(&blitter->vp, blitter->ilo->dev, + blitter->vp_data, sizeof(blitter->vp_data)); blitter->initialized = true; diff --git a/src/gallium/drivers/ilo/ilo_render.c b/src/gallium/drivers/ilo/ilo_render.c index f5be3360f05..92898704cde 100644 --- a/src/gallium/drivers/ilo/ilo_render.c +++ b/src/gallium/drivers/ilo/ilo_render.c @@ -447,11 +447,19 @@ draw_session_prepare(struct ilo_render *render, session->prim_changed = true; session->primitive_restart_changed = true; + + ilo_state_viewport_full_delta(&vec->viewport.vp, render->dev, + &session->vp_delta); } else { session->prim_changed = (render->state.reduced_prim != session->reduced_prim); session->primitive_restart_changed = (render->state.primitive_restart != vec->draw->primitive_restart); + + if (vec->dirty & ILO_DIRTY_VIEWPORT) { + ilo_state_viewport_full_delta(&vec->viewport.vp, render->dev, + &session->vp_delta); + } } } diff --git a/src/gallium/drivers/ilo/ilo_render_dynamic.c b/src/gallium/drivers/ilo/ilo_render_dynamic.c index d7822281611..cc3791eb470 100644 --- a/src/gallium/drivers/ilo/ilo_render_dynamic.c +++ b/src/gallium/drivers/ilo/ilo_render_dynamic.c @@ -42,16 +42,14 @@ gen6_emit_draw_dynamic_viewports(struct ilo_render *r, { ILO_DEV_ASSERT(r->dev, 6, 6); - /* SF_VIEWPORT, CLIP_VIEWPORT, and CC_VIEWPORT */ - if (DIRTY(VIEWPORT)) { + /* CLIP_VIEWPORT, SF_VIEWPORT, and CC_VIEWPORT */ + if ((session->vp_delta.dirty & (ILO_STATE_VIEWPORT_SF_CLIP_VIEWPORT | + ILO_STATE_VIEWPORT_CC_VIEWPORT)) || + r->state_bo_changed) { r->state.CLIP_VIEWPORT = gen6_CLIP_VIEWPORT(r->builder, - vec->viewport.cso, vec->viewport.count); - - r->state.SF_VIEWPORT = gen6_SF_VIEWPORT(r->builder, - vec->viewport.cso, vec->viewport.count); - - r->state.CC_VIEWPORT = gen6_CC_VIEWPORT(r->builder, - vec->viewport.cso, vec->viewport.count); + &vec->viewport.vp); + r->state.SF_VIEWPORT = gen6_SF_VIEWPORT(r->builder, &vec->viewport.vp); + r->state.CC_VIEWPORT = gen6_CC_VIEWPORT(r->builder, &vec->viewport.vp); session->viewport_changed = true; } @@ -65,12 +63,12 @@ gen7_emit_draw_dynamic_viewports(struct ilo_render *r, ILO_DEV_ASSERT(r->dev, 7, 8); /* SF_CLIP_VIEWPORT and CC_VIEWPORT */ - if (DIRTY(VIEWPORT)) { + if ((session->vp_delta.dirty & (ILO_STATE_VIEWPORT_SF_CLIP_VIEWPORT | + ILO_STATE_VIEWPORT_CC_VIEWPORT)) || + r->state_bo_changed) { r->state.SF_CLIP_VIEWPORT = gen7_SF_CLIP_VIEWPORT(r->builder, - vec->viewport.cso, vec->viewport.count); - - r->state.CC_VIEWPORT = gen6_CC_VIEWPORT(r->builder, - vec->viewport.cso, vec->viewport.count); + &vec->viewport.vp); + r->state.CC_VIEWPORT = gen6_CC_VIEWPORT(r->builder, &vec->viewport.vp); session->viewport_changed = true; } @@ -84,10 +82,10 @@ gen6_emit_draw_dynamic_scissors(struct ilo_render *r, ILO_DEV_ASSERT(r->dev, 6, 8); /* SCISSOR_RECT */ - if (DIRTY(SCISSOR) || DIRTY(VIEWPORT)) { - /* there should be as many scissors as there are viewports */ + if ((session->vp_delta.dirty & ILO_STATE_VIEWPORT_SCISSOR_RECT) || + r->state_bo_changed) { r->state.SCISSOR_RECT = gen6_SCISSOR_RECT(r->builder, - &vec->scissor, vec->viewport.count); + &vec->viewport.vp); session->scissor_changed = true; } @@ -463,7 +461,7 @@ ilo_render_emit_rectlist_dynamic_states(struct ilo_render *render, if (blitter->uses & ILO_BLITTER_USE_VIEWPORT) { render->state.CC_VIEWPORT = - gen6_CC_VIEWPORT(render->builder, &blitter->viewport, 1); + gen6_CC_VIEWPORT(render->builder, &blitter->vp); } assert(ilo_builder_dynamic_used(render->builder) <= dynamic_used + diff --git a/src/gallium/drivers/ilo/ilo_render_gen.h b/src/gallium/drivers/ilo/ilo_render_gen.h index acfe8be3088..5de41623214 100644 --- a/src/gallium/drivers/ilo/ilo_render_gen.h +++ b/src/gallium/drivers/ilo/ilo_render_gen.h @@ -144,6 +144,8 @@ struct ilo_render_draw_session { bool prim_changed; bool primitive_restart_changed; + struct ilo_state_viewport_delta vp_delta; + /* dynamic states */ bool viewport_changed; bool scissor_changed; diff --git a/src/gallium/drivers/ilo/ilo_render_gen6.c b/src/gallium/drivers/ilo/ilo_render_gen6.c index f3f8ae4a088..31198723367 100644 --- a/src/gallium/drivers/ilo/ilo_render_gen6.c +++ b/src/gallium/drivers/ilo/ilo_render_gen6.c @@ -643,11 +643,18 @@ gen6_draw_clip(struct ilo_render *r, * unless we emulate viewport extent test on them. */ if (ilo_dev_gen(r->dev) < ILO_GEN(8)) { - for (i = 0; i < vec->viewport.count; i++) { - const struct ilo_viewport_cso *vp = &vec->viewport.cso[i]; - - if (vp->min_x > 0.0f || vp->max_x < vec->fb.state.width || - vp->min_y > 0.0f || vp->max_y < vec->fb.state.height) { + for (i = 0; i < vec->viewport.params.count; i++) { + const struct ilo_state_viewport_matrix_info *mat = + &vec->viewport.matrices[i]; + float min_x, max_x, min_y, max_y; + + min_x = -1.0f * fabsf(mat->scale[0]) + mat->translate[0]; + max_x = 1.0f * fabsf(mat->scale[0]) + mat->translate[0]; + min_y = -1.0f * fabsf(mat->scale[1]) + mat->translate[1]; + max_y = 1.0f * fabsf(mat->scale[1]) + mat->translate[1]; + + if (min_x > 0.0f || max_x < vec->fb.state.width || + min_y > 0.0f || max_y < vec->fb.state.height) { enable_guardband = false; break; } diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c index 82fa6696e90..d4d12ca8431 100644 --- a/src/gallium/drivers/ilo/ilo_state.c +++ b/src/gallium/drivers/ilo/ilo_state.c @@ -330,6 +330,22 @@ finalize_vertex_elements(struct ilo_context *ilo) } } +static void +finalize_viewport(struct ilo_context *ilo) +{ + const struct ilo_dev *dev = ilo->dev; + struct ilo_state_vector *vec = &ilo->state_vector; + + if (vec->dirty & ILO_DIRTY_VIEWPORT) { + ilo_state_viewport_set_params(&vec->viewport.vp, + dev, &vec->viewport.params, false); + } else if (vec->dirty & ILO_DIRTY_SCISSOR) { + ilo_state_viewport_set_params(&vec->viewport.vp, + dev, &vec->viewport.params, true); + vec->dirty |= ILO_DIRTY_VIEWPORT; + } +} + /** * Finalize states. Some states depend on other states and are * incomplete/invalid until finalized. @@ -345,6 +361,8 @@ ilo_finalize_3d_states(struct ilo_context *ilo, finalize_index_buffer(ilo); finalize_vertex_elements(ilo); + finalize_viewport(ilo); + u_upload_unmap(ilo->uploader); } @@ -933,11 +951,26 @@ ilo_set_scissor_states(struct pipe_context *pipe, unsigned num_scissors, const struct pipe_scissor_state *scissors) { - const struct ilo_dev *dev = ilo_context(pipe)->dev; struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; + unsigned i; + + for (i = 0; i < num_scissors; i++) { + struct ilo_state_viewport_scissor_info *info = + &vec->viewport.scissors[start_slot + i]; - ilo_gpe_set_scissor(dev, start_slot, num_scissors, - scissors, &vec->scissor); + if (scissors[i].minx < scissors[i].maxx && + scissors[i].miny < scissors[i].maxy) { + info->min_x = scissors[i].minx; + info->min_y = scissors[i].miny; + info->max_x = scissors[i].maxx - 1; + info->max_y = scissors[i].maxy - 1; + } else { + info->min_x = 1; + info->min_y = 1; + info->max_x = 0; + info->max_y = 0; + } + } vec->dirty |= ILO_DIRTY_SCISSOR; } @@ -948,28 +981,31 @@ ilo_set_viewport_states(struct pipe_context *pipe, unsigned num_viewports, const struct pipe_viewport_state *viewports) { - const struct ilo_dev *dev = ilo_context(pipe)->dev; struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; if (viewports) { unsigned i; for (i = 0; i < num_viewports; i++) { - ilo_gpe_set_viewport_cso(dev, &viewports[i], - &vec->viewport.cso[start_slot + i]); + struct ilo_state_viewport_matrix_info *info = + &vec->viewport.matrices[start_slot + i]; + + memcpy(info->scale, viewports[i].scale, sizeof(info->scale)); + memcpy(info->translate, viewports[i].translate, + sizeof(info->translate)); } - if (vec->viewport.count < start_slot + num_viewports) - vec->viewport.count = start_slot + num_viewports; + if (vec->viewport.params.count < start_slot + num_viewports) + vec->viewport.params.count = start_slot + num_viewports; /* need to save viewport 0 for util_blitter */ if (!start_slot && num_viewports) vec->viewport.viewport0 = viewports[0]; } else { - if (vec->viewport.count <= start_slot + num_viewports && - vec->viewport.count > start_slot) - vec->viewport.count = start_slot; + if (vec->viewport.params.count <= start_slot + num_viewports && + vec->viewport.params.count > start_slot) + vec->viewport.params.count = start_slot; } vec->dirty |= ILO_DIRTY_VIEWPORT; @@ -1530,7 +1566,12 @@ void ilo_state_vector_init(const struct ilo_dev *dev, struct ilo_state_vector *vec) { - ilo_gpe_set_scissor_null(dev, &vec->scissor); + ilo_state_viewport_init_data_only(&vec->viewport.vp, dev, + vec->viewport.vp_data, sizeof(vec->viewport.vp_data)); + assert(vec->viewport.vp.array_size >= ILO_MAX_VIEWPORTS); + + vec->viewport.params.matrices = vec->viewport.matrices; + vec->viewport.params.scissors = vec->viewport.scissors; ilo_state_surface_init_for_null(&vec->fb.null_rt, dev); ilo_state_zs_init_for_null(&vec->fb.null_zs, dev); diff --git a/src/gallium/drivers/ilo/ilo_state.h b/src/gallium/drivers/ilo/ilo_state.h index 95dbe73bfdc..5541c40ba18 100644 --- a/src/gallium/drivers/ilo/ilo_state.h +++ b/src/gallium/drivers/ilo/ilo_state.h @@ -31,6 +31,7 @@ #include "core/ilo_state_3d.h" #include "core/ilo_state_sampler.h" #include "core/ilo_state_surface.h" +#include "core/ilo_state_viewport.h" #include "core/ilo_state_zs.h" #include "pipe/p_state.h" #include "util/u_dynarray.h" @@ -169,6 +170,18 @@ struct ilo_view_state { unsigned count; }; +struct ilo_viewport_state { + struct ilo_state_viewport_matrix_info matrices[ILO_MAX_VIEWPORTS]; + struct ilo_state_viewport_scissor_info scissors[ILO_MAX_VIEWPORTS]; + struct ilo_state_viewport_params_info params; + + struct pipe_viewport_state viewport0; + struct pipe_scissor_state scissor0; + + struct ilo_state_viewport vp; + uint32_t vp_data[20 * ILO_MAX_VIEWPORTS]; +}; + struct ilo_global_binding_cso { struct pipe_resource *resource; uint32_t *handle; @@ -208,8 +221,8 @@ struct ilo_state_vector { struct ilo_so_state so; struct pipe_clip_state clip; + struct ilo_viewport_state viewport; - struct ilo_scissor_state scissor; const struct ilo_rasterizer_state *rasterizer; struct pipe_poly_stipple poly_stipple;