mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #9284 from hrydgard/fbo-cleanup-2
Use a common API for framebuffers.
This commit is contained in:
commit
96c450e265
67 changed files with 1328 additions and 1293 deletions
|
@ -814,6 +814,8 @@ add_library(native STATIC
|
|||
ext/native/file/vfs.h
|
||||
ext/native/file/zip_read.cpp
|
||||
ext/native/file/zip_read.h
|
||||
ext/native/gfx/GLStateCache.cpp
|
||||
ext/native/gfx/GLStateCache.h
|
||||
ext/native/gfx/gl_common.h
|
||||
ext/native/gfx/gl_debug_log.cpp
|
||||
ext/native/gfx/gl_debug_log.h
|
||||
|
@ -1080,12 +1082,8 @@ endif()
|
|||
set(GPU_GLES
|
||||
GPU/GLES/DepalettizeShaderGLES.cpp
|
||||
GPU/GLES/DepalettizeShaderGLES.h
|
||||
GPU/GLES/FBO.cpp
|
||||
GPU/GLES/FBO.h
|
||||
GPU/GLES/GPU_GLES.cpp
|
||||
GPU/GLES/GPU_GLES.h
|
||||
GPU/GLES/GLStateCache.cpp
|
||||
GPU/GLES/GLStateCache.h
|
||||
GPU/GLES/FragmentShaderGeneratorGLES.cpp
|
||||
GPU/GLES/FragmentShaderGeneratorGLES.h
|
||||
GPU/GLES/FragmentTestCacheGLES.cpp
|
||||
|
@ -1156,8 +1154,6 @@ set(GPU_D3D9
|
|||
GPU/Directx9/TextureScalerDX9.h
|
||||
GPU/Directx9/VertexShaderGeneratorDX9.cpp
|
||||
GPU/Directx9/VertexShaderGeneratorDX9.h
|
||||
GPU/Directx9/helper/dx_fbo.cpp
|
||||
GPU/Directx9/helper/dx_fbo.h
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
// Needs casting to the appropriate type, unfortunately. Should find a better solution..
|
||||
virtual void *GetAPIContext() { return nullptr; }
|
||||
|
||||
virtual Draw::DrawContext *CreateDrawContext() = 0;
|
||||
virtual Draw::DrawContext *GetDrawContext() = 0;
|
||||
};
|
||||
|
||||
class DummyGraphicsContext : public GraphicsContext {
|
||||
|
@ -35,5 +35,5 @@ public:
|
|||
void SwapBuffers() override {}
|
||||
void Resize() override {}
|
||||
|
||||
Draw::DrawContext *CreateDrawContext() override { return nullptr; }
|
||||
Draw::DrawContext *GetDrawContext() override { return nullptr; }
|
||||
};
|
|
@ -230,13 +230,7 @@ bool TakeGameScreenshot(const char *filename, ScreenshotFormat fmt, ScreenshotTy
|
|||
w = maxRes > 0 ? 480 * maxRes : PSP_CoreParameter().renderWidth;
|
||||
h = maxRes > 0 ? 272 * maxRes : PSP_CoreParameter().renderHeight;
|
||||
} else {
|
||||
if (GetGPUBackend() == GPUBackend::OPENGL) {
|
||||
success = GPU_GLES::GetOutputFramebuffer(buf);
|
||||
#ifdef _WIN32
|
||||
} else if (GetGPUBackend() == GPUBackend::DIRECT3D9) {
|
||||
success = DX9::GPU_DX9::GetOutputFramebuffer(buf);
|
||||
#endif
|
||||
}
|
||||
success = gpuDebug->GetOutputFramebuffer(buf);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "Common/Log.h"
|
||||
#include "Core/Reporting.h"
|
||||
#include "GPU/GPUState.h"
|
||||
#include "GPU/GLES/GLStateCache.h"
|
||||
#include "ext/native/gfx/GLStateCache.h"
|
||||
#include "GPU/Common/DepalettizeShaderCommon.h"
|
||||
|
||||
|
||||
|
|
|
@ -46,9 +46,8 @@ enum {
|
|||
FBO_READFBOMEMORY_MIN = 2
|
||||
};
|
||||
|
||||
struct FBO;
|
||||
namespace DX9 {
|
||||
struct FBO_DX9;
|
||||
namespace Draw {
|
||||
class Framebuffer;
|
||||
}
|
||||
|
||||
class VulkanFBO;
|
||||
|
@ -91,11 +90,7 @@ struct VirtualFramebuffer {
|
|||
|
||||
// TODO: Handle fbo and colorDepth better.
|
||||
u8 colorDepth;
|
||||
union {
|
||||
FBO *fbo;
|
||||
DX9::FBO_DX9 *fbo_dx9;
|
||||
VulkanFBO *fbo_vk;
|
||||
};
|
||||
Draw::Framebuffer *fbo;
|
||||
|
||||
u16 drawnWidth;
|
||||
u16 drawnHeight;
|
||||
|
|
|
@ -237,6 +237,10 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
virtual bool GetOutputFramebuffer(GPUDebugBuffer &buffer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// cached framebuffers / textures / vertices?
|
||||
// get content of specific framebuffer / texture?
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include <map>
|
||||
#include <d3d9.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "Common/Log.h"
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include <map>
|
||||
#include <d3d9.h>
|
||||
|
||||
#include <d3d9.h>
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "GPU/ge_constants.h"
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "math/lin/matrix4x4.h"
|
||||
#include "ext/native/thin3d/thin3d.h"
|
||||
|
||||
#include "Common/ColorConv.h"
|
||||
#include "Core/Host.h"
|
||||
|
@ -28,8 +29,6 @@
|
|||
#include "GPU/Debugger/Stepping.h"
|
||||
|
||||
#include "gfx/d3d9_state.h"
|
||||
#include "helper/dx_fbo.h"
|
||||
|
||||
#include "GPU/Common/FramebufferCommon.h"
|
||||
#include "GPU/Common/TextureDecoder.h"
|
||||
#include "GPU/Directx9/FramebufferDX9.h"
|
||||
|
@ -165,7 +164,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
drawPixelsTex_->Release();
|
||||
}
|
||||
for (auto it = tempFBOs_.begin(), end = tempFBOs_.end(); it != end; ++it) {
|
||||
fbo_destroy(it->second.fbo);
|
||||
delete it->second.fbo;
|
||||
}
|
||||
for (auto it = offscreenSurfaces_.begin(), end = offscreenSurfaces_.end(); it != end; ++it) {
|
||||
it->second.surface->Release();
|
||||
|
@ -262,8 +261,8 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
}
|
||||
|
||||
void FramebufferManagerDX9::DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) {
|
||||
if (useBufferedRendering_ && vfb && vfb->fbo_dx9) {
|
||||
fbo_bind_as_render_target(vfb->fbo_dx9);
|
||||
if (useBufferedRendering_ && vfb && vfb->fbo) {
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo);
|
||||
D3DVIEWPORT9 vp{ 0, 0, vfb->renderWidth, vfb->renderHeight, 0.0f, 1.0f };
|
||||
pD3Ddevice->SetViewport(&vp);
|
||||
} else {
|
||||
|
@ -349,9 +348,9 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
|
||||
void FramebufferManagerDX9::DestroyFramebuf(VirtualFramebuffer *v) {
|
||||
textureCache_->NotifyFramebuffer(v->fb_address, v, NOTIFY_FB_DESTROYED);
|
||||
if (v->fbo_dx9) {
|
||||
fbo_destroy(v->fbo_dx9);
|
||||
v->fbo_dx9 = 0;
|
||||
if (v->fbo) {
|
||||
delete v->fbo;
|
||||
v->fbo = nullptr;
|
||||
}
|
||||
|
||||
// Wipe some pointers
|
||||
|
@ -368,10 +367,10 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
}
|
||||
|
||||
void FramebufferManagerDX9::RebindFramebuffer() {
|
||||
if (currentRenderVfb_ && currentRenderVfb_->fbo_dx9) {
|
||||
fbo_bind_as_render_target(currentRenderVfb_->fbo_dx9);
|
||||
if (currentRenderVfb_ && currentRenderVfb_->fbo) {
|
||||
draw_->BindFramebufferAsRenderTarget(currentRenderVfb_->fbo);
|
||||
} else {
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -399,49 +398,49 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
}
|
||||
|
||||
if (trueColor) {
|
||||
vfb->colorDepth = FBO_8888;
|
||||
vfb->colorDepth = Draw::FBO_8888;
|
||||
} else {
|
||||
switch (vfb->format) {
|
||||
case GE_FORMAT_4444:
|
||||
vfb->colorDepth = FBO_4444;
|
||||
vfb->colorDepth = Draw::FBO_4444;
|
||||
break;
|
||||
case GE_FORMAT_5551:
|
||||
vfb->colorDepth = FBO_5551;
|
||||
vfb->colorDepth = Draw::FBO_5551;
|
||||
break;
|
||||
case GE_FORMAT_565:
|
||||
vfb->colorDepth = FBO_565;
|
||||
vfb->colorDepth = Draw::FBO_565;
|
||||
break;
|
||||
case GE_FORMAT_8888:
|
||||
default:
|
||||
vfb->colorDepth = FBO_8888;
|
||||
vfb->colorDepth = Draw::FBO_8888;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
textureCache_->ForgetLastTexture();
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
|
||||
if (!useBufferedRendering_) {
|
||||
if (vfb->fbo_dx9) {
|
||||
fbo_destroy(vfb->fbo_dx9);
|
||||
vfb->fbo_dx9 = 0;
|
||||
if (vfb->fbo) {
|
||||
delete vfb->fbo;
|
||||
vfb->fbo = nullptr;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
vfb->fbo_dx9 = fbo_create({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (FBOColorDepth)vfb->colorDepth });
|
||||
if (old.fbo_dx9) {
|
||||
vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (Draw::FBColorDepth)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) {
|
||||
fbo_bind_as_render_target(vfb->fbo_dx9);
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo);
|
||||
ClearBuffer();
|
||||
if (!skipCopy && !g_Config.bDisableSlowFramebufEffects) {
|
||||
BlitFramebuffer(vfb, 0, 0, &old, 0, 0, std::min(vfb->bufferWidth, vfb->width), std::min(vfb->height, vfb->bufferHeight), 0);
|
||||
}
|
||||
}
|
||||
fbo_destroy(old.fbo_dx9);
|
||||
if (vfb->fbo_dx9) {
|
||||
fbo_bind_as_render_target(vfb->fbo_dx9);
|
||||
delete old.fbo;
|
||||
if (vfb->fbo) {
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -452,7 +451,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
|
||||
void FramebufferManagerDX9::NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb) {
|
||||
if (!useBufferedRendering_) {
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
// Let's ignore rendering to targets that have not (yet) been displayed.
|
||||
gstate_c.skipDrawReason |= SKIPDRAW_NON_DISPLAYED_FB;
|
||||
}
|
||||
|
@ -480,20 +479,20 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
textureCache_->ForgetLastTexture();
|
||||
|
||||
if (useBufferedRendering_) {
|
||||
if (vfb->fbo_dx9) {
|
||||
fbo_bind_as_render_target(vfb->fbo_dx9);
|
||||
if (vfb->fbo) {
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo);
|
||||
} else {
|
||||
// wtf? This should only happen very briefly when toggling bBufferedRendering
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
}
|
||||
} else {
|
||||
if (vfb->fbo_dx9) {
|
||||
if (vfb->fbo) {
|
||||
// wtf? This should only happen very briefly when toggling bBufferedRendering
|
||||
textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_DESTROYED);
|
||||
fbo_destroy(vfb->fbo_dx9);
|
||||
vfb->fbo_dx9 = nullptr;
|
||||
delete vfb->fbo;
|
||||
vfb->fbo = nullptr;
|
||||
}
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
|
||||
// Let's ignore rendering to targets that have not (yet) been displayed.
|
||||
if (vfb->usageFlags & FB_USAGE_DISPLAYED_FRAMEBUFFER) {
|
||||
|
@ -506,7 +505,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
|
||||
// Copy depth pixel value from the read framebuffer to the draw framebuffer
|
||||
if (prevVfb && !g_Config.bDisableSlowFramebufEffects) {
|
||||
if (!prevVfb->fbo_dx9 || !vfb->fbo_dx9 || !useBufferedRendering_ || !prevVfb->depthUpdated || isClearingDepth) {
|
||||
if (!prevVfb->fbo || !vfb->fbo || !useBufferedRendering_ || !prevVfb->depthUpdated || isClearingDepth) {
|
||||
// If depth wasn't updated, then we're at least "two degrees" away from the data.
|
||||
// This is an optimization: it probably doesn't need to be copied in this case.
|
||||
} else {
|
||||
|
@ -547,11 +546,11 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
}
|
||||
|
||||
void FramebufferManagerDX9::ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) {
|
||||
if (!useBufferedRendering_ || !vfb->fbo_dx9) {
|
||||
if (!useBufferedRendering_ || !vfb->fbo) {
|
||||
return;
|
||||
}
|
||||
|
||||
fbo_bind_as_render_target(vfb->fbo_dx9);
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo);
|
||||
|
||||
// Technically, we should at this point re-interpret the bytes of the old format to the new.
|
||||
// That might get tricky, and could cause unnecessary slowness in some games.
|
||||
|
@ -630,10 +629,10 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
bool matchingSize = src->width == dst->width && src->height == dst->height;
|
||||
if (matchingDepthBuffer && matchingSize) {
|
||||
// Doesn't work. Use a shader maybe?
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
|
||||
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);
|
||||
LPDIRECT3DTEXTURE9 srcTex = (LPDIRECT3DTEXTURE9)draw_->GetFramebufferAPITexture(src->fbo, Draw::FB_DEPTH_BIT, 0);
|
||||
LPDIRECT3DTEXTURE9 dstTex = (LPDIRECT3DTEXTURE9)draw_->GetFramebufferAPITexture(dst->fbo, Draw::FB_DEPTH_BIT, 0);
|
||||
|
||||
if (srcTex && dstTex) {
|
||||
D3DSURFACE_DESC srcDesc;
|
||||
|
@ -674,7 +673,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
}
|
||||
}
|
||||
|
||||
FBO_DX9 *FramebufferManagerDX9::GetTempFBO(u16 w, u16 h, FBOColorDepth depth) {
|
||||
Draw::Framebuffer *FramebufferManagerDX9::GetTempFBO(u16 w, u16 h, Draw::FBColorDepth depth) {
|
||||
u64 key = ((u64)depth << 32) | ((u32)w << 16) | h;
|
||||
auto it = tempFBOs_.find(key);
|
||||
if (it != tempFBOs_.end()) {
|
||||
|
@ -683,10 +682,10 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
}
|
||||
|
||||
textureCache_->ForgetLastTexture();
|
||||
FBO_DX9 *fbo = fbo_create({ w, h, 1, 1, false, depth });
|
||||
Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, false, depth });
|
||||
if (!fbo)
|
||||
return fbo;
|
||||
fbo_bind_as_render_target(fbo);
|
||||
draw_->BindFramebufferAsRenderTarget(fbo);
|
||||
dxstate.viewport.force(0, 0, w, h);
|
||||
ClearBuffer(true);
|
||||
dxstate.viewport.restore();
|
||||
|
@ -745,10 +744,10 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
}
|
||||
if (!skipCopy && currentRenderVfb_ && framebuffer->fb_address == gstate.getFrameBufRawAddress()) {
|
||||
// TODO: Maybe merge with bvfbs_? Not sure if those could be packing, and they're created at a different size.
|
||||
FBO_DX9 *renderCopy = GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, (FBOColorDepth)framebuffer->colorDepth);
|
||||
Draw::Framebuffer *renderCopy = GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, (Draw::FBColorDepth)framebuffer->colorDepth);
|
||||
if (renderCopy) {
|
||||
VirtualFramebuffer copyInfo = *framebuffer;
|
||||
copyInfo.fbo_dx9 = renderCopy;
|
||||
copyInfo.fbo = renderCopy;
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
@ -773,19 +772,19 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
BlitFramebuffer(©Info, x, y, framebuffer, x, y, w, h, 0);
|
||||
|
||||
RebindFramebuffer();
|
||||
fbo_bind_as_texture(renderCopy, stage, FB_COLOR_BIT, 0);
|
||||
draw_->BindFramebufferAsTexture(renderCopy, stage, Draw::FB_COLOR_BIT, 0);
|
||||
} else {
|
||||
fbo_bind_as_texture(framebuffer->fbo_dx9, stage, FB_COLOR_BIT, 0);
|
||||
draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0);
|
||||
}
|
||||
} else {
|
||||
fbo_bind_as_texture(framebuffer->fbo_dx9, stage, FB_COLOR_BIT, 0);
|
||||
draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void FramebufferManagerDX9::CopyDisplayToOutput() {
|
||||
DownloadFramebufferOnSwitch(currentRenderVfb_);
|
||||
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
currentRenderVfb_ = 0;
|
||||
|
||||
if (displayFramebufPtr_ == 0) {
|
||||
|
@ -885,7 +884,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
if (vfb->fbo) {
|
||||
DEBUG_LOG(SCEGE, "Displaying FBO %08x", vfb->fb_address);
|
||||
DisableState();
|
||||
fbo_bind_as_texture(vfb->fbo_dx9, 0, FB_COLOR_BIT, 0);
|
||||
draw_->BindFramebufferAsTexture(vfb->fbo, 0, Draw::FB_COLOR_BIT, 0);
|
||||
|
||||
// Output coordinates
|
||||
float x, y, w, h;
|
||||
|
@ -900,12 +899,12 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
if (1) {
|
||||
const u32 rw = PSP_CoreParameter().pixelWidth;
|
||||
const u32 rh = PSP_CoreParameter().pixelHeight;
|
||||
bool result = fbo_blit(vfb->fbo_dx9,
|
||||
bool result = draw_->BlitFramebuffer(vfb->fbo,
|
||||
(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);
|
||||
Draw::FB_COLOR_BIT,
|
||||
g_Config.iBufFilter == SCALE_LINEAR ? Draw::FB_BLIT_LINEAR : Draw::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, 0.0f, 1.0f);
|
||||
|
@ -925,7 +924,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
/*
|
||||
else if (usePostShader_ && extraFBOs_.size() == 1 && !postShaderAtOutputResolution_) {
|
||||
// An additional pass, post-processing shader to the extra FBO.
|
||||
fbo_bind_as_render_target(extraFBOs_[0]);
|
||||
BindFramebufferAsRenderTarget(extraFBOs_[0]);
|
||||
int fbo_w, fbo_h;
|
||||
fbo_get_dimensions(extraFBOs_[0], &fbo_w, &fbo_h);
|
||||
DXSetViewport(0, 0, fbo_w, fbo_h);
|
||||
|
@ -1005,15 +1004,15 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
}
|
||||
|
||||
bool FramebufferManagerDX9::CreateDownloadTempBuffer(VirtualFramebuffer *nvfb) {
|
||||
nvfb->colorDepth = FBO_8888;
|
||||
nvfb->colorDepth = Draw::FBO_8888;
|
||||
|
||||
nvfb->fbo_dx9 = fbo_create({ nvfb->width, nvfb->height, 1, 1, true, (FBOColorDepth)nvfb->colorDepth });
|
||||
if (!(nvfb->fbo_dx9)) {
|
||||
nvfb->fbo = draw_->CreateFramebuffer({ nvfb->width, nvfb->height, 1, 1, true, (Draw::FBColorDepth)nvfb->colorDepth });
|
||||
if (!(nvfb->fbo)) {
|
||||
ERROR_LOG(SCEGE, "Error creating FBO! %i x %i", nvfb->renderWidth, nvfb->renderHeight);
|
||||
return false;
|
||||
}
|
||||
|
||||
fbo_bind_as_render_target(nvfb->fbo_dx9);
|
||||
draw_->BindFramebufferAsRenderTarget(nvfb->fbo);
|
||||
ClearBuffer();
|
||||
return true;
|
||||
}
|
||||
|
@ -1025,7 +1024,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
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_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1052,23 +1051,23 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
int dstY2 = (dstY + h) * dstYFactor;
|
||||
|
||||
// Direct3D 9 doesn't support rect -> self.
|
||||
FBO_DX9 *srcFBO = src->fbo_dx9;
|
||||
Draw::Framebuffer *srcFBO = src->fbo;
|
||||
if (src == dst) {
|
||||
FBO_DX9 *tempFBO = GetTempFBO(src->renderWidth, src->renderHeight, (FBOColorDepth)src->colorDepth);
|
||||
HRESULT hr = fbo_blit(
|
||||
src->fbo_dx9, srcX1, srcY1, srcX2, srcY2,
|
||||
Draw::Framebuffer *tempFBO = GetTempFBO(src->renderWidth, src->renderHeight, (Draw::FBColorDepth)src->colorDepth);
|
||||
bool result = draw_->BlitFramebuffer(
|
||||
src->fbo, srcX1, srcY1, srcX2, srcY2,
|
||||
tempFBO, dstX1, dstY1, dstX2, dstY2,
|
||||
FB_COLOR_BIT, FB_BLIT_NEAREST);
|
||||
if (SUCCEEDED(hr)) {
|
||||
Draw::FB_COLOR_BIT, Draw::FB_BLIT_NEAREST);
|
||||
if (result) {
|
||||
srcFBO = tempFBO;
|
||||
}
|
||||
}
|
||||
HRESULT hr = fbo_blit(
|
||||
bool result = draw_->BlitFramebuffer(
|
||||
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);
|
||||
dst->fbo, dstX1, dstY1, dstX2, dstY2,
|
||||
Draw::FB_COLOR_BIT, Draw::FB_BLIT_NEAREST);
|
||||
if (!result) {
|
||||
ERROR_LOG_REPORT(G3D, "fbo_blit_color failed in blit: %08x (%08x -> %08x)", src->fb_address, dst->fb_address);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1125,7 +1124,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
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_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1136,7 +1135,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
// Right now that's always 8888.
|
||||
DEBUG_LOG(HLE, "Reading framebuffer to mem, fb_address = %08x", fb_address);
|
||||
|
||||
LPDIRECT3DSURFACE9 renderTarget = (LPDIRECT3DSURFACE9)fbo_get_api_texture(vfb->fbo_dx9, FB_COLOR_BIT | FB_SURFACE_BIT, 0);
|
||||
LPDIRECT3DSURFACE9 renderTarget = (LPDIRECT3DSURFACE9)draw_->GetFramebufferAPITexture(vfb->fbo, Draw::FB_COLOR_BIT | Draw::FB_SURFACE_BIT, 0);
|
||||
D3DSURFACE_DESC desc;
|
||||
renderTarget->GetDesc(&desc);
|
||||
|
||||
|
@ -1175,7 +1174,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
|
||||
DEBUG_LOG(SCEGE, "Reading depthbuffer to mem at %08x for vfb=%08x", z_address, vfb->fb_address);
|
||||
|
||||
LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)fbo_get_api_texture(vfb->fbo_dx9, FB_DEPTH_BIT, 0);
|
||||
LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)draw_->GetFramebufferAPITexture(vfb->fbo, Draw::FB_DEPTH_BIT, 0);
|
||||
if (tex) {
|
||||
D3DSURFACE_DESC desc;
|
||||
D3DLOCKED_RECT locked;
|
||||
|
@ -1273,7 +1272,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
|
||||
void FramebufferManagerDX9::DecimateFBOs() {
|
||||
if (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) {
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
}
|
||||
currentRenderVfb_ = 0;
|
||||
bool updateVram = !(g_Config.iRenderingMode == FB_NON_BUFFERED_MODE || g_Config.iRenderingMode == FB_BUFFERED_MODE);
|
||||
|
@ -1302,7 +1301,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
for (auto it = tempFBOs_.begin(); it != tempFBOs_.end(); ) {
|
||||
int age = frameLastFramebufUsed_ - it->second.last_frame_used;
|
||||
if (age > FBO_OLD_AGE) {
|
||||
fbo_destroy(it->second.fbo);
|
||||
delete it->second.fbo;
|
||||
tempFBOs_.erase(it++);
|
||||
} else {
|
||||
++it;
|
||||
|
@ -1332,7 +1331,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
}
|
||||
|
||||
void FramebufferManagerDX9::DestroyAllFBOs(bool forceDelete) {
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
currentRenderVfb_ = 0;
|
||||
displayFramebuf_ = 0;
|
||||
prevDisplayFramebuf_ = 0;
|
||||
|
@ -1352,7 +1351,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
bvfbs_.clear();
|
||||
|
||||
for (auto it = tempFBOs_.begin(), end = tempFBOs_.end(); it != end; ++it) {
|
||||
fbo_destroy(it->second.fbo);
|
||||
delete it->second.fbo;
|
||||
}
|
||||
tempFBOs_.clear();
|
||||
|
||||
|
@ -1393,19 +1392,19 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
buffer = GPUDebugBuffer(Memory::GetPointer(fb_address | 0x04000000), fb_stride, 512, fb_format);
|
||||
return true;
|
||||
}
|
||||
LPDIRECT3DSURFACE9 renderTarget = vfb->fbo_dx9 ? (LPDIRECT3DSURFACE9)fbo_get_api_texture(vfb->fbo_dx9, FB_COLOR_BIT | FB_SURFACE_BIT, 0) : nullptr;
|
||||
LPDIRECT3DSURFACE9 renderTarget = vfb->fbo ? (LPDIRECT3DSURFACE9)draw_->GetFramebufferAPITexture(vfb->fbo, Draw::FB_COLOR_BIT | Draw::FB_SURFACE_BIT, 0) : nullptr;
|
||||
bool success = false;
|
||||
if (renderTarget) {
|
||||
FBO_DX9 *tempFBO = nullptr;
|
||||
Draw::Framebuffer *tempFBO = nullptr;
|
||||
int w = vfb->renderWidth, h = vfb->renderHeight;
|
||||
|
||||
if (maxRes > 0 && vfb->renderWidth > vfb->width * maxRes) {
|
||||
// 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, 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);
|
||||
tempFBO = draw_->CreateFramebuffer({ w, h, 1, 1, false, Draw::FBO_8888 });
|
||||
if (draw_->BlitFramebuffer(vfb->fbo, 0, 0, vfb->renderWidth, vfb->renderHeight, tempFBO, 0, 0, w, h, Draw::FB_COLOR_BIT, g_Config.iBufFilter == SCALE_LINEAR ? Draw::FB_BLIT_LINEAR : Draw::FB_BLIT_NEAREST)) {
|
||||
renderTarget = (LPDIRECT3DSURFACE9)draw_->GetFramebufferAPITexture(tempFBO, Draw::FB_COLOR_BIT | Draw::FB_SURFACE_BIT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1414,7 +1413,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
success = GetRenderTargetFramebuffer(renderTarget, offscreen, w, h, buffer);
|
||||
}
|
||||
if (tempFBO) {
|
||||
fbo_destroy(tempFBO);
|
||||
delete tempFBO;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1422,7 +1421,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
}
|
||||
|
||||
bool FramebufferManagerDX9::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
|
||||
LPDIRECT3DSURFACE9 renderTarget = nullptr;
|
||||
HRESULT hr = pD3Ddevice->GetRenderTarget(0, &renderTarget);
|
||||
|
@ -1484,7 +1483,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
}
|
||||
|
||||
bool success = false;
|
||||
LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)fbo_get_api_texture(vfb->fbo_dx9, FB_DEPTH_BIT, 0);
|
||||
LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)draw_->GetFramebufferAPITexture(vfb->fbo, Draw::FB_DEPTH_BIT, 0);
|
||||
if (tex) {
|
||||
D3DSURFACE_DESC desc;
|
||||
D3DLOCKED_RECT locked;
|
||||
|
@ -1528,7 +1527,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
|
|||
}
|
||||
|
||||
bool success = false;
|
||||
LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)fbo_get_api_texture(vfb->fbo_dx9, FB_DEPTH_BIT, 0);
|
||||
LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)draw_->GetFramebufferAPITexture(vfb->fbo, Draw::FB_DEPTH_BIT, 0);
|
||||
if (tex) {
|
||||
D3DSURFACE_DESC desc;
|
||||
D3DLOCKED_RECT locked;
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
#include "d3d9.h"
|
||||
|
||||
#include "GPU/Directx9/helper/dx_fbo.h"
|
||||
// Keeps track of allocated FBOs.
|
||||
// Also provides facilities for drawing and later converting raw
|
||||
// pixel data.
|
||||
|
@ -33,6 +32,7 @@
|
|||
#include "GPU/GPUCommon.h"
|
||||
#include "GPU/Common/FramebufferCommon.h"
|
||||
#include "Core/Config.h"
|
||||
#include "ext/native/thin3d/thin3d.h"
|
||||
|
||||
namespace DX9 {
|
||||
|
||||
|
@ -85,11 +85,11 @@ public:
|
|||
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes);
|
||||
bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer);
|
||||
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer);
|
||||
static bool GetOutputFramebuffer(GPUDebugBuffer &buffer);
|
||||
bool GetOutputFramebuffer(GPUDebugBuffer &buffer);
|
||||
|
||||
virtual void RebindFramebuffer() override;
|
||||
|
||||
FBO_DX9 *GetTempFBO(u16 w, u16 h, FBOColorDepth depth = FBO_8888);
|
||||
Draw::Framebuffer *GetTempFBO(u16 w, u16 h, Draw::FBColorDepth depth = Draw::FBO_8888);
|
||||
LPDIRECT3DSURFACE9 GetOffscreenSurface(LPDIRECT3DSURFACE9 similarSurface, VirtualFramebuffer *vfb);
|
||||
LPDIRECT3DSURFACE9 GetOffscreenSurface(D3DFORMAT fmt, u32 w, u32 h);
|
||||
|
||||
|
@ -142,12 +142,12 @@ private:
|
|||
DrawEngineDX9 *drawEngine_;
|
||||
|
||||
// Used by post-processing shader
|
||||
std::vector<FBO *> extraFBOs_;
|
||||
std::vector<Draw::Framebuffer *> extraFBOs_;
|
||||
|
||||
bool resized_;
|
||||
|
||||
struct TempFBO {
|
||||
FBO_DX9 *fbo;
|
||||
Draw::Framebuffer *fbo;
|
||||
int last_frame_used;
|
||||
};
|
||||
struct OffscreenSurface {
|
||||
|
|
|
@ -520,12 +520,10 @@ GPU_DX9::~GPU_DX9() {
|
|||
// Needs to be called on GPU thread, not reporting thread.
|
||||
void GPU_DX9::BuildReportingInfo() {
|
||||
using namespace Draw;
|
||||
DrawContext *thin3d = gfxCtx_->CreateDrawContext();
|
||||
DrawContext *thin3d = gfxCtx_->GetDrawContext();
|
||||
|
||||
reportingPrimaryInfo_ = thin3d->GetInfoString(InfoField::VENDORSTRING);
|
||||
reportingFullInfo_ = reportingPrimaryInfo_ + " - " + System_GetProperty(SYSPROP_GPUDRIVER_VERSION) + " - " + thin3d->GetInfoString(InfoField::SHADELANGVERSION);
|
||||
|
||||
thin3d->Release();
|
||||
}
|
||||
|
||||
void GPU_DX9::DeviceLost() {
|
||||
|
@ -1082,7 +1080,7 @@ bool GPU_DX9::GetCurrentClut(GPUDebugBuffer &buffer) {
|
|||
}
|
||||
|
||||
bool GPU_DX9::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
|
||||
return FramebufferManagerDX9::GetOutputFramebuffer(buffer);
|
||||
return framebufferManagerDX9_->GetOutputFramebuffer(buffer);
|
||||
}
|
||||
|
||||
bool GPU_DX9::GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices) {
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "GPU/Directx9/DrawEngineDX9.h"
|
||||
#include "GPU/Directx9/TextureCacheDX9.h"
|
||||
#include "GPU/Directx9/DepalettizeShaderDX9.h"
|
||||
#include "GPU/Directx9/helper/dx_fbo.h"
|
||||
#include "GPU/Common/VertexDecoderCommon.h"
|
||||
|
||||
namespace DX9 {
|
||||
|
@ -71,7 +70,7 @@ public:
|
|||
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer) override;
|
||||
bool GetCurrentTexture(GPUDebugBuffer &buffer, int level) override;
|
||||
bool GetCurrentClut(GPUDebugBuffer &buffer) override;
|
||||
static bool GetOutputFramebuffer(GPUDebugBuffer &buffer);
|
||||
bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override;
|
||||
bool GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices) override;
|
||||
|
||||
typedef void (GPU_DX9::*CmdFunc)(u32 op, u32 diff);
|
||||
|
|
4
GPU/Directx9/StateMappingDX9.h
Normal file
4
GPU/Directx9/StateMappingDX9.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
#include "helper/global.h"
|
||||
#include "ext/native/gfx/dx_state.h"
|
|
@ -15,10 +15,12 @@
|
|||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include <d3d9.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
|
||||
#include "gfx/d3d9_state.h"
|
||||
#include "helper/dx_fbo.h"
|
||||
#include "ext/native/thin3d/thin3d.h"
|
||||
#include "Core/Reporting.h"
|
||||
#include "GPU/Directx9/FramebufferDX9.h"
|
||||
#include "GPU/Directx9/PixelShaderGeneratorDX9.h"
|
||||
|
@ -218,8 +220,8 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, bool skipZer
|
|||
u16 w = dstBuffer->renderWidth;
|
||||
u16 h = dstBuffer->renderHeight;
|
||||
|
||||
if (dstBuffer->fbo_dx9) {
|
||||
fbo_bind_as_render_target(dstBuffer->fbo_dx9);
|
||||
if (dstBuffer->fbo) {
|
||||
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo);
|
||||
}
|
||||
D3DVIEWPORT9 vp{ 0, 0, w, h, 0.0f, 1.0f };
|
||||
pD3Ddevice->SetViewport(&vp);
|
||||
|
|
|
@ -573,9 +573,9 @@ void TextureCacheDX9::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebu
|
|||
|
||||
nextTexture_ = entry;
|
||||
} else {
|
||||
if (framebuffer->fbo_dx9) {
|
||||
fbo_destroy(framebuffer->fbo_dx9);
|
||||
framebuffer->fbo_dx9 = 0;
|
||||
if (framebuffer->fbo) {
|
||||
delete framebuffer->fbo;
|
||||
framebuffer->fbo = nullptr;
|
||||
}
|
||||
pD3Ddevice->SetTexture(0, NULL);
|
||||
gstate_c.needShaderTexClamp = false;
|
||||
|
@ -779,8 +779,8 @@ void TextureCacheDX9::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFrame
|
|||
if (pshader) {
|
||||
LPDIRECT3DTEXTURE9 clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_);
|
||||
|
||||
FBO_DX9 *depalFBO = framebufferManager_->GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, FBO_8888);
|
||||
fbo_bind_as_render_target(depalFBO);
|
||||
Draw::Framebuffer *depalFBO = framebufferManager_->GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, Draw::FBO_8888);
|
||||
draw_->BindFramebufferAsRenderTarget(depalFBO);
|
||||
shaderManager_->DirtyLastShader();
|
||||
|
||||
float xoff = -0.5f / framebuffer->renderWidth;
|
||||
|
@ -802,7 +802,7 @@ void TextureCacheDX9::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFrame
|
|||
|
||||
shaderApply.Shade();
|
||||
|
||||
fbo_bind_as_texture(depalFBO, 0, FB_COLOR_BIT, 0);
|
||||
draw_->BindFramebufferAsTexture(depalFBO, 0, Draw::FB_COLOR_BIT, 0);
|
||||
|
||||
const u32 bytesPerColor = clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16);
|
||||
const u32 clutTotalColors = clutMaxBytes_ / bytesPerColor;
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <d3d9.h>
|
||||
|
||||
#include "../Globals.h"
|
||||
#include "helper/dx_fbo.h"
|
||||
#include "GPU/GPU.h"
|
||||
#include "GPU/GPUInterface.h"
|
||||
#include "GPU/Directx9/TextureScalerDX9.h"
|
||||
|
|
|
@ -1,195 +0,0 @@
|
|||
// Copyright (c) 2012- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "dx_fbo.h"
|
||||
#include "gfx/d3d9_state.h"
|
||||
|
||||
namespace DX9 {
|
||||
|
||||
struct FBO_DX9 {
|
||||
uint32_t id;
|
||||
LPDIRECT3DSURFACE9 surf;
|
||||
LPDIRECT3DSURFACE9 depthstencil;
|
||||
LPDIRECT3DTEXTURE9 tex;
|
||||
LPDIRECT3DTEXTURE9 depthstenciltex;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
DX9::FBOColorDepth colorDepth;
|
||||
};
|
||||
|
||||
static LPDIRECT3DSURFACE9 deviceRTsurf;
|
||||
static LPDIRECT3DSURFACE9 deviceDSsurf;
|
||||
static bool supportsINTZ = false;
|
||||
static LPDIRECT3DDEVICE9 g_device;
|
||||
#define FB_DIV 1
|
||||
#define FOURCC_INTZ ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z')))
|
||||
|
||||
void fbo_init(LPDIRECT3D9 d3d, LPDIRECT3DDEVICE9 device) {
|
||||
g_device = device;
|
||||
g_device->GetRenderTarget(0, &deviceRTsurf);
|
||||
g_device->GetDepthStencilSurface(&deviceDSsurf);
|
||||
|
||||
if (d3d) {
|
||||
D3DDISPLAYMODE displayMode;
|
||||
d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode);
|
||||
|
||||
// To be safe, make sure both the display format and the FBO format support INTZ.
|
||||
HRESULT displayINTZ = d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, displayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_INTZ);
|
||||
HRESULT fboINTZ = d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_INTZ);
|
||||
supportsINTZ = SUCCEEDED(displayINTZ) && SUCCEEDED(fboINTZ);
|
||||
}
|
||||
}
|
||||
|
||||
void fbo_shutdown() {
|
||||
deviceRTsurf->Release();
|
||||
deviceDSsurf->Release();
|
||||
}
|
||||
|
||||
FBO_DX9 *fbo_create(const FramebufferDesc &desc) {
|
||||
static uint32_t id = 0;
|
||||
|
||||
FBO_DX9 *fbo = new FBO_DX9();
|
||||
fbo->width = desc.width;
|
||||
fbo->height = desc.height;
|
||||
fbo->colorDepth = desc.colorDepth;
|
||||
fbo->depthstenciltex = nullptr;
|
||||
|
||||
HRESULT rtResult = g_device->CreateTexture(fbo->width, fbo->height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &fbo->tex, NULL);
|
||||
if (FAILED(rtResult)) {
|
||||
ELOG("Failed to create render target");
|
||||
delete fbo;
|
||||
return NULL;
|
||||
}
|
||||
fbo->tex->GetSurfaceLevel(0, &fbo->surf);
|
||||
|
||||
HRESULT dsResult;
|
||||
if (supportsINTZ) {
|
||||
dsResult = g_device->CreateTexture(fbo->width, fbo->height, 1, D3DUSAGE_DEPTHSTENCIL, FOURCC_INTZ, D3DPOOL_DEFAULT, &fbo->depthstenciltex, NULL);
|
||||
if (SUCCEEDED(dsResult)) {
|
||||
dsResult = fbo->depthstenciltex->GetSurfaceLevel(0, &fbo->depthstencil);
|
||||
}
|
||||
} else {
|
||||
dsResult = g_device->CreateDepthStencilSurface(fbo->width, fbo->height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->depthstencil, NULL);
|
||||
}
|
||||
if (FAILED(dsResult)) {
|
||||
ELOG("Failed to create depth buffer");
|
||||
fbo->surf->Release();
|
||||
fbo->tex->Release();
|
||||
if (fbo->depthstenciltex) {
|
||||
fbo->depthstenciltex->Release();
|
||||
}
|
||||
delete fbo;
|
||||
return NULL;
|
||||
}
|
||||
fbo->id = id++;
|
||||
return fbo;
|
||||
}
|
||||
|
||||
void fbo_destroy(FBO_DX9 *fbo) {
|
||||
fbo->tex->Release();
|
||||
fbo->surf->Release();
|
||||
fbo->depthstencil->Release();
|
||||
if (fbo->depthstenciltex) {
|
||||
fbo->depthstenciltex->Release();
|
||||
}
|
||||
delete fbo;
|
||||
}
|
||||
|
||||
void fbo_bind_backbuffer_as_render_target() {
|
||||
g_device->SetRenderTarget(0, deviceRTsurf);
|
||||
g_device->SetDepthStencilSurface(deviceDSsurf);
|
||||
dxstate.scissorRect.restore();
|
||||
dxstate.viewport.restore();
|
||||
}
|
||||
|
||||
void fbo_resolve(FBO_DX9 *fbo) {
|
||||
}
|
||||
|
||||
void fbo_bind_as_render_target(FBO_DX9 *fbo) {
|
||||
g_device->SetRenderTarget(0, fbo->surf);
|
||||
g_device->SetDepthStencilSurface(fbo->depthstencil);
|
||||
dxstate.scissorRect.restore();
|
||||
dxstate.viewport.restore();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void fbo_bind_as_texture(FBO_DX9 *fbo, int binding, FBOChannel channelBit, int color) {
|
||||
switch (channelBit) {
|
||||
case FB_DEPTH_BIT:
|
||||
if (fbo->depthstenciltex) {
|
||||
g_device->SetTexture(binding, fbo->depthstenciltex);
|
||||
}
|
||||
break;
|
||||
case FB_COLOR_BIT:
|
||||
default:
|
||||
if (fbo->tex) {
|
||||
g_device->SetTexture(binding, fbo->tex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void fbo_get_dimensions(FBO_DX9 *fbo, int *w, int *h) {
|
||||
*w = fbo->width;
|
||||
*h = fbo->height;
|
||||
}
|
||||
|
||||
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 SUCCEEDED(g_device->StretchRect(srcSurf, &srcRect, dstSurf, &dstRect, filter == FB_BLIT_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT));
|
||||
}
|
||||
|
||||
} // namespace
|
|
@ -1,85 +0,0 @@
|
|||
// Copyright (c) 2012- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <d3d9.h>
|
||||
|
||||
// Simple wrapper around FBO functionality.
|
||||
// Very C-ish API because that's what I felt like, and it's cool to completely
|
||||
// hide the data from callers...
|
||||
|
||||
namespace DX9 {
|
||||
|
||||
struct FBO_DX9;
|
||||
|
||||
enum FBOColorDepth {
|
||||
FBO_8888,
|
||||
FBO_565,
|
||||
FBO_4444,
|
||||
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.
|
||||
// num_color_textures must be 1 for now.
|
||||
// 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(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.
|
||||
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);
|
||||
|
||||
// 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, LPDIRECT3DDEVICE9 device);
|
||||
void fbo_shutdown();
|
||||
|
||||
};
|
|
@ -22,7 +22,7 @@
|
|||
#include "Core/Reporting.h"
|
||||
#include "DepalettizeShaderGLES.h"
|
||||
#include "GPU/GLES/TextureCacheGLES.h"
|
||||
#include "GPU/GLES/GLStateCache.h"
|
||||
#include "ext/native/gfx/GLStateCache.h"
|
||||
#include "GPU/Common/DepalettizeShaderCommon.h"
|
||||
|
||||
static const int DEPAL_TEXTURE_OLD_AGE = 120;
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
#include "GPU/Common/SplineCommon.h"
|
||||
#include "GPU/Common/VertexDecoderCommon.h"
|
||||
#include "GPU/Common/SoftwareTransformCommon.h"
|
||||
#include "GPU/GLES/GLStateCache.h"
|
||||
#include "ext/native/gfx/GLStateCache.h"
|
||||
#include "GPU/GLES/FragmentTestCacheGLES.h"
|
||||
#include "GPU/GLES/StateMappingGLES.h"
|
||||
#include "GPU/GLES/TextureCacheGLES.h"
|
||||
|
|
429
GPU/GLES/FBO.cpp
429
GPU/GLES/FBO.cpp
|
@ -1,429 +0,0 @@
|
|||
// Copyright (c) 2012- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "gfx/gl_common.h"
|
||||
|
||||
#include "GPU/GLES/GLStateCache.h"
|
||||
#include "GPU/GLES/FBO.h"
|
||||
|
||||
#ifdef IOS
|
||||
extern void bindDefaultFBO();
|
||||
#endif
|
||||
|
||||
struct FBO {
|
||||
GLuint handle;
|
||||
GLuint color_texture;
|
||||
GLuint z_stencil_buffer; // Either this is set, or the two below.
|
||||
GLuint z_buffer;
|
||||
GLuint stencil_buffer;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
FBOColorDepth colorDepth;
|
||||
};
|
||||
|
||||
static GLuint currentDrawHandle_ = 0;
|
||||
static GLuint currentReadHandle_ = 0;
|
||||
|
||||
// On PC, we always use GL_DEPTH24_STENCIL8.
|
||||
// On Android, we try to use what's available.
|
||||
|
||||
#ifndef USING_GLES2
|
||||
FBO *fbo_ext_create(const FramebufferDesc &desc) {
|
||||
FBO *fbo = new FBO();
|
||||
fbo->width = desc.width;
|
||||
fbo->height = desc.height;
|
||||
fbo->colorDepth = desc.colorDepth;
|
||||
|
||||
// Color texture is same everywhere
|
||||
glGenFramebuffersEXT(1, &fbo->handle);
|
||||
glGenTextures(1, &fbo->color_texture);
|
||||
|
||||
// Create the surfaces.
|
||||
glBindTexture(GL_TEXTURE_2D, fbo->color_texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
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 (fbo->colorDepth) {
|
||||
case FBO_8888:
|
||||
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, 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, 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, fbo->width, fbo->height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
fbo->stencil_buffer = 0;
|
||||
fbo->z_buffer = 0;
|
||||
// 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, fbo->width, fbo->height);
|
||||
//glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8, width, height);
|
||||
|
||||
// Bind it all together
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->handle);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbo->color_texture, 0);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->z_stencil_buffer);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->z_stencil_buffer);
|
||||
|
||||
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
switch(status) {
|
||||
case GL_FRAMEBUFFER_COMPLETE_EXT:
|
||||
// ILOG("Framebuffer verified complete.");
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||
ELOG("GL_FRAMEBUFFER_UNSUPPORTED");
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
|
||||
ELOG("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT ");
|
||||
break;
|
||||
default:
|
||||
FLOG("Other framebuffer error: %i", status);
|
||||
break;
|
||||
}
|
||||
// Unbind state we don't need
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
currentDrawHandle_ = fbo->handle;
|
||||
currentReadHandle_ = fbo->handle;
|
||||
return fbo;
|
||||
}
|
||||
#endif
|
||||
|
||||
int fbo_preferred_z_bitdepth() {
|
||||
// This matches the fbo_create() logic.
|
||||
if (gl_extensions.IsGLES) {
|
||||
if (gl_extensions.OES_packed_depth_stencil) {
|
||||
return 24;
|
||||
}
|
||||
return gl_extensions.OES_depth24 ? 24 : 16;
|
||||
} else {
|
||||
return 24;
|
||||
}
|
||||
}
|
||||
|
||||
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(desc);
|
||||
} else if (!gl_extensions.ARB_framebuffer_object) {
|
||||
return nullptr;
|
||||
}
|
||||
// If GLES2, we have basic FBO support and can just proceed.
|
||||
#endif
|
||||
|
||||
FBO *fbo = new FBO();
|
||||
fbo->width = desc.width;
|
||||
fbo->height = desc.height;
|
||||
fbo->colorDepth = desc.colorDepth;
|
||||
|
||||
// Color texture is same everywhere
|
||||
glGenFramebuffers(1, &fbo->handle);
|
||||
glGenTextures(1, &fbo->color_texture);
|
||||
|
||||
// Create the surfaces.
|
||||
glBindTexture(GL_TEXTURE_2D, fbo->color_texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
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 (fbo->colorDepth) {
|
||||
case FBO_8888:
|
||||
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, 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, 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, fbo->width, fbo->height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
if (gl_extensions.IsGLES) {
|
||||
if (gl_extensions.OES_packed_depth_stencil) {
|
||||
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, fbo->width, fbo->height);
|
||||
|
||||
// Bind it all together
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture, 0);
|
||||
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", 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, 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, fbo->width, fbo->height);
|
||||
|
||||
// Bind it all together
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_buffer);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->stencil_buffer);
|
||||
}
|
||||
} else {
|
||||
fbo->stencil_buffer = 0;
|
||||
fbo->z_buffer = 0;
|
||||
// 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, fbo->width, fbo->height);
|
||||
|
||||
// Bind it all together
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer);
|
||||
}
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
switch (status) {
|
||||
case GL_FRAMEBUFFER_COMPLETE:
|
||||
// ILOG("Framebuffer verified complete.");
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED:
|
||||
ELOG("GL_FRAMEBUFFER_UNSUPPORTED");
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
|
||||
ELOG("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT ");
|
||||
break;
|
||||
default:
|
||||
FLOG("Other framebuffer error: %i", status);
|
||||
break;
|
||||
}
|
||||
// Unbind state we don't need
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
currentDrawHandle_ = fbo->handle;
|
||||
currentReadHandle_ = fbo->handle;
|
||||
return fbo;
|
||||
}
|
||||
|
||||
static GLenum fbo_get_fb_target(bool read, GLuint **cached) {
|
||||
bool supportsBlit = gl_extensions.ARB_framebuffer_object;
|
||||
if (gl_extensions.IsGLES) {
|
||||
supportsBlit = (gl_extensions.GLES3 || gl_extensions.NV_framebuffer_blit);
|
||||
}
|
||||
|
||||
// Note: GL_FRAMEBUFFER_EXT and GL_FRAMEBUFFER have the same value, same with _NV.
|
||||
if (supportsBlit) {
|
||||
if (read) {
|
||||
*cached = ¤tReadHandle_;
|
||||
return GL_READ_FRAMEBUFFER;
|
||||
} else {
|
||||
*cached = ¤tDrawHandle_;
|
||||
return GL_DRAW_FRAMEBUFFER;
|
||||
}
|
||||
} else {
|
||||
*cached = ¤tDrawHandle_;
|
||||
return GL_FRAMEBUFFER;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
} else {
|
||||
#ifndef USING_GLES2
|
||||
glBindFramebufferEXT(target, name);
|
||||
#endif
|
||||
}
|
||||
*cached = name;
|
||||
}
|
||||
}
|
||||
|
||||
static void fbo_unbind() {
|
||||
#ifndef USING_GLES2
|
||||
if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
} else if (gl_extensions.EXT_framebuffer_object) {
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
#else
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
#endif
|
||||
|
||||
#ifdef IOS
|
||||
bindDefaultFBO();
|
||||
#endif
|
||||
|
||||
currentDrawHandle_ = 0;
|
||||
currentReadHandle_ = 0;
|
||||
}
|
||||
|
||||
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.
|
||||
fbo_bind_fb_target(false, fbo->handle);
|
||||
// Always restore viewport after render target binding
|
||||
glstate.viewport.restore();
|
||||
}
|
||||
|
||||
void fbo_bind_backbuffer_as_render_target() {
|
||||
fbo_unbind();
|
||||
}
|
||||
|
||||
// For GL_EXT_FRAMEBUFFER_BLIT and similar.
|
||||
void fbo_bind_for_read(FBO *fbo) {
|
||||
fbo_bind_fb_target(true, fbo->handle);
|
||||
}
|
||||
|
||||
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_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 (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers(1, &fbo->handle);
|
||||
glDeleteRenderbuffers(1, &fbo->z_stencil_buffer);
|
||||
glDeleteRenderbuffers(1, &fbo->z_buffer);
|
||||
glDeleteRenderbuffers(1, &fbo->stencil_buffer);
|
||||
} else if (gl_extensions.EXT_framebuffer_object) {
|
||||
#ifndef USING_GLES2
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->handle);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER_EXT, 0);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
glDeleteFramebuffersEXT(1, &fbo->handle);
|
||||
glDeleteRenderbuffersEXT(1, &fbo->z_stencil_buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
currentDrawHandle_ = 0;
|
||||
currentReadHandle_ = 0;
|
||||
|
||||
glDeleteTextures(1, &fbo->color_texture);
|
||||
delete fbo;
|
||||
}
|
||||
|
||||
void fbo_get_dimensions(FBO *fbo, int *w, int *h) {
|
||||
*w = fbo->width;
|
||||
*h = fbo->height;
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
// Copyright (c) 2012- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Simple wrapper around FBO functionality.
|
||||
// Very C-ish API because that's what I felt like, and it's cool to completely
|
||||
// hide the data from callers...
|
||||
|
||||
#include "gfx/gl_common.h"
|
||||
|
||||
struct FBO;
|
||||
|
||||
|
||||
enum FBOColorDepth {
|
||||
FBO_8888,
|
||||
FBO_565,
|
||||
FBO_4444,
|
||||
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.
|
||||
// No mipmap support.
|
||||
// num_color_textures must be 1 for now.
|
||||
// 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(const FramebufferDesc &desc);
|
||||
void fbo_destroy(FBO *fbo);
|
||||
|
||||
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_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_as_texture(FBO *fbo, int binding, FBOChannel channelBit, int attachment);
|
||||
void fbo_bind_for_read(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);
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include <map>
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "GPU/GLES/GLStateCache.h"
|
||||
#include "ext/native/gfx/GLStateCache.h"
|
||||
#include "GPU/GLES/TextureCacheGLES.h"
|
||||
|
||||
#include "GPU/ge_constants.h"
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "profiler/profiler.h"
|
||||
|
||||
#include "gfx_es2/glsl_program.h"
|
||||
#include "thin3d/thin3d.h"
|
||||
|
||||
#include "base/timeutil.h"
|
||||
#include "math/lin/matrix4x4.h"
|
||||
|
@ -39,8 +40,7 @@
|
|||
#include "GPU/Common/TextureDecoder.h"
|
||||
#include "GPU/Common/FramebufferCommon.h"
|
||||
#include "GPU/Debugger/Stepping.h"
|
||||
#include "GPU/GLES/GLStateCache.h"
|
||||
#include "GPU/GLES/FBO.h"
|
||||
#include "ext/native/gfx/GLStateCache.h"
|
||||
#include "GPU/GLES/FramebufferManagerGLES.h"
|
||||
#include "GPU/GLES/TextureCacheGLES.h"
|
||||
#include "GPU/GLES/DrawEngineGLES.h"
|
||||
|
@ -116,21 +116,21 @@ void FramebufferManagerGLES::DisableState() {
|
|||
|
||||
void FramebufferManagerGLES::SetNumExtraFBOs(int num) {
|
||||
for (size_t i = 0; i < extraFBOs_.size(); i++) {
|
||||
fbo_destroy(extraFBOs_[i]);
|
||||
delete extraFBOs_[i];
|
||||
}
|
||||
extraFBOs_.clear();
|
||||
for (int i = 0; i < num; i++) {
|
||||
// No depth/stencil for post processing
|
||||
FBO *fbo = fbo_create({ (int)renderWidth_, (int)renderHeight_, 1, 1, false, FBO_8888 });
|
||||
Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ (int)renderWidth_, (int)renderHeight_, 1, 1, false, Draw::FBO_8888 });
|
||||
extraFBOs_.push_back(fbo);
|
||||
|
||||
// The new FBO is still bound after creation, but let's bind it anyway.
|
||||
fbo_bind_as_render_target(fbo);
|
||||
draw_->BindFramebufferAsRenderTarget(fbo);
|
||||
ClearBuffer();
|
||||
}
|
||||
|
||||
currentRenderVfb_ = 0;
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
}
|
||||
|
||||
void FramebufferManagerGLES::CompileDraw2DProgram() {
|
||||
|
@ -273,7 +273,7 @@ FramebufferManagerGLES::~FramebufferManagerGLES() {
|
|||
SetNumExtraFBOs(0);
|
||||
|
||||
for (auto it = tempFBOs_.begin(), end = tempFBOs_.end(); it != end; ++it) {
|
||||
fbo_destroy(it->second.fbo);
|
||||
delete it->second.fbo;
|
||||
}
|
||||
|
||||
delete [] pixelBufObj_;
|
||||
|
@ -362,7 +362,7 @@ void FramebufferManagerGLES::MakePixelTexture(const u8 *srcPixels, GEBufferForma
|
|||
void FramebufferManagerGLES::DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) {
|
||||
float v0 = 0.0f, v1 = 1.0f;
|
||||
if (useBufferedRendering_ && vfb && vfb->fbo) {
|
||||
fbo_bind_as_render_target(vfb->fbo);
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo);
|
||||
glViewport(0, 0, vfb->renderWidth, vfb->renderHeight);
|
||||
} else {
|
||||
// We are drawing to the back buffer so need to flip.
|
||||
|
@ -532,8 +532,8 @@ void FramebufferManagerGLES::DrawActiveTexture(GLuint texture, float x, float y,
|
|||
void FramebufferManagerGLES::DestroyFramebuf(VirtualFramebuffer *v) {
|
||||
textureCache_->NotifyFramebuffer(v->fb_address, v, NOTIFY_FB_DESTROYED);
|
||||
if (v->fbo) {
|
||||
fbo_destroy(v->fbo);
|
||||
v->fbo = 0;
|
||||
delete v->fbo;
|
||||
v->fbo = nullptr;
|
||||
}
|
||||
|
||||
// Wipe some pointers
|
||||
|
@ -551,9 +551,9 @@ void FramebufferManagerGLES::DestroyFramebuf(VirtualFramebuffer *v) {
|
|||
|
||||
void FramebufferManagerGLES::RebindFramebuffer() {
|
||||
if (currentRenderVfb_ && currentRenderVfb_->fbo) {
|
||||
fbo_bind_as_render_target(currentRenderVfb_->fbo);
|
||||
draw_->BindFramebufferAsRenderTarget(currentRenderVfb_->fbo);
|
||||
} else {
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
}
|
||||
if (g_Config.iRenderingMode == FB_NON_BUFFERED_MODE)
|
||||
glstate.viewport.restore();
|
||||
|
@ -583,49 +583,49 @@ void FramebufferManagerGLES::ResizeFramebufFBO(VirtualFramebuffer *vfb, u16 w, u
|
|||
}
|
||||
|
||||
if (trueColor) {
|
||||
vfb->colorDepth = FBO_8888;
|
||||
vfb->colorDepth = Draw::FBO_8888;
|
||||
} else {
|
||||
switch (vfb->format) {
|
||||
case GE_FORMAT_4444:
|
||||
vfb->colorDepth = FBO_4444;
|
||||
vfb->colorDepth = Draw::FBO_4444;
|
||||
break;
|
||||
case GE_FORMAT_5551:
|
||||
vfb->colorDepth = FBO_5551;
|
||||
vfb->colorDepth = Draw::FBO_5551;
|
||||
break;
|
||||
case GE_FORMAT_565:
|
||||
vfb->colorDepth = FBO_565;
|
||||
vfb->colorDepth = Draw::FBO_565;
|
||||
break;
|
||||
case GE_FORMAT_8888:
|
||||
default:
|
||||
vfb->colorDepth = FBO_8888;
|
||||
vfb->colorDepth = Draw::FBO_8888;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
textureCache_->ForgetLastTexture();
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
|
||||
if (!useBufferedRendering_) {
|
||||
if (vfb->fbo) {
|
||||
fbo_destroy(vfb->fbo);
|
||||
vfb->fbo = 0;
|
||||
delete vfb->fbo;
|
||||
vfb->fbo = nullptr;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
vfb->fbo = fbo_create({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (FBOColorDepth)vfb->colorDepth });
|
||||
vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (Draw::FBColorDepth)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) {
|
||||
fbo_bind_as_render_target(vfb->fbo);
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo);
|
||||
ClearBuffer();
|
||||
if (!skipCopy && !g_Config.bDisableSlowFramebufEffects) {
|
||||
BlitFramebuffer(vfb, 0, 0, &old, 0, 0, std::min(vfb->bufferWidth, vfb->width), std::min(vfb->height, vfb->bufferHeight), 0);
|
||||
}
|
||||
}
|
||||
fbo_destroy(old.fbo);
|
||||
delete old.fbo;
|
||||
if (vfb->fbo) {
|
||||
fbo_bind_as_render_target(vfb->fbo);
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -636,7 +636,7 @@ void FramebufferManagerGLES::ResizeFramebufFBO(VirtualFramebuffer *vfb, u16 w, u
|
|||
|
||||
void FramebufferManagerGLES::NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb) {
|
||||
if (!useBufferedRendering_) {
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
// Let's ignore rendering to targets that have not (yet) been displayed.
|
||||
gstate_c.skipDrawReason |= SKIPDRAW_NON_DISPLAYED_FB;
|
||||
}
|
||||
|
@ -663,19 +663,19 @@ void FramebufferManagerGLES::NotifyRenderFramebufferSwitched(VirtualFramebuffer
|
|||
|
||||
if (useBufferedRendering_) {
|
||||
if (vfb->fbo) {
|
||||
fbo_bind_as_render_target(vfb->fbo);
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo);
|
||||
} else {
|
||||
// wtf? This should only happen very briefly when toggling bBufferedRendering
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
}
|
||||
} else {
|
||||
if (vfb->fbo) {
|
||||
// wtf? This should only happen very briefly when toggling bBufferedRendering
|
||||
textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_DESTROYED);
|
||||
fbo_destroy(vfb->fbo);
|
||||
vfb->fbo = 0;
|
||||
delete vfb->fbo;
|
||||
vfb->fbo = nullptr;
|
||||
}
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
|
||||
// Let's ignore rendering to targets that have not (yet) been displayed.
|
||||
if (vfb->usageFlags & FB_USAGE_DISPLAYED_FRAMEBUFFER) {
|
||||
|
@ -747,7 +747,7 @@ void FramebufferManagerGLES::ReformatFramebufferFrom(VirtualFramebuffer *vfb, GE
|
|||
return;
|
||||
}
|
||||
|
||||
fbo_bind_as_render_target(vfb->fbo);
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo);
|
||||
|
||||
// Technically, we should at this point re-interpret the bytes of the old format to the new.
|
||||
// That might get tricky, and could cause unnecessary slowness in some games.
|
||||
|
@ -786,14 +786,14 @@ void FramebufferManagerGLES::BlitFramebufferDepth(VirtualFramebuffer *src, Virtu
|
|||
if (gstate_c.Supports(GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT | GPU_SUPPORTS_NV_FRAMEBUFFER_BLIT)) {
|
||||
// Let's only do this if not clearing depth.
|
||||
glstate.scissorTest.force(false);
|
||||
fbo_blit(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, FB_DEPTH_BIT, FB_BLIT_NEAREST);
|
||||
draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST);
|
||||
// WARNING: If we set dst->depthUpdated here, our optimization above would be pointless.
|
||||
glstate.scissorTest.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FBO *FramebufferManagerGLES::GetTempFBO(u16 w, u16 h, FBOColorDepth depth) {
|
||||
Draw::Framebuffer *FramebufferManagerGLES::GetTempFBO(u16 w, u16 h, Draw::FBColorDepth depth) {
|
||||
u64 key = ((u64)depth << 32) | ((u32)w << 16) | h;
|
||||
auto it = tempFBOs_.find(key);
|
||||
if (it != tempFBOs_.end()) {
|
||||
|
@ -802,10 +802,10 @@ FBO *FramebufferManagerGLES::GetTempFBO(u16 w, u16 h, FBOColorDepth depth) {
|
|||
}
|
||||
|
||||
textureCache_->ForgetLastTexture();
|
||||
FBO *fbo = fbo_create({ w, h, 1, 1, false, depth });
|
||||
Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, false, depth });
|
||||
if (!fbo)
|
||||
return fbo;
|
||||
fbo_bind_as_render_target(fbo);
|
||||
draw_->BindFramebufferAsRenderTarget(fbo);
|
||||
ClearBuffer(true);
|
||||
const TempFBO info = {fbo, gpuStats.numFlips};
|
||||
tempFBOs_[key] = info;
|
||||
|
@ -836,7 +836,7 @@ void FramebufferManagerGLES::BindFramebufferColor(int stage, u32 fbRawAddress, V
|
|||
}
|
||||
if (!skipCopy && currentRenderVfb_ && framebuffer->fb_address == fbRawAddress) {
|
||||
// TODO: Maybe merge with bvfbs_? Not sure if those could be packing, and they're created at a different size.
|
||||
FBO *renderCopy = GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, (FBOColorDepth)framebuffer->colorDepth);
|
||||
Draw::Framebuffer *renderCopy = GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, (Draw::FBColorDepth)framebuffer->colorDepth);
|
||||
if (renderCopy) {
|
||||
VirtualFramebuffer copyInfo = *framebuffer;
|
||||
copyInfo.fbo = renderCopy;
|
||||
|
@ -863,12 +863,12 @@ void FramebufferManagerGLES::BindFramebufferColor(int stage, u32 fbRawAddress, V
|
|||
|
||||
BlitFramebuffer(©Info, x, y, framebuffer, x, y, w, h, 0);
|
||||
|
||||
fbo_bind_as_texture(renderCopy, 0, FB_COLOR_BIT, 0);
|
||||
draw_->BindFramebufferAsTexture(renderCopy, 0, Draw::FB_COLOR_BIT, 0);
|
||||
} else {
|
||||
fbo_bind_as_texture(framebuffer->fbo, 0, FB_COLOR_BIT, 0);
|
||||
draw_->BindFramebufferAsTexture(framebuffer->fbo, 0, Draw::FB_COLOR_BIT, 0);
|
||||
}
|
||||
} else {
|
||||
fbo_bind_as_texture(framebuffer->fbo, 0, FB_COLOR_BIT, 0);
|
||||
draw_->BindFramebufferAsTexture(framebuffer->fbo, 0, Draw::FB_COLOR_BIT, 0);
|
||||
}
|
||||
|
||||
if (stage != GL_TEXTURE0) {
|
||||
|
@ -906,7 +906,7 @@ void FramebufferManagerGLES::CopyDisplayToOutput() {
|
|||
DownloadFramebufferOnSwitch(currentRenderVfb_);
|
||||
|
||||
glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_);
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
currentRenderVfb_ = 0;
|
||||
|
||||
if (displayFramebufPtr_ == 0) {
|
||||
|
@ -1015,7 +1015,7 @@ void FramebufferManagerGLES::CopyDisplayToOutput() {
|
|||
DEBUG_LOG(SCEGE, "Displaying FBO %08x", vfb->fb_address);
|
||||
DisableState();
|
||||
|
||||
fbo_bind_as_texture(vfb->fbo, 0, FB_COLOR_BIT, 0);
|
||||
draw_->BindFramebufferAsTexture(vfb->fbo, 0, Draw::FB_COLOR_BIT, 0);
|
||||
|
||||
int uvRotation = (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) ? g_Config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL;
|
||||
|
||||
|
@ -1049,16 +1049,16 @@ void FramebufferManagerGLES::CopyDisplayToOutput() {
|
|||
}
|
||||
} else if (usePostShader_ && extraFBOs_.size() == 1 && !postShaderAtOutputResolution_) {
|
||||
// An additional pass, post-processing shader to the extra FBO.
|
||||
fbo_bind_as_render_target(extraFBOs_[0]);
|
||||
draw_->BindFramebufferAsRenderTarget(extraFBOs_[0]);
|
||||
int fbo_w, fbo_h;
|
||||
fbo_get_dimensions(extraFBOs_[0], &fbo_w, &fbo_h);
|
||||
draw_->GetFramebufferDimensions(extraFBOs_[0], &fbo_w, &fbo_h);
|
||||
glstate.viewport.set(0, 0, fbo_w, fbo_h);
|
||||
shaderManager_->DirtyLastShader(); // dirty lastShader_
|
||||
glsl_bind(postShaderProgram_);
|
||||
UpdatePostShaderUniforms(vfb->bufferWidth, vfb->bufferHeight, renderWidth_, renderHeight_);
|
||||
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_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
|
||||
// Use the extra FBO, with applied post-processing shader, as a texture.
|
||||
// fbo_bind_as_texture(extraFBOs_[0], FB_COLOR_BIT, 0);
|
||||
|
@ -1066,7 +1066,7 @@ void FramebufferManagerGLES::CopyDisplayToOutput() {
|
|||
ERROR_LOG(G3D, "WTF?");
|
||||
return;
|
||||
}
|
||||
fbo_bind_as_texture(extraFBOs_[0], 0, FB_COLOR_BIT, 0);
|
||||
draw_->BindFramebufferAsTexture(extraFBOs_[0], 0, Draw::FB_COLOR_BIT, 0);
|
||||
|
||||
// We are doing the DrawActiveTexture call directly to the backbuffer after here. Hence, we must
|
||||
// flip V.
|
||||
|
@ -1087,7 +1087,7 @@ void FramebufferManagerGLES::CopyDisplayToOutput() {
|
|||
}
|
||||
|
||||
if (gl_extensions.GLES3 && glInvalidateFramebuffer != nullptr) {
|
||||
fbo_bind_as_render_target(extraFBOs_[0]);
|
||||
draw_->BindFramebufferAsRenderTarget(extraFBOs_[0]);
|
||||
GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT };
|
||||
glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, attachments);
|
||||
}
|
||||
|
@ -1197,28 +1197,28 @@ bool FramebufferManagerGLES::CreateDownloadTempBuffer(VirtualFramebuffer *nvfb)
|
|||
if (!gstate_c.Supports(GPU_PREFER_CPU_DOWNLOAD)) {
|
||||
switch (nvfb->format) {
|
||||
case GE_FORMAT_4444:
|
||||
nvfb->colorDepth = FBO_4444;
|
||||
nvfb->colorDepth = Draw::FBO_4444;
|
||||
break;
|
||||
case GE_FORMAT_5551:
|
||||
nvfb->colorDepth = FBO_5551;
|
||||
nvfb->colorDepth = Draw::FBO_5551;
|
||||
break;
|
||||
case GE_FORMAT_565:
|
||||
nvfb->colorDepth = FBO_565;
|
||||
nvfb->colorDepth = Draw::FBO_565;
|
||||
break;
|
||||
case GE_FORMAT_8888:
|
||||
default:
|
||||
nvfb->colorDepth = FBO_8888;
|
||||
nvfb->colorDepth = Draw::FBO_8888;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nvfb->fbo = fbo_create({ nvfb->width, nvfb->height, 1, 1, false, (FBOColorDepth)nvfb->colorDepth });
|
||||
nvfb->fbo = draw_->CreateFramebuffer({ nvfb->width, nvfb->height, 1, 1, false, (Draw::FBColorDepth)nvfb->colorDepth });
|
||||
if (!nvfb->fbo) {
|
||||
ERROR_LOG(SCEGE, "Error creating FBO! %i x %i", nvfb->renderWidth, nvfb->renderHeight);
|
||||
return false;
|
||||
}
|
||||
|
||||
fbo_bind_as_render_target(nvfb->fbo);
|
||||
draw_->BindFramebufferAsRenderTarget(nvfb->fbo);
|
||||
ClearBuffer();
|
||||
glDisable(GL_DITHER);
|
||||
return true;
|
||||
|
@ -1229,11 +1229,11 @@ void FramebufferManagerGLES::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb)
|
|||
|
||||
// Discard the previous contents of this buffer where possible.
|
||||
if (gl_extensions.GLES3 && glInvalidateFramebuffer != nullptr) {
|
||||
fbo_bind_as_render_target(nvfb->fbo);
|
||||
draw_->BindFramebufferAsRenderTarget(nvfb->fbo);
|
||||
GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_STENCIL_ATTACHMENT, GL_DEPTH_ATTACHMENT };
|
||||
glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, attachments);
|
||||
} else if (gl_extensions.IsGLES) {
|
||||
fbo_bind_as_render_target(nvfb->fbo);
|
||||
draw_->BindFramebufferAsRenderTarget(nvfb->fbo);
|
||||
ClearBuffer();
|
||||
}
|
||||
}
|
||||
|
@ -1241,7 +1241,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_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1286,17 +1286,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)) {
|
||||
fbo_copy_image(src->fbo, 0, srcX1, srcY1, 0, dst->fbo, 0, dstX1, dstY1, 0, dstX2 - dstX1, dstY2 - dstY1, 1);
|
||||
draw_->CopyFramebufferImage(src->fbo, 0, srcX1, srcY1, 0, dst->fbo, 0, dstX1, dstY1, 0, dstX2 - dstX1, dstY2 - dstY1, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
glstate.scissorTest.force(false);
|
||||
if (useBlit) {
|
||||
fbo_blit(src->fbo, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, FB_COLOR_BIT, FB_BLIT_NEAREST);
|
||||
draw_->BlitFramebuffer(src->fbo, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, Draw::FB_COLOR_BIT, Draw::FB_BLIT_NEAREST);
|
||||
} else {
|
||||
fbo_bind_as_render_target(dst->fbo);
|
||||
fbo_bind_as_texture(src->fbo, 0, FB_COLOR_BIT, 0);
|
||||
draw_->BindFramebufferAsRenderTarget(dst->fbo);
|
||||
draw_->BindFramebufferAsTexture(src->fbo, 0, Draw::FB_COLOR_BIT, 0);
|
||||
|
||||
// Make sure our 2D drawing program is ready. Compiles only if not already compiled.
|
||||
CompileDraw2DProgram();
|
||||
|
@ -1576,7 +1576,7 @@ void FramebufferManagerGLES::PackFramebufferAsync_(VirtualFramebuffer *vfb) {
|
|||
u32 fb_address = (0x04000000) | vfb->fb_address;
|
||||
|
||||
if (vfb->fbo) {
|
||||
fbo_bind_for_read(vfb->fbo);
|
||||
draw_->BindFramebufferForRead(vfb->fbo);
|
||||
} else {
|
||||
ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackFramebufferAsync_: vfb->fbo == 0");
|
||||
return;
|
||||
|
@ -1619,7 +1619,7 @@ void FramebufferManagerGLES::PackFramebufferAsync_(VirtualFramebuffer *vfb) {
|
|||
|
||||
void FramebufferManagerGLES::PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h) {
|
||||
if (vfb->fbo) {
|
||||
fbo_bind_for_read(vfb->fbo);
|
||||
draw_->BindFramebufferForRead(vfb->fbo);
|
||||
} else {
|
||||
ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackFramebufferSync_: vfb->fbo == 0");
|
||||
return;
|
||||
|
@ -1673,7 +1673,7 @@ void FramebufferManagerGLES::PackFramebufferSync_(VirtualFramebuffer *vfb, int x
|
|||
if (gl_extensions.GLES3 && glInvalidateFramebuffer != nullptr) {
|
||||
#ifdef USING_GLES2
|
||||
// GLES3 doesn't support using GL_READ_FRAMEBUFFER here.
|
||||
fbo_bind_as_render_target(vfb->fbo);
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo);
|
||||
const GLenum target = GL_FRAMEBUFFER;
|
||||
#else
|
||||
const GLenum target = GL_READ_FRAMEBUFFER;
|
||||
|
@ -1685,7 +1685,7 @@ void FramebufferManagerGLES::PackFramebufferSync_(VirtualFramebuffer *vfb, int x
|
|||
|
||||
void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h) {
|
||||
if (vfb->fbo) {
|
||||
fbo_bind_for_read(vfb->fbo);
|
||||
draw_->BindFramebufferForRead(vfb->fbo);
|
||||
} else {
|
||||
ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackDepthbuffer: vfb->fbo == 0");
|
||||
return;
|
||||
|
@ -1788,11 +1788,11 @@ void FramebufferManagerGLES::EndFrame() {
|
|||
continue;
|
||||
}
|
||||
|
||||
fbo_bind_as_render_target(temp.second.fbo);
|
||||
draw_->BindFramebufferAsRenderTarget(temp.second.fbo);
|
||||
GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_STENCIL_ATTACHMENT, GL_DEPTH_ATTACHMENT };
|
||||
glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, attachments);
|
||||
}
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1822,7 +1822,7 @@ std::vector<FramebufferInfo> FramebufferManagerGLES::GetFramebufferList() {
|
|||
}
|
||||
|
||||
void FramebufferManagerGLES::DecimateFBOs() {
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
currentRenderVfb_ = 0;
|
||||
|
||||
for (size_t i = 0; i < vfbs_.size(); ++i) {
|
||||
|
@ -1849,7 +1849,7 @@ void FramebufferManagerGLES::DecimateFBOs() {
|
|||
for (auto it = tempFBOs_.begin(); it != tempFBOs_.end(); ) {
|
||||
int age = frameLastFramebufUsed_ - it->second.last_frame_used;
|
||||
if (age > FBO_OLD_AGE) {
|
||||
fbo_destroy(it->second.fbo);
|
||||
delete it->second.fbo;
|
||||
tempFBOs_.erase(it++);
|
||||
} else {
|
||||
++it;
|
||||
|
@ -1869,7 +1869,7 @@ void FramebufferManagerGLES::DecimateFBOs() {
|
|||
}
|
||||
|
||||
void FramebufferManagerGLES::DestroyAllFBOs(bool forceDelete) {
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
currentRenderVfb_ = 0;
|
||||
displayFramebuf_ = 0;
|
||||
prevDisplayFramebuf_ = 0;
|
||||
|
@ -1889,11 +1889,11 @@ void FramebufferManagerGLES::DestroyAllFBOs(bool forceDelete) {
|
|||
bvfbs_.clear();
|
||||
|
||||
for (auto it = tempFBOs_.begin(), end = tempFBOs_.end(); it != end; ++it) {
|
||||
fbo_destroy(it->second.fbo);
|
||||
delete it->second.fbo;
|
||||
}
|
||||
tempFBOs_.clear();
|
||||
|
||||
fbo_bind_backbuffer_as_render_target();
|
||||
draw_->BindBackbufferAsRenderTarget();
|
||||
DisableState();
|
||||
}
|
||||
|
||||
|
@ -1930,7 +1930,7 @@ bool FramebufferManagerGLES::GetFramebuffer(u32 fb_address, int fb_stride, GEBuf
|
|||
w = vfb->width * maxRes;
|
||||
h = vfb->height * maxRes;
|
||||
|
||||
FBO *tempFBO = GetTempFBO(w, h);
|
||||
Draw::Framebuffer *tempFBO = GetTempFBO(w, h);
|
||||
VirtualFramebuffer tempVfb = *vfb;
|
||||
tempVfb.fbo = tempFBO;
|
||||
tempVfb.bufferWidth = vfb->width;
|
||||
|
@ -1939,9 +1939,9 @@ bool FramebufferManagerGLES::GetFramebuffer(u32 fb_address, int fb_stride, GEBuf
|
|||
tempVfb.renderHeight = h;
|
||||
BlitFramebuffer(&tempVfb, 0, 0, vfb, 0, 0, vfb->width, vfb->height, 0);
|
||||
|
||||
fbo_bind_for_read(tempFBO);
|
||||
draw_->BindFramebufferForRead(tempFBO);
|
||||
} else {
|
||||
fbo_bind_for_read(vfb->fbo);
|
||||
draw_->BindFramebufferForRead(vfb->fbo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1986,7 +1986,7 @@ bool FramebufferManagerGLES::GetDepthbuffer(u32 fb_address, int fb_stride, u32 z
|
|||
buffer.Allocate(vfb->renderWidth, vfb->renderHeight, GPU_DBG_FORMAT_FLOAT, !useBufferedRendering_);
|
||||
}
|
||||
if (vfb->fbo)
|
||||
fbo_bind_for_read(vfb->fbo);
|
||||
draw_->BindFramebufferForRead(vfb->fbo);
|
||||
if (gl_extensions.GLES3 || !gl_extensions.IsGLES)
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
||||
|
@ -2011,7 +2011,7 @@ bool FramebufferManagerGLES::GetStencilbuffer(u32 fb_address, int fb_stride, GPU
|
|||
#ifndef USING_GLES2
|
||||
buffer.Allocate(vfb->renderWidth, vfb->renderHeight, GPU_DBG_FORMAT_8BIT, !useBufferedRendering_);
|
||||
if (vfb->fbo)
|
||||
fbo_bind_for_read(vfb->fbo);
|
||||
draw_->BindFramebufferForRead(vfb->fbo);
|
||||
if (gl_extensions.GLES3 || !gl_extensions.IsGLES)
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 2);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <algorithm>
|
||||
|
||||
#include "gfx/gl_common.h"
|
||||
#include "ext/native/thin3d/thin3d.h"
|
||||
// Keeps track of allocated FBOs.
|
||||
// Also provides facilities for drawing and later converting raw
|
||||
// pixel data.
|
||||
|
@ -29,7 +30,6 @@
|
|||
|
||||
#include "Globals.h"
|
||||
#include "GPU/GPUCommon.h"
|
||||
#include "GPU/GLES/FBO.h"
|
||||
#include "GPU/Common/FramebufferCommon.h"
|
||||
#include "Core/Config.h"
|
||||
|
||||
|
@ -115,7 +115,7 @@ public:
|
|||
|
||||
virtual void RebindFramebuffer() override;
|
||||
|
||||
FBO *GetTempFBO(u16 w, u16 h, FBOColorDepth depth = FBO_8888);
|
||||
Draw::Framebuffer *GetTempFBO(u16 w, u16 h, Draw::FBColorDepth depth = Draw::FBO_8888);
|
||||
|
||||
// Cardboard Settings Calculator
|
||||
struct CardboardSettings * GetCardboardSettings(struct CardboardSettings * cardboardSettings);
|
||||
|
@ -169,12 +169,12 @@ private:
|
|||
DrawEngineGLES *drawEngine_;
|
||||
|
||||
// Used by post-processing shader
|
||||
std::vector<FBO *> extraFBOs_;
|
||||
std::vector<Draw::Framebuffer *> extraFBOs_;
|
||||
|
||||
bool resized_;
|
||||
|
||||
struct TempFBO {
|
||||
FBO *fbo;
|
||||
Draw::Framebuffer *fbo;
|
||||
int last_frame_used;
|
||||
};
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "GPU/GeDisasm.h"
|
||||
#include "GPU/Common/FramebufferCommon.h"
|
||||
|
||||
#include "GPU/GLES/GLStateCache.h"
|
||||
#include "ext/native/gfx/GLStateCache.h"
|
||||
#include "GPU/GLES/ShaderManagerGLES.h"
|
||||
#include "GPU/GLES/GPU_GLES.h"
|
||||
#include "GPU/GLES/FramebufferManagerGLES.h"
|
||||
|
@ -605,14 +605,15 @@ 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_preferred_z_bitdepth() > 16) {
|
||||
bool prefer24 = draw_->GetDeviceCaps().preferredDepthBufferFormat == Draw::DataFormat::D24_S8;
|
||||
if (prefer24) {
|
||||
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_preferred_z_bitdepth() == 24 && (features & GPU_SUPPORTS_ACCURATE_DEPTH) != 0) {
|
||||
} else if (prefer24 && (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;
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include <deque>
|
||||
|
||||
#include "GPU/GPUCommon.h"
|
||||
#include "GPU/GLES/FBO.h"
|
||||
#include "GPU/GLES/FramebufferManagerGLES.h"
|
||||
#include "GPU/GLES/DrawEngineGLES.h"
|
||||
#include "GPU/GLES/TextureCacheGLES.h"
|
||||
|
@ -73,7 +72,7 @@ public:
|
|||
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer) override;
|
||||
bool GetCurrentTexture(GPUDebugBuffer &buffer, int level) override;
|
||||
bool GetCurrentClut(GPUDebugBuffer &buffer) override;
|
||||
static bool GetOutputFramebuffer(GPUDebugBuffer &buffer);
|
||||
bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override;
|
||||
bool GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices) override;
|
||||
|
||||
bool DescribeCodePtr(const u8 *ptr, std::string &name) override;
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "GPU/Math3D.h"
|
||||
#include "GPU/GPUState.h"
|
||||
#include "GPU/ge_constants.h"
|
||||
#include "GPU/GLES/GLStateCache.h"
|
||||
#include "ext/native/gfx/GLStateCache.h"
|
||||
#include "GPU/GLES/ShaderManagerGLES.h"
|
||||
#include "GPU/GLES/DrawEngineGLES.h"
|
||||
#include "FramebufferManagerGLES.h"
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "Core/Config.h"
|
||||
#include "Core/Reporting.h"
|
||||
#include "GPU/GLES/GPU_GLES.h"
|
||||
#include "GPU/GLES/GLStateCache.h"
|
||||
#include "ext/native/gfx/GLStateCache.h"
|
||||
#include "GPU/GLES/ShaderManagerGLES.h"
|
||||
#include "GPU/GLES/TextureCacheGLES.h"
|
||||
#include "GPU/GLES/FramebufferManagerGLES.h"
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#include "gfx_es2/glsl_program.h"
|
||||
#include "Core/Reporting.h"
|
||||
#include "GPU/GLES/GLStateCache.h"
|
||||
#include "ext/native/gfx/GLStateCache.h"
|
||||
#include "GPU/GLES/FramebufferManagerGLES.h"
|
||||
#include "GPU/GLES/ShaderManagerGLES.h"
|
||||
#include "GPU/GLES/TextureCacheGLES.h"
|
||||
|
@ -180,12 +180,12 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe
|
|||
u16 w = useBlit ? dstBuffer->bufferWidth : dstBuffer->renderWidth;
|
||||
u16 h = useBlit ? dstBuffer->bufferHeight : dstBuffer->renderHeight;
|
||||
|
||||
FBO *blitFBO = NULL;
|
||||
Draw::Framebuffer *blitFBO = nullptr;
|
||||
if (useBlit) {
|
||||
blitFBO = GetTempFBO(w, h, FBO_8888);
|
||||
fbo_bind_as_render_target(blitFBO);
|
||||
blitFBO = GetTempFBO(w, h, Draw::FBO_8888);
|
||||
draw_->BindFramebufferAsRenderTarget(blitFBO);
|
||||
} else if (dstBuffer->fbo) {
|
||||
fbo_bind_as_render_target(dstBuffer->fbo);
|
||||
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo);
|
||||
}
|
||||
glViewport(0, 0, w, h);
|
||||
|
||||
|
@ -220,7 +220,7 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe
|
|||
glstate.stencilMask.set(0xFF);
|
||||
|
||||
if (useBlit) {
|
||||
fbo_blit(blitFBO, 0, 0, w, h, dstBuffer->fbo, 0, 0, dstBuffer->renderWidth, dstBuffer->renderHeight, FB_STENCIL_BIT, FB_BLIT_NEAREST);
|
||||
draw_->BlitFramebuffer(blitFBO, 0, 0, w, h, dstBuffer->fbo, 0, 0, dstBuffer->renderWidth, dstBuffer->renderHeight, Draw::FB_STENCIL_BIT, Draw::FB_BLIT_NEAREST);
|
||||
}
|
||||
|
||||
RebindFramebuffer();
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "Core/Reporting.h"
|
||||
#include "GPU/ge_constants.h"
|
||||
#include "GPU/GPUState.h"
|
||||
#include "GPU/GLES/GLStateCache.h"
|
||||
#include "ext/native/gfx/GLStateCache.h"
|
||||
#include "GPU/GLES/TextureCacheGLES.h"
|
||||
#include "GPU/GLES/FramebufferManagerGLES.h"
|
||||
#include "GPU/GLES/FragmentShaderGeneratorGLES.h"
|
||||
|
@ -637,8 +637,8 @@ void TextureCacheGLES::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFrameb
|
|||
nextTexture_ = entry;
|
||||
} else {
|
||||
if (framebuffer->fbo) {
|
||||
fbo_destroy(framebuffer->fbo);
|
||||
framebuffer->fbo = 0;
|
||||
delete framebuffer->fbo;
|
||||
framebuffer->fbo = nullptr;
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
gstate_c.needShaderTexClamp = false;
|
||||
|
@ -849,8 +849,8 @@ void TextureCacheGLES::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFram
|
|||
}
|
||||
if (depal) {
|
||||
GLuint clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_);
|
||||
FBO *depalFBO = framebufferManager_->GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, FBO_8888);
|
||||
fbo_bind_as_render_target(depalFBO);
|
||||
Draw::Framebuffer *depalFBO = framebufferManager_->GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, Draw::FBO_8888);
|
||||
draw_->BindFramebufferAsRenderTarget(depalFBO);
|
||||
shaderManager_->DirtyLastShader();
|
||||
|
||||
TextureShaderApplier shaderApply(depal, framebuffer->bufferWidth, framebuffer->bufferHeight, framebuffer->renderWidth, framebuffer->renderHeight);
|
||||
|
@ -867,7 +867,7 @@ void TextureCacheGLES::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFram
|
|||
|
||||
shaderApply.Shade();
|
||||
|
||||
fbo_bind_as_texture(depalFBO, 0, FB_COLOR_BIT, 0);
|
||||
draw_->BindFramebufferAsTexture(depalFBO, 0, Draw::FB_COLOR_BIT, 0);
|
||||
|
||||
const u32 bytesPerColor = clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16);
|
||||
const u32 clutTotalColors = clutMaxBytes_ / bytesPerColor;
|
||||
|
|
|
@ -20,11 +20,10 @@
|
|||
#include <map>
|
||||
|
||||
#include "gfx_es2/gpu_features.h"
|
||||
|
||||
#include "gfx/gl_common.h"
|
||||
#include "Globals.h"
|
||||
#include "GPU/GPUInterface.h"
|
||||
#include "GPU/GPUState.h"
|
||||
#include "GPU/GLES/FBO.h"
|
||||
#include "GPU/GLES/TextureScalerGLES.h"
|
||||
#include "GPU/Common/TextureCacheCommon.h"
|
||||
|
||||
|
|
|
@ -206,7 +206,6 @@
|
|||
<ClInclude Include="Debugger\Stepping.h" />
|
||||
<ClInclude Include="Directx9\DepalettizeShaderDX9.h" />
|
||||
<ClInclude Include="Directx9\GPU_DX9.h" />
|
||||
<ClInclude Include="Directx9\helper\dx_fbo.h" />
|
||||
<ClInclude Include="Directx9\PixelShaderGeneratorDX9.h" />
|
||||
<ClInclude Include="Directx9\FramebufferDX9.h" />
|
||||
<ClInclude Include="Directx9\ShaderManagerDX9.h" />
|
||||
|
@ -217,12 +216,10 @@
|
|||
<ClInclude Include="ge_constants.h" />
|
||||
<ClInclude Include="GeDisasm.h" />
|
||||
<ClInclude Include="GLES\DepalettizeShaderGLES.h" />
|
||||
<ClInclude Include="GLES\FBO.h" />
|
||||
<ClInclude Include="GLES\FragmentShaderGeneratorGLES.h" />
|
||||
<ClInclude Include="GLES\FragmentTestCacheGLES.h" />
|
||||
<ClInclude Include="GLES\FramebufferManagerGLES.h" />
|
||||
<ClInclude Include="GLES\GPU_GLES.h" />
|
||||
<ClInclude Include="GLES\GLStateCache.h" />
|
||||
<ClInclude Include="GLES\ShaderManagerGLES.h" />
|
||||
<ClInclude Include="GLES\StateMappingGLES.h" />
|
||||
<ClInclude Include="GLES\TextureCacheGLES.h" />
|
||||
|
@ -293,7 +290,6 @@
|
|||
<ClCompile Include="Debugger\Stepping.cpp" />
|
||||
<ClCompile Include="Directx9\DepalettizeShaderDX9.cpp" />
|
||||
<ClCompile Include="Directx9\GPU_DX9.cpp" />
|
||||
<ClCompile Include="Directx9\helper\dx_fbo.cpp" />
|
||||
<ClCompile Include="Directx9\PixelShaderGeneratorDX9.cpp" />
|
||||
<ClCompile Include="Directx9\FramebufferDX9.cpp" />
|
||||
<ClCompile Include="Directx9\ShaderManagerDX9.cpp" />
|
||||
|
@ -305,12 +301,10 @@
|
|||
<ClCompile Include="Directx9\VertexShaderGeneratorDX9.cpp" />
|
||||
<ClCompile Include="GeDisasm.cpp" />
|
||||
<ClCompile Include="GLES\DepalettizeShaderGLES.cpp" />
|
||||
<ClCompile Include="GLES\FBO.cpp" />
|
||||
<ClCompile Include="GLES\FragmentShaderGeneratorGLES.cpp" />
|
||||
<ClCompile Include="GLES\FragmentTestCacheGLES.cpp" />
|
||||
<ClCompile Include="GLES\FramebufferManagerGLES.cpp" />
|
||||
<ClCompile Include="GLES\GPU_GLES.cpp" />
|
||||
<ClCompile Include="GLES\GLStateCache.cpp" />
|
||||
<ClCompile Include="GLES\ShaderManagerGLES.cpp" />
|
||||
<ClCompile Include="GLES\StateMappingGLES.cpp" />
|
||||
<ClCompile Include="GLES\StencilBufferGLES.cpp" />
|
||||
|
@ -350,4 +344,4 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -150,15 +150,6 @@
|
|||
<ClInclude Include="GPU.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GLES\FBO.h">
|
||||
<Filter>GLES</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Directx9\helper\dx_fbo.h">
|
||||
<Filter>DirectX9\helper</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GLES\GLStateCache.h">
|
||||
<Filter>GLES</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\ShaderCommon.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
|
@ -365,15 +356,6 @@
|
|||
<ClCompile Include="GPU.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GLES\FBO.cpp">
|
||||
<Filter>GLES</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Directx9\helper\dx_fbo.cpp">
|
||||
<Filter>DirectX9\helper</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GLES\GLStateCache.cpp">
|
||||
<Filter>GLES</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Common\GPUStateUtils.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
|
@ -447,4 +429,4 @@
|
|||
<Filter>GLES</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -35,6 +35,9 @@ public:
|
|||
GPUCommon(GraphicsContext *gfxCtx, Draw::DrawContext *draw);
|
||||
virtual ~GPUCommon();
|
||||
|
||||
Draw::DrawContext *GetDrawContext() override {
|
||||
return draw_;
|
||||
}
|
||||
void Reinitialize() override;
|
||||
|
||||
void BeginHostFrame() override;
|
||||
|
|
|
@ -204,12 +204,18 @@ struct GPUEvent {
|
|||
}
|
||||
};
|
||||
|
||||
namespace Draw {
|
||||
class DrawContext;
|
||||
}
|
||||
|
||||
class GPUInterface {
|
||||
public:
|
||||
virtual ~GPUInterface() {}
|
||||
|
||||
static const int DisplayListMaxCount = 64;
|
||||
|
||||
virtual Draw::DrawContext *GetDrawContext() = 0;
|
||||
|
||||
// Initialization
|
||||
virtual void InitClear() = 0;
|
||||
virtual void Reinitialize() = 0;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "base/timeutil.h"
|
||||
#include "math/lin/matrix4x4.h"
|
||||
#include "ext/native/thin3d/thin3d.h"
|
||||
|
||||
#include "Common/Vulkan/VulkanContext.h"
|
||||
#include "Common/Vulkan/VulkanMemory.h"
|
||||
|
@ -402,7 +403,7 @@ void FramebufferManagerVulkan::DrawPixels(VirtualFramebuffer *vfb, int dstX, int
|
|||
VkViewport vp;
|
||||
vp.minDepth = 0.0;
|
||||
vp.maxDepth = 1.0;
|
||||
if (useBufferedRendering_ && vfb && vfb->fbo_vk) {
|
||||
if (useBufferedRendering_ && vfb && vfb->fbo) {
|
||||
vp.x = 0;
|
||||
vp.y = 0;
|
||||
vp.width = vfb->renderWidth;
|
||||
|
@ -537,9 +538,9 @@ void FramebufferManagerVulkan::DrawTexture(VulkanTexture *texture, float x, floa
|
|||
|
||||
void FramebufferManagerVulkan::DestroyFramebuf(VirtualFramebuffer *v) {
|
||||
textureCache_->NotifyFramebuffer(v->fb_address, v, NOTIFY_FB_DESTROYED);
|
||||
if (v->fbo_vk) {
|
||||
delete v->fbo_vk;
|
||||
v->fbo_vk = 0;
|
||||
if (v->fbo) {
|
||||
delete v->fbo;
|
||||
v->fbo = 0;
|
||||
}
|
||||
|
||||
// Wipe some pointers
|
||||
|
@ -608,31 +609,31 @@ void FramebufferManagerVulkan::ResizeFramebufFBO(VirtualFramebuffer *vfb, u16 w,
|
|||
textureCache_->ForgetLastTexture();
|
||||
|
||||
if (!useBufferedRendering_) {
|
||||
if (vfb->fbo_vk) {
|
||||
delete vfb->fbo_vk;
|
||||
vfb->fbo_vk = 0;
|
||||
if (vfb->fbo) {
|
||||
delete vfb->fbo;
|
||||
vfb->fbo = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
vfb->fbo_vk = new VulkanFBO();
|
||||
vfb->fbo = new VulkanFBO();
|
||||
// bo_create(vfb->renderWidth, vfb->renderHeight, 1, true, (FBOColorDepth)vfb->colorDepth);
|
||||
if (old.fbo_vk) {
|
||||
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_vk) {
|
||||
/// fbo_bind_as_render_target(vfb->fbo_vk);
|
||||
if (vfb->fbo) {
|
||||
/// BindFramebufferAsRenderTargetvfb->fbo);
|
||||
ClearBuffer();
|
||||
if (!skipCopy && !g_Config.bDisableSlowFramebufEffects) {
|
||||
BlitFramebuffer(vfb, 0, 0, &old, 0, 0, std::min(vfb->bufferWidth, vfb->width), std::min(vfb->height, vfb->bufferHeight), 0);
|
||||
}
|
||||
}
|
||||
delete old.fbo_vk;
|
||||
if (vfb->fbo_vk) {
|
||||
// fbo_bind_as_render_target(vfb->fbo_vk);
|
||||
delete old.fbo;
|
||||
if (vfb->fbo) {
|
||||
// BindFramebufferAsRenderTargetvfb->fbo);
|
||||
}
|
||||
}
|
||||
|
||||
if (!vfb->fbo_vk) {
|
||||
if (!vfb->fbo) {
|
||||
ERROR_LOG(SCEGE, "Error creating FBO! %i x %i", vfb->renderWidth, vfb->renderHeight);
|
||||
}
|
||||
*/
|
||||
|
@ -660,15 +661,15 @@ void FramebufferManagerVulkan::NotifyRenderFramebufferSwitched(VirtualFramebuffe
|
|||
textureCache_->ForgetLastTexture();
|
||||
|
||||
if (useBufferedRendering_) {
|
||||
if (vfb->fbo_vk) {
|
||||
// vfb->fbo_vk->GetColorImageView();
|
||||
if (vfb->fbo) {
|
||||
// vfb->fbo->GetColorImageView();
|
||||
}
|
||||
} else {
|
||||
if (vfb->fbo_vk) {
|
||||
if (vfb->fbo) {
|
||||
// wtf? This should only happen very briefly when toggling bBufferedRendering
|
||||
textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_DESTROYED);
|
||||
delete vfb->fbo_vk;
|
||||
vfb->fbo_vk = nullptr;
|
||||
delete vfb->fbo;
|
||||
vfb->fbo = nullptr;
|
||||
}
|
||||
|
||||
// Let's ignore rendering to targets that have not (yet) been displayed.
|
||||
|
@ -682,7 +683,7 @@ void FramebufferManagerVulkan::NotifyRenderFramebufferSwitched(VirtualFramebuffe
|
|||
|
||||
// Copy depth pixel value from the read framebuffer to the draw framebuffer
|
||||
if (prevVfb && !g_Config.bDisableSlowFramebufEffects) {
|
||||
if (!prevVfb->fbo_vk || !vfb->fbo_vk || !useBufferedRendering_ || !prevVfb->depthUpdated || isClearingDepth) {
|
||||
if (!prevVfb->fbo || !vfb->fbo || !useBufferedRendering_ || !prevVfb->depthUpdated || isClearingDepth) {
|
||||
// If depth wasn't updated, then we're at least "two degrees" away from the data.
|
||||
// This is an optimization: it probably doesn't need to be copied in this case.
|
||||
} else {
|
||||
|
@ -730,12 +731,12 @@ int FramebufferManagerVulkan::GetLineWidth() {
|
|||
}
|
||||
|
||||
void FramebufferManagerVulkan::ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) {
|
||||
if (!useBufferedRendering_ || !vfb->fbo_vk) {
|
||||
if (!useBufferedRendering_ || !vfb->fbo) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
fbo_bind_as_render_target(vfb->fbo);
|
||||
BindFramebufferAsRenderTargetvfb->fbo);
|
||||
|
||||
// Technically, we should at this point re-interpret the bytes of the old format to the new.
|
||||
// That might get tricky, and could cause unnecessary slowness in some games.
|
||||
|
@ -767,8 +768,8 @@ void FramebufferManagerVulkan::BlitFramebufferDepth(VirtualFramebuffer *src, Vir
|
|||
region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
region.extent = { dst->renderWidth, dst->renderHeight, 1 };
|
||||
region.extent.depth = 1;
|
||||
// vkCmdCopyImage(curCmd_, src->fbo_vk->GetDepthStencil()->GetImage(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
// dst->fbo_vk->GetDepthStencil()->GetImage(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, ®ion);
|
||||
// vkCmdCopyImage(curCmd_, src->fbo->GetDepthStencil()->GetImage(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
// dst->fbo->GetDepthStencil()->GetImage(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1, ®ion);
|
||||
|
||||
// If we set dst->depthUpdated here, our optimization above would be pointless.
|
||||
}
|
||||
|
@ -779,7 +780,7 @@ VulkanTexture *FramebufferManagerVulkan::GetFramebufferColor(u32 fbRawAddress, V
|
|||
framebuffer = currentRenderVfb_;
|
||||
}
|
||||
|
||||
if (!framebuffer->fbo_vk || !useBufferedRendering_) {
|
||||
if (!framebuffer->fbo || !useBufferedRendering_) {
|
||||
gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -792,13 +793,13 @@ VulkanTexture *FramebufferManagerVulkan::GetFramebufferColor(u32 fbRawAddress, V
|
|||
}
|
||||
if (!skipCopy && currentRenderVfb_ && framebuffer->fb_address == fbRawAddress) {
|
||||
// TODO: Enable the below code
|
||||
return framebuffer->fbo_vk->GetColor();
|
||||
return nullptr; // framebuffer->fbo->GetColor();
|
||||
/*
|
||||
// TODO: Maybe merge with bvfbs_? Not sure if those could be packing, and they're created at a different size.
|
||||
VulkanFBO *renderCopy = GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, (FBOColorDepth)framebuffer->colorDepth);
|
||||
if (renderCopy) {
|
||||
VirtualFramebuffer copyInfo = *framebuffer;
|
||||
copyInfo.fbo_vk = renderCopy;
|
||||
copyInfo.fbo = renderCopy;
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
@ -824,11 +825,11 @@ VulkanTexture *FramebufferManagerVulkan::GetFramebufferColor(u32 fbRawAddress, V
|
|||
|
||||
return nullptr; // fbo_bind_color_as_texture(renderCopy, 0);
|
||||
} else {
|
||||
return framebuffer->fbo_vk->GetColor();
|
||||
return framebuffer->fbo->GetColor();
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
return framebuffer->fbo_vk->GetColor();
|
||||
return nullptr; // framebuffer->fbo->GetColor();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -945,7 +946,7 @@ void FramebufferManagerVulkan::CopyDisplayToOutput() {
|
|||
}
|
||||
displayFramebuf_ = vfb;
|
||||
|
||||
if (vfb->fbo_vk) {
|
||||
if (vfb->fbo) {
|
||||
struct CardboardSettings cardboardSettings;
|
||||
GetCardboardSettings(&cardboardSettings);
|
||||
|
||||
|
@ -953,8 +954,9 @@ void FramebufferManagerVulkan::CopyDisplayToOutput() {
|
|||
|
||||
// We should not be in a renderpass here so can just copy.
|
||||
|
||||
// GLuint colorTexture = fbo_get_color_texture(vfb->fbo_vk);
|
||||
VulkanTexture *colorTexture = vfb->fbo_vk->GetColor();
|
||||
// GLuint colorTexture = fbo_get_color_texture(vfb->fbo);
|
||||
// VulkanTexture *colorTexture = vfb->fbo->GetColor();
|
||||
VulkanTexture *colorTexture = nullptr;
|
||||
|
||||
int uvRotation = (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) ? g_Config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL;
|
||||
|
||||
|
@ -999,7 +1001,7 @@ void FramebufferManagerVulkan::CopyDisplayToOutput() {
|
|||
} else if (usePostShader_ && !postShaderAtOutputResolution_) {
|
||||
// An additional pass, post-processing shader to the extra FBO.
|
||||
/*
|
||||
fbo_bind_as_render_target(extraFBOs_[0]);
|
||||
BindFramebufferAsRenderTargetextraFBOs_[0]);
|
||||
int fbo_w, fbo_h;
|
||||
fbo_get_dimensions(extraFBOs_[0], &fbo_w, &fbo_h);
|
||||
glstate.viewport.set(0, 0, fbo_w, fbo_h);
|
||||
|
@ -1135,13 +1137,13 @@ bool FramebufferManagerVulkan::CreateDownloadTempBuffer(VirtualFramebuffer *nvfb
|
|||
}
|
||||
|
||||
/*
|
||||
nvfb->fbo = fbo_create(nvfb->width, nvfb->height, 1, false, (FBOColorDepth)nvfb->colorDepth);
|
||||
nvfb->fbo = CreateFramebuffer(nvfb->width, nvfb->height, 1, false, (FBOColorDepth)nvfb->colorDepth);
|
||||
if (!(nvfb->fbo)) {
|
||||
ERROR_LOG(SCEGE, "Error creating FBO! %i x %i", nvfb->renderWidth, nvfb->renderHeight);
|
||||
return false;
|
||||
}
|
||||
|
||||
fbo_bind_as_render_target(nvfb->fbo);
|
||||
BindFramebufferAsRenderTargetnvfb->fbo);
|
||||
ClearBuffer();
|
||||
glDisable(GL_DITHER);
|
||||
*/
|
||||
|
@ -1154,11 +1156,11 @@ void FramebufferManagerVulkan::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb
|
|||
// Discard the previous contents of this buffer where possible.
|
||||
/*
|
||||
if (gl_extensions.GLES3 && glInvalidateFramebuffer != nullptr) {
|
||||
fbo_bind_as_render_target(nvfb->fbo);
|
||||
BindFramebufferAsRenderTargetnvfb->fbo);
|
||||
GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_STENCIL_ATTACHMENT, GL_DEPTH_ATTACHMENT };
|
||||
glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, attachments);
|
||||
} else if (gl_extensions.IsGLES) {
|
||||
fbo_bind_as_render_target(nvfb->fbo);
|
||||
BindFramebufferAsRenderTargetnvfb->fbo);
|
||||
ClearBuffer();
|
||||
}
|
||||
*/
|
||||
|
@ -1221,7 +1223,7 @@ void FramebufferManagerVulkan::BlitFramebuffer(VirtualFramebuffer *dst, int dstX
|
|||
return;
|
||||
}
|
||||
|
||||
// fbo_bind_as_render_target(dst->fbo);
|
||||
// BindFramebufferAsRenderTargetdst->fbo);
|
||||
|
||||
if (useBlit) {
|
||||
// fbo_bind_for_read(src->fbo);
|
||||
|
@ -1652,8 +1654,8 @@ bool FramebufferManagerVulkan::GetFramebuffer(u32 fb_address, int fb_stride, GEB
|
|||
}
|
||||
|
||||
buffer.Allocate(vfb->renderWidth, vfb->renderHeight, GE_FORMAT_8888, false, true);
|
||||
if (vfb->fbo_vk)
|
||||
fbo_bind_for_read(vfb->fbo_vk);
|
||||
if (vfb->fbo)
|
||||
fbo_bind_for_read(vfb->fbo);
|
||||
if (gl_extensions.GLES3 || !gl_extensions.IsGLES)
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "i18n/i18n.h"
|
||||
#include "math/math_util.h"
|
||||
#include "profiler/profiler.h"
|
||||
#include "thin3d/thin3d.h"
|
||||
#include "Common/ColorConv.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/Host.h"
|
||||
|
@ -637,9 +638,9 @@ void TextureCacheVulkan::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFram
|
|||
|
||||
nextTexture_ = entry;
|
||||
} else {
|
||||
if (framebuffer->fbo_vk) {
|
||||
delete framebuffer->fbo_vk;
|
||||
framebuffer->fbo_vk = 0;
|
||||
if (framebuffer->fbo) {
|
||||
delete framebuffer->fbo;
|
||||
framebuffer->fbo = nullptr;
|
||||
}
|
||||
gstate_c.needShaderTexClamp = false;
|
||||
}
|
||||
|
|
|
@ -14,10 +14,11 @@
|
|||
//commented out until someone bothers to maintain it
|
||||
//#include "GPU/GLES/VertexDecoder.h"
|
||||
|
||||
Debugger_DisplayList::Debugger_DisplayList(DebugInterface *_cpu, MainWindow* mainWindow_, QWidget *parent) :
|
||||
Debugger_DisplayList::Debugger_DisplayList(DebugInterface *_cpu, Draw::DrawContext *draw, MainWindow* mainWindow_, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::Debugger_DisplayList),
|
||||
cpu(_cpu),
|
||||
draw_(draw),
|
||||
mainWindow(mainWindow_),
|
||||
currentRenderFrameDisplay(0),
|
||||
currentTextureDisplay(0),
|
||||
|
@ -1348,12 +1349,12 @@ void Debugger_DisplayList::UpdateRenderBufferGUI()
|
|||
}
|
||||
else
|
||||
{
|
||||
fbo_get_dimensions(currentTextureDisplay, &FRAME_WIDTH, &FRAME_HEIGHT);
|
||||
draw_->GetFramebufferDimensions(currentTextureDisplay, &FRAME_WIDTH, &FRAME_HEIGHT);
|
||||
data = new u8[FRAME_WIDTH * FRAME_HEIGHT * 4];
|
||||
memset(data,0,FRAME_WIDTH * FRAME_HEIGHT * 4);
|
||||
if(currentRenderFrameDisplay == 0)
|
||||
{
|
||||
fbo_bind_as_texture(currentTextureDisplay, 0, FB_COLOR_BIT, 0);
|
||||
draw_->BindFramebufferAsTexture(currentTextureDisplay, 0, Draw::FB_COLOR_BIT, 0);
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);
|
||||
}
|
||||
}
|
||||
|
@ -1439,7 +1440,7 @@ void Debugger_DisplayList::UpdateRenderBufferListGUI()
|
|||
void Debugger_DisplayList::on_fboList_itemClicked(QTreeWidgetItem *item, int column)
|
||||
{
|
||||
u64 addr = item->data(0,Qt::UserRole).toULongLong();
|
||||
FBO* fbo = (FBO*)addr;
|
||||
Draw::Framebuffer * fbo = (Draw::Framebuffer *)addr;
|
||||
currentTextureDisplay = fbo;
|
||||
UpdateRenderBufferGUI();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef DEBUGGER_DISPLAYLIST_H
|
||||
#define DEBUGGER_DISPLAYLIST_H
|
||||
#pragma once
|
||||
|
||||
#include "Core/Debugger/DebugInterface.h"
|
||||
|
||||
|
@ -7,7 +6,7 @@
|
|||
#include <QTreeWidgetItem>
|
||||
|
||||
#include "GPU/GPUState.h"
|
||||
#include "GPU/GLES/FBO.h"
|
||||
#include "thin3d/thin3d.h"
|
||||
|
||||
class MainWindow;
|
||||
namespace Ui {
|
||||
|
@ -38,7 +37,7 @@ class Debugger_DisplayList : public QDialog
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Debugger_DisplayList(DebugInterface *_cpu, MainWindow *mainWindow_, QWidget *parent = 0);
|
||||
Debugger_DisplayList(DebugInterface *_cpu, Draw::DrawContext *draw, MainWindow *mainWindow_, QWidget *parent = 0);
|
||||
~Debugger_DisplayList();
|
||||
|
||||
void UpdateDisplayList();
|
||||
|
@ -88,12 +87,13 @@ private:
|
|||
|
||||
Ui::Debugger_DisplayList *ui;
|
||||
DebugInterface* cpu;
|
||||
Draw::DrawContext* draw_;
|
||||
MainWindow* mainWindow;
|
||||
QTreeWidgetItem* displayListRowSelected;
|
||||
QTreeWidgetItem* displayListDataSelected;
|
||||
QTreeWidgetItem* textureDataSelected;
|
||||
int currentRenderFrameDisplay;
|
||||
FBO* currentTextureDisplay;
|
||||
Draw::Framebuffer *currentTextureDisplay;
|
||||
float fboZoomFactor;
|
||||
int maxVtxDisplay;
|
||||
int maxIdxDisplay;
|
||||
|
@ -102,5 +102,3 @@ private:
|
|||
std::map<u32, int> vtxBufferSize;
|
||||
std::map<u32, int> idxBufferSize;
|
||||
};
|
||||
|
||||
#endif // DEBUGGER_DISPLAYLIST_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "debugger_memorytex.h"
|
||||
#include "GPU/GLES/GLStateCache.h"
|
||||
#include "gfx/GLStateCache.h"
|
||||
#include "gfx/gl_common.h"
|
||||
#include "gfx/gl_lost_manager.h"
|
||||
#include "ui_debugger_memorytex.h"
|
||||
|
|
|
@ -140,7 +140,7 @@ void MainWindow::Boot()
|
|||
|
||||
memoryWindow = new Debugger_Memory(currentDebugMIPS, this, this);
|
||||
memoryTexWindow = new Debugger_MemoryTex(this);
|
||||
displaylistWindow = new Debugger_DisplayList(currentDebugMIPS, this, this);
|
||||
displaylistWindow = new Debugger_DisplayList(currentDebugMIPS, gpu->GetDrawContext(), this, this);
|
||||
|
||||
notifyMapsLoaded();
|
||||
|
||||
|
|
|
@ -525,7 +525,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
|
|||
void NativeInitGraphics(GraphicsContext *graphicsContext) {
|
||||
using namespace Draw;
|
||||
Core_SetGraphicsContext(graphicsContext);
|
||||
g_draw = graphicsContext->CreateDrawContext();
|
||||
g_draw = graphicsContext->GetDrawContext();
|
||||
|
||||
ui_draw2d.SetAtlas(&ui_atlas);
|
||||
ui_draw2d_front.SetAtlas(&ui_atlas);
|
||||
|
@ -656,11 +656,6 @@ void NativeShutdownGraphics() {
|
|||
|
||||
colorPipeline->Release();
|
||||
texColorPipeline->Release();
|
||||
|
||||
// TODO: Reconsider this annoying ref counting stuff.
|
||||
if (g_draw->Release()) {
|
||||
g_draw = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void TakeScreenshot() {
|
||||
|
|
|
@ -122,20 +122,22 @@ bool ManagedTexture::LoadFromFile(const std::string &filename, ImageFileType typ
|
|||
size_t fileSize;
|
||||
uint8_t *buffer = VFSReadFile(filename.c_str(), &fileSize);
|
||||
if (!buffer) {
|
||||
ELOG("Failed to read file %s", filename.c_str());
|
||||
return false;
|
||||
}
|
||||
bool retval = LoadFromFileData(buffer, fileSize, type);
|
||||
if (retval) {
|
||||
filename_ = filename;
|
||||
}
|
||||
else {
|
||||
ELOG("%s: Failed to load texture %s", __FUNCTION__, filename.c_str());
|
||||
} else {
|
||||
ELOG("Failed to load texture %s", filename.c_str());
|
||||
}
|
||||
delete[] buffer;
|
||||
return retval;
|
||||
}
|
||||
|
||||
ManagedTexture *CreateTextureFromFile(Draw::DrawContext *draw, const char *filename, ImageFileType type) {
|
||||
if (!draw)
|
||||
return nullptr;
|
||||
ManagedTexture *mtex = new ManagedTexture(draw);
|
||||
if (!mtex->LoadFromFile(filename, type)) {
|
||||
delete mtex;
|
||||
|
@ -146,6 +148,8 @@ ManagedTexture *CreateTextureFromFile(Draw::DrawContext *draw, const char *filen
|
|||
|
||||
// TODO: Remove the code duplication between this and LoadFromFileData
|
||||
ManagedTexture *CreateTextureFromFileData(Draw::DrawContext *draw, const uint8_t *data, int size, ImageFileType type) {
|
||||
if (!draw)
|
||||
return nullptr;
|
||||
ManagedTexture *mtex = new ManagedTexture(draw);
|
||||
mtex->LoadFromFileData(data, size, type);
|
||||
return mtex;
|
||||
|
|
|
@ -15,10 +15,6 @@ void D3D11Context::SwapBuffers() {
|
|||
swapChain_->Present(0, 0);
|
||||
}
|
||||
|
||||
Draw::DrawContext *D3D11Context::CreateDrawContext() {
|
||||
return Draw::T3DCreateD3D11Context(device_, context_);
|
||||
}
|
||||
|
||||
static void GetRes(HWND hWnd, int &xres, int &yres) {
|
||||
RECT rc;
|
||||
GetClientRect(hWnd, &rc);
|
||||
|
@ -199,6 +195,7 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
|||
int xres, yres;
|
||||
GetRes(hWnd_, xres, yres);
|
||||
|
||||
draw_ = Draw::T3DCreateD3D11Context(device_, context_);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -211,8 +208,6 @@ void D3D11Context::Resize() {
|
|||
bool h_changed = pp.BackBufferHeight != yres;
|
||||
|
||||
if (device && (w_changed || h_changed)) {
|
||||
// DX9::fbo_shutdown();
|
||||
|
||||
pp.BackBufferWidth = xres;
|
||||
pp.BackBufferHeight = yres;
|
||||
HRESULT hr = device_->Reset(&pp);
|
||||
|
@ -221,19 +216,20 @@ void D3D11Context::Resize() {
|
|||
ERROR_LOG_REPORT(G3D, "Unable to reset D3D device");
|
||||
PanicAlert("Unable to reset D3D11 device");
|
||||
}
|
||||
// DX9::fbo_init(d3d);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void D3D11Context::Shutdown() {
|
||||
delete draw_;
|
||||
draw_ = nullptr;
|
||||
|
||||
context_->Release();
|
||||
context_ = nullptr;
|
||||
device_->Release();
|
||||
device_ = nullptr;
|
||||
/*
|
||||
DX9::DestroyShaders();
|
||||
DX9::fbo_shutdown();
|
||||
device->EndScene();
|
||||
device->Release();
|
||||
d3d->Release();
|
||||
|
|
|
@ -27,7 +27,7 @@ class DrawContext;
|
|||
|
||||
class D3D11Context : public WindowsGraphicsContext {
|
||||
public:
|
||||
D3D11Context() : adapterId(-1), hDC(nullptr), hWnd_(nullptr), hD3D11(nullptr) {
|
||||
D3D11Context() : draw_(nullptr), adapterId(-1), hDC(nullptr), hWnd_(nullptr), hD3D11(nullptr) {
|
||||
}
|
||||
|
||||
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
|
||||
|
@ -37,9 +37,10 @@ public:
|
|||
|
||||
void Resize() override;
|
||||
|
||||
Draw::DrawContext *CreateDrawContext() override;
|
||||
Draw::DrawContext *GetDrawContext() override { return draw_; }
|
||||
|
||||
private:
|
||||
Draw::DrawContext *draw_;
|
||||
ID3D11Device *device_;
|
||||
ID3D11DeviceContext *context_;
|
||||
IDXGISwapChain *swapChain_ = nullptr;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include <d3d9.h>
|
||||
|
||||
#include "gfx/d3d9_state.h"
|
||||
#include "GPU/Directx9/helper/dx_fbo.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "util/text/utf8.h"
|
||||
|
@ -16,21 +15,17 @@
|
|||
#include "thin3d/d3dx9_loader.h"
|
||||
|
||||
void D3D9Context::SwapBuffers() {
|
||||
if (has9Ex) {
|
||||
deviceEx->EndScene();
|
||||
deviceEx->PresentEx(NULL, NULL, NULL, NULL, 0);
|
||||
deviceEx->BeginScene();
|
||||
if (has9Ex_) {
|
||||
deviceEx_->EndScene();
|
||||
deviceEx_->PresentEx(NULL, NULL, NULL, NULL, 0);
|
||||
deviceEx_->BeginScene();
|
||||
} else {
|
||||
device->EndScene();
|
||||
device->Present(NULL, NULL, NULL, NULL);
|
||||
device->BeginScene();
|
||||
device_->EndScene();
|
||||
device_->Present(NULL, NULL, NULL, NULL);
|
||||
device_->BeginScene();
|
||||
}
|
||||
}
|
||||
|
||||
Draw::DrawContext *D3D9Context::CreateDrawContext() {
|
||||
return Draw::T3DCreateDX9Context(d3d, d3dEx, adapterId, device, deviceEx);
|
||||
}
|
||||
|
||||
typedef HRESULT (__stdcall *DIRECT3DCREATE9EX)(UINT, IDirect3D9Ex**);
|
||||
|
||||
bool IsWin7OrLater() {
|
||||
|
@ -54,12 +49,12 @@ void D3D9Context::SwapInterval(int interval) {
|
|||
|
||||
bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
||||
bool windowed = true;
|
||||
hWnd = wnd;
|
||||
hWnd_ = wnd;
|
||||
|
||||
DIRECT3DCREATE9EX g_pfnCreate9ex;
|
||||
|
||||
hD3D9 = LoadLibrary(TEXT("d3d9.dll"));
|
||||
if (!hD3D9) {
|
||||
hD3D9_ = LoadLibrary(TEXT("d3d9.dll"));
|
||||
if (!hD3D9_) {
|
||||
ELOG("Missing d3d9.dll");
|
||||
*error_message = "D3D9.dll missing - try reinstalling DirectX.";
|
||||
return false;
|
||||
|
@ -71,21 +66,21 @@ bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
|||
return false;
|
||||
}
|
||||
|
||||
g_pfnCreate9ex = (DIRECT3DCREATE9EX)GetProcAddress(hD3D9, "Direct3DCreate9Ex");
|
||||
has9Ex = (g_pfnCreate9ex != NULL) && IsVistaOrHigher();
|
||||
g_pfnCreate9ex = (DIRECT3DCREATE9EX)GetProcAddress(hD3D9_, "Direct3DCreate9Ex");
|
||||
has9Ex_ = (g_pfnCreate9ex != NULL) && IsVistaOrHigher();
|
||||
|
||||
if (has9Ex) {
|
||||
HRESULT result = g_pfnCreate9ex(D3D_SDK_VERSION, &d3dEx);
|
||||
d3d = d3dEx;
|
||||
if (has9Ex_) {
|
||||
HRESULT result = g_pfnCreate9ex(D3D_SDK_VERSION, &d3dEx_);
|
||||
d3d_ = d3dEx_;
|
||||
if (FAILED(result)) {
|
||||
FreeLibrary(hD3D9);
|
||||
FreeLibrary(hD3D9_);
|
||||
*error_message = "D3D9Ex available but context creation failed. Try reinstalling DirectX.";
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
d3d = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
if (!d3d) {
|
||||
FreeLibrary(hD3D9);
|
||||
d3d_ = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
if (!d3d_) {
|
||||
FreeLibrary(hD3D9_);
|
||||
*error_message = "Failed to create D3D9 context. Try reinstalling DirectX.";
|
||||
return false;
|
||||
}
|
||||
|
@ -94,21 +89,21 @@ bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
|||
D3DCAPS9 d3dCaps;
|
||||
|
||||
D3DDISPLAYMODE d3ddm;
|
||||
if (FAILED(d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) {
|
||||
if (FAILED(d3d_->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) {
|
||||
*error_message = "GetAdapterDisplayMode failed";
|
||||
d3d->Release();
|
||||
d3d_->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
adapterId = D3DADAPTER_DEFAULT;
|
||||
if (FAILED(d3d->GetDeviceCaps(adapterId, D3DDEVTYPE_HAL, &d3dCaps))) {
|
||||
adapterId_ = D3DADAPTER_DEFAULT;
|
||||
if (FAILED(d3d_->GetDeviceCaps(adapterId_, D3DDEVTYPE_HAL, &d3dCaps))) {
|
||||
*error_message = "GetDeviceCaps failed (???)";
|
||||
d3d->Release();
|
||||
d3d_->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT hr;
|
||||
if (FAILED(hr = d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT,
|
||||
if (FAILED(hr = d3d_->CheckDeviceFormat(D3DADAPTER_DEFAULT,
|
||||
D3DDEVTYPE_HAL,
|
||||
d3ddm.Format,
|
||||
D3DUSAGE_DEPTHSTENCIL,
|
||||
|
@ -116,7 +111,7 @@ bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
|||
D3DFMT_D24S8))) {
|
||||
if (hr == D3DERR_NOTAVAILABLE) {
|
||||
*error_message = "D24S8 depth/stencil not available";
|
||||
d3d->Release();
|
||||
d3d_->Release();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -128,86 +123,85 @@ bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
|
|||
dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
|
||||
|
||||
int xres, yres;
|
||||
GetRes(hWnd, xres, yres);
|
||||
GetRes(hWnd_, xres, yres);
|
||||
|
||||
memset(&pp, 0, sizeof(pp));
|
||||
pp.BackBufferWidth = xres;
|
||||
pp.BackBufferHeight = yres;
|
||||
pp.BackBufferFormat = d3ddm.Format;
|
||||
pp.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
pp.Windowed = windowed;
|
||||
pp.hDeviceWindow = wnd;
|
||||
pp.EnableAutoDepthStencil = true;
|
||||
pp.AutoDepthStencilFormat = D3DFMT_D24S8;
|
||||
pp.PresentationInterval = (g_Config.bVSync) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
presentParams_ = {};
|
||||
presentParams_.BackBufferWidth = xres;
|
||||
presentParams_.BackBufferHeight = yres;
|
||||
presentParams_.BackBufferFormat = d3ddm.Format;
|
||||
presentParams_.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
presentParams_.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
presentParams_.Windowed = windowed;
|
||||
presentParams_.hDeviceWindow = wnd;
|
||||
presentParams_.EnableAutoDepthStencil = true;
|
||||
presentParams_.AutoDepthStencilFormat = D3DFMT_D24S8;
|
||||
presentParams_.PresentationInterval = (g_Config.bVSync) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
|
||||
if (has9Ex) {
|
||||
if (has9Ex_) {
|
||||
if (windowed && IsWin7OrLater()) {
|
||||
// This new flip mode gives higher performance.
|
||||
// TODO: This makes it slower?
|
||||
// This "new" flip mode should give higher performance but doesn't.
|
||||
//pp.BackBufferCount = 2;
|
||||
//pp.SwapEffect = D3DSWAPEFFECT_FLIPEX;
|
||||
}
|
||||
hr = d3dEx->CreateDeviceEx(adapterId, D3DDEVTYPE_HAL, wnd, dwBehaviorFlags, &pp, NULL, &deviceEx);
|
||||
device = deviceEx;
|
||||
hr = d3dEx_->CreateDeviceEx(adapterId_, D3DDEVTYPE_HAL, wnd, dwBehaviorFlags, &presentParams_, NULL, &deviceEx_);
|
||||
device_ = deviceEx_;
|
||||
} else {
|
||||
hr = d3d->CreateDevice(adapterId, D3DDEVTYPE_HAL, wnd, dwBehaviorFlags, &pp, &device);
|
||||
hr = d3d_->CreateDevice(adapterId_, D3DDEVTYPE_HAL, wnd, dwBehaviorFlags, &presentParams_, &device_);
|
||||
}
|
||||
|
||||
if (FAILED(hr)) {
|
||||
*error_message = "Failed to create D3D device";
|
||||
d3d->Release();
|
||||
d3d_->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
device->BeginScene();
|
||||
DX9::pD3Ddevice = device;
|
||||
DX9::pD3DdeviceEx = deviceEx;
|
||||
device_->BeginScene();
|
||||
DX9::pD3Ddevice = device_;
|
||||
DX9::pD3DdeviceEx = deviceEx_;
|
||||
|
||||
DX9::fbo_init(d3d, device);
|
||||
|
||||
if (deviceEx && IsWin7OrLater()) {
|
||||
if (deviceEx_ && IsWin7OrLater()) {
|
||||
// TODO: This makes it slower?
|
||||
//deviceEx->SetMaximumFrameLatency(1);
|
||||
}
|
||||
|
||||
draw_ = Draw::T3DCreateDX9Context(d3d_, d3dEx_, -1, device_, deviceEx_);
|
||||
if (draw_)
|
||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER);
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3D9Context::Resize() {
|
||||
// This should only be called from the emu thread.
|
||||
|
||||
int xres, yres;
|
||||
GetRes(hWnd, xres, yres);
|
||||
bool w_changed = pp.BackBufferWidth != xres;
|
||||
bool h_changed = pp.BackBufferHeight != yres;
|
||||
GetRes(hWnd_, xres, yres);
|
||||
bool w_changed = presentParams_.BackBufferWidth != xres;
|
||||
bool h_changed = presentParams_.BackBufferHeight != yres;
|
||||
|
||||
if (device && (w_changed || h_changed)) {
|
||||
DX9::fbo_shutdown();
|
||||
|
||||
pp.BackBufferWidth = xres;
|
||||
pp.BackBufferHeight = yres;
|
||||
HRESULT hr = device->Reset(&pp);
|
||||
if (device_ && (w_changed || h_changed)) {
|
||||
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER);
|
||||
presentParams_.BackBufferWidth = xres;
|
||||
presentParams_.BackBufferHeight = yres;
|
||||
HRESULT hr = device_->Reset(&presentParams_);
|
||||
if (FAILED(hr)) {
|
||||
// Had to remove DXGetErrorStringA calls here because dxerr.lib is deprecated and will not link with VS 2015.
|
||||
ERROR_LOG_REPORT(G3D, "Unable to reset D3D device");
|
||||
PanicAlert("Unable to reset D3D9 device");
|
||||
}
|
||||
DX9::fbo_init(d3d, device);
|
||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
void D3D9Context::Shutdown() {
|
||||
DX9::fbo_shutdown();
|
||||
device->EndScene();
|
||||
device->Release();
|
||||
d3d->Release();
|
||||
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER);
|
||||
delete draw_;
|
||||
draw_ = nullptr;
|
||||
device_->EndScene();
|
||||
device_->Release();
|
||||
d3d_->Release();
|
||||
UnloadD3DXDynamic();
|
||||
DX9::pD3Ddevice = nullptr;
|
||||
DX9::pD3DdeviceEx = nullptr;
|
||||
device = nullptr;
|
||||
hWnd = nullptr;
|
||||
FreeLibrary(hD3D9);
|
||||
hD3D9 = nullptr;
|
||||
device_ = nullptr;
|
||||
hWnd_ = nullptr;
|
||||
FreeLibrary(hD3D9_);
|
||||
hD3D9_ = nullptr;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace Draw {
|
|||
|
||||
class D3D9Context : public WindowsGraphicsContext {
|
||||
public:
|
||||
D3D9Context() : has9Ex(false), d3d(nullptr), d3dEx(nullptr), adapterId(-1), device(nullptr), deviceEx(nullptr), hDC(nullptr), hWnd(nullptr), hD3D9(nullptr), pp{} {
|
||||
D3D9Context() : draw_(nullptr), has9Ex_(false), d3d_(nullptr), d3dEx_(nullptr), adapterId_(-1), device_(nullptr), deviceEx_(nullptr), hDC_(nullptr), hWnd_(nullptr), hD3D9_(nullptr), presentParams_{} {
|
||||
}
|
||||
|
||||
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
|
||||
|
@ -39,18 +39,19 @@ public:
|
|||
|
||||
void Resize() override;
|
||||
|
||||
Draw::DrawContext *CreateDrawContext() override;
|
||||
Draw::DrawContext *GetDrawContext() override { return draw_; }
|
||||
|
||||
private:
|
||||
bool has9Ex;
|
||||
LPDIRECT3D9 d3d;
|
||||
LPDIRECT3D9EX d3dEx;
|
||||
int adapterId;
|
||||
LPDIRECT3DDEVICE9 device;
|
||||
LPDIRECT3DDEVICE9EX deviceEx;
|
||||
HDC hDC; // Private GDI Device Context
|
||||
HWND hWnd; // Holds Our Window Handle
|
||||
HMODULE hD3D9;
|
||||
D3DPRESENT_PARAMETERS pp;
|
||||
Draw::DrawContext *draw_;
|
||||
bool has9Ex_;
|
||||
LPDIRECT3D9 d3d_;
|
||||
LPDIRECT3D9EX d3dEx_;
|
||||
int adapterId_;
|
||||
LPDIRECT3DDEVICE9 device_;
|
||||
LPDIRECT3DDEVICE9EX deviceEx_;
|
||||
HDC hDC_; // Private GDI Device Context
|
||||
HWND hWnd_; // Holds Our Window Handle
|
||||
HMODULE hD3D9_;
|
||||
D3DPRESENT_PARAMETERS presentParams_;
|
||||
};
|
||||
|
||||
|
|
|
@ -362,6 +362,8 @@ bool WindowsGLContext::Init(HINSTANCE hInst, HWND window, std::string *error_mes
|
|||
pauseEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
resumeEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
return true; // Success
|
||||
}
|
||||
|
||||
|
@ -372,6 +374,8 @@ void WindowsGLContext::SwapInterval(int interval) {
|
|||
}
|
||||
|
||||
void WindowsGLContext::Shutdown() {
|
||||
delete draw_;
|
||||
draw_ = nullptr;
|
||||
CloseHandle(pauseEvent);
|
||||
CloseHandle(resumeEvent);
|
||||
if (hRC) {
|
||||
|
@ -399,8 +403,3 @@ void WindowsGLContext::Shutdown() {
|
|||
|
||||
void WindowsGLContext::Resize() {
|
||||
}
|
||||
|
||||
Draw::DrawContext *WindowsGLContext::CreateDrawContext() {
|
||||
CheckGLExtensions();
|
||||
return Draw::T3DCreateGLContext();
|
||||
}
|
||||
|
|
|
@ -21,9 +21,10 @@ public:
|
|||
|
||||
void Resize() override;
|
||||
|
||||
Draw::DrawContext *CreateDrawContext() override;
|
||||
Draw::DrawContext *GetDrawContext() override { return draw_; }
|
||||
|
||||
private:
|
||||
Draw::DrawContext *draw_;
|
||||
HDC hDC; // Private GDI Device Context
|
||||
HGLRC hRC; // Permanent Rendering Context
|
||||
HWND hWnd; // Holds Our Window Handle
|
||||
|
@ -32,5 +33,6 @@ private:
|
|||
HANDLE pauseEvent;
|
||||
HANDLE resumeEvent;
|
||||
|
||||
int xres, yres;
|
||||
int xres;
|
||||
int yres;
|
||||
};
|
||||
|
|
|
@ -193,10 +193,15 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m
|
|||
g_Vulkan->InitSurfaceWin32(hInst, hWnd);
|
||||
g_Vulkan->InitObjects(true);
|
||||
|
||||
draw_ = Draw::T3DCreateVulkanContext(g_Vulkan);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WindowsVulkanContext::Shutdown() {
|
||||
delete draw_;
|
||||
draw_ = nullptr;
|
||||
|
||||
g_Vulkan->WaitUntilQueueIdle();
|
||||
g_Vulkan->DestroyObjects();
|
||||
g_Vulkan->DestroyDevice();
|
||||
|
@ -207,10 +212,6 @@ void WindowsVulkanContext::Shutdown() {
|
|||
finalize_glslang();
|
||||
}
|
||||
|
||||
Draw::DrawContext *WindowsVulkanContext::CreateDrawContext() {
|
||||
return Draw::T3DCreateVulkanContext(g_Vulkan);
|
||||
}
|
||||
|
||||
void WindowsVulkanContext::SwapBuffers() {
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
class WindowsVulkanContext : public WindowsGraphicsContext {
|
||||
public:
|
||||
WindowsVulkanContext() : draw_(nullptr) {}
|
||||
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
|
||||
void Shutdown() override;
|
||||
void SwapInterval(int interval) override;
|
||||
|
@ -31,6 +32,8 @@ public:
|
|||
|
||||
void *GetAPIContext();
|
||||
|
||||
Draw::DrawContext *CreateDrawContext() override;
|
||||
Draw::DrawContext *GetDrawContext() override { return draw_; }
|
||||
private:
|
||||
Draw::DrawContext *draw_;
|
||||
};
|
||||
|
||||
|
|
|
@ -229,8 +229,6 @@ EXEC_AND_LIB_FILES := \
|
|||
$(SRC)/GPU/GLES/FramebufferManagerGLES.cpp \
|
||||
$(SRC)/GPU/GLES/DepalettizeShaderGLES.cpp \
|
||||
$(SRC)/GPU/GLES/GPU_GLES.cpp.arm \
|
||||
$(SRC)/GPU/GLES/GLStateCache.cpp.arm \
|
||||
$(SRC)/GPU/GLES/FBO.cpp \
|
||||
$(SRC)/GPU/GLES/StencilBufferGLES.cpp.arm \
|
||||
$(SRC)/GPU/GLES/TextureCacheGLES.cpp.arm \
|
||||
$(SRC)/GPU/GLES/DrawEngineGLES.cpp.arm \
|
||||
|
|
|
@ -74,18 +74,18 @@ public:
|
|||
|
||||
class AndroidEGLGraphicsContext : public AndroidGraphicsContext {
|
||||
public:
|
||||
AndroidEGLGraphicsContext() : wnd_(nullptr), gl(nullptr) {}
|
||||
AndroidEGLGraphicsContext() : draw_(nullptr), wnd_(nullptr), gl(nullptr) {}
|
||||
bool Init(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) override;
|
||||
void Shutdown() override;
|
||||
void SwapBuffers() override;
|
||||
void SwapInterval(int interval) override {}
|
||||
void Resize() override {}
|
||||
Draw::DrawContext *CreateDrawContext() override {
|
||||
CheckGLExtensions();
|
||||
return Draw::T3DCreateGLContext();
|
||||
Draw::DrawContext *GetDrawContext() override {
|
||||
return draw_;
|
||||
}
|
||||
|
||||
private:
|
||||
Draw::DrawContext *draw_;
|
||||
ANativeWindow *wnd_;
|
||||
cInterfaceBase *gl;
|
||||
};
|
||||
|
@ -108,7 +108,7 @@ bool AndroidEGLGraphicsContext::Init(ANativeWindow *wnd, int backbufferWidth, in
|
|||
// This workaround seems only be needed on some really old devices.
|
||||
if (androidVersion < ANDROID_VERSION_ICS) {
|
||||
switch (backbufferFormat) {
|
||||
case 4: // PixelFormat.RGB_565
|
||||
case 4: // PixelFormat.RGB_565
|
||||
use565 = true;
|
||||
break;
|
||||
default:
|
||||
|
@ -123,10 +123,14 @@ bool AndroidEGLGraphicsContext::Init(ANativeWindow *wnd, int backbufferWidth, in
|
|||
return false;
|
||||
}
|
||||
gl->MakeCurrent();
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
return true;
|
||||
}
|
||||
|
||||
void AndroidEGLGraphicsContext::Shutdown() {
|
||||
delete draw_;
|
||||
draw_ = nullptr;
|
||||
gl->ClearCurrent();
|
||||
gl->Shutdown();
|
||||
delete gl;
|
||||
|
@ -140,16 +144,22 @@ void AndroidEGLGraphicsContext::SwapBuffers() {
|
|||
// Doesn't do much. Just to fit in.
|
||||
class AndroidJavaEGLGraphicsContext : public GraphicsContext {
|
||||
public:
|
||||
AndroidJavaEGLGraphicsContext() {}
|
||||
bool Init(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) { return true; }
|
||||
AndroidJavaEGLGraphicsContext() {
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
}
|
||||
~AndroidJavaEGLGraphicsContext() {
|
||||
delete draw_;
|
||||
}
|
||||
void Shutdown() override {}
|
||||
void SwapBuffers() override {}
|
||||
void SwapInterval(int interval) override {}
|
||||
void Resize() override {}
|
||||
Draw::DrawContext *CreateDrawContext() override {
|
||||
CheckGLExtensions();
|
||||
return Draw::T3DCreateGLContext();
|
||||
Draw::DrawContext *GetDrawContext() override {
|
||||
return draw_;
|
||||
}
|
||||
private:
|
||||
Draw::DrawContext *draw_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -158,7 +168,7 @@ static VulkanContext *g_Vulkan;
|
|||
|
||||
class AndroidVulkanContext : public AndroidGraphicsContext {
|
||||
public:
|
||||
AndroidVulkanContext() {}
|
||||
AndroidVulkanContext() : draw_(nullptr) {}
|
||||
bool Init(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) override;
|
||||
void Shutdown() override;
|
||||
void SwapInterval(int interval) override;
|
||||
|
@ -167,9 +177,11 @@ public:
|
|||
|
||||
void *GetAPIContext() override { return g_Vulkan; }
|
||||
|
||||
Draw::DrawContext *CreateDrawContext() override {
|
||||
return Draw::T3DCreateVulkanContext(g_Vulkan);
|
||||
Draw::DrawContext *GetDrawContext() override {
|
||||
return draw_;
|
||||
}
|
||||
private:
|
||||
Draw::DrawContext *draw_;
|
||||
};
|
||||
|
||||
struct VulkanLogOptions {
|
||||
|
@ -274,7 +286,7 @@ bool AndroidVulkanContext::Init(ANativeWindow *wnd, int desiredBackbufferSizeX,
|
|||
g_Vulkan->InitDebugMsgCallback(&Vulkan_Dbg, bits, &g_LogOptions);
|
||||
}
|
||||
g_Vulkan->InitObjects(true);
|
||||
|
||||
draw_ = Draw::T3DCreateVulkanContext(g_Vulkan);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -283,6 +295,9 @@ void AndroidVulkanContext::Shutdown() {
|
|||
g_Vulkan->DestroyObjects();
|
||||
g_Vulkan->DestroyDebugMsgCallback();
|
||||
g_Vulkan->DestroyDevice();
|
||||
delete draw_;
|
||||
draw_ = nullptr;
|
||||
|
||||
delete g_Vulkan;
|
||||
g_Vulkan = nullptr;
|
||||
|
||||
|
@ -296,7 +311,7 @@ void AndroidVulkanContext::Resize() {
|
|||
g_Vulkan->WaitUntilQueueIdle();
|
||||
g_Vulkan->DestroyObjects();
|
||||
|
||||
// backbufferResize updated these values. TODO: Notify another way?
|
||||
// backbufferResize updated these values. TODO: Notify another way?
|
||||
g_Vulkan->ReinitSurfaceAndroid(pixel_xres, pixel_yres);
|
||||
g_Vulkan->InitObjects(g_Vulkan);
|
||||
}
|
||||
|
@ -330,7 +345,7 @@ static int deviceType;
|
|||
static int display_dpi;
|
||||
static int display_xres;
|
||||
static int display_yres;
|
||||
static int backbuffer_format; // Android PixelFormat enum
|
||||
static int backbuffer_format; // Android PixelFormat enum
|
||||
|
||||
static int desiredBackbufferSizeX;
|
||||
static int desiredBackbufferSizeY;
|
||||
|
@ -397,7 +412,7 @@ std::string System_GetProperty(SystemProperty prop) {
|
|||
switch (prop) {
|
||||
case SYSPROP_NAME:
|
||||
return systemName;
|
||||
case SYSPROP_LANGREGION: // "en_US"
|
||||
case SYSPROP_LANGREGION: // "en_US"
|
||||
return langRegion;
|
||||
case SYSPROP_MOGA_VERSION:
|
||||
return mogaVersion;
|
||||
|
@ -427,7 +442,7 @@ int System_GetPropertyInt(SystemProperty prop) {
|
|||
case SYSPROP_DISPLAY_REFRESH_RATE:
|
||||
return (int)(display_hz * 1000.0);
|
||||
case SYSPROP_SUPPORTS_PERMISSIONS:
|
||||
return androidVersion >= 23; // 6.0 Marshmallow introduced run time permissions.
|
||||
return androidVersion >= 23; // 6.0 Marshmallow introduced run time permissions.
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
@ -480,7 +495,7 @@ extern "C" jstring Java_org_ppsspp_ppsspp_NativeApp_queryConfig
|
|||
}
|
||||
|
||||
extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init
|
||||
(JNIEnv *env, jclass, jstring jmodel, jint jdeviceType, jstring jlangRegion, jstring japkpath,
|
||||
(JNIEnv *env, jclass, jstring jmodel, jint jdeviceType, jstring jlangRegion, jstring japkpath,
|
||||
jstring jdataDir, jstring jexternalDir, jstring jlibraryDir, jstring jcacheDir, jstring jshortcutParam,
|
||||
jint jAndroidVersion, jstring jboard) {
|
||||
jniEnvUI = env;
|
||||
|
@ -572,7 +587,7 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_audioInit(JNIEnv *, jclass) {
|
|||
sampleRate = 44100;
|
||||
}
|
||||
|
||||
ILOG("NativeApp.audioInit() -- Using OpenSL audio! frames/buffer: %i optimal sr: %i actual sr: %i", optimalFramesPerBuffer, optimalSampleRate, sampleRate);
|
||||
ILOG("NativeApp.audioInit() -- Using OpenSL audio! frames/buffer: %i optimal sr: %i actual sr: %i", optimalFramesPerBuffer, optimalSampleRate, sampleRate);
|
||||
AndroidAudio_Init(&NativeMix, library_path, framesPerBuffer, sampleRate);
|
||||
}
|
||||
|
||||
|
@ -600,10 +615,10 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_shutdown(JNIEnv *, jclass) {
|
|||
|
||||
// JavaEGL
|
||||
extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, jobject obj) {
|
||||
ILOG("NativeApp.displayInit()");
|
||||
if (javaGL && !graphicsContext) {
|
||||
graphicsContext = new AndroidJavaEGLGraphicsContext();
|
||||
}
|
||||
ILOG("NativeApp.displayInit() (graphicsContext=%p)", graphicsContext);
|
||||
|
||||
if (!renderer_inited) {
|
||||
NativeInitGraphics(graphicsContext);
|
||||
|
@ -705,6 +720,9 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayShutdown(JNIEnv *en
|
|||
if (renderer_inited) {
|
||||
NativeDeviceLost();
|
||||
NativeShutdownGraphics();
|
||||
graphicsContext->Shutdown();
|
||||
delete graphicsContext;
|
||||
graphicsContext = nullptr;
|
||||
renderer_inited = false;
|
||||
NativeMessageReceived("recreateviews", "");
|
||||
}
|
||||
|
@ -1077,6 +1095,7 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J
|
|||
|
||||
graphicsContext->Shutdown();
|
||||
delete graphicsContext;
|
||||
graphicsContext = nullptr;
|
||||
renderLoopRunning = false;
|
||||
WLOG("Render loop function exited.");
|
||||
return true;
|
||||
|
|
|
@ -74,6 +74,7 @@ LOCAL_SRC_FILES :=\
|
|||
gfx_es2/gl3stub.c \
|
||||
gfx_es2/draw_buffer.cpp.arm \
|
||||
gfx_es2/draw_text.cpp.arm \
|
||||
gfx/GLStateCache.cpp.arm \
|
||||
gfx/gl_debug_log.cpp \
|
||||
gfx/gl_lost_manager.cpp \
|
||||
gfx/texture_atlas.cpp \
|
||||
|
|
|
@ -48,10 +48,17 @@ SDLJoystick *joystick = NULL;
|
|||
|
||||
class GLDummyGraphicsContext : public DummyGraphicsContext {
|
||||
public:
|
||||
Draw::DrawContext *CreateDrawContext() override {
|
||||
GLDummyGraphicsContext() {
|
||||
CheckGLExtensions();
|
||||
return Draw::T3DCreateGLContext();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
}
|
||||
~GLDummyGraphicsContext() { delete draw_; }
|
||||
|
||||
Draw::DrawContext *GetDrawContext() override {
|
||||
return draw_;
|
||||
}
|
||||
private:
|
||||
Draw::DrawContext *draw_;
|
||||
};
|
||||
|
||||
GlobalUIState lastUIState = UISTATE_MENU;
|
||||
|
@ -204,20 +211,19 @@ void EGL_Close() {
|
|||
}
|
||||
#endif
|
||||
|
||||
int getDisplayNumber(void)
|
||||
{
|
||||
int displayNumber = 0;
|
||||
char * displayNumberStr;
|
||||
int getDisplayNumber(void) {
|
||||
int displayNumber = 0;
|
||||
char * displayNumberStr;
|
||||
|
||||
//get environment
|
||||
displayNumberStr=getenv("SDL_VIDEO_FULLSCREEN_HEAD");
|
||||
//get environment
|
||||
displayNumberStr=getenv("SDL_VIDEO_FULLSCREEN_HEAD");
|
||||
|
||||
if (displayNumberStr)
|
||||
{
|
||||
displayNumber = atoi(displayNumberStr);
|
||||
}
|
||||
if (displayNumberStr)
|
||||
{
|
||||
displayNumber = atoi(displayNumberStr);
|
||||
}
|
||||
|
||||
return displayNumber;
|
||||
return displayNumber;
|
||||
}
|
||||
|
||||
// Simple implementations of System functions
|
||||
|
|
|
@ -40,9 +40,18 @@ void SimulateGamepad(InputState *input);
|
|||
|
||||
class QtDummyGraphicsContext : public DummyGraphicsContext {
|
||||
public:
|
||||
Draw::DrawContext *CreateDrawContext() override {
|
||||
return Draw::T3DCreateGLContext();
|
||||
QtDummyGraphicsContext() {
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
}
|
||||
~QtDummyGraphicsContext() {
|
||||
delete draw_;
|
||||
}
|
||||
|
||||
Draw::DrawContext *GetDrawContext() override {
|
||||
return draw_;
|
||||
}
|
||||
private:
|
||||
Draw::DrawContext *draw_;
|
||||
};
|
||||
|
||||
//GUI
|
||||
|
@ -50,32 +59,32 @@ class MainUI : public QGLWidget
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MainUI(QWidget *parent = 0);
|
||||
~MainUI();
|
||||
explicit MainUI(QWidget *parent = 0);
|
||||
~MainUI();
|
||||
|
||||
public slots:
|
||||
QString InputBoxGetQString(QString title, QString defaultValue);
|
||||
QString InputBoxGetQString(QString title, QString defaultValue);
|
||||
|
||||
signals:
|
||||
void doubleClick();
|
||||
void newFrame();
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *);
|
||||
void changeEvent(QEvent *e);
|
||||
bool event(QEvent *e);
|
||||
void timerEvent(QTimerEvent *);
|
||||
void changeEvent(QEvent *e);
|
||||
bool event(QEvent *e);
|
||||
|
||||
void initializeGL();
|
||||
void resizeGL(int w, int h);
|
||||
void paintGL();
|
||||
void initializeGL();
|
||||
void resizeGL(int w, int h);
|
||||
void paintGL();
|
||||
|
||||
void updateAccelerometer();
|
||||
void updateAccelerometer();
|
||||
|
||||
private:
|
||||
InputState input_state;
|
||||
QtDummyGraphicsContext *graphicsContext;
|
||||
|
||||
float xscale, yscale;
|
||||
float xscale, yscale;
|
||||
#if defined(MOBILE_DEVICE)
|
||||
QAccelerometer* acc;
|
||||
#endif
|
||||
|
@ -91,11 +100,11 @@ class MainAudio: public QObject
|
|||
Q_OBJECT
|
||||
public:
|
||||
MainAudio() {}
|
||||
~MainAudio();
|
||||
~MainAudio();
|
||||
public slots:
|
||||
void run();
|
||||
void run();
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *);
|
||||
void timerEvent(QTimerEvent *);
|
||||
private:
|
||||
QIODevice* feed;
|
||||
QAudioOutput* output;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "base/logging.h"
|
||||
|
||||
#include "GPU/GLES/GLStateCache.h"
|
||||
#include "gfx/GLStateCache.h"
|
||||
|
||||
OpenGLState glstate;
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <cstring> // for memcmp
|
||||
|
||||
#include "gfx/gl_common.h"
|
||||
#include "gfx_es2/gpu_features.h"
|
|
@ -231,6 +231,7 @@
|
|||
<ClInclude Include="file\free.h" />
|
||||
<ClInclude Include="gfx\d3d9_shader.h" />
|
||||
<ClInclude Include="gfx\d3d9_state.h" />
|
||||
<ClInclude Include="gfx\GLStateCache.h" />
|
||||
<ClInclude Include="gfx\gl_common.h" />
|
||||
<ClInclude Include="gfx\gl_debug_log.h" />
|
||||
<ClInclude Include="gfx\gl_lost_manager.h" />
|
||||
|
@ -684,6 +685,7 @@
|
|||
<ClCompile Include="file\free.cpp" />
|
||||
<ClCompile Include="gfx\d3d9_shader.cpp" />
|
||||
<ClCompile Include="gfx\d3d9_state.cpp" />
|
||||
<ClCompile Include="gfx\GLStateCache.cpp" />
|
||||
<ClCompile Include="gfx\gl_debug_log.cpp" />
|
||||
<ClCompile Include="gfx\gl_lost_manager.cpp" />
|
||||
<ClCompile Include="gfx\texture_atlas.cpp" />
|
||||
|
@ -748,4 +750,4 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -317,6 +317,12 @@
|
|||
<ClInclude Include="gfx\d3d9_state.h">
|
||||
<Filter>gfx</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="gfx\GLStateCache.h">
|
||||
<Filter>gfx</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="gfx\dx_state.h">
|
||||
<Filter>gfx</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="gfx\gl_debug_log.cpp">
|
||||
|
@ -763,6 +769,12 @@
|
|||
<ClCompile Include="gfx\d3d9_state.cpp">
|
||||
<Filter>gfx</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gfx\GLStateCache.cpp">
|
||||
<Filter>gfx</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gfx\dx_state.cpp">
|
||||
<Filter>gfx</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="gfx">
|
||||
|
@ -835,4 +847,4 @@
|
|||
<UniqueIdentifier>{06c6305a-a646-485b-85b9-645a24dd6553}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -310,6 +310,40 @@ enum class NativeObject {
|
|||
DEVICE_EX,
|
||||
};
|
||||
|
||||
enum FBColorDepth {
|
||||
FBO_8888,
|
||||
FBO_565,
|
||||
FBO_4444,
|
||||
FBO_5551,
|
||||
};
|
||||
|
||||
enum FBChannel {
|
||||
FB_COLOR_BIT = 1,
|
||||
FB_DEPTH_BIT = 2,
|
||||
FB_STENCIL_BIT = 4,
|
||||
FB_SURFACE_BIT = 32, // Used in conjunction with the others in D3D9 to get surfaces through get_api_texture
|
||||
};
|
||||
|
||||
enum FBBlitFilter {
|
||||
FB_BLIT_NEAREST = 0,
|
||||
FB_BLIT_LINEAR = 1,
|
||||
};
|
||||
|
||||
enum class Event {
|
||||
// These happen on D3D resize
|
||||
LOST_BACKBUFFER,
|
||||
GOT_BACKBUFFER,
|
||||
};
|
||||
|
||||
struct FramebufferDesc {
|
||||
int width;
|
||||
int height;
|
||||
int depth;
|
||||
int numColorAttachments;
|
||||
bool z_stencil;
|
||||
FBColorDepth colorDepth;
|
||||
};
|
||||
|
||||
// Binary compatible with D3D11 viewport.
|
||||
struct Viewport {
|
||||
float TopLeftX;
|
||||
|
@ -344,6 +378,10 @@ class DepthStencilState : public RefCountedObject {
|
|||
public:
|
||||
};
|
||||
|
||||
class Framebuffer : public RefCountedObject {
|
||||
public:
|
||||
};
|
||||
|
||||
class Buffer : public RefCountedObject {
|
||||
public:
|
||||
virtual void SetData(const uint8_t *data, size_t size) = 0;
|
||||
|
@ -495,7 +533,7 @@ struct TextureDesc {
|
|||
std::vector<uint8_t *> initData;
|
||||
};
|
||||
|
||||
class DrawContext : public RefCountedObject {
|
||||
class DrawContext {
|
||||
public:
|
||||
virtual ~DrawContext();
|
||||
|
||||
|
@ -520,10 +558,26 @@ public:
|
|||
// Resources
|
||||
virtual Buffer *CreateBuffer(size_t size, uint32_t usageFlags) = 0;
|
||||
virtual Texture *CreateTexture(const TextureDesc &desc) = 0;
|
||||
// On some hardware, you might get a 24-bit depth buffer even though you only wanted a 16-bit one.
|
||||
virtual Framebuffer *CreateFramebuffer(const FramebufferDesc &desc) = 0;
|
||||
|
||||
virtual ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) = 0;
|
||||
virtual Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) = 0;
|
||||
|
||||
virtual void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) = 0;
|
||||
virtual bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) = 0;
|
||||
|
||||
// These functions should be self explanatory.
|
||||
virtual void BindFramebufferAsRenderTarget(Framebuffer *fbo) = 0;
|
||||
// color must be 0, for now.
|
||||
virtual void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) = 0;
|
||||
virtual void BindFramebufferForRead(Framebuffer *fbo) = 0;
|
||||
|
||||
virtual void BindBackbufferAsRenderTarget() = 0;
|
||||
virtual uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) = 0;
|
||||
|
||||
virtual void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) = 0;
|
||||
|
||||
// Dynamic state
|
||||
virtual void SetScissorRect(int left, int top, int width, int height) = 0;
|
||||
virtual void SetViewports(int count, Viewport *viewports) = 0;
|
||||
|
@ -559,9 +613,10 @@ public:
|
|||
}
|
||||
|
||||
virtual std::string GetInfoString(InfoField info) const = 0;
|
||||
|
||||
virtual uintptr_t GetNativeObject(NativeObject obj) const = 0;
|
||||
|
||||
virtual void HandleEvent(Event ev) = 0;
|
||||
|
||||
protected:
|
||||
void CreatePresets();
|
||||
|
||||
|
@ -583,4 +638,4 @@ DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *co
|
|||
|
||||
DrawContext *T3DCreateVulkanContext(VulkanContext *context);
|
||||
|
||||
} // namespace Draw
|
||||
} // namespace Draw
|
||||
|
|
|
@ -39,6 +39,21 @@ public:
|
|||
Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) override;
|
||||
Texture *CreateTexture(const TextureDesc &desc) override;
|
||||
ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) override;
|
||||
Framebuffer *CreateFramebuffer(const FramebufferDesc &desc) override;
|
||||
|
||||
void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) override;
|
||||
bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) override;
|
||||
|
||||
// These functions should be self explanatory.
|
||||
void BindFramebufferAsRenderTarget(Framebuffer *fbo) override;
|
||||
// color must be 0, for now.
|
||||
void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override;
|
||||
void BindFramebufferForRead(Framebuffer *fbo) override;
|
||||
|
||||
void BindBackbufferAsRenderTarget() override;
|
||||
uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) override;
|
||||
|
||||
void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) override;
|
||||
|
||||
void BindTextures(int start, int count, Texture **textures) override;
|
||||
void BindSamplerStates(int start, int count, SamplerState **states) override;
|
||||
|
@ -81,6 +96,8 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void HandleEvent(Event ev) override {}
|
||||
|
||||
private:
|
||||
void ApplyCurrentState();
|
||||
|
||||
|
@ -520,6 +537,39 @@ uint32_t D3D11DrawContext::GetDataFormatSupport(DataFormat fmt) const {
|
|||
}
|
||||
}
|
||||
|
||||
// A D3D11Framebuffer is a D3D11Framebuffer plus all the textures it owns.
|
||||
class D3D11Framebuffer : public Framebuffer {
|
||||
public:
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
Framebuffer *D3D11DrawContext::CreateFramebuffer(const FramebufferDesc &desc) {
|
||||
D3D11Framebuffer *fb = new D3D11Framebuffer();
|
||||
fb->width = desc.width;
|
||||
fb->height = desc.height;
|
||||
|
||||
return fb;
|
||||
}
|
||||
|
||||
void D3D11DrawContext::CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) {}
|
||||
bool D3D11DrawContext::BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) { return true; }
|
||||
|
||||
// These functions should be self explanatory.
|
||||
void D3D11DrawContext::BindFramebufferAsRenderTarget(Framebuffer *fbo) {}
|
||||
// color must be 0, for now.
|
||||
void D3D11DrawContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) {}
|
||||
void D3D11DrawContext::BindFramebufferForRead(Framebuffer *fbo) {}
|
||||
|
||||
void D3D11DrawContext::BindBackbufferAsRenderTarget() {}
|
||||
uintptr_t D3D11DrawContext::GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) { return 0; }
|
||||
|
||||
void D3D11DrawContext::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) {
|
||||
D3D11Framebuffer *fb = (D3D11Framebuffer *)fbo;
|
||||
*w = fb->width;
|
||||
*h = fb->height;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *context) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "math/lin/matrix4x4.h"
|
||||
#include "thin3d/thin3d.h"
|
||||
#include "thin3d/d3dx9_loader.h"
|
||||
#include "gfx/d3d9_state.h"
|
||||
|
||||
namespace Draw {
|
||||
|
||||
|
@ -548,6 +549,21 @@ public:
|
|||
InputLayout *CreateInputLayout(const InputLayoutDesc &desc) override;
|
||||
Texture *CreateTexture(const TextureDesc &desc) override;
|
||||
|
||||
Framebuffer *CreateFramebuffer(const FramebufferDesc &desc) override;
|
||||
void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) override {}
|
||||
bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) override;
|
||||
|
||||
// These functions should be self explanatory.
|
||||
void BindFramebufferAsRenderTarget(Framebuffer *fbo) override;
|
||||
// color must be 0, for now.
|
||||
void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override;
|
||||
void BindFramebufferForRead(Framebuffer *fbo) override {}
|
||||
|
||||
void BindBackbufferAsRenderTarget() override;
|
||||
uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) override;
|
||||
|
||||
void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) override;
|
||||
|
||||
void BindTextures(int start, int count, Texture **textures) override;
|
||||
void BindSamplerStates(int start, int count, SamplerState **states) override {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
|
@ -605,6 +621,8 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void HandleEvent(Event ev) override;
|
||||
|
||||
private:
|
||||
LPDIRECT3D9 d3d_;
|
||||
LPDIRECT3D9EX d3dEx_;
|
||||
|
@ -622,8 +640,16 @@ private:
|
|||
int curVBufferOffsets_[4];
|
||||
D3D9Buffer *curIBuffer_;
|
||||
int curIBufferOffset_;
|
||||
|
||||
// Framebuffer state
|
||||
LPDIRECT3DSURFACE9 deviceRTsurf = 0;
|
||||
LPDIRECT3DSURFACE9 deviceDSsurf = 0;
|
||||
bool supportsINTZ = false;
|
||||
};
|
||||
|
||||
#define FB_DIV 1
|
||||
#define FOURCC_INTZ ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z')))
|
||||
|
||||
D3D9Context::D3D9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx)
|
||||
: d3d_(d3d), d3dEx_(d3dEx), adapterId_(adapterId), device_(device), deviceEx_(deviceEx), caps_{} {
|
||||
CreatePresets();
|
||||
|
@ -636,6 +662,18 @@ D3D9Context::D3D9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, ID
|
|||
caps_.multiViewport = false;
|
||||
caps_.anisoSupported = true;
|
||||
caps_.depthRangeMinusOneToOne = false;
|
||||
caps_.preferredDepthBufferFormat = DataFormat::D24_S8;
|
||||
caps_.dualSourceBlend = false;
|
||||
caps_.tesselationShaderSupported = false;
|
||||
if (d3d) {
|
||||
D3DDISPLAYMODE displayMode;
|
||||
d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode);
|
||||
|
||||
// To be safe, make sure both the display format and the FBO format support INTZ.
|
||||
HRESULT displayINTZ = d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, displayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_INTZ);
|
||||
HRESULT fboINTZ = d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_INTZ);
|
||||
supportsINTZ = SUCCEEDED(displayINTZ) && SUCCEEDED(fboINTZ);
|
||||
}
|
||||
}
|
||||
|
||||
D3D9Context::~D3D9Context() {
|
||||
|
@ -950,6 +988,169 @@ void D3D9ShaderModule::SetMatrix4x4(LPDIRECT3DDEVICE9 device, const char *name,
|
|||
}
|
||||
}
|
||||
|
||||
class D3D9Framebuffer : public Framebuffer {
|
||||
public:
|
||||
~D3D9Framebuffer();
|
||||
uint32_t id;
|
||||
LPDIRECT3DSURFACE9 surf;
|
||||
LPDIRECT3DSURFACE9 depthstencil;
|
||||
LPDIRECT3DTEXTURE9 tex;
|
||||
LPDIRECT3DTEXTURE9 depthstenciltex;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
FBColorDepth colorDepth;
|
||||
};
|
||||
|
||||
Framebuffer *D3D9Context::CreateFramebuffer(const FramebufferDesc &desc) {
|
||||
static uint32_t id = 0;
|
||||
|
||||
D3D9Framebuffer *fbo = new D3D9Framebuffer{};
|
||||
fbo->width = desc.width;
|
||||
fbo->height = desc.height;
|
||||
fbo->colorDepth = desc.colorDepth;
|
||||
fbo->depthstenciltex = nullptr;
|
||||
|
||||
HRESULT rtResult = device_->CreateTexture(fbo->width, fbo->height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &fbo->tex, NULL);
|
||||
if (FAILED(rtResult)) {
|
||||
ELOG("Failed to create render target");
|
||||
delete fbo;
|
||||
return NULL;
|
||||
}
|
||||
fbo->tex->GetSurfaceLevel(0, &fbo->surf);
|
||||
|
||||
HRESULT dsResult;
|
||||
if (supportsINTZ) {
|
||||
dsResult = device_->CreateTexture(fbo->width, fbo->height, 1, D3DUSAGE_DEPTHSTENCIL, FOURCC_INTZ, D3DPOOL_DEFAULT, &fbo->depthstenciltex, NULL);
|
||||
if (SUCCEEDED(dsResult)) {
|
||||
dsResult = fbo->depthstenciltex->GetSurfaceLevel(0, &fbo->depthstencil);
|
||||
}
|
||||
} else {
|
||||
dsResult = device_->CreateDepthStencilSurface(fbo->width, fbo->height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->depthstencil, NULL);
|
||||
}
|
||||
if (FAILED(dsResult)) {
|
||||
ELOG("Failed to create depth buffer");
|
||||
fbo->surf->Release();
|
||||
fbo->tex->Release();
|
||||
if (fbo->depthstenciltex) {
|
||||
fbo->depthstenciltex->Release();
|
||||
}
|
||||
delete fbo;
|
||||
return NULL;
|
||||
}
|
||||
fbo->id = id++;
|
||||
return fbo;
|
||||
}
|
||||
|
||||
D3D9Framebuffer::~D3D9Framebuffer() {
|
||||
tex->Release();
|
||||
surf->Release();
|
||||
depthstencil->Release();
|
||||
if (depthstenciltex) {
|
||||
depthstenciltex->Release();
|
||||
}
|
||||
}
|
||||
|
||||
void D3D9Context::BindBackbufferAsRenderTarget() {
|
||||
using namespace DX9;
|
||||
|
||||
device_->SetRenderTarget(0, deviceRTsurf);
|
||||
device_->SetDepthStencilSurface(deviceDSsurf);
|
||||
dxstate.scissorRect.restore();
|
||||
dxstate.viewport.restore();
|
||||
}
|
||||
|
||||
void D3D9Context::BindFramebufferAsRenderTarget(Framebuffer *fbo) {
|
||||
using namespace DX9;
|
||||
|
||||
D3D9Framebuffer *fb = (D3D9Framebuffer *)fbo;
|
||||
device_->SetRenderTarget(0, fb->surf);
|
||||
device_->SetDepthStencilSurface(fb->depthstencil);
|
||||
dxstate.scissorRect.restore();
|
||||
dxstate.viewport.restore();
|
||||
}
|
||||
|
||||
uintptr_t D3D9Context::GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) {
|
||||
D3D9Framebuffer *fb = (D3D9Framebuffer *)fbo;
|
||||
if (channelBits & FB_SURFACE_BIT) {
|
||||
switch (channelBits & 7) {
|
||||
case FB_DEPTH_BIT:
|
||||
return (uintptr_t)fb->depthstencil;
|
||||
case FB_STENCIL_BIT:
|
||||
return (uintptr_t)fb->depthstencil;
|
||||
case FB_COLOR_BIT:
|
||||
default:
|
||||
return (uintptr_t)fb->surf;
|
||||
}
|
||||
} else {
|
||||
switch (channelBits & 7) {
|
||||
case FB_DEPTH_BIT:
|
||||
return (uintptr_t)fb->depthstenciltex;
|
||||
case FB_STENCIL_BIT:
|
||||
return 0; // Can't texture from stencil
|
||||
case FB_COLOR_BIT:
|
||||
default:
|
||||
return (uintptr_t)fb->tex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LPDIRECT3DSURFACE9 fbo_get_color_for_read(D3D9Framebuffer *fbo) {
|
||||
return fbo->surf;
|
||||
}
|
||||
|
||||
void D3D9Context::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int color) {
|
||||
D3D9Framebuffer *fb = (D3D9Framebuffer *)fbo;
|
||||
switch (channelBit) {
|
||||
case FB_DEPTH_BIT:
|
||||
if (fb->depthstenciltex) {
|
||||
device_->SetTexture(binding, fb->depthstenciltex);
|
||||
}
|
||||
break;
|
||||
case FB_COLOR_BIT:
|
||||
default:
|
||||
if (fb->tex) {
|
||||
device_->SetTexture(binding, fb->tex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void D3D9Context::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) {
|
||||
D3D9Framebuffer *fb = (D3D9Framebuffer *)fbo;
|
||||
*w = fb->width;
|
||||
*h = fb->height;
|
||||
}
|
||||
|
||||
bool D3D9Context::BlitFramebuffer(Framebuffer *srcfb, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dstfb, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) {
|
||||
D3D9Framebuffer *src = (D3D9Framebuffer *)srcfb;
|
||||
D3D9Framebuffer *dst = (D3D9Framebuffer *)dstfb;
|
||||
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 SUCCEEDED(device_->StretchRect(srcSurf, &srcRect, dstSurf, &dstRect, filter == FB_BLIT_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT));
|
||||
}
|
||||
|
||||
void D3D9Context::HandleEvent(Event ev) {
|
||||
switch (ev) {
|
||||
case Event::LOST_BACKBUFFER:
|
||||
if (deviceRTsurf)
|
||||
deviceRTsurf->Release();
|
||||
if (deviceDSsurf)
|
||||
deviceDSsurf->Release();
|
||||
deviceRTsurf = nullptr;
|
||||
deviceDSsurf = nullptr;
|
||||
break;
|
||||
case Event::GOT_BACKBUFFER:
|
||||
device_->GetRenderTarget(0, &deviceRTsurf);
|
||||
device_->GetDepthStencilSurface(&deviceDSsurf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DrawContext *T3DCreateDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx) {
|
||||
int d3dx_ver = LoadD3DX9Dynamic();
|
||||
if (!d3dx_ver) {
|
||||
|
|
|
@ -8,9 +8,14 @@
|
|||
#include "math/lin/matrix4x4.h"
|
||||
#include "thin3d/thin3d.h"
|
||||
#include "gfx/gl_common.h"
|
||||
#include "gfx/GLStateCache.h"
|
||||
#include "gfx_es2/gpu_features.h"
|
||||
#include "gfx/gl_lost_manager.h"
|
||||
|
||||
#ifdef IOS
|
||||
extern void bindDefaultFBO();
|
||||
#endif
|
||||
|
||||
namespace Draw {
|
||||
|
||||
static const unsigned short compToGL[] = {
|
||||
|
@ -488,6 +493,8 @@ private:
|
|||
std::map<std::string, UniformInfo> uniforms_;
|
||||
};
|
||||
|
||||
class OpenGLFramebuffer;
|
||||
|
||||
class OpenGLContext : public DrawContext {
|
||||
public:
|
||||
OpenGLContext();
|
||||
|
@ -509,12 +516,27 @@ public:
|
|||
BlendState *CreateBlendState(const BlendStateDesc &desc) override;
|
||||
SamplerState *CreateSamplerState(const SamplerStateDesc &desc) override;
|
||||
RasterState *CreateRasterState(const RasterStateDesc &desc) override;
|
||||
Buffer *CreateBuffer(size_t size, uint32_t usageFlags) override;
|
||||
Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) override;
|
||||
InputLayout *CreateInputLayout(const InputLayoutDesc &desc) override;
|
||||
ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) override;
|
||||
|
||||
Texture *CreateTexture(const TextureDesc &desc) override;
|
||||
Buffer *CreateBuffer(size_t size, uint32_t usageFlags) override;
|
||||
Framebuffer *CreateFramebuffer(const FramebufferDesc &desc) override;
|
||||
|
||||
void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) override;
|
||||
bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) override;
|
||||
|
||||
// These functions should be self explanatory.
|
||||
void BindFramebufferAsRenderTarget(Framebuffer *fbo) override;
|
||||
// color must be 0, for now.
|
||||
void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override;
|
||||
void BindFramebufferForRead(Framebuffer *fbo) override;
|
||||
|
||||
void BindBackbufferAsRenderTarget() override;
|
||||
uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) override;
|
||||
|
||||
void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) override;
|
||||
|
||||
void BindSamplerStates(int start, int count, SamplerState **states) override {
|
||||
if (samplerStates_.size() < (size_t)(start + count)) {
|
||||
|
@ -610,6 +632,13 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
void HandleEvent(Event ev) override {}
|
||||
|
||||
OpenGLFramebuffer *fbo_ext_create(const FramebufferDesc &desc);
|
||||
void fbo_bind_fb_target(bool read, GLuint name);
|
||||
GLenum fbo_get_fb_target(bool read, GLuint **cached);
|
||||
void fbo_unbind();
|
||||
|
||||
private:
|
||||
std::vector<OpenGLSamplerState *> samplerStates_;
|
||||
DeviceCaps caps_;
|
||||
|
@ -620,11 +649,25 @@ private:
|
|||
int curVBufferOffsets_[4];
|
||||
OpenGLBuffer *curIBuffer_;
|
||||
int curIBufferOffset_;
|
||||
|
||||
// Framebuffer state
|
||||
GLuint currentDrawHandle_ = 0;
|
||||
GLuint currentReadHandle_ = 0;
|
||||
};
|
||||
|
||||
OpenGLContext::OpenGLContext() {
|
||||
CreatePresets();
|
||||
// TODO: Detect caps
|
||||
|
||||
// TODO: Detect more caps
|
||||
if (gl_extensions.IsGLES) {
|
||||
if (gl_extensions.OES_packed_depth_stencil || gl_extensions.OES_depth24) {
|
||||
caps_.preferredDepthBufferFormat = DataFormat::D24_S8;
|
||||
} else {
|
||||
caps_.preferredDepthBufferFormat = DataFormat::D16;
|
||||
}
|
||||
} else {
|
||||
caps_.preferredDepthBufferFormat = DataFormat::D24_S8;
|
||||
}
|
||||
}
|
||||
|
||||
OpenGLContext::~OpenGLContext() {
|
||||
|
@ -1171,6 +1214,402 @@ void OpenGLInputLayout::Unapply() {
|
|||
}
|
||||
}
|
||||
|
||||
class OpenGLFramebuffer : public Framebuffer {
|
||||
public:
|
||||
~OpenGLFramebuffer();
|
||||
GLuint handle;
|
||||
GLuint color_texture;
|
||||
GLuint z_stencil_buffer; // Either this is set, or the two below.
|
||||
GLuint z_buffer;
|
||||
GLuint stencil_buffer;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
FBColorDepth colorDepth;
|
||||
};
|
||||
|
||||
// On PC, we always use GL_DEPTH24_STENCIL8.
|
||||
// On Android, we try to use what's available.
|
||||
|
||||
#ifndef USING_GLES2
|
||||
OpenGLFramebuffer *OpenGLContext::fbo_ext_create(const FramebufferDesc &desc) {
|
||||
OpenGLFramebuffer *fbo = new OpenGLFramebuffer();
|
||||
fbo->width = desc.width;
|
||||
fbo->height = desc.height;
|
||||
fbo->colorDepth = desc.colorDepth;
|
||||
|
||||
// Color texture is same everywhere
|
||||
glGenFramebuffersEXT(1, &fbo->handle);
|
||||
glGenTextures(1, &fbo->color_texture);
|
||||
|
||||
// Create the surfaces.
|
||||
glBindTexture(GL_TEXTURE_2D, fbo->color_texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
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 (fbo->colorDepth) {
|
||||
case FBO_8888:
|
||||
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, 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, 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, fbo->width, fbo->height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
fbo->stencil_buffer = 0;
|
||||
fbo->z_buffer = 0;
|
||||
// 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, fbo->width, fbo->height);
|
||||
//glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8, width, height);
|
||||
|
||||
// Bind it all together
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->handle);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbo->color_texture, 0);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->z_stencil_buffer);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->z_stencil_buffer);
|
||||
|
||||
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
switch (status) {
|
||||
case GL_FRAMEBUFFER_COMPLETE_EXT:
|
||||
// ILOG("Framebuffer verified complete.");
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||
ELOG("GL_FRAMEBUFFER_UNSUPPORTED");
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
|
||||
ELOG("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT ");
|
||||
break;
|
||||
default:
|
||||
FLOG("Other framebuffer error: %i", status);
|
||||
break;
|
||||
}
|
||||
// Unbind state we don't need
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
currentDrawHandle_ = fbo->handle;
|
||||
currentReadHandle_ = fbo->handle;
|
||||
return fbo;
|
||||
}
|
||||
#endif
|
||||
|
||||
Framebuffer *OpenGLContext::CreateFramebuffer(const FramebufferDesc &desc) {
|
||||
CheckGLExtensions();
|
||||
|
||||
#ifndef USING_GLES2
|
||||
if (!gl_extensions.ARB_framebuffer_object && gl_extensions.EXT_framebuffer_object) {
|
||||
return fbo_ext_create(desc);
|
||||
} else if (!gl_extensions.ARB_framebuffer_object) {
|
||||
return nullptr;
|
||||
}
|
||||
// If GLES2, we have basic FBO support and can just proceed.
|
||||
#endif
|
||||
|
||||
OpenGLFramebuffer *fbo = new OpenGLFramebuffer();
|
||||
fbo->width = desc.width;
|
||||
fbo->height = desc.height;
|
||||
fbo->colorDepth = desc.colorDepth;
|
||||
|
||||
// Color texture is same everywhere
|
||||
glGenFramebuffers(1, &fbo->handle);
|
||||
glGenTextures(1, &fbo->color_texture);
|
||||
|
||||
// Create the surfaces.
|
||||
glBindTexture(GL_TEXTURE_2D, fbo->color_texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
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 (fbo->colorDepth) {
|
||||
case FBO_8888:
|
||||
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, 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, 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, fbo->width, fbo->height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
if (gl_extensions.IsGLES) {
|
||||
if (gl_extensions.OES_packed_depth_stencil) {
|
||||
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, fbo->width, fbo->height);
|
||||
|
||||
// Bind it all together
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture, 0);
|
||||
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", 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, 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, fbo->width, fbo->height);
|
||||
|
||||
// Bind it all together
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_buffer);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->stencil_buffer);
|
||||
}
|
||||
} else {
|
||||
fbo->stencil_buffer = 0;
|
||||
fbo->z_buffer = 0;
|
||||
// 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, fbo->width, fbo->height);
|
||||
|
||||
// Bind it all together
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer);
|
||||
}
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
switch (status) {
|
||||
case GL_FRAMEBUFFER_COMPLETE:
|
||||
// ILOG("Framebuffer verified complete.");
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED:
|
||||
ELOG("GL_FRAMEBUFFER_UNSUPPORTED");
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
|
||||
ELOG("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT ");
|
||||
break;
|
||||
default:
|
||||
FLOG("Other framebuffer error: %i", status);
|
||||
break;
|
||||
}
|
||||
// Unbind state we don't need
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
currentDrawHandle_ = fbo->handle;
|
||||
currentReadHandle_ = fbo->handle;
|
||||
return fbo;
|
||||
}
|
||||
|
||||
GLenum OpenGLContext::fbo_get_fb_target(bool read, GLuint **cached) {
|
||||
bool supportsBlit = gl_extensions.ARB_framebuffer_object;
|
||||
if (gl_extensions.IsGLES) {
|
||||
supportsBlit = (gl_extensions.GLES3 || gl_extensions.NV_framebuffer_blit);
|
||||
}
|
||||
|
||||
// Note: GL_FRAMEBUFFER_EXT and GL_FRAMEBUFFER have the same value, same with _NV.
|
||||
if (supportsBlit) {
|
||||
if (read) {
|
||||
*cached = ¤tReadHandle_;
|
||||
return GL_READ_FRAMEBUFFER;
|
||||
} else {
|
||||
*cached = ¤tDrawHandle_;
|
||||
return GL_DRAW_FRAMEBUFFER;
|
||||
}
|
||||
} else {
|
||||
*cached = ¤tDrawHandle_;
|
||||
return GL_FRAMEBUFFER;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLContext::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);
|
||||
} else {
|
||||
#ifndef USING_GLES2
|
||||
glBindFramebufferEXT(target, name);
|
||||
#endif
|
||||
}
|
||||
*cached = name;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLContext::fbo_unbind() {
|
||||
#ifndef USING_GLES2
|
||||
if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
} else if (gl_extensions.EXT_framebuffer_object) {
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
#else
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
#endif
|
||||
|
||||
#ifdef IOS
|
||||
bindDefaultFBO();
|
||||
#endif
|
||||
|
||||
currentDrawHandle_ = 0;
|
||||
currentReadHandle_ = 0;
|
||||
}
|
||||
|
||||
void OpenGLContext::BindFramebufferAsRenderTarget(Framebuffer *fbo) {
|
||||
OpenGLFramebuffer *fb = (OpenGLFramebuffer *)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.
|
||||
fbo_bind_fb_target(false, fb->handle);
|
||||
// Always restore viewport after render target binding
|
||||
glstate.viewport.restore();
|
||||
}
|
||||
|
||||
void OpenGLContext::BindBackbufferAsRenderTarget() {
|
||||
fbo_unbind();
|
||||
}
|
||||
|
||||
// For GL_EXT_FRAMEBUFFER_BLIT and similar.
|
||||
void OpenGLContext::BindFramebufferForRead(Framebuffer *fbo) {
|
||||
OpenGLFramebuffer *fb = (OpenGLFramebuffer *)fbo;
|
||||
fbo_bind_fb_target(true, fb->handle);
|
||||
}
|
||||
|
||||
void OpenGLContext::CopyFramebufferImage(Framebuffer *fbsrc, int srcLevel, int srcX, int srcY, int srcZ, Framebuffer *fbdst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) {
|
||||
OpenGLFramebuffer *src = (OpenGLFramebuffer *)fbsrc;
|
||||
OpenGLFramebuffer *dst = (OpenGLFramebuffer *)fbdst;
|
||||
#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
|
||||
}
|
||||
|
||||
bool OpenGLContext::BlitFramebuffer(Framebuffer *fbsrc, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *fbdst, int dstX1, int dstY1, int dstX2, int dstY2, int channels, FBBlitFilter linearFilter) {
|
||||
OpenGLFramebuffer *src = (OpenGLFramebuffer *)fbsrc;
|
||||
OpenGLFramebuffer *dst = (OpenGLFramebuffer *)fbdst;
|
||||
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;
|
||||
BindFramebufferAsRenderTarget(dst);
|
||||
BindFramebufferForRead(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.
|
||||
return true;
|
||||
} 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__)
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t OpenGLContext::GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) {
|
||||
// Unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OpenGLContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int color) {
|
||||
OpenGLFramebuffer *fb = (OpenGLFramebuffer *)fbo;
|
||||
// glActiveTexture(GL_TEXTURE0 + binding);
|
||||
switch (channelBit) {
|
||||
case FB_COLOR_BIT:
|
||||
default:
|
||||
if (fbo) {
|
||||
glBindTexture(GL_TEXTURE_2D, fb->color_texture);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OpenGLFramebuffer::~OpenGLFramebuffer() {
|
||||
if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, handle);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers(1, &handle);
|
||||
glDeleteRenderbuffers(1, &z_stencil_buffer);
|
||||
glDeleteRenderbuffers(1, &z_buffer);
|
||||
glDeleteRenderbuffers(1, &stencil_buffer);
|
||||
} else if (gl_extensions.EXT_framebuffer_object) {
|
||||
#ifndef USING_GLES2
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, handle);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER_EXT, 0);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
glDeleteFramebuffersEXT(1, &handle);
|
||||
glDeleteRenderbuffersEXT(1, &z_stencil_buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
glDeleteTextures(1, &color_texture);
|
||||
}
|
||||
|
||||
void OpenGLContext::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) {
|
||||
OpenGLFramebuffer *fb = (OpenGLFramebuffer *)fbo;
|
||||
*w = fb->width;
|
||||
*h = fb->height;
|
||||
}
|
||||
|
||||
uint32_t OpenGLContext::GetDataFormatSupport(DataFormat fmt) const {
|
||||
switch (fmt) {
|
||||
case DataFormat::B8G8R8A8_UNORM:
|
||||
|
|
|
@ -359,7 +359,6 @@ public:
|
|||
|
||||
DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override;
|
||||
BlendState *CreateBlendState(const BlendStateDesc &desc) override;
|
||||
Buffer *CreateBuffer(size_t size, uint32_t usageFlags) override;
|
||||
InputLayout *CreateInputLayout(const InputLayoutDesc &desc) override;
|
||||
SamplerState *CreateSamplerState(const SamplerStateDesc &desc) override;
|
||||
RasterState *CreateRasterState(const RasterStateDesc &desc) override;
|
||||
|
@ -367,6 +366,22 @@ public:
|
|||
ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) override;
|
||||
|
||||
Texture *CreateTexture(const TextureDesc &desc) override;
|
||||
Buffer *CreateBuffer(size_t size, uint32_t usageFlags) override;
|
||||
Framebuffer *CreateFramebuffer(const FramebufferDesc &desc) override;
|
||||
|
||||
void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) override;
|
||||
bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) override;
|
||||
|
||||
// These functions should be self explanatory.
|
||||
void BindFramebufferAsRenderTarget(Framebuffer *fbo) override;
|
||||
// color must be 0, for now.
|
||||
void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override;
|
||||
void BindFramebufferForRead(Framebuffer *fbo) override;
|
||||
|
||||
void BindBackbufferAsRenderTarget() override;
|
||||
uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) override;
|
||||
|
||||
void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) override;
|
||||
|
||||
void SetScissorRect(int left, int top, int width, int height) override;
|
||||
void SetViewports(int count, Viewport *viewports) override;
|
||||
|
@ -425,6 +440,8 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
void HandleEvent(Event ev) override {}
|
||||
|
||||
private:
|
||||
void ApplyDynamicState();
|
||||
void DirtyDynamicState();
|
||||
|
@ -1255,4 +1272,37 @@ uint32_t VKContext::GetDataFormatSupport(DataFormat fmt) const {
|
|||
}
|
||||
}
|
||||
|
||||
// A VKFramebuffer is a VkFramebuffer plus all the textures it owns.
|
||||
class VKFramebuffer : public Framebuffer {
|
||||
public:
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
Framebuffer *VKContext::CreateFramebuffer(const FramebufferDesc &desc) {
|
||||
VKFramebuffer *fb = new VKFramebuffer();
|
||||
fb->width = desc.width;
|
||||
fb->height = desc.height;
|
||||
|
||||
return fb;
|
||||
}
|
||||
|
||||
void VKContext::CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) {}
|
||||
bool VKContext::BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) { return true; }
|
||||
|
||||
// These functions should be self explanatory.
|
||||
void VKContext::BindFramebufferAsRenderTarget(Framebuffer *fbo) {}
|
||||
// color must be 0, for now.
|
||||
void VKContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) {}
|
||||
void VKContext::BindFramebufferForRead(Framebuffer *fbo) {}
|
||||
|
||||
void VKContext::BindBackbufferAsRenderTarget() {}
|
||||
uintptr_t VKContext::GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) { return 0; }
|
||||
|
||||
void VKContext::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) {
|
||||
VKFramebuffer *fb = (VKFramebuffer *)fbo;
|
||||
*w = fb->width;
|
||||
*h = fb->height;
|
||||
}
|
||||
|
||||
} // namespace Draw
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
#include "Core/Config.h"
|
||||
#include "Common/GraphicsContext.h"
|
||||
#include "GPU/GLES/FBO.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
@ -36,10 +35,18 @@
|
|||
|
||||
class IOSDummyGraphicsContext : public DummyGraphicsContext {
|
||||
public:
|
||||
Draw::DrawContext *CreateDrawContext() override {
|
||||
CheckGLExtensions();
|
||||
return Draw::T3DCreateGLContext();
|
||||
}
|
||||
IOSDummyGraphicsContext() {
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
}
|
||||
~IOSDummyGraphicsContext() {
|
||||
delete draw_;
|
||||
}
|
||||
Draw::DrawContext *GetDrawContext() override {
|
||||
return draw_;
|
||||
}
|
||||
private:
|
||||
Draw::DrawContext *draw_;
|
||||
};
|
||||
|
||||
float dp_xscale = 1.0f;
|
||||
|
|
Loading…
Add table
Reference in a new issue