This patch-series implements the ARB_viewport_array for nvc0 and does
a little house-cleanig afterwords.
Tobias Klausmann (3):
  nvc0: implement multiple viewports/scissors, enable ARB_viewport_array
  nvc0: mark scissor in nvc0_clear_{}
  nv50/ir: Remove NV50_SEMANTIC_VIEWPORTINDEX and its last consumer
 .../drivers/nouveau/codegen/nv50_ir_driver.h       |   1 -
 .../nouveau/codegen/nv50_ir_target_nv50.cpp        |   1 -
 src/gallium/drivers/nouveau/nvc0/nvc0_context.h    |   7 +-
 src/gallium/drivers/nouveau/nvc0/nvc0_program.c    |   2 +-
 src/gallium/drivers/nouveau/nvc0/nvc0_screen.c     |  20 ++--
 src/gallium/drivers/nouveau/nvc0/nvc0_screen.h     |   3 +
 src/gallium/drivers/nouveau/nvc0/nvc0_state.c      |  27 ++++-
 .../drivers/nouveau/nvc0/nvc0_state_validate.c     | 121 +++++++++++++--------
 src/gallium/drivers/nouveau/nvc0/nvc0_surface.c    |   3 +
 9 files changed, 120 insertions(+), 65 deletions(-)
-- 
1.8.4.5
Tobias Klausmann
2014-Jun-14  14:41 UTC
[Nouveau] [PATCH 1/3] nvc0: implement multiple viewports/scissors, enable ARB_viewport_array
Signed-off-by: Tobias Klausmann <tobias.johannes.klausmann at mni.thm.de>
---
 src/gallium/drivers/nouveau/nvc0/nvc0_context.h    |   7 +-
 src/gallium/drivers/nouveau/nvc0/nvc0_program.c    |   2 +-
 src/gallium/drivers/nouveau/nvc0/nvc0_screen.c     |  20 ++--
 src/gallium/drivers/nouveau/nvc0/nvc0_screen.h     |   3 +
 src/gallium/drivers/nouveau/nvc0/nvc0_state.c      |  27 ++++-
 .../drivers/nouveau/nvc0/nvc0_state_validate.c     | 121 +++++++++++++--------
 6 files changed, 117 insertions(+), 63 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
index 76416a0..674dd3c 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
@@ -178,8 +178,11 @@ 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 1c82a9a..667fbc8 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 3e6b011..3fdb6ae 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 c58add5..4802057 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 27e5cd8..c92aaac 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 dcec910..31140af 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
@@ -236,59 +236,88 @@ 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;
-    nvc0->state.scissor = nvc0->rast->pipe.scissor;
+   if (!(nvc0->dirty & NVC0_NEW_SCISSOR) &&
+      nvc0->rast->pipe.scissor == nvc0->state.scissor)
+      return;
 
