[Mesa-dev] [PATCH] nv50,nvc0: add support for cull distances

Tobias Klausmann tobias.johannes.klausmann at mni.thm.de
Sun May 15 12:39:59 UTC 2016


Looks a bit silly to review this patch as it is run under my name, but 
anyway:

Reviewed-by: Tobias Klausmann <tobias.johannes.klausmann at mni.thm.de>


On 14.05.2016 16:21, Ilia Mirkin wrote:
> From: Tobias Klausmann <tobias.johannes.klausmann at mni.thm.de>
>
> 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 at mni.thm.de>
> [imirkin: add enables on nvc0, add nv50 support]
> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
> ---
>   docs/GL3.txt                                           |  2 +-
>   docs/relnotes/11.3.0.html                              |  2 +-
>   src/gallium/drivers/nouveau/nv50/nv50_program.c        |  9 ++++++++-
>   src/gallium/drivers/nouveau/nv50/nv50_program.h        |  3 +++
>   src/gallium/drivers/nouveau/nv50/nv50_screen.c         |  2 +-
>   src/gallium/drivers/nouveau/nv50/nv50_screen.h         |  1 +
>   src/gallium/drivers/nouveau/nv50/nv50_shader_state.c   |  5 +++--
>   src/gallium/drivers/nouveau/nv50/nv50_state_validate.c | 15 +++++++++++----
>   src/gallium/drivers/nouveau/nvc0/nvc0_program.c        |  5 +++--
>   src/gallium/drivers/nouveau/nvc0/nvc0_program.h        |  1 +
>   src/gallium/drivers/nouveau/nvc0/nvc0_screen.c         |  2 +-
>   src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c |  1 +
>   12 files changed, 35 insertions(+), 13 deletions(-)
>
> diff --git a/docs/GL3.txt b/docs/GL3.txt
> index 5e49c57..b8b4361 100644
> --- a/docs/GL3.txt
> +++ b/docs/GL3.txt
> @@ -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)
> diff --git a/docs/relnotes/11.3.0.html b/docs/relnotes/11.3.0.html
> index 6a964f2..f456c0e 100644
> --- a/docs/relnotes/11.3.0.html
> +++ b/docs/relnotes/11.3.0.html
> @@ -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>
> diff --git a/src/gallium/drivers/nouveau/nv50/nv50_program.c b/src/gallium/drivers/nouveau/nv50/nv50_program.c
> index 89db67f..648cb73 100644
> --- a/src/gallium/drivers/nouveau/nv50/nv50_program.c
> +++ b/src/gallium/drivers/nouveau/nv50/nv50_program.c
> @@ -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;
> diff --git a/src/gallium/drivers/nouveau/nv50/nv50_program.h b/src/gallium/drivers/nouveau/nv50/nv50_program.h
> index 1de5122..0a22e5b 100644
> --- a/src/gallium/drivers/nouveau/nv50/nv50_program.h
> +++ b/src/gallium/drivers/nouveau/nv50/nv50_program.h
> @@ -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 {
> diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
> index 0912150..fa2493c 100644
> --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
> +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
> @@ -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:
> diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.h b/src/gallium/drivers/nouveau/nv50/nv50_screen.h
> index cce92f0..5bb7a51 100644
> --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.h
> +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.h
> @@ -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;
> diff --git a/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c b/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c
> index 3d2ebfb..f838d15 100644
> --- a/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c
> +++ b/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c
> @@ -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);
>   
> diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c b/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
> index 5120493..65f7338 100644
> --- a/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
> +++ b/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
> @@ -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
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
> index 9db45c0..b573ac0 100644
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
> @@ -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);
>   
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_program.h b/src/gallium/drivers/nouveau/nvc0/nvc0_program.h
> index 08af3c8..328088e 100644
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_program.h
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_program.h
> @@ -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;
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
> index eaf9c78..3178588 100644
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
> @@ -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:
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
> index 4280db4..7a9abe5 100644
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
> @@ -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;



More information about the mesa-dev mailing list