Use glCopyImageSubData() when it's available.
There's 4 different extensions providing this functionality. NV is supported on desktop and mobile, EXT/OES on mobile, and ARB on desktop. Mostly these are only supported by desktop cards and NVIDIA mobile. Good improvement in performance on NVIDIA when blit is called a lot, since it doesn't need to rebind anything or change state. Example is in desert city in Tales of Phantasia.
This commit is contained in:
parent
a2e09eada7
commit
fbc4b4e7a1
8 changed files with 59 additions and 13 deletions
|
@ -1330,7 +1330,6 @@ void FramebufferManager::ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool s
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: If dimensions are the same, we can use glCopyImageSubData.
|
||||
void FramebufferManager::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) {
|
||||
if (!dst->fbo || !src->fbo || !useBufferedRendering_) {
|
||||
// This can happen if they recently switched from non-buffered.
|
||||
|
@ -1338,9 +1337,6 @@ void FramebufferManager::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int
|
|||
return;
|
||||
}
|
||||
|
||||
fbo_bind_as_render_target(dst->fbo);
|
||||
glstate.scissorTest.force(false);
|
||||
|
||||
bool useBlit = gstate_c.Supports(GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT | GPU_SUPPORTS_NV_FRAMEBUFFER_BLIT);
|
||||
bool useNV = useBlit && !gstate_c.Supports(GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT);
|
||||
|
||||
|
@ -1366,6 +1362,39 @@ void FramebufferManager::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int
|
|||
int dstY1 = dstY * dstYFactor;
|
||||
int dstY2 = (dstY + h) * dstYFactor;
|
||||
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_ANY_COPY_IMAGE)) {
|
||||
// Only if it's the same size.
|
||||
if (dstX2 - dstX1 == srcX2 - srcX1 && dstY2 - dstY1 == srcY2 - srcY1) {
|
||||
#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);
|
||||
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_for_read(src->fbo);
|
||||
if (!useNV) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue