summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChia-I Wu <olvaffe@gmail.com>2015-05-18 00:00:37 +0800
committerChia-I Wu <olvaffe@gmail.com>2015-06-15 01:06:45 +0800
commitded7d412d04cf702596e91f36ba586b18f1933a2 (patch)
tree4ff925e3bf25e92d266ddf1cfbec8ab13ff4e46b
parent4b5c0a83415137ba1f894d70a6cf73db83d21f15 (diff)
ilo: embed ilo_state_viewport in ilo_viewport_state
-rw-r--r--src/gallium/drivers/ilo/core/ilo_builder_3d_bottom.h163
-rw-r--r--src/gallium/drivers/ilo/core/ilo_state_3d.h42
-rw-r--r--src/gallium/drivers/ilo/core/ilo_state_3d_bottom.c149
-rw-r--r--src/gallium/drivers/ilo/ilo_blitter.h4
-rw-r--r--src/gallium/drivers/ilo/ilo_blitter_pipe.c2
-rw-r--r--src/gallium/drivers/ilo/ilo_blitter_rectlist.c10
-rw-r--r--src/gallium/drivers/ilo/ilo_render.c8
-rw-r--r--src/gallium/drivers/ilo/ilo_render_dynamic.c34
-rw-r--r--src/gallium/drivers/ilo/ilo_render_gen.h2
-rw-r--r--src/gallium/drivers/ilo/ilo_render_gen6.c17
-rw-r--r--src/gallium/drivers/ilo/ilo_state.c65
-rw-r--r--src/gallium/drivers/ilo/ilo_state.h15
12 files changed, 142 insertions, 369 deletions
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 c49f4e470e..0c0403fb73 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 260f94bf76..9d9dd29831 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];
@@ -241,22 +215,6 @@ ilo_gpe_init_ve_nosrc(const struct ilo_dev *dev,
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,
struct ilo_rasterizer_state *rasterizer);
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 31d9a203c5..67233cf3d0 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 4284f415c1..1967c485ca 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 c4c02bd3e5..0bfe7827f1 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 6d8afed9dc..84100c0f3c 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 f5be3360f0..92898704cd 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 d782228161..cc3791eb47 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 acfe8be308..5de4162321 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 f3f8ae4a08..3119872336 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 82fa6696e9..d4d12ca843 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 95dbe73bfd..5541c40ba1 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;