[virglrenderer-devel] [PATCH] renderer: add memory barrier support. (v2)

Dave Airlie airlied at gmail.com
Tue Jul 24 23:08:41 UTC 2018


From: Dave Airlie <airlied at redhat.com>

GL4.2/GLES3.1 adds glMemoryBarrier so make sure we can handle it.

v2: add a cap bit for this for guest
---
 src/gallium/include/pipe/p_defines.h | 12 ++++++++++
 src/virgl_hw.h                       |  1 +
 src/virgl_protocol.h                 |  5 ++++
 src/vrend_decode.c                   | 13 +++++++++++
 src/vrend_renderer.c                 | 45 ++++++++++++++++++++++++++++++++++++
 src/vrend_renderer.h                 |  3 ++-
 6 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index ebc1e68..610fc41 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -329,6 +329,18 @@ enum pipe_flush_flags {
  * Flags for pipe_context::memory_barrier.
  */
 #define PIPE_BARRIER_MAPPED_BUFFER     (1 << 0)
+#define PIPE_BARRIER_SHADER_BUFFER     (1 << 1)
+#define PIPE_BARRIER_QUERY_BUFFER      (1 << 2)
+#define PIPE_BARRIER_VERTEX_BUFFER     (1 << 3)
+#define PIPE_BARRIER_INDEX_BUFFER      (1 << 4)
+#define PIPE_BARRIER_CONSTANT_BUFFER   (1 << 5)
+#define PIPE_BARRIER_INDIRECT_BUFFER   (1 << 6)
+#define PIPE_BARRIER_TEXTURE           (1 << 7)
+#define PIPE_BARRIER_IMAGE             (1 << 8)
+#define PIPE_BARRIER_FRAMEBUFFER       (1 << 9)
+#define PIPE_BARRIER_STREAMOUT_BUFFER  (1 << 10)
+#define PIPE_BARRIER_GLOBAL_BUFFER     (1 << 11)
+#define PIPE_BARRIER_ALL               ((1 << 12) - 1)
 
 /*
  * Resource binding flags -- state tracker must specify in advance all
diff --git a/src/virgl_hw.h b/src/virgl_hw.h
index 81193e7..a0269da 100644
--- a/src/virgl_hw.h
+++ b/src/virgl_hw.h
@@ -223,6 +223,7 @@ enum virgl_formats {
 #define VIRGL_CAP_COPY_IMAGE           (1 << 3)
 #define VIRGL_CAP_TGSI_PRECISE         (1 << 4)
 #define VIRGL_CAP_TXQS                 (1 << 5)
+#define VIRGL_CAP_MEMORY_BARRIER       (1 << 6)
 
 /* virgl bind flags - these are compatible with mesa 10.5 gallium.
  * but are fixed, no other should be passed to virgl either.
diff --git a/src/virgl_protocol.h b/src/virgl_protocol.h
index a23e318..dee2e4c 100644
--- a/src/virgl_protocol.h
+++ b/src/virgl_protocol.h
@@ -87,6 +87,7 @@ enum virgl_context_cmd {
    VIRGL_CCMD_SET_MIN_SAMPLES,
    VIRGL_CCMD_SET_SHADER_BUFFERS,
    VIRGL_CCMD_SET_SHADER_IMAGES,
+   VIRGL_CCMD_MEMORY_BARRIER,
 };
 
 /*
@@ -512,4 +513,8 @@ enum virgl_context_cmd {
 #define VIRGL_SET_SHADER_IMAGE_LEVEL_SIZE(x) ((x) * VIRGL_SET_SHADER_IMAGE_ELEMENT_SIZE + 6)
 #define VIRGL_SET_SHADER_IMAGE_RES_HANDLE(x) ((x) * VIRGL_SET_SHADER_IMAGE_ELEMENT_SIZE + 7)
 
+/* memory barrier */
+#define VIRGL_MEMORY_BARRIER_SIZE 1
+#define VIRGL_MEMORY_BARRIER_FLAGS 1
+
 #endif
diff --git a/src/vrend_decode.c b/src/vrend_decode.c
index 4cf56d7..90fb1cb 100644
--- a/src/vrend_decode.c
+++ b/src/vrend_decode.c
@@ -1137,6 +1137,16 @@ static int vrend_decode_set_shader_images(struct vrend_decode_ctx *ctx, uint16_t
    return 0;
 }
 
+static int vrend_decode_memory_barrier(struct vrend_decode_ctx *ctx, uint16_t length)
+{
+   if (length != VIRGL_MEMORY_BARRIER_SIZE)
+      return EINVAL;
+
+   unsigned flags = get_buf_entry(ctx, VIRGL_MEMORY_BARRIER_FLAGS);
+   vrend_memory_barrier(ctx->grctx, flags);
+   return 0;
+}
+
 static int vrend_decode_set_streamout_targets(struct vrend_decode_ctx *ctx,
                                               uint16_t length)
 {
@@ -1371,6 +1381,9 @@ int vrend_decode_block(uint32_t ctx_id, uint32_t *block, int ndw)
       case VIRGL_CCMD_SET_SHADER_IMAGES:
          ret = vrend_decode_set_shader_images(gdctx, len);
          break;
+      case VIRGL_CCMD_MEMORY_BARRIER:
+         ret = vrend_decode_memory_barrier(gdctx, len);
+         break;
       default:
          ret = EINVAL;
       }
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index e9a5d38..51e613a 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -92,6 +92,7 @@ enum features_id
    feat_arb_or_gles_ext_texture_buffer,
    feat_arb_robustness,
    feat_base_instance,
+   feat_barrier,
    feat_bit_encoding,
    feat_copy_image,
    feat_conditional_render_inverted,
@@ -117,6 +118,7 @@ enum features_id
    feat_sample_shading,
    feat_samplers,
    feat_ssbo,
+   feat_ssbo_barrier,
    feat_stencil_texturing,
    feat_tessellation,
    feat_texture_array,
@@ -145,6 +147,7 @@ static const  struct {
    [feat_arb_or_gles_ext_texture_buffer] = { 31, UNAVAIL, { "GL_ARB_texture_buffer_object", "GL_EXT_texture_buffer", NULL } },
    [feat_arb_robustness] = { UNAVAIL, UNAVAIL, { "GL_ARB_robustness" } },
    [feat_base_instance] = { 42, UNAVAIL, { "GL_ARB_base_instance", "GL_EXT_base_instance" } },
+   [feat_barrier] = { 42, 31, {} },
    [feat_bit_encoding] = { 33, UNAVAIL, { "GL_ARB_shader_bit_encoding" } },
    [feat_copy_image] = { 43, 32, { "GL_ARB_copy_image", "GL_EXT_copy_image", "GL_OES_copy_image" } },
    [feat_conditional_render_inverted] = { 45, UNAVAIL, { "GL_ARB_conditional_render_inverted" } },
@@ -170,6 +173,7 @@ static const  struct {
    [feat_sample_shading] = { 40, UNAVAIL, { "GL_ARB_sample_shading" } },
    [feat_samplers] = { 33, UNAVAIL, { "GL_ARB_sampler_objects" } },
    [feat_ssbo] = { 43, 31, { "GL_ARB_shader_storage_buffer_object" } },
+   [feat_ssbo_barrier] = { 43, 31, {} },
    [feat_stencil_texturing] = { 43, UNAVAIL, { "GL_ARB_stencil_texturing" } },
    [feat_tessellation] = { 40, UNAVAIL, { "GL_ARB_tessellation_shader" } },
    [feat_texture_array] = { 30, 30, { "GL_EXT_texture_array" } },
@@ -2520,6 +2524,44 @@ void vrend_set_single_ssbo(struct vrend_context *ctx,
    }
 }
 
+void vrend_memory_barrier(struct vrend_context *ctx,
+                          unsigned flags)
+{
+   GLbitfield gl_barrier = 0;
+
+   if (!has_feature(feat_barrier))
+      return;
+
+   if ((flags & PIPE_BARRIER_ALL) == PIPE_BARRIER_ALL)
+      gl_barrier = GL_ALL_BARRIER_BITS;
+   else {
+      if (flags & PIPE_BARRIER_VERTEX_BUFFER)
+         gl_barrier |= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT;
+      if (flags & PIPE_BARRIER_INDEX_BUFFER)
+         gl_barrier |= GL_ELEMENT_ARRAY_BARRIER_BIT;
+      if (flags & PIPE_BARRIER_CONSTANT_BUFFER)
+         gl_barrier |= GL_UNIFORM_BARRIER_BIT;
+      if (flags & PIPE_BARRIER_TEXTURE)
+         gl_barrier |= GL_TEXTURE_FETCH_BARRIER_BIT | GL_PIXEL_BUFFER_BARRIER_BIT;
+      if (flags & PIPE_BARRIER_IMAGE)
+         gl_barrier |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;
+      if (flags & PIPE_BARRIER_INDIRECT_BUFFER)
+         gl_barrier |= GL_COMMAND_BARRIER_BIT;
+      if (flags & PIPE_BARRIER_MAPPED_BUFFER)
+         gl_barrier |= GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT;
+      if (flags & PIPE_BARRIER_FRAMEBUFFER)
+         gl_barrier |= GL_FRAMEBUFFER_BARRIER_BIT;
+      if (flags & PIPE_BARRIER_STREAMOUT_BUFFER)
+         gl_barrier |= GL_TRANSFORM_FEEDBACK_BARRIER_BIT;
+      if (flags & PIPE_BARRIER_SHADER_BUFFER) {
+         gl_barrier |= GL_ATOMIC_COUNTER_BARRIER_BIT;
+         if (has_feature(feat_ssbo_barrier))
+            gl_barrier |= GL_SHADER_STORAGE_BARRIER_BIT;
+      }
+   }
+   glMemoryBarrier(gl_barrier);
+}
+
 static void vrend_destroy_shader_object(void *obj_ptr)
 {
    struct vrend_shader_selector *state = obj_ptr;
@@ -8028,6 +8070,9 @@ void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
    if (has_feature(feat_txqs))
       caps->v2.capability_bits |= VIRGL_CAP_TXQS;
 
+   if (has_feature(feat_barrier))
+      caps->v2.capability_bits |= VIRGL_CAP_MEMORY_BARRIER;
+
    if (has_feature(feat_copy_image))
       caps->v2.capability_bits |= VIRGL_CAP_COPY_IMAGE;
 }
diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h
index 9e0bcdf..fe05fcc 100644
--- a/src/vrend_renderer.h
+++ b/src/vrend_renderer.h
@@ -240,7 +240,8 @@ void vrend_set_single_ssbo(struct vrend_context *ctx,
                            int index,
                            uint32_t offset, uint32_t length,
                            uint32_t handle);
-
+void vrend_memory_barrier(struct vrend_context *ctx,
+                          unsigned flags);
 #define VREND_TRANSFER_WRITE 1
 #define VREND_TRANSFER_READ 2
 int vrend_renderer_transfer_iov(const struct vrend_transfer_info *info, int transfer_mode);
-- 
2.14.3



More information about the virglrenderer-devel mailing list