From 8c0293979457dab49f0055075d1ca4daa3fb8033 Mon Sep 17 00:00:00 2001 From: Tobias Klausmann Date: Sun, 8 May 2016 22:44:11 +0200 Subject: [PATCH] nv50,nvc0: add support for cull distances 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 [imirkin: add enables on nvc0, add nv50 support] Signed-off-by: Ilia Mirkin Reviewed-by: Tobias Klausmann --- 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 + .../drivers/nouveau/nv50/nv50_shader_state.c | 5 +++-- .../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 +- .../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 5e49c571dcf..b8b4361bf1e 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 6a964f20122..f456c0e18f4 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.
  • OpenGL 4.2 on radeonsi
  • GL_ARB_compute_shader on radeonsi, softpipe
  • -
  • GL_ARB_cull_distance on i965/gen6+
  • +
  • GL_ARB_cull_distance on i965/gen6+, nv50, nvc0
  • GL_ARB_framebuffer_no_attachments on nvc0, r600, radeonsi, softpipe
  • GL_ARB_internalformat_query2 on all drivers
  • GL_ARB_query_buffer_object on i965/hsw+
  • diff --git a/src/gallium/drivers/nouveau/nv50/nv50_program.c b/src/gallium/drivers/nouveau/nv50/nv50_program.c index 89db67f0524..648cb7314bf 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 1de5122a56e..0a22e5bbbcf 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 091215057d5..fa2493cc60e 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 cce92f0dd5e..5bb7a516686 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 3d2ebfbcc46..f838d151161 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 51204930031..65f7338f43e 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 9db45c0759a..b573ac0b8bc 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 08af3c823b8..328088e4cc4 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 eaf9c78d24b..3178588819c 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 4280db44bb6..7a9abe58754 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; -- 2.30.2