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