From c0ba3c28bb502fd1c014a533e782fee03fec9409 Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Wed, 17 Aug 2022 10:41:53 +0200 Subject: [PATCH 1/4] vrend: replace local sysvalue block by sub_ctx member Signed-off-by: Gert Wollny --- src/vrend_renderer.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index 285be7ac1..be030d62b 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -739,6 +739,7 @@ struct vrend_sub_context { bool drawing; struct vrend_context *parent; GLuint stipple_pattern[VREND_POLYGON_STIPPLE_SIZE]; + struct sysval_uniform_block sysvalue_data; }; struct vrend_untyped_resource { @@ -4969,34 +4970,34 @@ vrend_fill_sysval_uniform_block (struct vrend_sub_context *sub_ctx) if (sub_ctx->prog->virgl_block_bind == -1) return; - struct sysval_uniform_block virgl_uniform_block; - memset(&virgl_uniform_block, 0, sizeof(struct sysval_uniform_block)); + struct sysval_uniform_block *virgl_uniform_block = &sub_ctx->sysvalue_data; + memset(virgl_uniform_block, 0, sizeof(struct sysval_uniform_block)); if (vrend_state.use_core_profile) { - virgl_uniform_block.alpha_ref_val = sub_ctx->dsa_state.alpha.ref_value; + virgl_uniform_block->alpha_ref_val = sub_ctx->dsa_state.alpha.ref_value; /* std140 aligns array elements at 16 byte */ for (int i = 0; i < VREND_POLYGON_STIPPLE_SIZE ; ++i) - virgl_uniform_block.stipple_pattern[i][0] = sub_ctx->stipple_pattern[i]; + virgl_uniform_block->stipple_pattern[i][0] = sub_ctx->stipple_pattern[i]; } - virgl_uniform_block.winsys_adjust_y = sub_ctx->viewport_is_negative ? -1.f : 1.f; + virgl_uniform_block->winsys_adjust_y = sub_ctx->viewport_is_negative ? -1.f : 1.f; if (has_feature(feat_cull_distance)) { if (sub_ctx->rs_state.clip_plane_enable) { - virgl_uniform_block.clip_plane_enabled = 1.f; + virgl_uniform_block->clip_plane_enabled = 1.f; for (int i = 0 ; i < VIRGL_NUM_CLIP_PLANES; i++) { - memcpy(&virgl_uniform_block.clipp[i], + memcpy(&virgl_uniform_block->clipp[i], (const GLfloat *) &sub_ctx->ucp_state.ucp[i], sizeof(GLfloat) * 4); } } else { - virgl_uniform_block.clip_plane_enabled = 0.f; + virgl_uniform_block->clip_plane_enabled = 0.f; } } glBindBuffer(GL_UNIFORM_BUFFER, sub_ctx->prog->ubo_sysval_buffer_id); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(struct sysval_uniform_block), - &virgl_uniform_block); + virgl_uniform_block); glBindBuffer(GL_UNIFORM_BUFFER, 0); } -- GitLab From fed9848032162fcc29bc912d5e91c93f92474006 Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Wed, 17 Aug 2022 10:51:46 +0200 Subject: [PATCH 2/4] vrend: assign sysvalue in UBO staging area when state changes With that we can avoid additional copying that was otherwise done with each draw call. Signed-off-by: Gert Wollny --- src/vrend_renderer.c | 57 ++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index be030d62b..9e02886ff 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -738,7 +738,6 @@ struct vrend_sub_context { int prim_mode; bool drawing; struct vrend_context *parent; - GLuint stipple_pattern[VREND_POLYGON_STIPPLE_SIZE]; struct sysval_uniform_block sysvalue_data; }; @@ -3122,8 +3121,11 @@ void vrend_set_viewport_states(struct vrend_context *ctx, } if (idx == 0) { - if (ctx->sub->viewport_is_negative != viewport_is_negative) + if (ctx->sub->viewport_is_negative != viewport_is_negative) { ctx->sub->viewport_is_negative = viewport_is_negative; + ctx->sub->sysvalue_data.winsys_adjust_y = + viewport_is_negative ? -1.f : 1.f; + } } } } @@ -4968,36 +4970,11 @@ static void vrend_fill_sysval_uniform_block (struct vrend_sub_context *sub_ctx) { if (sub_ctx->prog->virgl_block_bind == -1) - return; - - struct sysval_uniform_block *virgl_uniform_block = &sub_ctx->sysvalue_data; - memset(virgl_uniform_block, 0, sizeof(struct sysval_uniform_block)); - - if (vrend_state.use_core_profile) { - virgl_uniform_block->alpha_ref_val = sub_ctx->dsa_state.alpha.ref_value; - - /* std140 aligns array elements at 16 byte */ - for (int i = 0; i < VREND_POLYGON_STIPPLE_SIZE ; ++i) - virgl_uniform_block->stipple_pattern[i][0] = sub_ctx->stipple_pattern[i]; - } - - virgl_uniform_block->winsys_adjust_y = sub_ctx->viewport_is_negative ? -1.f : 1.f; - - if (has_feature(feat_cull_distance)) { - if (sub_ctx->rs_state.clip_plane_enable) { - virgl_uniform_block->clip_plane_enabled = 1.f; - for (int i = 0 ; i < VIRGL_NUM_CLIP_PLANES; i++) { - memcpy(&virgl_uniform_block->clipp[i], - (const GLfloat *) &sub_ctx->ucp_state.ucp[i], sizeof(GLfloat) * 4); - } - } else { - virgl_uniform_block->clip_plane_enabled = 0.f; - } - } + return; glBindBuffer(GL_UNIFORM_BUFFER, sub_ctx->prog->ubo_sysval_buffer_id); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(struct sysval_uniform_block), - virgl_uniform_block); + &sub_ctx->sysvalue_data); glBindBuffer(GL_UNIFORM_BUFFER, 0); } @@ -6042,6 +6019,8 @@ void vrend_object_bind_dsa(struct vrend_context *ctx, } ctx->sub->dsa_state = *state; ctx->sub->dsa = state; + ctx->sub->sysvalue_data.alpha_ref_val = state->alpha.ref_value; + vrend_hw_emit_dsa(ctx); } @@ -6291,6 +6270,13 @@ static void vrend_hw_emit_rs(struct vrend_context *ctx) else glDisable(GL_CLIP_PLANE0 + i); } + + if (ctx->sub->rs_state.clip_plane_enable) { + ctx->sub->sysvalue_data.clip_plane_enabled = 1.f; + } else { + ctx->sub->sysvalue_data.clip_plane_enabled = 0.f; + } + } if (vrend_state.use_core_profile == false) { glLineStipple(state->line_stipple_factor, state->line_stipple_pattern); @@ -9233,8 +9219,11 @@ void vrend_set_polygon_stipple(struct vrend_context *ctx, struct pipe_poly_stipple *ps) { if (vrend_state.use_core_profile) { - memcpy(ctx->sub->stipple_pattern, ps->stipple, - VREND_POLYGON_STIPPLE_SIZE * sizeof(GLuint)); + + /* std140 aligns array elements at 16 byte */ + for (int i = 0; i < VREND_POLYGON_STIPPLE_SIZE ; ++i) + ctx->sub->sysvalue_data.stipple_pattern[i][0] = ps->stipple[i]; + } else { glPolygonStipple((const GLubyte *)ps->stipple); } @@ -9244,6 +9233,10 @@ void vrend_set_clip_state(struct vrend_context *ctx, struct pipe_clip_state *ucp { if (vrend_state.use_core_profile) { ctx->sub->ucp_state = *ucp; + for (int i = 0 ; i < VIRGL_NUM_CLIP_PLANES; i++) { + memcpy(&ctx->sub->sysvalue_data.clipp[i], + (const GLfloat *) &ctx->sub->ucp_state.ucp[i], sizeof(GLfloat) * 4); + } } else { int i, j; GLdouble val[4]; @@ -11922,6 +11915,8 @@ void vrend_renderer_create_sub_ctx(struct vrend_context *ctx, int sub_ctx_id) sub->object_hash = vrend_object_init_ctx_table(); + sub->sysvalue_data.winsys_adjust_y = 1.f; + ctx->sub = sub; list_add(&sub->head, &ctx->sub_ctxs); if (sub_ctx_id == 0) -- GitLab From 6a5d2392545d87cfb08819331c511fbc5fe560fd Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Wed, 17 Aug 2022 11:52:56 +0200 Subject: [PATCH 3/4] vrend: Upload sysvalue data only if it has been changed since last use Keep a cookie with the shader program to be able to check against the sysvalue data cookie whether it has been touched, and upload the data only then. Signed-off-by: Gert Wollny --- src/vrend_renderer.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index 9e02886ff..6bb1e3458 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -433,6 +433,7 @@ struct vrend_linked_shader_program { GLuint separate_virgl_block_id[PIPE_SHADER_TYPES]; GLint virgl_block_bind; + uint32_t sysvalue_data_cookie; GLint ubo_sysval_buffer_id; uint32_t images_used_mask[PIPE_SHADER_TYPES]; @@ -739,6 +740,7 @@ struct vrend_sub_context { bool drawing; struct vrend_context *parent; struct sysval_uniform_block sysvalue_data; + uint32_t sysvalue_data_cookie; }; struct vrend_untyped_resource { @@ -3125,6 +3127,7 @@ void vrend_set_viewport_states(struct vrend_context *ctx, ctx->sub->viewport_is_negative = viewport_is_negative; ctx->sub->sysvalue_data.winsys_adjust_y = viewport_is_negative ? -1.f : 1.f; + ctx->sub->sysvalue_data_cookie++; } } } @@ -4972,10 +4975,13 @@ vrend_fill_sysval_uniform_block (struct vrend_sub_context *sub_ctx) if (sub_ctx->prog->virgl_block_bind == -1) return; - glBindBuffer(GL_UNIFORM_BUFFER, sub_ctx->prog->ubo_sysval_buffer_id); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(struct sysval_uniform_block), - &sub_ctx->sysvalue_data); - glBindBuffer(GL_UNIFORM_BUFFER, 0); + if (sub_ctx->sysvalue_data_cookie != sub_ctx->prog->sysvalue_data_cookie) { + glBindBuffer(GL_UNIFORM_BUFFER, sub_ctx->prog->ubo_sysval_buffer_id); + glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(struct sysval_uniform_block), + &sub_ctx->sysvalue_data); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + sub_ctx->prog->sysvalue_data_cookie = sub_ctx->sysvalue_data_cookie; + } } static void vrend_draw_bind_objects(struct vrend_sub_context *sub_ctx, bool new_program) @@ -6019,8 +6025,11 @@ void vrend_object_bind_dsa(struct vrend_context *ctx, } ctx->sub->dsa_state = *state; ctx->sub->dsa = state; - ctx->sub->sysvalue_data.alpha_ref_val = state->alpha.ref_value; + if (ctx->sub->sysvalue_data.alpha_ref_val != state->alpha.ref_value) { + ctx->sub->sysvalue_data.alpha_ref_val = state->alpha.ref_value; + ctx->sub->sysvalue_data_cookie++; + } vrend_hw_emit_dsa(ctx); } @@ -6271,12 +6280,12 @@ static void vrend_hw_emit_rs(struct vrend_context *ctx) glDisable(GL_CLIP_PLANE0 + i); } + ctx->sub->sysvalue_data_cookie++; if (ctx->sub->rs_state.clip_plane_enable) { ctx->sub->sysvalue_data.clip_plane_enabled = 1.f; } else { ctx->sub->sysvalue_data.clip_plane_enabled = 0.f; } - } if (vrend_state.use_core_profile == false) { glLineStipple(state->line_stipple_factor, state->line_stipple_pattern); @@ -9223,7 +9232,7 @@ void vrend_set_polygon_stipple(struct vrend_context *ctx, /* std140 aligns array elements at 16 byte */ for (int i = 0; i < VREND_POLYGON_STIPPLE_SIZE ; ++i) ctx->sub->sysvalue_data.stipple_pattern[i][0] = ps->stipple[i]; - + ctx->sub->sysvalue_data_cookie++; } else { glPolygonStipple((const GLubyte *)ps->stipple); } @@ -9233,6 +9242,8 @@ void vrend_set_clip_state(struct vrend_context *ctx, struct pipe_clip_state *ucp { if (vrend_state.use_core_profile) { ctx->sub->ucp_state = *ucp; + + ctx->sub->sysvalue_data_cookie++; for (int i = 0 ; i < VIRGL_NUM_CLIP_PLANES; i++) { memcpy(&ctx->sub->sysvalue_data.clipp[i], (const GLfloat *) &ctx->sub->ucp_state.ucp[i], sizeof(GLfloat) * 4); @@ -11916,6 +11927,7 @@ void vrend_renderer_create_sub_ctx(struct vrend_context *ctx, int sub_ctx_id) sub->object_hash = vrend_object_init_ctx_table(); sub->sysvalue_data.winsys_adjust_y = 1.f; + sub->sysvalue_data_cookie = 1; ctx->sub = sub; list_add(&sub->head, &ctx->sub_ctxs); -- GitLab From 425c0977ac8983eda1c8ebb8a954dee98dfae234 Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Wed, 17 Aug 2022 17:24:12 +0200 Subject: [PATCH 4/4] vrend: use direct state access for buffers access when available Signed-off-by: Gert Wollny --- src/vrend_renderer.c | 221 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 183 insertions(+), 38 deletions(-) diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index 6bb1e3458..cdeec2524 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -143,6 +143,7 @@ enum features_id feat_cull_distance, feat_debug_cb, feat_depth_clamp, + feat_direct_state_access, feat_draw_instance, feat_dual_src_blend, feat_egl_image_external, @@ -247,6 +248,7 @@ static const struct { FEAT(draw_instance, 31, 30, "GL_ARB_draw_instanced" ), FEAT(dual_src_blend, 33, UNAVAIL, "GL_ARB_blend_func_extended", "GL_EXT_blend_func_extended" ), FEAT(depth_clamp, 32, UNAVAIL, "GL_ARB_depth_clamp", "GL_EXT_depth_clamp", "GL_NV_depth_clamp"), + FEAT(direct_state_access, 45, UNAVAIL, "GL_ARB_direct_state_access"), FEAT(enhanced_layouts, 44, UNAVAIL, "GL_ARB_enhanced_layouts"), FEAT(egl_image_external, UNAVAIL, UNAVAIL, "GL_OES_EGL_image_external"), FEAT(egl_image_storage, UNAVAIL, UNAVAIL, "GL_EXT_EGL_image_storage"), @@ -313,6 +315,27 @@ static const struct { FEAT(anisotropic_filter, 46, UNAVAIL, "GL_EXT_texture_filter_anisotropic", "GL_ARB_texture_filter_anisotropic"), }; +typedef void (*buffers_generate_f)(GLsizei n, GLuint *buffers); +typedef void (*buffer_allocate_data_f)(GLuint, GLsizeiptr size, GLbitfield flags); +typedef void (*buffer_sub_data_f)(GLuint bufid, GLintptr offset, GLsizeiptr size, const void *data); +typedef void (*buffer_storage_mem_f)(GLuint, GLsizeiptr size, unsigned memory, uint64_t offset); + +typedef void * (*buffer_map_range_f)(GLuint bufid, GLintptr offset, + GLsizeiptr length, GLbitfield access); +typedef GLboolean (*buffer_unmap_f)(GLuint bufid); + +struct buffer_interface { + buffers_generate_f generate; + buffer_allocate_data_f allocate; + buffer_sub_data_f sub_data; + buffer_storage_mem_f storage_mem; + buffer_map_range_f map_range; + buffer_map_range_f bind_if_needed_and_map_range; + buffer_unmap_f unmap; + buffer_unmap_f unmap_and_unbind; +}; + + struct global_renderer_state { struct vrend_context *ctx0; struct vrend_context *current_ctx; @@ -323,6 +346,8 @@ struct global_renderer_state { struct list_head fence_wait_list; struct vrend_fence *fence_waiting; + + int gl_major_ver; int gl_minor_ver; @@ -379,6 +404,8 @@ struct sysval_uniform_block { }; static struct global_renderer_state vrend_state; +static struct buffer_interface gl_buf; + static inline bool has_feature(enum features_id feature_id) { @@ -1636,8 +1663,8 @@ static void bind_virgl_block_loc(struct vrend_linked_shader_program *sprog, if (sprog->virgl_block_bind == -1) { sprog->virgl_block_bind = virgl_block_ubo_id; if (sprog->ubo_sysval_buffer_id == -1) { - glGenBuffers(1, (GLuint *) &sprog->ubo_sysval_buffer_id); - created_virgl_block_buffer = true; + gl_buf.generate(1, (GLuint *) &sprog->ubo_sysval_buffer_id); + created_virgl_block_buffer = true; } } @@ -1653,11 +1680,9 @@ static void bind_virgl_block_loc(struct vrend_linked_shader_program *sprog, GL_UNIFORM_BLOCK_DATA_SIZE, &virgl_block_size); assert((size_t) virgl_block_size >= sizeof(struct sysval_uniform_block)); - if (created_virgl_block_buffer) { - glBindBuffer(GL_UNIFORM_BUFFER, sprog->ubo_sysval_buffer_id); - glBufferData(GL_UNIFORM_BUFFER, virgl_block_size, NULL, GL_DYNAMIC_DRAW); - glBindBuffer(GL_UNIFORM_BUFFER, 0); - } + if (created_virgl_block_buffer) + gl_buf.allocate(sprog->ubo_sysval_buffer_id, + sizeof(struct sysval_uniform_block), 0); } } @@ -4618,7 +4643,8 @@ static void vrend_draw_bind_vertex_legacy(struct vrend_context *ctx, if (vbo->base.stride == 0) { void *data; /* for 0 stride we are kinda screwed */ - data = glMapBufferRange(GL_ARRAY_BUFFER, vbo->base.buffer_offset, ve->nr_chan * sizeof(GLfloat), GL_MAP_READ_BIT); + data = gl_buf.bind_if_needed_and_map_range(res->id, vbo->base.buffer_offset, + ve->nr_chan * sizeof(GLfloat), GL_MAP_READ_BIT); switch (ve->nr_chan) { case 1: @@ -4634,7 +4660,7 @@ static void vrend_draw_bind_vertex_legacy(struct vrend_context *ctx, glVertexAttrib4fv(loc, data); break; } - glUnmapBuffer(GL_ARRAY_BUFFER); + gl_buf.unmap_and_unbind(res->id); disable_bitmask |= (1 << loc); } else { GLint size = !vrend_state.use_gles && (va->zyxw_bitmask & (1 << i)) ? GL_BGRA : ve->nr_chan; @@ -4976,10 +5002,9 @@ vrend_fill_sysval_uniform_block (struct vrend_sub_context *sub_ctx) return; if (sub_ctx->sysvalue_data_cookie != sub_ctx->prog->sysvalue_data_cookie) { - glBindBuffer(GL_UNIFORM_BUFFER, sub_ctx->prog->ubo_sysval_buffer_id); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(struct sysval_uniform_block), - &sub_ctx->sysvalue_data); - glBindBuffer(GL_UNIFORM_BUFFER, 0); + gl_buf.sub_data(sub_ctx->prog->ubo_sysval_buffer_id, 0, + sizeof(struct sysval_uniform_block), + &sub_ctx->sysvalue_data); sub_ctx->prog->sysvalue_data_cookie = sub_ctx->sysvalue_data_cookie; } } @@ -6944,6 +6969,131 @@ static bool use_integer() { return false; } +static void +buffer_data(GLuint bufid, GLsizeiptr size, GLbitfield flags) +{ + if (flags == 0) + flags = GL_DYNAMIC_DRAW; + + glBindBuffer(GL_COPY_WRITE_BUFFER, bufid); + glBufferData(GL_COPY_WRITE_BUFFER, size, NULL, flags); + glBindBuffer(GL_COPY_WRITE_BUFFER, 0); +} + +static void +buffer_sub_data(GLuint bufid, GLintptr offset, GLsizeiptr size, const void *data) +{ + glBindBuffer(GL_COPY_WRITE_BUFFER, bufid); + glBufferSubData(GL_COPY_WRITE_BUFFER, offset, size, data); + glBindBuffer(GL_COPY_WRITE_BUFFER, 0); +} + +static void +buffer_storage(GLuint bufid, GLsizeiptr size, GLbitfield flags) +{ + if (flags == 0) + flags = GL_DYNAMIC_DRAW; + + glBindBuffer(GL_COPY_WRITE_BUFFER, bufid); + glBufferStorage(GL_COPY_WRITE_BUFFER, size, NULL, flags); + glBindBuffer(GL_COPY_WRITE_BUFFER, 0); +} + +static void +buffer_named_allocate(GLuint bufid, GLsizeiptr size, GLbitfield flags) +{ + if (flags == 0) + flags = GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT | GL_MAP_READ_BIT; + + glNamedBufferStorage(bufid, size, NULL, flags); +} + +static void +buffer_storage_mem_buffer_storage(GLuint bufid, GLsizeiptr size, + GLuint memory, GLuint64 offset) +{ + glBindBuffer(GL_COPY_WRITE_BUFFER, bufid); + glBufferStorageMemEXT(GL_COPY_WRITE_BUFFER, size, memory, offset); + glBindBuffer(GL_COPY_WRITE_BUFFER, 0); +} + +static void * +buffer_map_range(GLuint bufid, GLintptr offset, + GLsizeiptr length, GLbitfield access) +{ + glBindBuffer(GL_COPY_WRITE_BUFFER, bufid); + void *retval = glMapBufferRange(GL_COPY_WRITE_BUFFER, offset, length, access); + glBindBuffer(GL_COPY_WRITE_BUFFER, 0); + return retval; +} + +static void * +buffer_bind_if_needed_and_map_range(GLuint bufid, GLintptr offset, + GLsizeiptr length, GLbitfield access) +{ + glBindBuffer(GL_COPY_WRITE_BUFFER, bufid); + return glMapBufferRange(GL_COPY_WRITE_BUFFER, offset, length, access); +} + +static GLboolean +buffer_unmap(GLuint bufid) +{ + glBindBuffer(GL_COPY_WRITE_BUFFER, bufid); + GLboolean ret = glUnmapBuffer(GL_COPY_WRITE_BUFFER); + glBindBuffer(GL_COPY_WRITE_BUFFER, 0); + return ret; +} + +static GLboolean +buffer_unmap_bound(GLuint bufid) +{ + (void)bufid; + GLboolean ret = glUnmapBuffer(GL_COPY_WRITE_BUFFER); + glBindBuffer(GL_COPY_WRITE_BUFFER, 0); + return ret; +} + +static void +buffer_storage_mem_not_supported(GLuint bufid, GLsizeiptr size, + GLuint memory, GLuint64 offset) +{ + (void)bufid; + (void)size; + (void)memory; + (void)offset; + vrend_report_context_error(vrend_state.current_ctx, VIRGL_ERROR_CTX_UNSUPPORTED_FUNCTION, bufid); +} + +static void +initialize_buffer_interface(void) +{ + memset(&gl_buf, 0, sizeof(gl_buf)); + gl_buf.generate = glGenBuffers; + gl_buf.sub_data = buffer_sub_data; + gl_buf.allocate = buffer_data; + gl_buf.storage_mem = buffer_storage_mem_not_supported; + gl_buf.map_range = buffer_map_range; + gl_buf.bind_if_needed_and_map_range = buffer_bind_if_needed_and_map_range; + gl_buf.unmap = buffer_unmap; + gl_buf.unmap_and_unbind = buffer_unmap_bound; + + if (has_feature(feat_direct_state_access)) { + gl_buf.generate = glCreateBuffers; + gl_buf.allocate = buffer_named_allocate; + gl_buf.sub_data = glNamedBufferSubData; + gl_buf.map_range = glMapNamedBufferRange; + gl_buf.bind_if_needed_and_map_range = glMapNamedBufferRange; + gl_buf.unmap = glUnmapNamedBuffer; + gl_buf.unmap_and_unbind = glUnmapNamedBuffer; + if (has_feature(feat_memory_object) || has_feature(feat_memory_object_fd)) + gl_buf.storage_mem = glNamedBufferStorageMemEXT; + } else if (has_feature(feat_arb_buffer_storage)) { + gl_buf.allocate = buffer_storage; + if (has_feature(feat_memory_object) || has_feature(feat_memory_object_fd)) + gl_buf.storage_mem = buffer_storage_mem_buffer_storage; + } +} + int vrend_renderer_init(const struct vrend_if_cbs *cbs, uint32_t flags) { bool gles; @@ -7001,6 +7151,8 @@ int vrend_renderer_init(const struct vrend_if_cbs *cbs, uint32_t flags) vrend_printf( "gl_version %d - compat profile\n", gl_ver); } + initialize_buffer_interface(); + vrend_state.use_integer = use_integer(); init_features(gles ? 0 : gl_ver, @@ -7065,6 +7217,7 @@ int vrend_renderer_init(const struct vrend_if_cbs *cbs, uint32_t flags) /* create 0 context */ vrend_state.ctx0 = vrend_create_context(0, strlen("HOST"), "HOST"); + vrend_state.eventfd = -1; if (flags & VREND_USE_THREAD_SYNC) { if (flags & VREND_USE_ASYNC_FENCE_CB) @@ -7543,12 +7696,12 @@ static void vrend_create_buffer(struct vrend_resource *gr, uint32_t width, uint3 buffer_storage_flags |= GL_MAP_COHERENT_BIT; gr->storage_bits |= VREND_STORAGE_GL_BUFFER; - glGenBuffersARB(1, &gr->id); - glBindBufferARB(gr->target, gr->id); + gl_buf.generate(1, &gr->id); + if (buffer_storage_flags) { if (has_feature(feat_arb_buffer_storage) && !vrend_state.use_external_blob) { - glBufferStorage(gr->target, width, NULL, buffer_storage_flags); + gl_buf.allocate(gr->id, width, buffer_storage_flags); gr->map_info = vrend_state.inferred_gl_caching_type; } #ifdef ENABLE_MINIGBM_ALLOCATION @@ -7573,7 +7726,7 @@ static void vrend_create_buffer(struct vrend_resource *gr, uint32_t width, uint3 glCreateMemoryObjectsEXT(1, &memobj); glImportMemoryFdEXT(memobj, width, GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd); - glBufferStorageMemEXT(gr->target, width, memobj, 0); + gl_buf.storage_mem(gr->id, width, memobj, 0); gr->gbm_bo = bo; gr->memobj = memobj; gr->storage_bits |= VREND_STORAGE_GBM_BUFFER | VREND_STORAGE_GL_MEMOBJ; @@ -7593,9 +7746,7 @@ static void vrend_create_buffer(struct vrend_resource *gr, uint32_t width, uint3 gr->buffer_storage_flags = buffer_storage_flags; gr->size = width; } else - glBufferData(gr->target, width, NULL, GL_STREAM_DRAW); - - glBindBufferARB(gr->target, 0); + gl_buf.allocate(gr->id, width, 0); } static int @@ -8311,16 +8462,14 @@ static int vrend_renderer_transfer_write_iov(struct vrend_context *ctx, if (!info->synchronized) map_flags |= GL_MAP_UNSYNCHRONIZED_BIT; - glBindBufferARB(res->target, res->id); - data = glMapBufferRange(res->target, info->box->x, info->box->width, map_flags); + data = gl_buf.bind_if_needed_and_map_range(res->id, info->box->x, info->box->width, map_flags); if (data == NULL) { vrend_printf("map failed for element buffer\n"); vrend_read_from_iovec_cb(iov, num_iovs, info->offset, info->box->width, &iov_buffer_upload, &d); } else { vrend_read_from_iovec(iov, num_iovs, info->offset, data, info->box->width); - glUnmapBuffer(res->target); } - glBindBufferARB(res->target, 0); + gl_buf.unmap_and_unbind(res->id); } else { GLenum glformat; GLenum gltype; @@ -8878,14 +9027,14 @@ static int vrend_renderer_transfer_send_iov(struct vrend_context *ctx, uint32_t send_size = info->box->width * util_format_get_blocksize(res->base.format); void *data; - glBindBufferARB(res->target, res->id); - data = glMapBufferRange(res->target, info->box->x, info->box->width, GL_MAP_READ_BIT); + data = gl_buf.bind_if_needed_and_map_range(res->id, info->box->x, + info->box->width, GL_MAP_READ_BIT); + if (!data) - vrend_printf("unable to open buffer for reading %d\n", res->target); + vrend_printf("unable to open buffer for reading %d\n", res->id); else vrend_write_to_iovec(iov, num_iovs, info->offset, data, send_size); - glUnmapBuffer(res->target); - glBindBufferARB(res->target, 0); + gl_buf.unmap_and_unbind(res->id); } else { int ret = -1; bool can_readpixels = true; @@ -10696,11 +10845,11 @@ void vrend_get_query_result(struct vrend_context *ctx, uint32_t handle, } #define COPY_QUERY_RESULT_TO_BUFFER(resid, offset, pvalue, size, multiplier) \ - glBindBuffer(GL_QUERY_BUFFER, resid); \ value *= multiplier; \ - void* buf = glMapBufferRange(GL_QUERY_BUFFER, offset, size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT); \ + void* buf = gl_buf.bind_if_needed_and_map_range(resid, offset, size, \ + GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT); \ if (buf) memcpy(buf, &value, size); \ - glUnmapBuffer(GL_QUERY_BUFFER); + gl_buf.unmap_and_unbind(resid); static inline void *buffer_offset(intptr_t i) { @@ -12193,12 +12342,10 @@ int vrend_renderer_resource_map(struct pipe_resource *pres, void **map, uint64_t if (!has_bits(res->storage_bits, VREND_STORAGE_GL_BUFFER | VREND_STORAGE_GL_IMMUTABLE)) return -EINVAL; - glBindBufferARB(res->target, res->id); - *map = glMapBufferRange(res->target, 0, res->size, res->buffer_storage_flags); + *map = gl_buf.map_range(res->id, 0, res->size, res->buffer_storage_flags); if (!*map) return -EINVAL; - glBindBufferARB(res->target, 0); *out_size = res->size; return 0; } @@ -12209,9 +12356,7 @@ int vrend_renderer_resource_unmap(struct pipe_resource *pres) if (!has_bits(res->storage_bits, VREND_STORAGE_GL_BUFFER | VREND_STORAGE_GL_IMMUTABLE)) return -EINVAL; - glBindBufferARB(res->target, res->id); - glUnmapBuffer(res->target); - glBindBufferARB(res->target, 0); + gl_buf.unmap(res->id); return 0; } -- GitLab