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 <akihiko.odaki@gmail.com>
Reviewed-by: Gert Wollny <gert.wollny@collabora.com>
macos/master
Akihiko Odaki 4 years ago committed by Gert Wollny
parent f390c4d673
commit 64d35b6a85
  1. 60
      src/vrend_renderer.c
  2. 5
      src/vrend_renderer.h

@ -7090,9 +7090,6 @@ vrend_renderer_resource_create(const struct vrend_renderer_resource_create_args
void vrend_renderer_resource_destroy(struct vrend_resource *res) 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)) { if (has_bit(res->storage_bits, VREND_STORAGE_GL_TEXTURE)) {
glDeleteTextures(1, &res->id); glDeleteTextures(1, &res->id);
} else if (has_bit(res->storage_bits, VREND_STORAGE_GL_BUFFER)) { } 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)) { if ((!vrend_state.use_core_profile) && (res->y_0_top)) {
GLuint buffers; GLuint buffers;
GLuint fb_id;
if (res->readback_fb_id == 0 || (int)res->readback_fb_level != info->level) { glGenFramebuffers(1, &fb_id);
GLuint fb_id; glBindFramebuffer(GL_FRAMEBUFFER, fb_id);
if (res->readback_fb_id) vrend_fb_bind_texture(res, 0, info->level, 0);
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);
}
buffers = GL_COLOR_ATTACHMENT0; buffers = GL_COLOR_ATTACHMENT0;
glDrawBuffers(1, &buffers); 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); 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, glDrawPixels(info->box->width, info->box->height, glformat, gltype,
data); data);
glDeleteFramebuffers(1, &fb_id);
} else { } else {
uint32_t comp_size; uint32_t comp_size;
GLint old_tex = 0; 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); glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &old_fbo);
if (res->readback_fb_id == 0 || (int)res->readback_fb_level != info->level || glGenFramebuffers(1, &fb_id);
(int)res->readback_fb_z != info->box->z) { glBindFramebuffer(GL_FRAMEBUFFER, 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, 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) if (actually_invert)
y1 = h - info->box->y - info->box->height; y1 = h - info->box->y - info->box->height;
else else
@ -7945,6 +7922,7 @@ static int vrend_transfer_send_readpixels(struct vrend_context *ctx,
free(data); free(data);
} }
glDeleteFramebuffers(1, &fb_id);
glBindFramebuffer(GL_FRAMEBUFFER, old_fbo); glBindFramebuffer(GL_FRAMEBUFFER, old_fbo);
return 0; return 0;
@ -10436,24 +10414,14 @@ void *vrend_renderer_get_cursor_contents(struct pipe_resource *pres,
} else if (vrend_state.use_gles) { } else if (vrend_state.use_gles) {
GLuint fb_id; GLuint fb_id;
if (res->readback_fb_id == 0 || res->readback_fb_level != 0 || res->readback_fb_z != 0) { glGenFramebuffers(1, &fb_id);
glBindFramebuffer(GL_FRAMEBUFFER, 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, 0, 0);
res->readback_fb_id = fb_id; vrend_fb_bind_texture(res, 0, 0, 0);
res->readback_fb_level = 0;
res->readback_fb_z = 0;
} else {
glBindFramebuffer(GL_FRAMEBUFFER, res->readback_fb_id);
}
do_readpixels(0, 0, *width, *height, format, type, size, data); do_readpixels(0, 0, *width, *height, format, type, size, data);
glDeleteFramebuffers(1, &fb_id);
} else { } else {
glBindTexture(res->target, res->id); glBindTexture(res->target, res->id);
glGetTexImage(res->target, 0, format, type, data); glGetTexImage(res->target, 0, format, type, data);

@ -71,11 +71,6 @@ struct vrend_resource {
GLuint id; GLuint id;
GLenum target; 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 */ GLuint tbo_tex_id;/* tbos have two ids to track */
bool y_0_top; bool y_0_top;

Loading…
Cancel
Save