summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTobias Klausmann <[email protected]>2014-09-22 04:40:58 +0200
committerIlia Mirkin <[email protected]>2014-10-26 07:33:16 -0400
commit1a170980a09d82201b88e3fe20684a0df2cfea80 (patch)
tree256b9b1cf122fca875c321c28f053bfd083cd4d5 /src
parent13862812dc910a4ef57cb72cb9fe777ce3c14515 (diff)
nv50: handle inverted render conditions
This enables ARB_conditional_render_inverted. Signed-off-by: Tobias Klausmann <[email protected]> Reviewed-by: Ilia Mirkin <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_context.h3
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_query.c54
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_screen.c2
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_surface.c2
4 files changed, 51 insertions, 10 deletions
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) {