nv50,nvc0: add support for cull distances
authorTobias Klausmann <tobias.johannes.klausmann@mni.thm.de>
Sun, 8 May 2016 20:44:11 +0000 (22:44 +0200)
committerIlia Mirkin <imirkin@alum.mit.edu>
Sun, 15 May 2016 14:48:39 +0000 (10:48 -0400)
Cull distances are just a special case of clip distances as far as the
hardware is concerned. Make sure that the relevant "planes" are enabled,
and flip the clip mode to cull for those.

Signed-off-by: Tobias Klausmann <tobias.johannes.klausmann@mni.thm.de>
[imirkin: add enables on nvc0, add nv50 support]
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Reviewed-by: Tobias Klausmann <tobias.johannes.klausmann@mni.thm.de>
12 files changed:
docs/GL3.txt
docs/relnotes/11.3.0.html
src/gallium/drivers/nouveau/nv50/nv50_program.c
src/gallium/drivers/nouveau/nv50/nv50_program.h
src/gallium/drivers/nouveau/nv50/nv50_screen.c
src/gallium/drivers/nouveau/nv50/nv50_screen.h
src/gallium/drivers/nouveau/nv50/nv50_shader_state.c
src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
src/gallium/drivers/nouveau/nvc0/nvc0_program.c
src/gallium/drivers/nouveau/nvc0/nvc0_program.h
src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c

