summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nouveau/nv50
diff options
context:
space:
mode:
authorTobias Klausmann <[email protected]>2016-05-08 22:44:11 +0200
committerIlia Mirkin <[email protected]>2016-05-15 10:48:39 -0400
commit8c0293979457dab49f0055075d1ca4daa3fb8033 (patch)
tree677ce1a79386b8b72ebdf51d6ac3120da6f2e6ba /src/gallium/drivers/nouveau/nv50
parent2ad970ecf49ecf79cb1b2c38cedc69e527eb3c28 (diff)
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 <[email protected]> [imirkin: add enables on nvc0, add nv50 support] Signed-off-by: Ilia Mirkin <[email protected]> Reviewed-by: Tobias Klausmann <[email protected]>
Diffstat (limited to 'src/gallium/drivers/nouveau/nv50')
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_program.c9
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_program.h3
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_screen.c2
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_screen.h1
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_shader_state.c5
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_state_validate.c15
6 files changed, 27 insertions, 8 deletions
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