GS/GL: Expand fb copy fallbacks.

Add nv extension GLAD_GL_NV_copy_image copy fallback.

Re add fbo copy fallback when no copy extension is supported and expand it for both color and depth.
This commit is contained in:
lightningterror
2026-06-04 02:22:17 +02:00
parent 88029a1411
commit b3b1ff0f50
+34 -3
View File
@@ -87,6 +87,12 @@ namespace Emulate_DSA
glTexSubImage2D(GL_TEXTURE_2D, level, xoffset, yoffset, width, height, format, type, pixels);
}
static void GLAPIENTRY CopyTextureSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
{
BindTextureUnit(7, texture);
glCopyTexSubImage2D(GL_TEXTURE_2D, level, xoffset, yoffset, x, y, width, height);
}
static void GLAPIENTRY CompressedTextureSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
{
@@ -126,6 +132,7 @@ namespace Emulate_DSA
glCreateTextures = CreateTexture;
glTextureStorage2D = TextureStorage;
glTextureSubImage2D = TextureSubImage;
glCopyTextureSubImage2D = CopyTextureSubImage;
glCompressedTextureSubImage2D = CompressedTextureSubImage;
glGetTextureImage = GetTexureImage;
glTextureParameteri = TextureParameteri;
@@ -769,12 +776,12 @@ bool GSDeviceOGL::CheckFeatures()
return false;
}
if (!GLAD_GL_VERSION_4_3 && !GLAD_GL_ARB_copy_image && !GLAD_GL_EXT_copy_image)
if (!GLAD_GL_VERSION_4_3 && !GLAD_GL_ARB_copy_image && !GLAD_GL_EXT_copy_image && !GLAD_GL_NV_copy_image)
{
Host::ReportFormattedErrorAsync(
"GS", "GL_ARB_copy_image is not supported, this is required for the OpenGL renderer.");
return false;
"GS", "GL_ARB_copy_image is not supported, copies will be slower.");
}
if (!GLAD_GL_VERSION_4_5 && !GLAD_GL_ARB_clip_control)
{
Host::ReportFormattedErrorAsync(
@@ -1676,6 +1683,30 @@ void GSDeviceOGL::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r
glCopyImageSubDataEXT(sid, GL_TEXTURE_2D, 0, r.x, r.y, 0, did, GL_TEXTURE_2D,
0, destX, destY, 0, r.width(), r.height(), 1);
}
else if (GLAD_GL_NV_copy_image)
{
glCopyImageSubDataNV(sid, GL_TEXTURE_2D, 0, r.x, r.y, 0, did, GL_TEXTURE_2D,
0, destX, destY, 0, r.width(), r.height(), 1);
}
else
{
const bool draw_in_depth = sTex->IsDepthStencil();
const GLenum attachment = draw_in_depth ? GL_DEPTH_STENCIL_ATTACHMENT : GL_COLOR_ATTACHMENT0;
// Bind attachments.
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, attachment, GL_TEXTURE_2D, sid, 0);
glReadBuffer(draw_in_depth ? GL_NONE : GL_COLOR_ATTACHMENT0);
// Do copy.
glCopyTextureSubImage2D(did, 0, destX, destY, r.x, r.y, r.width(), r.height());
// Unbind attachments.
if (draw_in_depth)
glReadBuffer(GL_COLOR_ATTACHMENT0);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, attachment, GL_TEXTURE_2D, 0, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
}
dTex->SetState(GSTexture::State::Dirty);
}