Hide glCopyImageSubData behind the FBO interface

This commit is contained in:
Henrik Rydgard 2017-02-04 14:51:21 +01:00 committed by Henrik Rydgård
parent c1f9f96621
commit d14a388441
3 changed files with 32 additions and 44 deletions

View file

@ -40,8 +40,6 @@ struct FBO {
bool native_fbo;
};
static FBO *g_overriddenBackbuffer;
static GLuint currentDrawHandle_ = 0;
static GLuint currentReadHandle_ = 0;
@ -323,7 +321,6 @@ static GLenum fbo_get_fb_target(bool read, GLuint **cached) {
static void fbo_bind_fb_target(bool read, GLuint name) {
GLuint *cached;
GLenum target = fbo_get_fb_target(read, &cached);
if (*cached != name) {
if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) {
glBindFramebuffer(target, name);
@ -337,12 +334,6 @@ static void fbo_bind_fb_target(bool read, GLuint name) {
}
void fbo_unbind() {
if (g_overriddenBackbuffer) {
fbo_bind_as_render_target(g_overriddenBackbuffer);
return;
}
CheckGLExtensions();
#ifndef USING_GLES2
if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
@ -361,10 +352,6 @@ void fbo_unbind() {
currentReadHandle_ = 0;
}
void fbo_override_backbuffer(FBO *fbo) {
g_overriddenBackbuffer = fbo;
}
void fbo_bind_as_render_target(FBO *fbo) {
// Without FBO_ARB / GLES3, this will collide with bind_for_read, but there's nothing
// in ES 2.0 that actually separate them anyway of course, so doesn't matter.
@ -386,6 +373,33 @@ void fbo_unbind_read() {
fbo_bind_fb_target(true, 0);
}
void fbo_copy_image(FBO *src, int srcLevel, int srcX, int srcY, int srcZ, FBO *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) {
#if defined(USING_GLES2)
#ifndef IOS
glCopyImageSubDataOES(
fbo_get_color_texture(src), GL_TEXTURE_2D, srcLevel, srcX, srcY, srcZ,
fbo_get_color_texture(dst), GL_TEXTURE_2D, dstLevel, dstX, dstY, dstZ,
width, height, depth);
return;
#endif
#else
if (gl_extensions.ARB_copy_image) {
glCopyImageSubData(
fbo_get_color_texture(src), GL_TEXTURE_2D, srcLevel, srcX, srcY, srcZ,
fbo_get_color_texture(dst), GL_TEXTURE_2D, dstLevel, dstX, dstY, dstZ,
width, height, depth);
return;
} else if (gl_extensions.NV_copy_image) {
// Older, pre GL 4.x NVIDIA cards.
glCopyImageSubDataNV(
fbo_get_color_texture(src), GL_TEXTURE_2D, srcLevel, srcX, srcY, srcZ,
fbo_get_color_texture(dst), GL_TEXTURE_2D, dstLevel, dstX, dstY, dstZ,
width, height, depth);
return;
}
#endif
}
void fbo_bind_color_as_texture(FBO *fbo, int color) {
if (fbo) {
glBindTexture(GL_TEXTURE_2D, fbo->color_texture);

View file

@ -43,11 +43,9 @@ enum FBOColorDepth {
// On some hardware, you might get a 24-bit depth buffer even though you only wanted a 16-bit one.
FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, FBOColorDepth colorDepth = FBO_8888);
int fbo_standard_z_depth();
void fbo_copy_image(FBO *src, int level, int x, int y, int z, FBO *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth);
// Create an opaque FBO from a native GL FBO, optionally reusing an existing FBO structure.
// Useful for overriding the backbuffer FBO that is generated outside of this wrapper.
FBO *fbo_create_from_native_fbo(GLuint native_fbo, FBO *fbo = NULL);
int fbo_standard_z_depth();
int fbo_check_framebuffer_status(FBO *fbo);
// These functions should be self explanatory.
@ -64,5 +62,3 @@ void fbo_get_dimensions(FBO *fbo, int *w, int *h);
int fbo_get_color_texture(FBO *fbo);
int fbo_get_depth_buffer(FBO *fbo);
int fbo_get_stencil_buffer(FBO *fbo);
void fbo_override_backbuffer(FBO *fbo); // Makes unbind bind this instead of the real backbuffer.

View file

@ -1296,37 +1296,14 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX,
const bool xOverlap = src == dst && srcX2 > dstX1 && srcX1 < dstX2;
const bool yOverlap = src == dst && srcY2 > dstY1 && srcY1 < dstY2;
if (sameSize && sameDepth && srcInsideBounds && dstInsideBounds && !(xOverlap && yOverlap)) {
#if defined(USING_GLES2)
#ifndef IOS
glCopyImageSubDataOES(
fbo_get_color_texture(src->fbo), GL_TEXTURE_2D, 0, srcX1, srcY1, 0,
fbo_get_color_texture(dst->fbo), GL_TEXTURE_2D, 0, dstX1, dstY1, 0,
dstX2 - dstX1, dstY2 - dstY1, 1);
fbo_copy_image(src->fbo, 0, srcX1, srcY1, 0, dst->fbo, 0, dstX1, dstY1, 0, dstX2 - dstX1, dstY2 - dstY1, 1);
return;
#endif
#else
if (gl_extensions.ARB_copy_image) {
glCopyImageSubData(
fbo_get_color_texture(src->fbo), GL_TEXTURE_2D, 0, srcX1, srcY1, 0,
fbo_get_color_texture(dst->fbo), GL_TEXTURE_2D, 0, dstX1, dstY1, 0,
dstX2 - dstX1, dstY2 - dstY1, 1);
return;
} else if (gl_extensions.NV_copy_image) {
// Older, pre GL 4.x NVIDIA cards.
glCopyImageSubDataNV(
fbo_get_color_texture(src->fbo), GL_TEXTURE_2D, 0, srcX1, srcY1, 0,
fbo_get_color_texture(dst->fbo), GL_TEXTURE_2D, 0, dstX1, dstY1, 0,
dstX2 - dstX1, dstY2 - dstY1, 1);
return;
}
#endif
}
}
fbo_bind_as_render_target(dst->fbo);
glstate.scissorTest.force(false);
if (useBlit) {
fbo_bind_as_render_target(dst->fbo);
fbo_bind_for_read(src->fbo);
if (!useNV) {
glBlitFramebuffer(srcX1, srcY1, srcX2, srcY2, dstX1, dstY1, dstX2, dstY2, GL_COLOR_BUFFER_BIT, GL_NEAREST);
@ -1338,6 +1315,7 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX,
fbo_unbind_read();
} else {
fbo_bind_as_render_target(dst->fbo);
fbo_bind_color_as_texture(src->fbo, 0);
// Make sure our 2D drawing program is ready. Compiles only if not already compiled.