Merge pull request #9280 from hrydgard/fbo-cleanup

FBO API cleanup
This commit is contained in:
Henrik Rydgård
2017-02-04 22:26:18 +01:00
committed by GitHub
13 changed files with 289 additions and 336 deletions
+46 -56
View File
@@ -298,7 +298,7 @@ namespace DX9 {
if (currentRenderVfb_ && currentRenderVfb_->fbo_dx9) {
fbo_bind_as_render_target(currentRenderVfb_->fbo_dx9);
} else {
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
}
}
@@ -346,7 +346,7 @@ namespace DX9 {
}
textureCache_->ForgetLastTexture();
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
if (!useBufferedRendering_) {
if (vfb->fbo_dx9) {
@@ -356,7 +356,7 @@ namespace DX9 {
return;
}
vfb->fbo_dx9 = fbo_create(vfb->renderWidth, vfb->renderHeight, 1, true, (FBOColorDepth)vfb->colorDepth);
vfb->fbo_dx9 = fbo_create({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (FBOColorDepth)vfb->colorDepth });
if (old.fbo_dx9) {
INFO_LOG(SCEGE, "Resizing FBO for %08x : %i x %i x %i", vfb->fb_address, w, h, vfb->format);
if (vfb->fbo) {
@@ -379,7 +379,7 @@ namespace DX9 {
void FramebufferManagerDX9::NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb) {
if (!useBufferedRendering_) {
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
// Let's ignore rendering to targets that have not (yet) been displayed.
gstate_c.skipDrawReason |= SKIPDRAW_NON_DISPLAYED_FB;
}
@@ -411,7 +411,7 @@ namespace DX9 {
fbo_bind_as_render_target(vfb->fbo_dx9);
} else {
// wtf? This should only happen very briefly when toggling bBufferedRendering
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
}
} else {
if (vfb->fbo_dx9) {
@@ -420,7 +420,7 @@ namespace DX9 {
fbo_destroy(vfb->fbo_dx9);
vfb->fbo_dx9 = nullptr;
}
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
// Let's ignore rendering to targets that have not (yet) been displayed.
if (vfb->usageFlags & FB_USAGE_DISPLAYED_FRAMEBUFFER) {
@@ -557,10 +557,10 @@ namespace DX9 {
bool matchingSize = src->width == dst->width && src->height == dst->height;
if (matchingDepthBuffer && matchingSize) {
// Doesn't work. Use a shader maybe?
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
LPDIRECT3DTEXTURE9 srcTex = fbo_get_depth_texture(src->fbo_dx9);
LPDIRECT3DTEXTURE9 dstTex = fbo_get_depth_texture(dst->fbo_dx9);
LPDIRECT3DTEXTURE9 srcTex = (LPDIRECT3DTEXTURE9)fbo_get_api_texture(src->fbo_dx9, FB_DEPTH_BIT, 0);
LPDIRECT3DTEXTURE9 dstTex = (LPDIRECT3DTEXTURE9)fbo_get_api_texture(dst->fbo_dx9, FB_DEPTH_BIT, 0);
if (srcTex && dstTex) {
D3DSURFACE_DESC srcDesc;
@@ -610,7 +610,7 @@ namespace DX9 {
}
textureCache_->ForgetLastTexture();
FBO_DX9 *fbo = fbo_create(w, h, 1, false, depth);
FBO_DX9 *fbo = fbo_create({ w, h, 1, 1, false, depth });
if (!fbo)
return fbo;
fbo_bind_as_render_target(fbo);
@@ -700,19 +700,19 @@ namespace DX9 {
BlitFramebuffer(&copyInfo, x, y, framebuffer, x, y, w, h, 0);
RebindFramebuffer();
pD3Ddevice->SetTexture(stage, fbo_get_color_texture(renderCopy));
fbo_bind_as_texture(renderCopy, stage, FB_COLOR_BIT, 0);
} else {
pD3Ddevice->SetTexture(stage, fbo_get_color_texture(framebuffer->fbo_dx9));
fbo_bind_as_texture(framebuffer->fbo_dx9, stage, FB_COLOR_BIT, 0);
}
} else {
pD3Ddevice->SetTexture(stage, fbo_get_color_texture(framebuffer->fbo_dx9));
fbo_bind_as_texture(framebuffer->fbo_dx9, stage, FB_COLOR_BIT, 0);
}
}
void FramebufferManagerDX9::CopyDisplayToOutput() {
DownloadFramebufferOnSwitch(currentRenderVfb_);
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
currentRenderVfb_ = 0;
if (displayFramebufPtr_ == 0) {
@@ -812,7 +812,7 @@ namespace DX9 {
if (vfb->fbo) {
DEBUG_LOG(SCEGE, "Displaying FBO %08x", vfb->fb_address);
DisableState();
LPDIRECT3DTEXTURE9 colorTexture = fbo_get_color_texture(vfb->fbo_dx9);
fbo_bind_as_texture(vfb->fbo_dx9, 0, FB_COLOR_BIT, 0);
// Output coordinates
float x, y, w, h;
@@ -827,11 +827,14 @@ namespace DX9 {
if (1) {
const u32 rw = PSP_CoreParameter().pixelWidth;
const u32 rh = PSP_CoreParameter().pixelHeight;
const RECT srcRect = {(LONG)(u0 * vfb->renderWidth), (LONG)(v0 * vfb->renderHeight), (LONG)(u1 * vfb->renderWidth), (LONG)(v1 * vfb->renderHeight)};
const RECT dstRect = {(LONG)(x * rw / w), (LONG)(y * rh / h), (LONG)((x + w) * rw / w), (LONG)((y + h) * rh / h)};
HRESULT hr = fbo_blit_color(vfb->fbo_dx9, &srcRect, nullptr, &dstRect, g_Config.iBufFilter == SCALE_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT);
if (FAILED(hr)) {
ERROR_LOG_REPORT_ONCE(blit_fail, G3D, "fbo_blit_color failed on display: %08x", hr);
bool result = fbo_blit(vfb->fbo_dx9,
(LONG)(u0 * vfb->renderWidth), (LONG)(v0 * vfb->renderHeight), (LONG)(u1 * vfb->renderWidth), (LONG)(v1 * vfb->renderHeight),
nullptr,
(LONG)(x * rw / w), (LONG)(y * rh / h), (LONG)((x + w) * rw / w), (LONG)((y + h) * rh / h),
FB_COLOR_BIT,
g_Config.iBufFilter == SCALE_LINEAR ? FB_BLIT_LINEAR : FB_BLIT_NEAREST);
if (!result) {
ERROR_LOG_REPORT_ONCE(blit_fail, G3D, "fbo_blit_color failed on display");
DXSetViewport(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
// These are in the output display coordinates
if (g_Config.iBufFilter == SCALE_LINEAR) {
@@ -843,7 +846,7 @@ namespace DX9 {
}
dxstate.texMipFilter.set(D3DTEXF_NONE);
dxstate.texMipLodBias.set(0);
DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, u0, v0, u1, v1, uvRotation);
DrawActiveTexture(0, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, u0, v0, u1, v1, uvRotation);
}
}
/*
@@ -931,7 +934,7 @@ namespace DX9 {
bool FramebufferManagerDX9::CreateDownloadTempBuffer(VirtualFramebuffer *nvfb) {
nvfb->colorDepth = FBO_8888;
nvfb->fbo_dx9 = fbo_create(nvfb->width, nvfb->height, 1, true, (FBOColorDepth)nvfb->colorDepth);
nvfb->fbo_dx9 = fbo_create({ nvfb->width, nvfb->height, 1, 1, true, (FBOColorDepth)nvfb->colorDepth });
if (!(nvfb->fbo_dx9)) {
ERROR_LOG(SCEGE, "Error creating FBO! %i x %i", nvfb->renderWidth, nvfb->renderHeight);
return false;
@@ -949,7 +952,7 @@ namespace DX9 {
void FramebufferManagerDX9::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.
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
return;
}
@@ -975,31 +978,22 @@ namespace DX9 {
int dstY1 = dstY * dstYFactor;
int dstY2 = (dstY + h) * dstYFactor;
LPDIRECT3DSURFACE9 srcSurf = fbo_get_color_for_read(src->fbo_dx9);
LPDIRECT3DSURFACE9 dstSurf = fbo_get_color_for_write(dst->fbo_dx9);
RECT srcRect = {srcX1, srcY1, srcX2, srcY2};
RECT dstRect = {dstX1, dstY1, dstX2, dstY2};
D3DSURFACE_DESC desc;
srcSurf->GetDesc(&desc);
srcRect.right = std::min(srcRect.right, (LONG)desc.Width);
srcRect.bottom = std::min(srcRect.bottom, (LONG)desc.Height);
dstSurf->GetDesc(&desc);
dstRect.right = std::min(dstRect.right, (LONG)desc.Width);
dstRect.bottom = std::min(dstRect.bottom, (LONG)desc.Height);
// Direct3D 9 doesn't support rect -> self.
FBO_DX9 *srcFBO = src->fbo_dx9;
if (src == dst) {
FBO_DX9 *tempFBO = GetTempFBO(src->renderWidth, src->renderHeight, (FBOColorDepth)src->colorDepth);
HRESULT hr = fbo_blit_color(src->fbo_dx9, &srcRect, tempFBO, &srcRect, D3DTEXF_POINT);
HRESULT hr = fbo_blit(
src->fbo_dx9, srcX1, srcY1, srcX2, srcY2,
tempFBO, dstX1, dstY1, dstX2, dstY2,
FB_COLOR_BIT, FB_BLIT_NEAREST);
if (SUCCEEDED(hr)) {
srcFBO = tempFBO;
}
}
HRESULT hr = fbo_blit_color(srcFBO, &srcRect, dst->fbo_dx9, &dstRect, D3DTEXF_POINT);
HRESULT hr = fbo_blit(
srcFBO, srcX1, srcY1, srcX2, srcY2,
dst->fbo_dx9, dstX1, dstY1, dstX2, dstY2,
FB_COLOR_BIT, FB_BLIT_NEAREST);
if (FAILED(hr)) {
ERROR_LOG_REPORT(G3D, "fbo_blit_color failed in blit: %08x (%08x -> %08x)", hr, src->fb_address, dst->fb_address);
}
@@ -1058,7 +1052,7 @@ namespace DX9 {
void FramebufferManagerDX9::PackFramebufferDirectx9_(VirtualFramebuffer *vfb, int x, int y, int w, int h) {
if (!vfb->fbo) {
ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackFramebufferDirectx9_: vfb->fbo == 0");
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
return;
}
@@ -1069,7 +1063,7 @@ namespace DX9 {
// Right now that's always 8888.
DEBUG_LOG(HLE, "Reading framebuffer to mem, fb_address = %08x", fb_address);
LPDIRECT3DSURFACE9 renderTarget = fbo_get_color_for_read(vfb->fbo_dx9);
LPDIRECT3DSURFACE9 renderTarget = (LPDIRECT3DSURFACE9)fbo_get_api_texture(vfb->fbo_dx9, FB_COLOR_BIT | FB_SURFACE_BIT, 0);
D3DSURFACE_DESC desc;
renderTarget->GetDesc(&desc);
@@ -1108,7 +1102,7 @@ namespace DX9 {
DEBUG_LOG(SCEGE, "Reading depthbuffer to mem at %08x for vfb=%08x", z_address, vfb->fb_address);
LPDIRECT3DTEXTURE9 tex = fbo_get_depth_texture(vfb->fbo_dx9);
LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)fbo_get_api_texture(vfb->fbo_dx9, FB_DEPTH_BIT, 0);
if (tex) {
D3DSURFACE_DESC desc;
D3DLOCKED_RECT locked;
@@ -1206,7 +1200,7 @@ namespace DX9 {
void FramebufferManagerDX9::DecimateFBOs() {
if (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) {
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
}
currentRenderVfb_ = 0;
bool updateVram = !(g_Config.iRenderingMode == FB_NON_BUFFERED_MODE || g_Config.iRenderingMode == FB_BUFFERED_MODE);
@@ -1265,7 +1259,7 @@ namespace DX9 {
}
void FramebufferManagerDX9::DestroyAllFBOs(bool forceDelete) {
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
currentRenderVfb_ = 0;
displayFramebuf_ = 0;
prevDisplayFramebuf_ = 0;
@@ -1326,8 +1320,7 @@ namespace DX9 {
buffer = GPUDebugBuffer(Memory::GetPointer(fb_address | 0x04000000), fb_stride, 512, fb_format);
return true;
}
LPDIRECT3DSURFACE9 renderTarget = vfb->fbo_dx9 ? fbo_get_color_for_read(vfb->fbo_dx9) : nullptr;
LPDIRECT3DSURFACE9 renderTarget = vfb->fbo_dx9 ? (LPDIRECT3DSURFACE9)fbo_get_api_texture(vfb->fbo_dx9, FB_COLOR_BIT | FB_SURFACE_BIT, 0) : nullptr;
bool success = false;
if (renderTarget) {
FBO_DX9 *tempFBO = nullptr;
@@ -1337,12 +1330,9 @@ namespace DX9 {
// Let's resize. We must stretch to a render target first.
w = vfb->width * maxRes;
h = vfb->height * maxRes;
tempFBO = fbo_create(w, h, 1, false);
RECT srcRect = {0, 0, vfb->renderWidth, vfb->renderHeight};
D3DTEXTUREFILTERTYPE filt = g_Config.iBufFilter == SCALE_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT;
if (SUCCEEDED(fbo_blit_color(vfb->fbo_dx9, &srcRect, tempFBO, nullptr, filt))) {
renderTarget = fbo_get_color_for_read(tempFBO);
tempFBO = fbo_create({ w, h, 1, 1, false, FBO_8888 });
if (fbo_blit(vfb->fbo_dx9, 0, 0, vfb->renderWidth, vfb->renderHeight, tempFBO, 0, 0, w, h, FB_COLOR_BIT, g_Config.iBufFilter == SCALE_LINEAR ? FB_BLIT_LINEAR : FB_BLIT_NEAREST)) {
renderTarget = (LPDIRECT3DSURFACE9)fbo_get_api_texture(tempFBO, FB_COLOR_BIT | FB_SURFACE_BIT, 0);
}
}
@@ -1359,7 +1349,7 @@ namespace DX9 {
}
bool FramebufferManagerDX9::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
LPDIRECT3DSURFACE9 renderTarget = nullptr;
HRESULT hr = pD3Ddevice->GetRenderTarget(0, &renderTarget);
@@ -1421,7 +1411,7 @@ namespace DX9 {
}
bool success = false;
LPDIRECT3DTEXTURE9 tex = fbo_get_depth_texture(vfb->fbo_dx9);
LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)fbo_get_api_texture(vfb->fbo_dx9, FB_DEPTH_BIT, 0);
if (tex) {
D3DSURFACE_DESC desc;
D3DLOCKED_RECT locked;
@@ -1465,7 +1455,7 @@ namespace DX9 {
}
bool success = false;
LPDIRECT3DTEXTURE9 tex = fbo_get_depth_texture(vfb->fbo_dx9);
LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)fbo_get_api_texture(vfb->fbo_dx9, FB_DEPTH_BIT, 0);
if (tex) {
D3DSURFACE_DESC desc;
D3DLOCKED_RECT locked;
+1 -1
View File
@@ -787,7 +787,7 @@ void TextureCacheDX9::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFrame
shaderApply.Shade();
fbo_bind_color_as_texture(depalFBO, 0);
fbo_bind_as_texture(depalFBO, 0, FB_COLOR_BIT, 0);
const u32 bytesPerColor = clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16);
const u32 clutTotalColors = clutMaxBytes_ / bytesPerColor;
+49 -27
View File
@@ -15,6 +15,8 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <algorithm>
#include "global.h"
#include <stdint.h>
#include <string.h>
@@ -64,13 +66,13 @@ void fbo_shutdown() {
deviceDSsurf->Release();
}
FBO_DX9 *fbo_create(int width, int height, int num_color_textures, bool z_stencil, FBOColorDepth colorDepth) {
FBO_DX9 *fbo_create(const FramebufferDesc &desc) {
static uint32_t id = 0;
FBO_DX9 *fbo = new FBO_DX9();
fbo->width = width;
fbo->height = height;
fbo->colorDepth = colorDepth;
fbo->width = desc.width;
fbo->height = desc.height;
fbo->colorDepth = desc.colorDepth;
fbo->depthstenciltex = nullptr;
HRESULT rtResult = pD3Ddevice->CreateTexture(fbo->width, fbo->height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &fbo->tex, NULL);
@@ -100,7 +102,6 @@ FBO_DX9 *fbo_create(int width, int height, int num_color_textures, bool z_stenci
delete fbo;
return NULL;
}
fbo->id = id++;
return fbo;
}
@@ -115,7 +116,7 @@ void fbo_destroy(FBO_DX9 *fbo) {
delete fbo;
}
void fbo_unbind() {
void fbo_bind_backbuffer_as_render_target() {
pD3Ddevice->SetRenderTarget(0, deviceRTsurf);
pD3Ddevice->SetDepthStencilSurface(deviceDSsurf);
dxstate.scissorRect.restore();
@@ -132,30 +133,47 @@ void fbo_bind_as_render_target(FBO_DX9 *fbo) {
dxstate.viewport.restore();
}
LPDIRECT3DTEXTURE9 fbo_get_color_texture(FBO_DX9 *fbo) {
return fbo->tex;
}
LPDIRECT3DTEXTURE9 fbo_get_depth_texture(FBO_DX9 *fbo) {
return fbo->depthstenciltex;
uintptr_t fbo_get_api_texture(FBO_DX9 *fbo, int channelBits, int attachment) {
if (channelBits & FB_SURFACE_BIT) {
switch (channelBits & 7) {
case FB_DEPTH_BIT:
return (uintptr_t)fbo->depthstencil;
case FB_STENCIL_BIT:
return (uintptr_t)fbo->depthstencil;
case FB_COLOR_BIT:
default:
return (uintptr_t)fbo->surf;
}
} else {
switch (channelBits & 7) {
case FB_DEPTH_BIT:
return (uintptr_t)fbo->depthstenciltex;
case FB_STENCIL_BIT:
return 0; // Can't texture from stencil
case FB_COLOR_BIT:
default:
return (uintptr_t)fbo->tex;
}
}
}
LPDIRECT3DSURFACE9 fbo_get_color_for_read(FBO_DX9 *fbo) {
return fbo->surf;
}
LPDIRECT3DSURFACE9 fbo_get_color_for_write(FBO_DX9 *fbo) {
return fbo->surf;
}
void fbo_bind_color_as_texture(FBO_DX9 *fbo, int color) {
pD3Ddevice->SetTexture(0, fbo->tex);
}
void fbo_bind_depth_as_texture(FBO_DX9 *fbo) {
if (fbo->depthstenciltex) {
pD3Ddevice->SetTexture(0, fbo->depthstenciltex);
void fbo_bind_as_texture(FBO_DX9 *fbo, int binding, FBOChannel channelBit, int color) {
switch (channelBit) {
case FB_DEPTH_BIT:
if (fbo->depthstenciltex) {
pD3Ddevice->SetTexture(binding, fbo->depthstenciltex);
}
break;
case FB_COLOR_BIT:
default:
if (fbo->tex) {
pD3Ddevice->SetTexture(binding, fbo->tex);
}
break;
}
}
@@ -164,10 +182,14 @@ void fbo_get_dimensions(FBO_DX9 *fbo, int *w, int *h) {
*h = fbo->height;
}
HRESULT fbo_blit_color(FBO_DX9 *src, const RECT *srcRect, FBO_DX9 *dst, const RECT *dstRect, D3DTEXTUREFILTERTYPE filter) {
bool fbo_blit(FBO_DX9 *src, int srcX1, int srcY1, int srcX2, int srcY2, FBO_DX9 *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) {
if (channelBits != FB_COLOR_BIT)
return false;
RECT srcRect{ (LONG)srcX1, (LONG)srcY1, (LONG)srcX2, (LONG)srcY2 };
RECT dstRect{ (LONG)dstX1, (LONG)dstY1, (LONG)dstX2, (LONG)dstY2 };
LPDIRECT3DSURFACE9 srcSurf = src ? src->surf : deviceRTsurf;
LPDIRECT3DSURFACE9 dstSurf = dst ? dst->surf : deviceRTsurf;
return pD3Ddevice->StretchRect(srcSurf, srcRect, dstSurf, dstRect, filter);
return SUCCEEDED(pD3Ddevice->StretchRect(srcSurf, &srcRect, dstSurf, &dstRect, filter == FB_BLIT_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT));
}
}
} // namespace
+30 -11
View File
@@ -32,6 +32,27 @@ enum FBOColorDepth {
FBO_5551,
};
enum FBOChannel {
FB_COLOR_BIT = 1,
FB_DEPTH_BIT = 2,
FB_STENCIL_BIT = 4,
FB_SURFACE_BIT = 32,
};
enum FBBlitFilter {
FB_BLIT_NEAREST = 0,
FB_BLIT_LINEAR = 1,
};
struct FramebufferDesc {
int width;
int height;
int depth;
int numColorAttachments;
bool z_stencil;
FBOColorDepth colorDepth;
};
// Creates a simple FBO with a RGBA32 color buffer stored in a texture, and
// optionally an accompanying Z/stencil buffer.
// No mipmap support.
@@ -39,23 +60,21 @@ enum FBOColorDepth {
// you lose bound texture state.
// On some hardware, you might get a 24-bit depth buffer even though you only wanted a 16-bit one.
FBO_DX9 *fbo_create(int width, int height, int num_color_textures, bool z_stencil, FBOColorDepth colorDepth = FBO_8888);
FBO_DX9 *fbo_create(const FramebufferDesc &desc);
void fbo_destroy(FBO_DX9 *fbo);
bool fbo_blit(FBO_DX9 *src, int srcX1, int srcY1, int srcX2, int srcY2, FBO_DX9 *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter);
// These functions should be self explanatory.
void fbo_bind_as_render_target(FBO_DX9 *fbo);
// color must be 0, for now.
void fbo_bind_color_as_texture(FBO_DX9 *fbo, int color);
void fbo_bind_depth_as_texture(FBO_DX9 *fbo);
LPDIRECT3DSURFACE9 fbo_get_color_for_read(FBO_DX9 *fbo);
LPDIRECT3DSURFACE9 fbo_get_color_for_write(FBO_DX9 *fbo);
void fbo_unbind();
void fbo_destroy(FBO_DX9 *fbo);
// color must be 0.
void fbo_bind_as_texture(FBO_DX9 *fbo, int binding, FBOChannel channelBit, int color);
void fbo_bind_backbuffer_as_render_target();
void fbo_get_dimensions(FBO_DX9 *fbo, int *w, int *h);
void fbo_resolve(FBO_DX9 *fbo);
HRESULT fbo_blit_color(FBO_DX9 *src, const RECT *srcRect, FBO_DX9 *dst, const RECT *dstRect, D3DTEXTUREFILTERTYPE filter);
LPDIRECT3DTEXTURE9 fbo_get_color_texture(FBO_DX9 *fbo);
LPDIRECT3DTEXTURE9 fbo_get_depth_texture(FBO_DX9 *fbo);
// Escape route until we complete the API
uintptr_t fbo_get_api_texture(FBO_DX9 *fbo, int channelBits, int attachment);
// To get default depth and rt surface
void fbo_init(LPDIRECT3D9 d3d);
+88 -102
View File
@@ -37,11 +37,8 @@ struct FBO {
int width;
int height;
FBOColorDepth colorDepth;
bool native_fbo;
};
static FBO *g_overriddenBackbuffer;
static GLuint currentDrawHandle_ = 0;
static GLuint currentReadHandle_ = 0;
@@ -49,12 +46,11 @@ static GLuint currentReadHandle_ = 0;
// On Android, we try to use what's available.
#ifndef USING_GLES2
FBO *fbo_ext_create(int width, int height, int num_color_textures, bool z_stencil, FBOColorDepth colorDepth) {
FBO *fbo_ext_create(const FramebufferDesc &desc) {
FBO *fbo = new FBO();
fbo->native_fbo = false;
fbo->width = width;
fbo->height = height;
fbo->colorDepth = colorDepth;
fbo->width = desc.width;
fbo->height = desc.height;
fbo->colorDepth = desc.colorDepth;
// Color texture is same everywhere
glGenFramebuffersEXT(1, &fbo->handle);
@@ -68,18 +64,18 @@ FBO *fbo_ext_create(int width, int height, int num_color_textures, bool z_stenci
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// TODO: We could opt to only create 16-bit render targets on slow devices. For later.
switch (colorDepth) {
switch (fbo->colorDepth) {
case FBO_8888:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fbo->width, fbo->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
break;
case FBO_4444:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fbo->width, fbo->height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, NULL);
break;
case FBO_5551:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fbo->width, fbo->height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, NULL);
break;
case FBO_565:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fbo->width, fbo->height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);
break;
}
@@ -93,7 +89,7 @@ FBO *fbo_ext_create(int width, int height, int num_color_textures, bool z_stenci
// 24-bit Z, 8-bit stencil
glGenRenderbuffersEXT(1, &fbo->z_stencil_buffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo->z_stencil_buffer);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, width, height);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, fbo->width, fbo->height);
//glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8, width, height);
// Bind it all together
@@ -127,23 +123,7 @@ FBO *fbo_ext_create(int width, int height, int num_color_textures, bool z_stenci
}
#endif
int fbo_check_framebuffer_status(FBO *fbo) {
GLenum fbStatus;
#ifndef USING_GLES2
if (!gl_extensions.ARB_framebuffer_object && gl_extensions.EXT_framebuffer_object) {
fbStatus = glCheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER);
} else if (gl_extensions.ARB_framebuffer_object) {
fbStatus = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER);
} else {
fbStatus = 0;
}
#else
fbStatus = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER);
#endif
return (int)fbStatus;
}
int fbo_standard_z_depth() {
int fbo_preferred_z_bitdepth() {
// This matches the fbo_create() logic.
if (gl_extensions.IsGLES) {
if (gl_extensions.OES_packed_depth_stencil) {
@@ -155,12 +135,12 @@ int fbo_standard_z_depth() {
}
}
FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, FBOColorDepth colorDepth) {
FBO *fbo_create(const FramebufferDesc &desc) {
CheckGLExtensions();
#ifndef USING_GLES2
if (!gl_extensions.ARB_framebuffer_object && gl_extensions.EXT_framebuffer_object) {
return fbo_ext_create(width, height, num_color_textures, z_stencil, colorDepth);
return fbo_ext_create(desc);
} else if (!gl_extensions.ARB_framebuffer_object) {
return nullptr;
}
@@ -168,10 +148,9 @@ FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, F
#endif
FBO *fbo = new FBO();
fbo->native_fbo = false;
fbo->width = width;
fbo->height = height;
fbo->colorDepth = colorDepth;
fbo->width = desc.width;
fbo->height = desc.height;
fbo->colorDepth = desc.colorDepth;
// Color texture is same everywhere
glGenFramebuffers(1, &fbo->handle);
@@ -185,18 +164,18 @@ FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, F
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// TODO: We could opt to only create 16-bit render targets on slow devices. For later.
switch (colorDepth) {
switch (fbo->colorDepth) {
case FBO_8888:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fbo->width, fbo->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
break;
case FBO_4444:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fbo->width, fbo->height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, NULL);
break;
case FBO_5551:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fbo->width, fbo->height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, NULL);
break;
case FBO_565:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fbo->width, fbo->height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);
break;
}
@@ -207,14 +186,14 @@ FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, F
if (gl_extensions.IsGLES) {
if (gl_extensions.OES_packed_depth_stencil) {
ILOG("Creating %i x %i FBO using DEPTH24_STENCIL8", width, height);
ILOG("Creating %i x %i FBO using DEPTH24_STENCIL8", fbo->width, fbo->height);
// Standard method
fbo->stencil_buffer = 0;
fbo->z_buffer = 0;
// 24-bit Z, 8-bit stencil combined
glGenRenderbuffers(1, &fbo->z_stencil_buffer);
glBindRenderbuffer(GL_RENDERBUFFER, fbo->z_stencil_buffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, fbo->width, fbo->height);
// Bind it all together
glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle);
@@ -222,19 +201,19 @@ FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, F
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer);
} else {
ILOG("Creating %i x %i FBO using separate stencil", width, height);
ILOG("Creating %i x %i FBO using separate stencil", fbo->width, fbo->height);
// TEGRA
fbo->z_stencil_buffer = 0;
// 16/24-bit Z, separate 8-bit stencil
glGenRenderbuffers(1, &fbo->z_buffer);
glBindRenderbuffer(GL_RENDERBUFFER, fbo->z_buffer);
// Don't forget to make sure fbo_standard_z_depth() matches.
glRenderbufferStorage(GL_RENDERBUFFER, gl_extensions.OES_depth24 ? GL_DEPTH_COMPONENT24 : GL_DEPTH_COMPONENT16, width, height);
glRenderbufferStorage(GL_RENDERBUFFER, gl_extensions.OES_depth24 ? GL_DEPTH_COMPONENT24 : GL_DEPTH_COMPONENT16, fbo->width, fbo->height);
// 8-bit stencil buffer
glGenRenderbuffers(1, &fbo->stencil_buffer);
glBindRenderbuffer(GL_RENDERBUFFER, fbo->stencil_buffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height);
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, fbo->width, fbo->height);
// Bind it all together
glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle);
@@ -248,7 +227,7 @@ FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, F
// 24-bit Z, 8-bit stencil
glGenRenderbuffers(1, &fbo->z_stencil_buffer);
glBindRenderbuffer(GL_RENDERBUFFER, fbo->z_stencil_buffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, fbo->width, fbo->height);
// Bind it all together
glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle);
@@ -258,7 +237,7 @@ FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, F
}
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch(status) {
switch (status) {
case GL_FRAMEBUFFER_COMPLETE:
// ILOG("Framebuffer verified complete.");
break;
@@ -281,24 +260,6 @@ FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, F
return fbo;
}
FBO *fbo_create_from_native_fbo(GLuint native_fbo, FBO *fbo)
{
if (!fbo)
fbo = new FBO();
fbo->native_fbo = true;
fbo->handle = native_fbo;
fbo->color_texture = 0;
fbo->z_stencil_buffer = 0;
fbo->z_buffer = 0;
fbo->stencil_buffer = 0;
fbo->width = 0;
fbo->height = 0;
fbo->colorDepth = FBO_8888;
return fbo;
}
static GLenum fbo_get_fb_target(bool read, GLuint **cached) {
bool supportsBlit = gl_extensions.ARB_framebuffer_object;
if (gl_extensions.IsGLES) {
@@ -323,7 +284,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);
@@ -336,13 +296,7 @@ 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();
static void fbo_unbind() {
#ifndef USING_GLES2
if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -361,10 +315,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.
@@ -373,7 +323,7 @@ void fbo_bind_as_render_target(FBO *fbo) {
glstate.viewport.restore();
}
void fbo_unbind_render_target() {
void fbo_bind_backbuffer_as_render_target() {
fbo_unbind();
}
@@ -382,22 +332,70 @@ void fbo_bind_for_read(FBO *fbo) {
fbo_bind_fb_target(true, fbo->handle);
}
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(
src->color_texture, GL_TEXTURE_2D, srcLevel, srcX, srcY, srcZ,
dst->color_texture, GL_TEXTURE_2D, dstLevel, dstX, dstY, dstZ,
width, height, depth);
return;
#endif
#else
if (gl_extensions.ARB_copy_image) {
glCopyImageSubData(
src->color_texture, GL_TEXTURE_2D, srcLevel, srcX, srcY, srcZ,
dst->color_texture, 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(
src->color_texture, GL_TEXTURE_2D, srcLevel, srcX, srcY, srcZ,
dst->color_texture, 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);
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__)
}
}
uintptr_t fbo_get_api_texture(FBO *fbo, FBOChannel channelBit, int attachment) {
// Unimplemented
return 0;
}
void fbo_bind_as_texture(FBO *fbo, int binding, FBOChannel channelBit, int color) {
// glActiveTexture(GL_TEXTURE0 + binding);
switch (channelBit) {
case FB_COLOR_BIT:
default:
if (fbo) {
glBindTexture(GL_TEXTURE_2D, fbo->color_texture);
}
break;
}
}
void fbo_destroy(FBO *fbo) {
if (fbo->native_fbo) {
delete fbo;
return;
}
if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) {
glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
@@ -429,15 +427,3 @@ void fbo_get_dimensions(FBO *fbo, int *w, int *h) {
*w = fbo->width;
*h = fbo->height;
}
int fbo_get_color_texture(FBO *fbo) {
return fbo->color_texture;
}
int fbo_get_depth_buffer(FBO *fbo) {
return fbo->z_buffer;
}
int fbo_get_stencil_buffer(FBO *fbo) {
return fbo->stencil_buffer;
}
+29 -17
View File
@@ -33,6 +33,25 @@ 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,
};
struct FramebufferDesc {
int width;
int height;
int depth;
int numColorAttachments;
bool z_stencil;
FBOColorDepth colorDepth;
};
// Creates a simple FBO with a RGBA32 color buffer stored in a texture, and
// optionally an accompanying Z/stencil buffer.
@@ -41,28 +60,21 @@ enum FBOColorDepth {
// you lose bound texture state.
// 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);
FBO *fbo_create(const FramebufferDesc &desc);
void fbo_destroy(FBO *fbo);
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);
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);
// 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_check_framebuffer_status(FBO *fbo);
int fbo_preferred_z_bitdepth();
// These functions should be self explanatory.
void fbo_bind_as_render_target(FBO *fbo);
// color must be 0, for now.
void fbo_bind_color_as_texture(FBO *fbo, int color);
void fbo_bind_as_texture(FBO *fbo, int binding, FBOChannel channelBit, int attachment);
void fbo_bind_for_read(FBO *fbo);
void fbo_unbind();
void fbo_unbind_render_target();
void fbo_unbind_read();
void fbo_destroy(FBO *fbo);
void fbo_bind_backbuffer_as_render_target();
uintptr_t fbo_get_api_texture(FBO *fbo, FBOChannel channelBit, int attachment);
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.
+41 -103
View File
@@ -121,7 +121,7 @@ void FramebufferManagerGLES::SetNumExtraFBOs(int num) {
extraFBOs_.clear();
for (int i = 0; i < num; i++) {
// No depth/stencil for post processing
FBO *fbo = fbo_create(renderWidth_, renderHeight_, 1, false, FBO_8888);
FBO *fbo = fbo_create({ (int)renderWidth_, (int)renderHeight_, 1, 1, false, FBO_8888 });
extraFBOs_.push_back(fbo);
// The new FBO is still bound after creation, but let's bind it anyway.
@@ -130,7 +130,7 @@ void FramebufferManagerGLES::SetNumExtraFBOs(int num) {
}
currentRenderVfb_ = 0;
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
}
void FramebufferManagerGLES::CompileDraw2DProgram() {
@@ -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,
@@ -551,7 +552,7 @@ void FramebufferManagerGLES::RebindFramebuffer() {
if (currentRenderVfb_ && currentRenderVfb_->fbo) {
fbo_bind_as_render_target(currentRenderVfb_->fbo);
} else {
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
}
if (g_Config.iRenderingMode == FB_NON_BUFFERED_MODE)
glstate.viewport.restore();
@@ -601,7 +602,7 @@ void FramebufferManagerGLES::ResizeFramebufFBO(VirtualFramebuffer *vfb, u16 w, u
}
textureCache_->ForgetLastTexture();
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
if (!useBufferedRendering_) {
if (vfb->fbo) {
@@ -611,7 +612,7 @@ void FramebufferManagerGLES::ResizeFramebufFBO(VirtualFramebuffer *vfb, u16 w, u
return;
}
vfb->fbo = fbo_create(vfb->renderWidth, vfb->renderHeight, 1, true, (FBOColorDepth)vfb->colorDepth);
vfb->fbo = fbo_create({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (FBOColorDepth)vfb->colorDepth });
if (old.fbo) {
INFO_LOG(SCEGE, "Resizing FBO for %08x : %i x %i x %i", vfb->fb_address, w, h, vfb->format);
if (vfb->fbo) {
@@ -634,7 +635,7 @@ void FramebufferManagerGLES::ResizeFramebufFBO(VirtualFramebuffer *vfb, u16 w, u
void FramebufferManagerGLES::NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb) {
if (!useBufferedRendering_) {
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
// Let's ignore rendering to targets that have not (yet) been displayed.
gstate_c.skipDrawReason |= SKIPDRAW_NON_DISPLAYED_FB;
}
@@ -664,7 +665,7 @@ void FramebufferManagerGLES::NotifyRenderFramebufferSwitched(VirtualFramebuffer
fbo_bind_as_render_target(vfb->fbo);
} else {
// wtf? This should only happen very briefly when toggling bBufferedRendering
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
}
} else {
if (vfb->fbo) {
@@ -673,7 +674,7 @@ void FramebufferManagerGLES::NotifyRenderFramebufferSwitched(VirtualFramebuffer
fbo_destroy(vfb->fbo);
vfb->fbo = 0;
}
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
// Let's ignore rendering to targets that have not (yet) been displayed.
if (vfb->usageFlags & FB_USAGE_DISPLAYED_FRAMEBUFFER) {
@@ -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();
}
}
@@ -812,7 +801,7 @@ FBO *FramebufferManagerGLES::GetTempFBO(u16 w, u16 h, FBOColorDepth depth) {
}
textureCache_->ForgetLastTexture();
FBO *fbo = fbo_create(w, h, 1, false, depth);
FBO *fbo = fbo_create({ w, h, 1, 1, false, depth });
if (!fbo)
return fbo;
fbo_bind_as_render_target(fbo);
@@ -873,12 +862,12 @@ void FramebufferManagerGLES::BindFramebufferColor(int stage, u32 fbRawAddress, V
BlitFramebuffer(&copyInfo, x, y, framebuffer, x, y, w, h, 0);
fbo_bind_color_as_texture(renderCopy, 0);
fbo_bind_as_texture(renderCopy, 0, FB_COLOR_BIT, 0);
} else {
fbo_bind_color_as_texture(framebuffer->fbo, 0);
fbo_bind_as_texture(framebuffer->fbo, 0, FB_COLOR_BIT, 0);
}
} else {
fbo_bind_color_as_texture(framebuffer->fbo, 0);
fbo_bind_as_texture(framebuffer->fbo, 0, FB_COLOR_BIT, 0);
}
if (stage != GL_TEXTURE0) {
@@ -916,7 +905,7 @@ void FramebufferManagerGLES::CopyDisplayToOutput() {
DownloadFramebufferOnSwitch(currentRenderVfb_);
glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_);
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
currentRenderVfb_ = 0;
if (displayFramebufPtr_ == 0) {
@@ -1025,7 +1014,7 @@ void FramebufferManagerGLES::CopyDisplayToOutput() {
DEBUG_LOG(SCEGE, "Displaying FBO %08x", vfb->fb_address);
DisableState();
GLuint colorTexture = fbo_get_color_texture(vfb->fbo);
fbo_bind_as_texture(vfb->fbo, 0, FB_COLOR_BIT, 0);
int uvRotation = (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) ? g_Config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL;
@@ -1047,15 +1036,15 @@ void FramebufferManagerGLES::CopyDisplayToOutput() {
if (cardboardSettings.enabled) {
// Left Eye Image
glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight);
DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL);
DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL);
// Right Eye Image
glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight);
DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL);
DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL);
} else {
// Fullscreen Image
glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_);
DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, uvRotation);
DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, uvRotation);
}
} else if (usePostShader_ && extraFBOs_.size() == 1 && !postShaderAtOutputResolution_) {
// An additional pass, post-processing shader to the extra FBO.
@@ -1066,17 +1055,17 @@ void FramebufferManagerGLES::CopyDisplayToOutput() {
shaderManager_->DirtyLastShader(); // dirty lastShader_
glsl_bind(postShaderProgram_);
UpdatePostShaderUniforms(vfb->bufferWidth, vfb->bufferHeight, renderWidth_, renderHeight_);
DrawActiveTexture(colorTexture, 0, 0, fbo_w, fbo_h, fbo_w, fbo_h, 0.0f, 0.0f, 1.0f, 1.0f, postShaderProgram_, ROTATION_LOCKED_HORIZONTAL);
DrawActiveTexture(0, 0, 0, fbo_w, fbo_h, fbo_w, fbo_h, 0.0f, 0.0f, 1.0f, 1.0f, postShaderProgram_, ROTATION_LOCKED_HORIZONTAL);
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
// Use the extra FBO, with applied post-processing shader, as a texture.
// fbo_bind_color_as_texture(extraFBOs_[0], 0);
// fbo_bind_as_texture(extraFBOs_[0], FB_COLOR_BIT, 0);
if (extraFBOs_.size() == 0) {
ERROR_LOG(G3D, "WTF?");
return;
}
colorTexture = fbo_get_color_texture(extraFBOs_[0]);
fbo_bind_as_texture(extraFBOs_[0], 0, FB_COLOR_BIT, 0);
// We are doing the DrawActiveTexture call directly to the backbuffer after here. Hence, we must
// flip V.
@@ -1085,15 +1074,15 @@ void FramebufferManagerGLES::CopyDisplayToOutput() {
if (g_Config.bEnableCardboard) {
// Left Eye Image
glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight);
DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL);
DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL);
// Right Eye Image
glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight);
DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL);
DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL);
} else {
// Fullscreen Image
glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_);
DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, uvRotation);
DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, uvRotation);
}
if (gl_extensions.GLES3 && glInvalidateFramebuffer != nullptr) {
@@ -1112,15 +1101,15 @@ void FramebufferManagerGLES::CopyDisplayToOutput() {
if (g_Config.bEnableCardboard) {
// Left Eye Image
glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight);
DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL);
DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL);
// Right Eye Image
glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight);
DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL);
DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL);
} else {
// Fullscreen Image
glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_);
DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, postShaderProgram_, uvRotation);
DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, postShaderProgram_, uvRotation);
}
}
@@ -1222,8 +1211,8 @@ bool FramebufferManagerGLES::CreateDownloadTempBuffer(VirtualFramebuffer *nvfb)
}
}
nvfb->fbo = fbo_create(nvfb->width, nvfb->height, 1, false, (FBOColorDepth)nvfb->colorDepth);
if (!(nvfb->fbo)) {
nvfb->fbo = fbo_create({ nvfb->width, nvfb->height, 1, 1, false, (FBOColorDepth)nvfb->colorDepth });
if (!nvfb->fbo) {
ERROR_LOG(SCEGE, "Error creating FBO! %i x %i", nvfb->renderWidth, nvfb->renderHeight);
return false;
}
@@ -1251,7 +1240,7 @@ void FramebufferManagerGLES::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb)
void FramebufferManagerGLES::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.
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
return;
}
@@ -1296,49 +1285,17 @@ 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_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_unbind_read();
fbo_blit(src->fbo, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, FB_COLOR_BIT, FB_BLIT_NEAREST);
} else {
fbo_bind_color_as_texture(src->fbo, 0);
fbo_bind_as_render_target(dst->fbo);
fbo_bind_as_texture(src->fbo, 0, FB_COLOR_BIT, 0);
// Make sure our 2D drawing program is ready. Compiles only if not already compiled.
CompileDraw2DProgram();
@@ -1621,16 +1578,6 @@ void FramebufferManagerGLES::PackFramebufferAsync_(VirtualFramebuffer *vfb) {
fbo_bind_for_read(vfb->fbo);
} else {
ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackFramebufferAsync_: vfb->fbo == 0");
fbo_unbind_read();
return;
}
GLenum fbStatus;
fbStatus = (GLenum)fbo_check_framebuffer_status(vfb->fbo);
if (fbStatus != GL_FRAMEBUFFER_COMPLETE) {
ERROR_LOG(SCEGE, "Incomplete source framebuffer, aborting read");
fbo_unbind_read();
return;
}
@@ -1652,7 +1599,6 @@ void FramebufferManagerGLES::PackFramebufferAsync_(VirtualFramebuffer *vfb) {
SafeGLReadPixels(0, 0, vfb->fb_stride, vfb->height, pixelFormat, pixelType, 0);
}
fbo_unbind_read();
unbind = true;
pixelBufObj_[currentPBO_].fb_address = fb_address;
@@ -1675,7 +1621,6 @@ void FramebufferManagerGLES::PackFramebufferSync_(VirtualFramebuffer *vfb, int x
fbo_bind_for_read(vfb->fbo);
} else {
ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackFramebufferSync_: vfb->fbo == 0");
fbo_unbind_read();
return;
}
@@ -1735,8 +1680,6 @@ void FramebufferManagerGLES::PackFramebufferSync_(VirtualFramebuffer *vfb, int x
GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT };
glInvalidateFramebuffer(target, 3, attachments);
}
fbo_unbind_read();
}
void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h) {
@@ -1778,8 +1721,6 @@ void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int
depth[i] = (int)scaled;
}
}
fbo_unbind_read();
}
void FramebufferManagerGLES::EndFrame() {
@@ -1850,7 +1791,7 @@ void FramebufferManagerGLES::EndFrame() {
GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_STENCIL_ATTACHMENT, GL_DEPTH_ATTACHMENT };
glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, attachments);
}
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
}
}
@@ -1880,7 +1821,7 @@ std::vector<FramebufferInfo> FramebufferManagerGLES::GetFramebufferList() {
}
void FramebufferManagerGLES::DecimateFBOs() {
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
currentRenderVfb_ = 0;
for (size_t i = 0; i < vfbs_.size(); ++i) {
@@ -1927,7 +1868,7 @@ void FramebufferManagerGLES::DecimateFBOs() {
}
void FramebufferManagerGLES::DestroyAllFBOs(bool forceDelete) {
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
currentRenderVfb_ = 0;
displayFramebuf_ = 0;
prevDisplayFramebuf_ = 0;
@@ -1951,7 +1892,7 @@ void FramebufferManagerGLES::DestroyAllFBOs(bool forceDelete) {
}
tempFBOs_.clear();
fbo_unbind();
fbo_bind_backbuffer_as_render_target();
DisableState();
}
@@ -2011,14 +1952,11 @@ bool FramebufferManagerGLES::GetFramebuffer(u32 fb_address, int fb_stride, GEBuf
SafeGLReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buffer.GetData());
// We may have clitted to a temp FBO.
fbo_unbind_read();
RebindFramebuffer();
return true;
}
bool FramebufferManagerGLES::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
fbo_unbind_read();
int pw = PSP_CoreParameter().pixelWidth;
int ph = PSP_CoreParameter().pixelHeight;
+2 -2
View File
@@ -605,14 +605,14 @@ void GPU_GLES::CheckGPUFeatures() {
features |= GPU_SUPPORTS_TEXTURE_FLOAT;
// If we already have a 16-bit depth buffer, we don't need to round.
if (fbo_standard_z_depth() > 16) {
if (fbo_preferred_z_bitdepth() > 16) {
if (!g_Config.bHighQualityDepth && (features & GPU_SUPPORTS_ACCURATE_DEPTH) != 0) {
features |= GPU_SCALE_DEPTH_FROM_24BIT_TO_16BIT;
} else if (PSP_CoreParameter().compat.flags().PixelDepthRounding) {
if (!gl_extensions.IsGLES || gl_extensions.GLES3) {
// Use fragment rounding on desktop and GLES3, most accurate.
features |= GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT;
} else if (fbo_standard_z_depth() == 24 && (features & GPU_SUPPORTS_ACCURATE_DEPTH) != 0) {
} else if (fbo_preferred_z_bitdepth() == 24 && (features & GPU_SUPPORTS_ACCURATE_DEPTH) != 0) {
// Here we can simulate a 16 bit depth buffer by scaling.
// Note that the depth buffer is fixed point, not floating, so dividing by 256 is pretty good.
features |= GPU_SCALE_DEPTH_FROM_24BIT_TO_16BIT;
+1 -10
View File
@@ -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();
+1 -1
View File
@@ -862,7 +862,7 @@ void TextureCacheGLES::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFram
shaderApply.Shade();
fbo_bind_color_as_texture(depalFBO, 0);
fbo_bind_as_texture(depalFBO, 0, FB_COLOR_BIT, 0);
const u32 bytesPerColor = clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16);
const u32 clutTotalColors = clutMaxBytes_ / bytesPerColor;
-1
View File
@@ -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;
+1 -1
View File
@@ -1353,7 +1353,7 @@ void Debugger_DisplayList::UpdateRenderBufferGUI()
memset(data,0,FRAME_WIDTH * FRAME_HEIGHT * 4);
if(currentRenderFrameDisplay == 0)
{
fbo_bind_color_as_texture(currentTextureDisplay,0);
fbo_bind_as_texture(currentTextureDisplay, 0, FB_COLOR_BIT, 0);
glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);
}
}
-4
View File
@@ -44,7 +44,6 @@
#include "Core/System.h"
#include "GPU/GPUState.h"
#include "GPU/GPUInterface.h"
#include "GPU/GLES/FBO.h"
#include "GPU/GLES/FramebufferManagerGLES.h"
#include "Core/HLE/sceCtrl.h"
#include "Core/HLE/sceDisplay.h"
@@ -1028,9 +1027,6 @@ void EmuScreen::render() {
if (invalid_)
return;
if (useBufferedRendering && GetGPUBackend() == GPUBackend::OPENGL)
fbo_unbind();
if (!osm.IsEmpty() || g_Config.bShowDebugStats || g_Config.iShowFPSCounter || g_Config.bShowTouchControls || g_Config.bShowDeveloperMenu || g_Config.bShowAudioDebug || saveStatePreview_->GetVisibility() != UI::V_GONE || g_Config.bShowFrameProfiler) {
DrawContext *thin3d = screenManager()->getDrawContext();