[virglrenderer-devel] [PATCH 7/8] renderer: add memory barrier support. (v2)
Dave Airlie
airlied at gmail.com
Mon Jul 30 04:56:18 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
Reviewed-by: Gert Wollny <gert.wollny at collabora.com>
---
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 52f1d5a..69b9394 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 2c6d3c2..292565f 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 0352d05..b3ae095 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 242fc57..be631cb 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,
@@ -118,6 +119,7 @@ enum features_id
feat_sample_shading,
feat_samplers,
feat_ssbo,
+ feat_ssbo_barrier,
feat_stencil_texturing,
feat_tessellation,
feat_texture_array,
@@ -146,6 +148,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" } },
@@ -172,6 +175,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" } },
@@ -2538,6 +2542,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;
@@ -7989,6 +8031,9 @@ void vrend_renderer_fill_caps(uint32_t set, UNUSED 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