-    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);
-    }
+   if (nvc0->state.scissor != nvc0->rast->pipe.scissor)
+      nvc0->scissors_dirty = (1 << NVC0_MAX_VIEWPORTS) - 1;
+
+   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)) &&
+          !(nvc0->viewports_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);
+      if (i == 0) {
+         nvc0->vport_int[0] = (w << 16) | x;
+         nvc0->vport_int[1] = (h << 16) | y;
+
+         PUSH_DATA (push, nvc0->vport_int[0]);
+         PUSH_DATA (push, nvc0->vport_int[1]);
+      }
+      else {
+         PUSH_DATA (push, (w << 16) | x);
+         PUSH_DATA (push, (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
-- 
1.8.4.5
Tobias Klausmann
2014-Jun-14  14:41 UTC
[Nouveau] [PATCH 2/3] nvc0: mark scissor in nvc0_clear_{}
Signed-off-by: Tobias Klausmann <tobias.johannes.klausmann at mni.thm.de>
---
 src/gallium/drivers/nouveau/nvc0/nvc0_surface.c | 3 +++
 1 file changed, 3 insertions(+)
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
index c28ec6d..72227b8 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
@@ -298,6 +298,7 @@ nvc0_clear_render_target(struct pipe_context *pipe,
    BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);
    PUSH_DATA (push, ( width << 16) | dstx);
    PUSH_DATA (push, (height << 16) | dsty);
+   nvc0->scissors_dirty |= 1;
 
    BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1);
    PUSH_DATA (push, 1);
@@ -447,6 +448,7 @@ nvc0_clear_buffer(struct pipe_context *pipe,
    BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);
    PUSH_DATA (push, width << 16);
    PUSH_DATA (push, height << 16);
+   nvc0->scissors_dirty |= 1;
 
    IMMED_NVC0(push, NVC0_3D(RT_CONTROL), 1);
 
@@ -521,6 +523,7 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe,
 	BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);
 	PUSH_DATA (push, ( width << 16) | dstx);
 	PUSH_DATA (push, (height << 16) | dsty);
+	nvc0->scissors_dirty |= 1;
 
 	BEGIN_NVC0(push, NVC0_3D(ZETA_ADDRESS_HIGH), 5);
 	PUSH_DATAh(push, mt->base.address + sf->offset);
-- 
1.8.4.5
Tobias Klausmann
2014-Jun-14  14:41 UTC
[Nouveau] [PATCH 3/3] nv50/ir: Remove NV50_SEMANTIC_VIEWPORTINDEX and its last consumer
We use TGSI_SEMANTIC_VIEWPORT_INDEX for nvc0 now as well.
Signed-off-by: Tobias Klausmann <tobias.johannes.klausmann at mni.thm.de>
---
 src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h        | 1 -
 src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp | 1 -
 2 files changed, 2 deletions(-)
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h
b/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h
index f829aac..c885c8c 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h
@@ -70,7 +70,6 @@ struct nv50_ir_varying
 #endif
 
 #define NV50_SEMANTIC_CLIPDISTANCE  (TGSI_SEMANTIC_COUNT + 0)
-#define NV50_SEMANTIC_VIEWPORTINDEX (TGSI_SEMANTIC_COUNT + 4)
 #define NV50_SEMANTIC_TESSFACTOR    (TGSI_SEMANTIC_COUNT + 7)
 #define NV50_SEMANTIC_TESSCOORD     (TGSI_SEMANTIC_COUNT + 8)
 #define NV50_SEMANTIC_COUNT         (TGSI_SEMANTIC_COUNT + 10)
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp
b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp
index abadc7f..7e314aa 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp
@@ -538,7 +538,6 @@ recordLocation(uint16_t *locs, uint8_t *masks,
    case TGSI_SEMANTIC_VERTEXID: locs[SV_VERTEX_ID] = addr; break;
    case TGSI_SEMANTIC_PRIMID: locs[SV_PRIMITIVE_ID] = addr; break;
    case TGSI_SEMANTIC_LAYER: locs[SV_LAYER] = addr; break;
-   case NV50_SEMANTIC_VIEWPORTINDEX: locs[SV_VIEWPORT_INDEX] = addr; break;
    default:
       break;
    }
-- 
1.8.4.5
Ilia Mirkin
2014-Jun-14  15:46 UTC
[Nouveau] [PATCH 2/3] nvc0: mark scissor in nvc0_clear_{}
On Sat, Jun 14, 2014 at 10:41 AM, Tobias Klausmann <tobias.johannes.klausmann at mni.thm.de> wrote:> Signed-off-by: Tobias Klausmann <tobias.johannes.klausmann at mni.thm.de> > --- > src/gallium/drivers/nouveau/nvc0/nvc0_surface.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c > index c28ec6d..72227b8 100644 > --- a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c > +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c > @@ -298,6 +298,7 @@ nvc0_clear_render_target(struct pipe_context *pipe, > BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2); > PUSH_DATA (push, ( width << 16) | dstx); > PUSH_DATA (push, (height << 16) | dsty); > + nvc0->scissors_dirty |= 1;Can you explain why these changes are needed? You don't modify the scissor here (only the screen scissor)...> > BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1); > PUSH_DATA (push, 1); > @@ -447,6 +448,7 @@ nvc0_clear_buffer(struct pipe_context *pipe, > BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2); > PUSH_DATA (push, width << 16); > PUSH_DATA (push, height << 16); > + nvc0->scissors_dirty |= 1; > > IMMED_NVC0(push, NVC0_3D(RT_CONTROL), 1); > > @@ -521,6 +523,7 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe, > BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2); > PUSH_DATA (push, ( width << 16) | dstx); > PUSH_DATA (push, (height << 16) | dsty); > + nvc0->scissors_dirty |= 1; > > BEGIN_NVC0(push, NVC0_3D(ZETA_ADDRESS_HIGH), 5); > PUSH_DATAh(push, mt->base.address + sf->offset); > -- > 1.8.4.5 >
Ilia Mirkin
2014-Jun-14  15:48 UTC
[Nouveau] [PATCH 3/3] nv50/ir: Remove NV50_SEMANTIC_VIEWPORTINDEX and its last consumer
On Sat, Jun 14, 2014 at 10:41 AM, Tobias Klausmann <tobias.johannes.klausmann at mni.thm.de> wrote:> We use TGSI_SEMANTIC_VIEWPORT_INDEX for nvc0 now as well. > > Signed-off-by: Tobias Klausmann <tobias.johannes.klausmann at mni.thm.de> > --- > src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h | 1 - > src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp | 1 - > 2 files changed, 2 deletions(-) > > diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h > index f829aac..c885c8c 100644 > --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h > +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_driver.h > @@ -70,7 +70,6 @@ struct nv50_ir_varying > #endif > > #define NV50_SEMANTIC_CLIPDISTANCE (TGSI_SEMANTIC_COUNT + 0) > -#define NV50_SEMANTIC_VIEWPORTINDEX (TGSI_SEMANTIC_COUNT + 4) > #define NV50_SEMANTIC_TESSFACTOR (TGSI_SEMANTIC_COUNT + 7) > #define NV50_SEMANTIC_TESSCOORD (TGSI_SEMANTIC_COUNT + 8) > #define NV50_SEMANTIC_COUNT (TGSI_SEMANTIC_COUNT + 10) > diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp > index abadc7f..7e314aa 100644 > --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp > +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp > @@ -538,7 +538,6 @@ recordLocation(uint16_t *locs, uint8_t *masks, > case TGSI_SEMANTIC_VERTEXID: locs[SV_VERTEX_ID] = addr; break; > case TGSI_SEMANTIC_PRIMID: locs[SV_PRIMITIVE_ID] = addr; break; > case TGSI_SEMANTIC_LAYER: locs[SV_LAYER] = addr; break; > - case NV50_SEMANTIC_VIEWPORTINDEX: locs[SV_VIEWPORT_INDEX] = addr; break;I know this goes against what I said earlier, but actually do you mind flipping this over to TGSI_SEMANTIC_VIEWPORT_INDEX -- I suspect when ARB_fragment_layer_viewport is implemented, layer/viewport might be system values in the fragment shader. -ilia
Ilia Mirkin
2014-Jun-14  15:53 UTC
[Nouveau] [PATCH 1/3] nvc0: implement multiple viewports/scissors, enable ARB_viewport_array
On Sat, Jun 14, 2014 at 10:41 AM, Tobias Klausmann <tobias.johannes.klausmann at mni.thm.de> wrote:> Signed-off-by: Tobias Klausmann <tobias.johannes.klausmann at mni.thm.de> > --- > src/gallium/drivers/nouveau/nvc0/nvc0_context.h | 7 +- > src/gallium/drivers/nouveau/nvc0/nvc0_program.c | 2 +- > src/gallium/drivers/nouveau/nvc0/nvc0_screen.c | 20 ++-- > src/gallium/drivers/nouveau/nvc0/nvc0_screen.h | 3 + > src/gallium/drivers/nouveau/nvc0/nvc0_state.c | 27 ++++- > .../drivers/nouveau/nvc0/nvc0_state_validate.c | 121 +++++++++++++-------- > 6 files changed, 117 insertions(+), 63 deletions(-) > > diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h > index 76416a0..674dd3c 100644 > --- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h > +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h > @@ -178,8 +178,11 @@ 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 1c82a9a..667fbc8 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 3e6b011..3fdb6ae 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 c58add5..4802057 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 27e5cd8..c92aaac 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 dcec910..31140af 100644 > --- a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c > +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c > @@ -236,59 +236,88 @@ 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; > - nvc0->state.scissor = nvc0->rast->pipe.scissor; > + if (!(nvc0->dirty & NVC0_NEW_SCISSOR) && > + nvc0->rast->pipe.scissor == nvc0->state.scissor) > + return; > > - 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); > - } > + if (nvc0->state.scissor != nvc0->rast->pipe.scissor) > + nvc0->scissors_dirty = (1 << NVC0_MAX_VIEWPORTS) - 1; > + > + 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)) && > + !(nvc0->viewports_dirty & (1 << i))) > + continue;Why do you care whether the viewport is dirty here? The values you're setting here don't depend on the viewport...> + > + > + 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); > + if (i == 0) { > + nvc0->vport_int[0] = (w << 16) | x; > + nvc0->vport_int[1] = (h << 16) | y; > + > + PUSH_DATA (push, nvc0->vport_int[0]); > + PUSH_DATA (push, nvc0->vport_int[1]); > + } > + else { > + PUSH_DATA (push, (w << 16) | x); > + PUSH_DATA (push, (h << 16) | y); > + }This looks confusing, IMO. How about BEGIN_NVC0(...) PUSH_DATA(...) PUSH_DATA(...) if (i == 0) { nvc0->vport_int[0] = ... }> + > + 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 > -- > 1.8.4.5 >
Review comments sent; you should also add a separate patch that marks off ARB_viewport_array in GL3.txt and adds it to relnotes for 10.3. On Sat, Jun 14, 2014 at 10:41 AM, Tobias Klausmann <tobias.johannes.klausmann at mni.thm.de> wrote:> This patch-series implements the ARB_viewport_array for nvc0 and does > a little house-cleanig afterwords. > > Tobias Klausmann (3): > nvc0: implement multiple viewports/scissors, enable ARB_viewport_array > nvc0: mark scissor in nvc0_clear_{} > nv50/ir: Remove NV50_SEMANTIC_VIEWPORTINDEX and its last consumer > > .../drivers/nouveau/codegen/nv50_ir_driver.h | 1 - > .../nouveau/codegen/nv50_ir_target_nv50.cpp | 1 - > src/gallium/drivers/nouveau/nvc0/nvc0_context.h | 7 +- > src/gallium/drivers/nouveau/nvc0/nvc0_program.c | 2 +- > src/gallium/drivers/nouveau/nvc0/nvc0_screen.c | 20 ++-- > src/gallium/drivers/nouveau/nvc0/nvc0_screen.h | 3 + > src/gallium/drivers/nouveau/nvc0/nvc0_state.c | 27 ++++- > .../drivers/nouveau/nvc0/nvc0_state_validate.c | 121 +++++++++++++-------- > src/gallium/drivers/nouveau/nvc0/nvc0_surface.c | 3 + > 9 files changed, 120 insertions(+), 65 deletions(-) > > -- > 1.8.4.5 >