index 5e49c571dcff0c3e486b2cef626411daf7064871..b8b4361bf1e9cdd20ec18d3172aca238fee2b7be 100644 (file)
@@ -211,7 +211,7 @@ GL 4.5, GLSL 4.50:
   GL_ARB_ES3_1_compatibility                            not started
   GL_ARB_clip_control                                   DONE (i965, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
   GL_ARB_conditional_render_inverted                    DONE (i965, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
-  GL_ARB_cull_distance                                  DONE (i965)
+  GL_ARB_cull_distance                                  DONE (i965, nv50, nvc0)
   GL_ARB_derivative_control                             DONE (i965, nv50, nvc0, r600, radeonsi)
   GL_ARB_direct_state_access                            DONE (all drivers)
   GL_ARB_get_texture_sub_image                          DONE (all drivers)
index 6a964f20122bcb9979ff65783485f089a11637d3..f456c0e18f414bbef6c79495fa456e0937cf1b0f 100644 (file)
@@ -46,7 +46,7 @@ Note: some of the new features are only available with certain drivers.
 <ul>
 <li>OpenGL 4.2 on radeonsi</li>
 <li>GL_ARB_compute_shader on radeonsi, softpipe</li>
-<li>GL_ARB_cull_distance on i965/gen6+</li>
+<li>GL_ARB_cull_distance on i965/gen6+, nv50, nvc0</li>
 <li>GL_ARB_framebuffer_no_attachments on nvc0, r600, radeonsi, softpipe</li>
 <li>GL_ARB_internalformat_query2 on all drivers</li>
 <li>GL_ARB_query_buffer_object on i965/hsw+</li>
index 89db67f0524a5fd97ac72688cae3ed1db016251f..648cb7314bf772626def61346509e2738f3b48b4 100644 (file)
@@ -319,7 +319,7 @@ nv50_program_translate(struct nv50_program *prog, uint16_t chipset,
                        struct pipe_debug_callback *debug)
 {
    struct nv50_ir_prog_info *info;
-   int ret;
+   int i, ret;
    const uint8_t map_undef = (prog->type == PIPE_SHADER_VERTEX) ? 0x40 : 0x80;
 
    info = CALLOC_STRUCT(nv50_ir_prog_info);
@@ -378,6 +378,13 @@ nv50_program_translate(struct nv50_program *prog, uint16_t chipset,
 
    prog->vp.need_vertex_id = info->io.vertexId < PIPE_MAX_SHADER_INPUTS;
 
+   prog->vp.clip_enable = (1 << info->io.clipDistances) - 1;
+   prog->vp.cull_enable =
+      ((1 << info->io.cullDistances) - 1) << info->io.clipDistances;
+   prog->vp.clip_mode = 0;
+   for (i = 0; i < info->io.cullDistances; ++i)
+      prog->vp.clip_mode |= 1 << ((info->io.clipDistances + i) * 4);
+
    if (prog->type == PIPE_SHADER_FRAGMENT) {
       if (info->prop.fp.writesDepth) {
          prog->fp.flags[0] |= NV50_3D_FP_CONTROL_EXPORTS_Z;
index 1de5122a56e86432a9c315e7393c1eaf64959bc8..0a22e5bbbcf3a4de18dc0108941bfc4ea045c58b 100644 (file)
@@ -79,6 +79,9 @@ struct nv50_program {
       ubyte clpd[2];     /* output slot of clip distance[i]'s 1st component */
       ubyte clpd_nr;
       bool need_vertex_id;
+      uint32_t clip_mode;
+      uint8_t clip_enable; /* mask of defined clip planes */
+      uint8_t cull_enable; /* mask of defined cull distances */
    } vp;
 
    struct {
index 091215057d5c6bdcfc78e513309a098bfd0116f3..fa2493cc60e180072729010653cb21b06c5bc2af 100644 (file)
@@ -195,6 +195,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
    case PIPE_CAP_INVALIDATE_BUFFER:
    case PIPE_CAP_STRING_MARKER:
+   case PIPE_CAP_CULL_DISTANCE:
       return 1;
    case PIPE_CAP_SEAMLESS_CUBE_MAP:
       return 1; /* class_3d >= NVA0_3D_CLASS; */
@@ -247,7 +248,6 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_PCI_FUNCTION:
    case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
    case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
-   case PIPE_CAP_CULL_DISTANCE:
       return 0;
 
    case PIPE_CAP_VENDOR_ID:
index cce92f0dd5e0f49a2cf0a78153b526521bf49dca..5bb7a516686584b178dff8d8e2abe795069313a5 100644 (file)
@@ -36,6 +36,7 @@ struct nv50_graph_state {
    uint32_t semantic_color;
    uint32_t semantic_psize;
    int32_t index_bias;
+   uint32_t clip_mode;
    bool uniform_buffer_bound[3];
    bool prim_restart;
    bool point_sprite;
index 3d2ebfbcc465858593c598368d63cf9b3c5782b9..f838d151161c6664a0f45d803aea3483ea49c407 100644 (file)
@@ -389,6 +389,7 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
    uint32_t psiz = 0x000;
    uint32_t interp = fp->fp.interp;
    uint32_t colors = fp->fp.colors;
+   uint32_t clpd_nr = util_last_bit(vp->vp.clip_enable | vp->vp.cull_enable);
    uint32_t lin[4];
    uint8_t map[64];
    uint8_t so_map[64];
@@ -415,7 +416,7 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
    dummy.linear = 0;
    m = nv50_vec4_map(map, 0, lin, &dummy, &vp->out[0]);
 
-   for (c = 0; c < vp->vp.clpd_nr; ++c)
+   for (c = 0; c < clpd_nr; ++c)
       map[m++] = vp->vp.clpd[c / 4] + (c % 4);
 
    colors |= m << 8; /* adjust BFC0 id */
@@ -522,7 +523,7 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
    BEGIN_NV04(push, NV50_3D(GP_VIEWPORT_ID_ENABLE), 5);
    PUSH_DATA (push, vp->gp.has_viewport);
    PUSH_DATA (push, colors);
-   PUSH_DATA (push, (vp->vp.clpd_nr << 8) | 4);
+   PUSH_DATA (push, (clpd_nr << 8) | 4);
    PUSH_DATA (push, layerid);
    PUSH_DATA (push, psiz);
 
index 512049300318924fb7595da02188c2671f0806d1..65f7338f43ebbc5252cc61f04ce4871d680b3cd9 100644 (file)
@@ -340,7 +340,7 @@ nv50_validate_clip(struct nv50_context *nv50)
 {
    struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nv50_program *vp;
-   uint8_t clip_enable;
+   uint8_t clip_enable = nv50->rast->pipe.clip_plane_enable;
 
    if (nv50->dirty_3d & NV50_NEW_3D_CLIP) {
       BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
@@ -353,13 +353,20 @@ nv50_validate_clip(struct nv50_context *nv50)
    if (likely(!vp))
       vp = nv50->vertprog;
 
-   clip_enable = nv50->rast->pipe.clip_plane_enable;
+   if (clip_enable)
+      nv50_check_program_ucps(nv50, vp, clip_enable);
+
+   clip_enable &= vp->vp.clip_enable;
+   clip_enable |= vp->vp.cull_enable;
 
    BEGIN_NV04(push, NV50_3D(CLIP_DISTANCE_ENABLE), 1);
    PUSH_DATA (push, clip_enable);
 
-   if (clip_enable)
-      nv50_check_program_ucps(nv50, vp, clip_enable);
+   if (nv50->state.clip_mode != vp->vp.clip_mode) {
+      nv50->state.clip_mode = vp->vp.clip_mode;
+      BEGIN_NV04(push, NV50_3D(CLIP_DISTANCE_MODE), 1);
+      PUSH_DATA (push, vp->vp.clip_mode);
+   }
 }
 
 static void
index 9db45c0759a69b61ca9deb769aff15092daa6836..b573ac0b8bce50778e4ba2c80f0b6a676ee30873 100644 (file)
@@ -251,8 +251,9 @@ nvc0_vtgp_gen_header(struct nvc0_program *vp, struct nv50_ir_prog_info *info)
       }
    }
 
-   vp->vp.clip_enable =
-      (1 << (info->io.clipDistances + info->io.cullDistances)) - 1;
+   vp->vp.clip_enable = (1 << info->io.clipDistances) - 1;
+   vp->vp.cull_enable =
+      ((1 << info->io.cullDistances) - 1) << info->io.clipDistances;
    for (i = 0; i < info->io.cullDistances; ++i)
       vp->vp.clip_mode |= 1 << ((info->io.clipDistances + i) * 4);
 
index 08af3c823b828a7bcbc8f960adf452dae103bb2a..328088e4cc4ea60fbd10c399d2b0c413f9ee8f97 100644 (file)
@@ -39,6 +39,7 @@ struct nvc0_program {
    struct {
       uint32_t clip_mode; /* clip/cull selection */
       uint8_t clip_enable; /* mask of defined clip planes */
+      uint8_t cull_enable; /* mask of defined cull distances */
       uint8_t num_ucps; /* also set to max if ClipDistance is used */
       uint8_t edgeflag; /* attribute index of edgeflag input */
       bool need_vertex_id;
index eaf9c78d24be4bdf41c0fa699773b04650ab6386..3178588819c9605bdc1872c97cc2924973a3c359 100644 (file)
@@ -227,6 +227,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_INVALIDATE_BUFFER:
    case PIPE_CAP_STRING_MARKER:
    case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
+   case PIPE_CAP_CULL_DISTANCE:
       return 1;
    case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
       return (class_3d >= NVE4_3D_CLASS) ? 1 : 0;
@@ -259,7 +260,6 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_PCI_DEVICE:
    case PIPE_CAP_PCI_FUNCTION:
    case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
-   case PIPE_CAP_CULL_DISTANCE:
       return 0;
 
    case PIPE_CAP_VENDOR_ID:
index 4280db44bb63216904ffed1668385beb484081fb..7a9abe58754854a9db1bd84bc75e26a815985e98 100644 (file)
@@ -389,6 +389,7 @@ nvc0_validate_clip(struct nvc0_context *nvc0)
          nvc0_upload_uclip_planes(nvc0, stage);
 
    clip_enable &= vp->vp.clip_enable;
+   clip_enable |= vp->vp.cull_enable;
 
    if (nvc0->state.clip_enable != clip_enable) {
       nvc0->state.clip_enable = clip_enable;