summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Klausmann <[email protected]>2014-06-15 21:24:04 +0200
committerIlia Mirkin <[email protected]>2014-06-16 23:08:03 -0400
commita2cb3a4a4fa5f22e983ac6081b22a04594c7a10a (patch)
tree30a7354be4a8cb91b2bfa4e6e39e93b4e1749acd
parentaf05270ccfaa15fde9845a2250922caa8902c0fe (diff)
nvc0: implement multiple viewports/scissors, enable ARB_viewport_array
Signed-off-by: Tobias Klausmann <[email protected]> [imirkin: mark things dirty on ctx switch, 3d blit] Reviewed-by: Ilia Mirkin <[email protected]>
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_context.h6
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_program.c2
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_screen.c20
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_screen.h3
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_state.c27
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c117
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_surface.c1
7 files changed, 113 insertions, 63 deletions
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
index 76416a0e3b2..41cee78c10a 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
@@ -178,8 +178,10 @@ struct nvc0_context {
struct pipe_blend_color blend_colour;
struct pipe_stencil_ref stencil_ref;
struct pipe_poly_stipple stipple;
- struct pipe_scissor_state scissor;
- struct pipe_viewport_state viewport;
+ struct pipe_scissor_state scissors[NVC0_MAX_VIEWPORTS];
+ unsigned scissors_dirty;
+ struct pipe_viewport_state viewports[NVC0_MAX_VIEWPORTS];
+ unsigned viewports_dirty;
struct pipe_clip_state clip;
unsigned sample_mask;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
index 1c82a9acffb..667fbc89323 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
@@ -64,7 +64,7 @@ nvc0_shader_output_address(unsigned sn, unsigned si, unsigned ubase)
case NV50_SEMANTIC_TESSFACTOR: return 0x000 + si * 0x4;
case TGSI_SEMANTIC_PRIMID: return 0x060;
case TGSI_SEMANTIC_LAYER: return 0x064;
- case NV50_SEMANTIC_VIEWPORTINDEX: return 0x068;
+ case TGSI_SEMANTIC_VIEWPORT_INDEX:return 0x068;
case TGSI_SEMANTIC_PSIZE: return 0x06c;
case TGSI_SEMANTIC_POSITION: return 0x070;
case TGSI_SEMANTIC_GENERIC: return ubase + si * 0x10;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index 3e6b0116e3c..3fdb6ae12c8 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -183,7 +183,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_FAKE_SW_MSAA:
return 0;
case PIPE_CAP_MAX_VIEWPORTS:
- return 1;
+ return NVC0_MAX_VIEWPORTS;
case PIPE_CAP_TEXTURE_QUERY_LOD:
case PIPE_CAP_SAMPLE_SHADING:
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
@@ -933,19 +933,23 @@ nvc0_screen_create(struct nouveau_device *dev)
BEGIN_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1);
PUSH_DATA (push, 1);
- BEGIN_NVC0(push, NVC0_3D(DEPTH_RANGE_NEAR(0)), 2);
- PUSH_DATAf(push, 0.0f);
- PUSH_DATAf(push, 1.0f);
+ for (i = 0; i < NVC0_MAX_VIEWPORTS; i++) {
+ BEGIN_NVC0(push, NVC0_3D(DEPTH_RANGE_NEAR(i)), 2);
+ PUSH_DATAf(push, 0.0f);
+ PUSH_DATAf(push, 1.0f);
+ }
BEGIN_NVC0(push, NVC0_3D(VIEW_VOLUME_CLIP_CTRL), 1);
PUSH_DATA (push, NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1);
/* We use scissors instead of exact view volume clipping,
* so they're always enabled.
*/
- BEGIN_NVC0(push, NVC0_3D(SCISSOR_ENABLE(0)), 3);
- PUSH_DATA (push, 1);
- PUSH_DATA (push, 8192 << 16);
- PUSH_DATA (push, 8192 << 16);
+ for (i = 0; i < NVC0_MAX_VIEWPORTS; i++) {
+ BEGIN_NVC0(push, NVC0_3D(SCISSOR_ENABLE(i)), 3);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, 8192 << 16);
+ PUSH_DATA (push, 8192 << 16);
+ }
#define MK_MACRO(m, n) i = nvc0_graph_set_macro(screen, m, i, sizeof(n), n);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
index c58add53788..4802057f70e 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
@@ -20,6 +20,9 @@
#define NVC0_MAX_SURFACE_SLOTS 16
+#define NVC0_MAX_VIEWPORTS 16
+
+
struct nvc0_context;
struct nvc0_blitter;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
index 27e5cd82d15..c92aaaca578 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
@@ -909,10 +909,17 @@ nvc0_set_scissor_states(struct pipe_context *pipe,
unsigned num_scissors,
const struct pipe_scissor_state *scissor)
{
- struct nvc0_context *nvc0 = nvc0_context(pipe);
+ struct nvc0_context *nvc0 = nvc0_context(pipe);
+ int i;
- nvc0->scissor = *scissor;
- nvc0->dirty |= NVC0_NEW_SCISSOR;
+ assert(start_slot + num_scissors <= NVC0_MAX_VIEWPORTS);
+ for (i = 0; i < num_scissors; i++) {
+ if (!memcmp(&nvc0->scissors[start_slot + i], &scissor[i], sizeof(*scissor)))
+ continue;
+ nvc0->scissors[start_slot + i] = scissor[i];
+ nvc0->scissors_dirty |= 1 << (start_slot + i);
+ nvc0->dirty |= NVC0_NEW_SCISSOR;
+ }
}
static void
@@ -921,10 +928,18 @@ nvc0_set_viewport_states(struct pipe_context *pipe,
unsigned num_viewports,
const struct pipe_viewport_state *vpt)
{
- struct nvc0_context *nvc0 = nvc0_context(pipe);
+ struct nvc0_context *nvc0 = nvc0_context(pipe);
+ int i;
+
+ assert(start_slot + num_viewports <= NVC0_MAX_VIEWPORTS);
+ for (i = 0; i < num_viewports; i++) {
+ if (!memcmp(&nvc0->viewports[start_slot + i], &vpt[i], sizeof(*vpt)))
+ continue;
+ nvc0->viewports[start_slot + i] = vpt[i];
+ nvc0->viewports_dirty |= 1 << (start_slot + i);
+ nvc0->dirty |= NVC0_NEW_VIEWPORT;
+ }
- nvc0->viewport = *vpt;
- nvc0->dirty |= NVC0_NEW_VIEWPORT;
}
static void
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
index dcec9108970..0cc7a5231f1 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
@@ -236,59 +236,82 @@ nvc0_validate_stipple(struct nvc0_context *nvc0)
static void
nvc0_validate_scissor(struct nvc0_context *nvc0)
{
- struct nouveau_pushbuf *push = nvc0->base.pushbuf;
- struct pipe_scissor_state *s = &nvc0->scissor;
+ int i;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+
+ if (!(nvc0->dirty & NVC0_NEW_SCISSOR) &&
+ nvc0->rast->pipe.scissor == nvc0->state.scissor)
+ return;
- if (!(nvc0->dirty & NVC0_NEW_SCISSOR) &&
- nvc0->rast->pipe.scissor == nvc0->state.scissor)
- return;
- nvc0->state.scissor = nvc0->rast->pipe.scissor;
+ if (nvc0->state.scissor != nvc0->rast->pipe.scissor)
+ nvc0->scissors_dirty = (1 << NVC0_MAX_VIEWPORTS) - 1;
- BEGIN_NVC0(push, NVC0_3D(SCISSOR_HORIZ(0)), 2);
- if (nvc0->rast->pipe.scissor) {
- PUSH_DATA(push, (s->maxx << 16) | s->minx);
- PUSH_DATA(push, (s->maxy << 16) | s->miny);
- } else {
- PUSH_DATA(push, (0xffff << 16) | 0);
- PUSH_DATA(push, (0xffff << 16) | 0);
- }
+ nvc0->state.scissor = nvc0->rast->pipe.scissor;
+
+ for (i = 0; i < NVC0_MAX_VIEWPORTS; i++) {
+ struct pipe_scissor_state *s = &nvc0->scissors[i];
+ if (!(nvc0->scissors_dirty & (1 << i)))
+ continue;
+
+ BEGIN_NVC0(push, NVC0_3D(SCISSOR_HORIZ(i)), 2);
+ if (nvc0->rast->pipe.scissor) {
+ PUSH_DATA(push, (s->maxx << 16) | s->minx);
+ PUSH_DATA(push, (s->maxy << 16) | s->miny);
+ } else {
+ PUSH_DATA(push, (0xffff << 16) | 0);
+ PUSH_DATA(push, (0xffff << 16) | 0);
+ }
+ }
+ nvc0->scissors_dirty = 0;
}
static void
nvc0_validate_viewport(struct nvc0_context *nvc0)
{
- struct nouveau_pushbuf *push = nvc0->base.pushbuf;
- struct pipe_viewport_state *vp = &nvc0->viewport;
- int x, y, w, h;
- float zmin, zmax;
-
- BEGIN_NVC0(push, NVC0_3D(VIEWPORT_TRANSLATE_X(0)), 3);
- PUSH_DATAf(push, vp->translate[0]);
- PUSH_DATAf(push, vp->translate[1]);
- PUSH_DATAf(push, vp->translate[2]);
- BEGIN_NVC0(push, NVC0_3D(VIEWPORT_SCALE_X(0)), 3);
- PUSH_DATAf(push, vp->scale[0]);
- PUSH_DATAf(push, vp->scale[1]);
- PUSH_DATAf(push, vp->scale[2]);
-
- /* now set the viewport rectangle to viewport dimensions for clipping */
-
- x = util_iround(MAX2(0.0f, vp->translate[0] - fabsf(vp->scale[0])));
- y = util_iround(MAX2(0.0f, vp->translate[1] - fabsf(vp->scale[1])));
- w = util_iround(vp->translate[0] + fabsf(vp->scale[0])) - x;
- h = util_iround(vp->translate[1] + fabsf(vp->scale[1])) - y;
-
- zmin = vp->translate[2] - fabsf(vp->scale[2]);
- zmax = vp->translate[2] + fabsf(vp->scale[2]);
-
- nvc0->vport_int[0] = (w << 16) | x;
- nvc0->vport_int[1] = (h << 16) | y;
- BEGIN_NVC0(push, NVC0_3D(VIEWPORT_HORIZ(0)), 2);
- PUSH_DATA (push, nvc0->vport_int[0]);
- PUSH_DATA (push, nvc0->vport_int[1]);
- BEGIN_NVC0(push, NVC0_3D(DEPTH_RANGE_NEAR(0)), 2);
- PUSH_DATAf(push, zmin);
- PUSH_DATAf(push, zmax);
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+ int x, y, w, h, i;
+ float zmin, zmax;
+
+ for (i = 0; i < NVC0_MAX_VIEWPORTS; i++) {
+ struct pipe_viewport_state *vp = &nvc0->viewports[i];
+
+ if (!(nvc0->viewports_dirty & (1 << i)))
+ continue;
+
+ BEGIN_NVC0(push, NVC0_3D(VIEWPORT_TRANSLATE_X(i)), 3);
+ PUSH_DATAf(push, vp->translate[0]);
+ PUSH_DATAf(push, vp->translate[1]);
+ PUSH_DATAf(push, vp->translate[2]);
+
+ BEGIN_NVC0(push, NVC0_3D(VIEWPORT_SCALE_X(i)), 3);
+ PUSH_DATAf(push, vp->scale[0]);
+ PUSH_DATAf(push, vp->scale[1]);
+ PUSH_DATAf(push, vp->scale[2]);
+
+ /* now set the viewport rectangle to viewport dimensions for clipping */
+
+ x = util_iround(MAX2(0.0f, vp->translate[0] - fabsf(vp->scale[0])));
+ y = util_iround(MAX2(0.0f, vp->translate[1] - fabsf(vp->scale[1])));
+ w = util_iround(vp->translate[0] + fabsf(vp->scale[0])) - x;
+ h = util_iround(vp->translate[1] + fabsf(vp->scale[1])) - y;
+
+ BEGIN_NVC0(push, NVC0_3D(VIEWPORT_HORIZ(i)), 2);
+ PUSH_DATA (push, (w << 16) | x);
+ PUSH_DATA (push, (h << 16) | y);
+
+ if (i == 0) {
+ nvc0->vport_int[0] = (w << 16) | x;
+ nvc0->vport_int[1] = (h << 16) | y;
+ }
+
+ zmin = vp->translate[2] - fabsf(vp->scale[2]);
+ zmax = vp->translate[2] + fabsf(vp->scale[2]);
+
+ BEGIN_NVC0(push, NVC0_3D(DEPTH_RANGE_NEAR(i)), 2);
+ PUSH_DATAf(push, zmin);
+ PUSH_DATAf(push, zmax);
+ }
+ nvc0->viewports_dirty = 0;
}
static INLINE void
@@ -527,6 +550,8 @@ nvc0_switch_pipe_context(struct nvc0_context *ctx_to)
ctx_to->state = ctx_from->state;
ctx_to->dirty = ~0;
+ ctx_to->viewports_dirty = ~0;
+ ctx_to->scissors_dirty = ~0;
for (s = 0; s < 5; ++s) {
ctx_to->samplers_dirty[s] = ~0;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
index c28ec6d77b9..f782eec3fb7 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
@@ -1016,6 +1016,7 @@ nvc0_blitctx_post_blit(struct nvc0_blitctx *blit)
NVC0_NEW_VERTPROG | NVC0_NEW_FRAGPROG |
NVC0_NEW_TCTLPROG | NVC0_NEW_TEVLPROG | NVC0_NEW_GMTYPROG |
NVC0_NEW_TFB_TARGETS | NVC0_NEW_VERTEX | NVC0_NEW_ARRAYS);
+ nvc0->scissors_dirty |= 1;
nvc0->base.pipe.set_min_samples(&nvc0->base.pipe, blit->saved.min_samples);
}