From 64d35b6a85c160ab27660d82bddf4d665985068d Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Mon, 1 Mar 2021 17:00:40 +0900 Subject: [PATCH] vrend: Do not cache frame buffer object in vrend resource vrend resource could cache a frame buffer object to read a texture back. However, vrend resource is independent of OpenGL context while a frame buffer object is not because it is a container object. On QEMU, a frame buffer object is typically cached on each renderer context while its destruction operation is performed on "0 context", resulting in destroying another frame buffer object whose name is identical but is created in "0 context". This change simply removes the caching mechanism and eliminates the need of a context switch when destroying a cached frame buffer object and some handling of cache misses. Signed-off-by: Akihiko Odaki Reviewed-by: Gert Wollny --- src/vrend_renderer.c | 60 +++++++++++--------------------------------- src/vrend_renderer.h | 5 ---- 2 files changed, 14 insertions(+), 51 deletions(-) diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index 4ff1435..0a7c6c1 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -7090,9 +7090,6 @@ vrend_renderer_resource_create(const struct vrend_renderer_resource_create_args void vrend_renderer_resource_destroy(struct vrend_resource *res) { - if (res->readback_fb_id) - glDeleteFramebuffers(1, &res->readback_fb_id); - if (has_bit(res->storage_bits, VREND_STORAGE_GL_TEXTURE)) { glDeleteTextures(1, &res->id); } else if (has_bit(res->storage_bits, VREND_STORAGE_GL_BUFFER)) { @@ -7526,21 +7523,11 @@ static int vrend_renderer_transfer_write_iov(struct vrend_context *ctx, if ((!vrend_state.use_core_profile) && (res->y_0_top)) { GLuint buffers; + GLuint fb_id; - if (res->readback_fb_id == 0 || (int)res->readback_fb_level != info->level) { - GLuint fb_id; - if (res->readback_fb_id) - glDeleteFramebuffers(1, &res->readback_fb_id); - - glGenFramebuffers(1, &fb_id); - glBindFramebuffer(GL_FRAMEBUFFER, fb_id); - vrend_fb_bind_texture(res, 0, info->level, 0); - - res->readback_fb_id = fb_id; - res->readback_fb_level = info->level; - } else { - glBindFramebuffer(GL_FRAMEBUFFER, res->readback_fb_id); - } + glGenFramebuffers(1, &fb_id); + glBindFramebuffer(GL_FRAMEBUFFER, fb_id); + vrend_fb_bind_texture(res, 0, info->level, 0); buffers = GL_COLOR_ATTACHMENT0; glDrawBuffers(1, &buffers); @@ -7558,6 +7545,7 @@ static int vrend_renderer_transfer_write_iov(struct vrend_context *ctx, glWindowPos2i(info->box->x, res->y_0_top ? (int)res->base.height0 - info->box->y : info->box->y); glDrawPixels(info->box->width, info->box->height, glformat, gltype, data); + glDeleteFramebuffers(1, &fb_id); } else { uint32_t comp_size; GLint old_tex = 0; @@ -7838,22 +7826,11 @@ static int vrend_transfer_send_readpixels(struct vrend_context *ctx, glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &old_fbo); - if (res->readback_fb_id == 0 || (int)res->readback_fb_level != info->level || - (int)res->readback_fb_z != info->box->z) { - - if (res->readback_fb_id) - glDeleteFramebuffers(1, &res->readback_fb_id); - - glGenFramebuffers(1, &fb_id); - glBindFramebuffer(GL_FRAMEBUFFER, fb_id); + glGenFramebuffers(1, &fb_id); + glBindFramebuffer(GL_FRAMEBUFFER, fb_id); - vrend_fb_bind_texture(res, 0, info->level, info->box->z); + vrend_fb_bind_texture(res, 0, info->level, info->box->z); - res->readback_fb_id = fb_id; - res->readback_fb_level = info->level; - res->readback_fb_z = info->box->z; - } else - glBindFramebuffer(GL_FRAMEBUFFER, res->readback_fb_id); if (actually_invert) y1 = h - info->box->y - info->box->height; else @@ -7945,6 +7922,7 @@ static int vrend_transfer_send_readpixels(struct vrend_context *ctx, free(data); } + glDeleteFramebuffers(1, &fb_id); glBindFramebuffer(GL_FRAMEBUFFER, old_fbo); return 0; @@ -10436,24 +10414,14 @@ void *vrend_renderer_get_cursor_contents(struct pipe_resource *pres, } else if (vrend_state.use_gles) { GLuint fb_id; - if (res->readback_fb_id == 0 || res->readback_fb_level != 0 || res->readback_fb_z != 0) { - - if (res->readback_fb_id) - glDeleteFramebuffers(1, &res->readback_fb_id); - - glGenFramebuffers(1, &fb_id); - glBindFramebuffer(GL_FRAMEBUFFER, fb_id); - - vrend_fb_bind_texture(res, 0, 0, 0); + glGenFramebuffers(1, &fb_id); + glBindFramebuffer(GL_FRAMEBUFFER, fb_id); - res->readback_fb_id = fb_id; - res->readback_fb_level = 0; - res->readback_fb_z = 0; - } else { - glBindFramebuffer(GL_FRAMEBUFFER, res->readback_fb_id); - } + vrend_fb_bind_texture(res, 0, 0, 0); do_readpixels(0, 0, *width, *height, format, type, size, data); + + glDeleteFramebuffers(1, &fb_id); } else { glBindTexture(res->target, res->id); glGetTexImage(res->target, 0, format, type, data); diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h index b9c070a..5c2151d 100644 --- a/src/vrend_renderer.h +++ b/src/vrend_renderer.h @@ -71,11 +71,6 @@ struct vrend_resource { GLuint id; GLenum target; - /* fb id if we need to readback this resource */ - GLuint readback_fb_id; - GLuint readback_fb_level; - GLuint readback_fb_z; - GLuint tbo_tex_id;/* tbos have two ids to track */ bool y_0_top;