From 8289e3f1d89718a814de7e64ec42076dc9d237b5 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 18 Jul 2018 13:11:39 +1000 Subject: [PATCH] renderer: add memory barrier support. (v2) 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 --- 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);