mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Hide glBlitFramebuffer behind fbo_blit
This commit is contained in:
parent
d14a388441
commit
8f00dd3f30
5 changed files with 36 additions and 35 deletions
|
@ -400,6 +400,25 @@ void fbo_copy_image(FBO *src, int srcLevel, int srcX, int srcY, int srcZ, FBO *d
|
|||
#endif
|
||||
}
|
||||
|
||||
void fbo_blit(FBO *src, int srcX1, int srcY1, int srcX2, int srcY2, FBO *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channels, FBBlitFilter linearFilter) {
|
||||
GLuint bits = 0;
|
||||
if (channels & FB_COLOR_BIT)
|
||||
bits |= GL_COLOR_BUFFER_BIT;
|
||||
if (channels & FB_DEPTH_BIT)
|
||||
bits |= GL_DEPTH_BUFFER_BIT;
|
||||
if (channels & FB_STENCIL_BIT)
|
||||
bits |= GL_STENCIL_BUFFER_BIT;
|
||||
fbo_bind_as_render_target(dst);
|
||||
fbo_bind_for_read(src);
|
||||
if (gl_extensions.GLES3 || gl_extensions.ARB_framebuffer_object) {
|
||||
glBlitFramebuffer(srcX1, srcY1, srcX2, srcY2, dstX1, dstY1, dstX2, dstY2, bits, linearFilter == FB_BLIT_LINEAR ? GL_LINEAR : GL_NEAREST);
|
||||
#if defined(USING_GLES2) && defined(__ANDROID__) // We only support this extension on Android, it's not even available on PC.
|
||||
} else if (gl_extensions.NV_framebuffer_blit) {
|
||||
glBlitFramebufferNV(srcX1, srcY1, srcX2, srcY2, dstX1, dstY1, dstX2, dstY2, bits, linearFilter == FB_BLIT_LINEAR ? GL_LINEAR : GL_NEAREST);
|
||||
#endif // defined(USING_GLES2) && defined(__ANDROID__)
|
||||
}
|
||||
}
|
||||
|
||||
void fbo_bind_color_as_texture(FBO *fbo, int color) {
|
||||
if (fbo) {
|
||||
glBindTexture(GL_TEXTURE_2D, fbo->color_texture);
|
||||
|
|
|
@ -33,6 +33,16 @@ enum FBOColorDepth {
|
|||
FBO_5551,
|
||||
};
|
||||
|
||||
enum FBOChannel {
|
||||
FB_COLOR_BIT = 1,
|
||||
FB_DEPTH_BIT = 2,
|
||||
FB_STENCIL_BIT = 4,
|
||||
};
|
||||
|
||||
enum FBBlitFilter {
|
||||
FB_BLIT_NEAREST = 0,
|
||||
FB_BLIT_LINEAR = 1,
|
||||
};
|
||||
|
||||
// Creates a simple FBO with a RGBA32 color buffer stored in a texture, and
|
||||
// optionally an accompanying Z/stencil buffer.
|
||||
|
@ -45,6 +55,8 @@ FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, F
|
|||
|
||||
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);
|
||||
|
||||
void fbo_blit(FBO *src, int srcX1, int srcY1, int srcX2, int srcY2, FBO *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter);
|
||||
|
||||
int fbo_standard_z_depth();
|
||||
int fbo_check_framebuffer_status(FBO *fbo);
|
||||
|
||||
|
|
|
@ -440,6 +440,7 @@ void FramebufferManagerGLES::DrawFramebufferToOutput(const u8 *srcPixels, GEBuff
|
|||
}
|
||||
|
||||
// x, y, w, h are relative coordinates against destW/destH, which is not very intuitive.
|
||||
// TODO: This could totally use fbo_blit.
|
||||
void FramebufferManagerGLES::DrawActiveTexture(GLuint texture, float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, GLSLProgram *program, int uvRotation) {
|
||||
float texCoords[8] = {
|
||||
u0,v0,
|
||||
|
@ -782,22 +783,10 @@ void FramebufferManagerGLES::BlitFramebufferDepth(VirtualFramebuffer *src, Virtu
|
|||
int h = std::min(src->renderHeight, dst->renderHeight);
|
||||
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT | GPU_SUPPORTS_NV_FRAMEBUFFER_BLIT)) {
|
||||
// Only use NV if ARB isn't supported.
|
||||
bool useNV = !gstate_c.Supports(GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT);
|
||||
|
||||
// Let's only do this if not clearing depth.
|
||||
fbo_bind_for_read(src->fbo);
|
||||
glstate.scissorTest.force(false);
|
||||
|
||||
if (useNV) {
|
||||
#if defined(USING_GLES2) && defined(__ANDROID__) // We only support this extension on Android, it's not even available on PC.
|
||||
glBlitFramebufferNV(0, 0, w, h, 0, 0, w, h, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
|
||||
#endif // defined(USING_GLES2) && defined(__ANDROID__)
|
||||
} else {
|
||||
glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
// If we set dst->depthUpdated here, our optimization above would be pointless.
|
||||
|
||||
fbo_blit(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, FB_DEPTH_BIT, FB_BLIT_NEAREST);
|
||||
// WARNING: If we set dst->depthUpdated here, our optimization above would be pointless.
|
||||
glstate.scissorTest.restore();
|
||||
}
|
||||
}
|
||||
|
@ -1303,16 +1292,7 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX,
|
|||
|
||||
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);
|
||||
} else {
|
||||
#if defined(USING_GLES2) && defined(__ANDROID__) // We only support this extension on Android, it's not even available on PC.
|
||||
glBlitFramebufferNV(srcX1, srcY1, srcX2, srcY2, dstX1, dstY1, dstX2, dstY2, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
#endif // defined(USING_GLES2) && defined(__ANDROID__)
|
||||
}
|
||||
|
||||
fbo_blit(src->fbo, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, FB_COLOR_BIT, FB_BLIT_NEAREST);
|
||||
fbo_unbind_read();
|
||||
} else {
|
||||
fbo_bind_as_render_target(dst->fbo);
|
||||
|
|
|
@ -171,7 +171,6 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe
|
|||
glstate.stencilOp.set(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
||||
|
||||
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);
|
||||
|
||||
// Our fragment shader (and discard) is slow. Since the source is 1x, we can stencil to 1x.
|
||||
// Then after we're done, we'll just blit it across and stretch it there.
|
||||
|
@ -221,15 +220,7 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe
|
|||
glstate.stencilMask.set(0xFF);
|
||||
|
||||
if (useBlit) {
|
||||
fbo_bind_as_render_target(dstBuffer->fbo);
|
||||
fbo_bind_for_read(blitFBO);
|
||||
if (!useNV) {
|
||||
glBlitFramebuffer(0, 0, w, h, 0, 0, dstBuffer->renderWidth, dstBuffer->renderHeight, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
|
||||
} else {
|
||||
#if defined(USING_GLES2) && defined(__ANDROID__) // We only support this extension on Android, it's not even available on PC.
|
||||
glBlitFramebufferNV(0, 0, w, h, 0, 0, dstBuffer->renderWidth, dstBuffer->renderHeight, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
|
||||
#endif // defined(USING_GLES2) && defined(__ANDROID__)
|
||||
}
|
||||
fbo_blit(blitFBO, 0, 0, w, h, dstBuffer->fbo, 0, 0, dstBuffer->renderWidth, dstBuffer->renderHeight, FB_STENCIL_BIT, FB_BLIT_NEAREST);
|
||||
}
|
||||
|
||||
RebindFramebuffer();
|
||||
|
|
|
@ -1201,7 +1201,6 @@ void FramebufferManagerVulkan::BlitFramebuffer(VirtualFramebuffer *dst, int dstX
|
|||
return;
|
||||
}
|
||||
|
||||
// glBlitFramebuffer can clip, but glCopyImageSubData is more restricted.
|
||||
// In case the src goes outside, we just skip the optimization in that case.
|
||||
const bool sameSize = dstX2 - dstX1 == srcX2 - srcX1 && dstY2 - dstY1 == srcY2 - srcY1;
|
||||
const bool sameDepth = dst->colorDepth == src->colorDepth;
|
||||
|
|
Loading…
Add table
Reference in a new issue