[Mesa-dev] Support 'GL_ARB_conditional_render_inverted' for r600 & radeonsi

Marek Olšák maraeo at gmail.com
Tue Jul 28 04:26:31 PDT 2015


Hi Edward,

please use git send-email next time. Now I have to paste your patch here.


diff --git a/docs/GL3.txt b/docs/GL3.txt
index 15bb57f..6d9d424 100644
--- a/docs/GL3.txt
+++ b/docs/GL3.txt
@@ -189,7 +189,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, llvmpipe, softpipe)
+  GL_ARB_conditional_render_inverted                   DONE (i965,
nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)

You forgot to expose the PIPE_CAP for r600 (in r600_pipe.c).

Also please update the release notes as well (docs/relnotes/10.7.html).


   GL_ARB_cull_distance                                 in progress (Tobias)
   GL_ARB_derivative_control                            DONE (i965,
nv50, nvc0, r600, radeonsi)
   GL_ARB_direct_state_access                           DONE (all drivers)
diff --git a/src/gallium/drivers/radeon/r600_query.c
b/src/gallium/drivers/radeon/r600_query.c
index a1d8241..33ffe76 100644
--- a/src/gallium/drivers/radeon/r600_query.c
+++ b/src/gallium/drivers/radeon/r600_query.c
@@ -290,45 +290,57 @@ static void r600_emit_query_predication(struct
r600_common_context *ctx, struct
                     int operation, bool flag_wait)
 {
     struct radeon_winsys_cs *cs = ctx->rings.gfx.cs;
+    struct r600_query_buffer *qbuf;
+    unsigned count;
+    uint32_t op = PRED_OP(operation);
+
+    // if true then invert, see GL_ARB_conditional_render_inverted

C++ comments are not allowed.


+    if (ctx->current_render_cond_cond)
+        op |= PREDICATION_DRAW_NOT_VISIBLE; // Draw if not visable/overflow
+    else
+        op |= PREDICATION_DRAW_VISIBLE; // Draw if visable/overflow

-    if (operation == PREDICATION_OP_CLEAR) {
+    switch (operation) {
+    case PREDICATION_OP_ZPASS: // query->type == PIPE_QUERY_OCCLUSION_PREDICATE
+        break;
+    case PREDICATION_OP_PRIMCOUNT: // query->type ==
PIPE_QUERY_SO_OVERFLOW_PREDICATE
+        break;
+    case PREDICATION_OP_CLEAR:

Please keep the if statement here instead of the switch.


         ctx->need_gfx_cs_space(&ctx->b, 3, FALSE);

         radeon_emit(cs, PKT3(PKT3_SET_PREDICATION, 1, 0));
         radeon_emit(cs, 0);
         radeon_emit(cs, PRED_OP(PREDICATION_OP_CLEAR));
-    } else {
-        struct r600_query_buffer *qbuf;
-        unsigned count;
-        uint32_t op;
-
-        /* Find how many results there are. */
-        count = 0;
-        for (qbuf = &query->buffer; qbuf; qbuf = qbuf->previous) {
-            count += qbuf->results_end / query->result_size;
-        }
+        return;
+    default:
+        break;
+    }

The following cleanup should be in a separate patch.

-        ctx->need_gfx_cs_space(&ctx->b, 5 * count, TRUE);
+    /* Find how many results there are. */
+    count = 0;
+    for (qbuf = &query->buffer; qbuf; qbuf = qbuf->previous) {
+        count += qbuf->results_end / query->result_size;
+    }

-        op = PRED_OP(operation) | PREDICATION_DRAW_VISIBLE |
-                (flag_wait ? PREDICATION_HINT_WAIT :
PREDICATION_HINT_NOWAIT_DRAW);
+    ctx->need_gfx_cs_space(&ctx->b, 5 * count, TRUE);

-        /* emit predicate packets for all data blocks */
-        for (qbuf = &query->buffer; qbuf; qbuf = qbuf->previous) {
-            unsigned results_base = 0;
-            uint64_t va = qbuf->buf->gpu_address;
+    op |= flag_wait ? PREDICATION_HINT_WAIT : PREDICATION_HINT_NOWAIT_DRAW;

-            while (results_base < qbuf->results_end) {
-                radeon_emit(cs, PKT3(PKT3_SET_PREDICATION, 1, 0));
-                radeon_emit(cs, (va + results_base) & 0xFFFFFFFFUL);
-                radeon_emit(cs, op | (((va + results_base) >> 32UL) & 0xFF));
-                r600_emit_reloc(ctx, &ctx->rings.gfx, qbuf->buf,
RADEON_USAGE_READ,
-                        RADEON_PRIO_MIN);
-                results_base += query->result_size;
+    /* emit predicate packets for all data blocks */
+    for (qbuf = &query->buffer; qbuf; qbuf = qbuf->previous) {
+        unsigned results_base = 0;
+        uint64_t va = qbuf->buf->gpu_address;

-                /* set CONTINUE bit for all packets except the first */
-                op |= PREDICATION_CONTINUE;
-            }
+        while (results_base < qbuf->results_end) {
+            radeon_emit(cs, PKT3(PKT3_SET_PREDICATION, 1, 0));
+            radeon_emit(cs, (va + results_base) & 0xFFFFFFFFUL);
+            radeon_emit(cs, op | (((va + results_base) >> 32UL) & 0xFF));
+            r600_emit_reloc(ctx, &ctx->rings.gfx, qbuf->buf, RADEON_USAGE_READ,
+                    RADEON_PRIO_MIN);
+            results_base += query->result_size;
+
+            /* set CONTINUE bit for all packets except the first */
+            op |= PREDICATION_CONTINUE;
         }
     }
 }
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c
b/src/gallium/drivers/radeonsi/si_pipe.c
index ebe1f5a..808b9bc 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -250,6 +250,7 @@ static int si_get_param(struct pipe_screen*
pscreen, enum pipe_cap param)
     case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
     case PIPE_CAP_TGSI_TEXCOORD:
     case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
+    case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
         return 1;

     case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
@@ -290,7 +291,6 @@ static int si_get_param(struct pipe_screen*
pscreen, enum pipe_cap param)
     case PIPE_CAP_USER_VERTEX_BUFFERS:
     case PIPE_CAP_FAKE_SW_MSAA:
     case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
-    case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
     case PIPE_CAP_SAMPLER_VIEW_TARGET:
     case PIPE_CAP_VERTEXID_NOBASE:
         return 0;
-- 
2.4.3

Marek


More information about the mesa-dev mailing list