From 1a170980a09d82201b88e3fe20684a0df2cfea80 Mon Sep 17 00:00:00 2001
From: Tobias Klausmann
Date: Mon, 22 Sep 2014 04:40:58 +0200
Subject: [PATCH] nv50: handle inverted render conditions
This enables ARB_conditional_render_inverted.
Signed-off-by: Tobias Klausmann
Reviewed-by: Ilia Mirkin
---
docs/GL3.txt | 2 +-
docs/relnotes/10.4.html | 1 +
.../drivers/nouveau/nv50/nv50_context.h | 3 +-
src/gallium/drivers/nouveau/nv50/nv50_query.c | 54 ++++++++++++++++---
.../drivers/nouveau/nv50/nv50_screen.c | 2 +-
.../drivers/nouveau/nv50/nv50_surface.c | 2 +-
6 files changed, 53 insertions(+), 11 deletions(-)
diff --git a/docs/GL3.txt b/docs/GL3.txt
index 6a988d5e710..84d1784c9d1 100644
--- a/docs/GL3.txt
+++ b/docs/GL3.txt
@@ -188,7 +188,7 @@ GL 4.5, GLSL 4.50:
GL_ARB_ES3_1_compatibility not started
GL_ARB_clip_control DONE (llvmpipe, softpipe, r300, r600, radeonsi)
- GL_ARB_conditional_render_inverted DONE (i965, nvc0, llvmpipe, softpipe)
+ GL_ARB_conditional_render_inverted DONE (i965, nv50, nvc0, llvmpipe, softpipe)
GL_ARB_cull_distance not started
GL_ARB_derivative_control DONE (i965, nv50, nvc0, r600)
GL_ARB_direct_state_access not started
diff --git a/docs/relnotes/10.4.html b/docs/relnotes/10.4.html
index 67c3087ee44..159c9a66483 100644
--- a/docs/relnotes/10.4.html
+++ b/docs/relnotes/10.4.html
@@ -44,6 +44,7 @@ Note: some of the new features are only available with certain drivers.
+- GL_ARB_conditional_render_inverted on nv50
- GL_ARB_sample_shading on r600
- GL_ARB_texture_view on nv50, nvc0
- GL_ARB_clip_control on llvmpipe, softpipe, r300, r600, radeonsi
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.h b/src/gallium/drivers/nouveau/nv50/nv50_context.h
index 9557317af9f..45eb554eb4f 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_context.h
+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.h
@@ -178,8 +178,9 @@ struct nv50_context {
uint32_t rt_array_mode;
struct pipe_query *cond_query;
- boolean cond_cond;
+ boolean cond_cond; /* inverted rendering condition */
uint cond_mode;
+ uint32_t cond_condmode; /* the calculated condition */
struct nv50_blitctx *blit;
};
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query.c b/src/gallium/drivers/nouveau/nv50/nv50_query.c
index a373dc60a67..e0671ce5375 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_query.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_query.c
@@ -158,7 +158,10 @@ nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
/* XXX: can we do this with the GPU, and sync with respect to a previous
* query ?
*/
+ q->data[0] = q->sequence; /* initialize sequence */
q->data[1] = 1; /* initial render condition = TRUE */
+ q->data[4] = q->sequence + 1; /* for comparison COND_MODE */
+ q->data[5] = 0;
}
if (!q->is64bit)
q->data[0] = q->sequence++; /* the previously used one */
@@ -327,30 +330,67 @@ nv50_render_condition(struct pipe_context *pipe,
struct nv50_context *nv50 = nv50_context(pipe);
struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv50_query *q;
+ uint32_t cond;
+ boolean wait =
+ mode != PIPE_RENDER_COND_NO_WAIT &&
+ mode != PIPE_RENDER_COND_BY_REGION_NO_WAIT;
+
+ if (!pq) {
+ cond = NV50_3D_COND_MODE_ALWAYS;
+ }
+ else {
+ q = nv50_query(pq);
+ /* NOTE: comparison of 2 queries only works if both have completed */
+ switch (q->type) {
+ case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
+ cond = condition ? NV50_3D_COND_MODE_EQUAL :
+ NV50_3D_COND_MODE_NOT_EQUAL;
+ wait = TRUE;
+ break;
+ case PIPE_QUERY_OCCLUSION_COUNTER:
+ case PIPE_QUERY_OCCLUSION_PREDICATE:
+ if (likely(!condition)) {
+ /* XXX: Placeholder, handle nesting here if available */
+ if (unlikely(false))
+ cond = wait ? NV50_3D_COND_MODE_NOT_EQUAL :
+ NV50_3D_COND_MODE_ALWAYS;
+ else
+ cond = NV50_3D_COND_MODE_RES_NON_ZERO;
+ } else {
+ cond = wait ? NV50_3D_COND_MODE_EQUAL : NV50_3D_COND_MODE_ALWAYS;
+ }
+ break;
+ default:
+ assert(!"render condition query not a predicate");
+ cond = NV50_3D_COND_MODE_ALWAYS;
+ break;
+ }
+ }
nv50->cond_query = pq;
nv50->cond_cond = condition;
+ nv50->cond_condmode = cond;
nv50->cond_mode = mode;
- PUSH_SPACE(push, 9);
-
if (!pq) {
+ PUSH_SPACE(push, 2);
BEGIN_NV04(push, NV50_3D(COND_MODE), 1);
- PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS);
+ PUSH_DATA (push, cond);
return;
}
- q = nv50_query(pq);
- if (mode == PIPE_RENDER_COND_WAIT ||
- mode == PIPE_RENDER_COND_BY_REGION_WAIT) {
+ PUSH_SPACE(push, 9);
+
+ if (wait) {
BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);
PUSH_DATA (push, 0);
}
+ PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
BEGIN_NV04(push, NV50_3D(COND_ADDRESS_HIGH), 3);
PUSH_DATAh(push, q->bo->offset + q->offset);
PUSH_DATA (push, q->bo->offset + q->offset);
- PUSH_DATA (push, NV50_3D_COND_MODE_RES_NON_ZERO);
+ PUSH_DATA (push, cond);
BEGIN_NV04(push, NV50_2D(COND_ADDRESS_HIGH), 2);
PUSH_DATAh(push, q->bo->offset + q->offset);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
index 4ee598032f2..825e0ba4997 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
@@ -172,6 +172,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
case PIPE_CAP_SAMPLER_VIEW_TARGET:
+ case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
return 1;
case PIPE_CAP_SEAMLESS_CUBE_MAP:
return 1; /* class_3d >= NVA0_3D_CLASS; */
@@ -203,7 +204,6 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
case PIPE_CAP_COMPUTE:
case PIPE_CAP_DRAW_INDIRECT:
- case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
case PIPE_CAP_CLIP_HALFZ:
return 0;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
index e1dd6e0eeb4..e1d2b2680e8 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
@@ -1297,7 +1297,7 @@ nv50_blit_eng2d(struct nv50_context *nv50, const struct pipe_blit_info *info)
if (nv50->cond_query && info->render_condition_enable) {
BEGIN_NV04(push, NV50_2D(COND_MODE), 1);
- PUSH_DATA (push, NV50_2D_COND_MODE_RES_NON_ZERO);
+ PUSH_DATA (push, nv50->cond_condmode);
}
if (mask != 0xffffffff) {
--
2.30.2