mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Refactor: Even more getting rid of gstate access in the framebuffer manager.
This commit is contained in:
parent
d7c76cb1da
commit
d7f4c47c22
12 changed files with 79 additions and 79 deletions
|
@ -248,7 +248,7 @@ void GetFramebufferHeuristicInputs(FramebufferHeuristicParams *params, const GPU
|
|||
params->scissorHeight = gstate.getScissorY2() + 1;
|
||||
}
|
||||
|
||||
VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const FramebufferHeuristicParams ¶ms) {
|
||||
VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const FramebufferHeuristicParams ¶ms, u32 skipDrawReason) {
|
||||
gstate_c.framebufChanged = false;
|
||||
|
||||
// Collect all parameters. This whole function has really become a cesspool of heuristics...
|
||||
|
@ -259,7 +259,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
|
|||
int drawing_width, drawing_height;
|
||||
EstimateDrawingSize(params.fb_address, params.fmt, params.viewportWidth, params.viewportHeight, params.regionWidth, params.regionHeight, params.scissorWidth, params.scissorHeight, std::max(params.fb_stride, 4), drawing_width, drawing_height);
|
||||
|
||||
gstate_c.cutRTOffsetX = 0;
|
||||
gstate_c.curRTOffsetX = 0;
|
||||
bool vfbFormatChanged = false;
|
||||
|
||||
// Find a matching framebuffer
|
||||
|
@ -290,7 +290,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
|
|||
if (v->format == params.fmt && v->fb_stride == params.fb_stride && x_offset < params.fb_stride && v->height >= drawing_height) {
|
||||
WARN_LOG_REPORT_ONCE(renderoffset, HLE, "Rendering to framebuffer offset: %08x +%dx%d", v->fb_address, x_offset, 0);
|
||||
vfb = v;
|
||||
gstate_c.cutRTOffsetX = x_offset;
|
||||
gstate_c.curRTOffsetX = x_offset;
|
||||
vfb->width = std::max((int)vfb->width, x_offset + drawing_width);
|
||||
// To prevent the newSize code from being confused.
|
||||
drawing_width += x_offset;
|
||||
|
@ -355,7 +355,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
|
|||
vfb->drawnHeight = 0;
|
||||
vfb->drawnFormat = params.fmt;
|
||||
vfb->usageFlags = FB_USAGE_RENDERTARGET;
|
||||
SetColorUpdated(vfb, gstate_c.skipDrawReason);
|
||||
SetColorUpdated(vfb, skipDrawReason);
|
||||
vfb->depthUpdated = false;
|
||||
|
||||
u32 byteSize = FramebufferByteSize(vfb);
|
||||
|
@ -417,7 +417,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
|
|||
vfb->last_frame_render = gpuStats.numFlips;
|
||||
frameLastFramebufUsed_ = gpuStats.numFlips;
|
||||
vfb->dirtyAfterDisplay = true;
|
||||
if ((gstate_c.skipDrawReason & SKIPDRAW_SKIPFRAME) == 0)
|
||||
if ((skipDrawReason & SKIPDRAW_SKIPFRAME) == 0)
|
||||
vfb->reallyDirtyAfterDisplay = true;
|
||||
|
||||
VirtualFramebuffer *prev = currentRenderVfb_;
|
||||
|
@ -427,7 +427,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
|
|||
vfb->last_frame_render = gpuStats.numFlips;
|
||||
frameLastFramebufUsed_ = gpuStats.numFlips;
|
||||
vfb->dirtyAfterDisplay = true;
|
||||
if ((gstate_c.skipDrawReason & SKIPDRAW_SKIPFRAME) == 0)
|
||||
if ((skipDrawReason & SKIPDRAW_SKIPFRAME) == 0)
|
||||
vfb->reallyDirtyAfterDisplay = true;
|
||||
|
||||
NotifyRenderFramebufferUpdated(vfb, vfbFormatChanged);
|
||||
|
@ -476,7 +476,7 @@ void FramebufferManagerCommon::UpdateFromMemory(u32 addr, int size, bool safe) {
|
|||
}
|
||||
}
|
||||
|
||||
bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, bool isMemset) {
|
||||
bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, bool isMemset, u32 skipDrawReason) {
|
||||
if (updateVRAM_ || size == 0) {
|
||||
return false;
|
||||
}
|
||||
|
@ -552,7 +552,7 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size,
|
|||
// Just do the blit!
|
||||
if (g_Config.bBlockTransferGPU) {
|
||||
BlitFramebuffer(dstBuffer, 0, dstY, srcBuffer, 0, srcY, srcBuffer->width, srcH, 0);
|
||||
SetColorUpdated(dstBuffer, gstate_c.skipDrawReason);
|
||||
SetColorUpdated(dstBuffer, skipDrawReason);
|
||||
RebindFramebuffer();
|
||||
}
|
||||
}
|
||||
|
@ -563,7 +563,7 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size,
|
|||
FlushBeforeCopy();
|
||||
const u8 *srcBase = Memory::GetPointerUnchecked(src);
|
||||
DrawPixels(dstBuffer, 0, dstY, srcBase, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->width, dstH);
|
||||
SetColorUpdated(dstBuffer, gstate_c.skipDrawReason);
|
||||
SetColorUpdated(dstBuffer, skipDrawReason);
|
||||
RebindFramebuffer();
|
||||
// This is a memcpy, let's still copy just in case.
|
||||
return false;
|
||||
|
@ -666,7 +666,7 @@ void FramebufferManagerCommon::FindTransferFramebuffers(VirtualFramebuffer *&dst
|
|||
}
|
||||
}
|
||||
|
||||
bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int width, int height, int bpp) {
|
||||
bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int width, int height, int bpp, u32 skipDrawReason) {
|
||||
if (!useBufferedRendering_ || updateVRAM_) {
|
||||
return false;
|
||||
}
|
||||
|
@ -692,7 +692,7 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst
|
|||
FlushBeforeCopy();
|
||||
BlitFramebuffer(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, dstWidth, dstHeight, bpp);
|
||||
RebindFramebuffer();
|
||||
SetColorUpdated(dstBuffer, gstate_c.skipDrawReason);
|
||||
SetColorUpdated(dstBuffer, skipDrawReason);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
|
@ -708,7 +708,7 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst
|
|||
FlushBeforeCopy();
|
||||
BlitFramebuffer(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, dstWidth, dstHeight, bpp);
|
||||
RebindFramebuffer();
|
||||
SetColorUpdated(dstBuffer, gstate_c.skipDrawReason);
|
||||
SetColorUpdated(dstBuffer, skipDrawReason);
|
||||
return true; // No need to actually do the memory copy behind, probably.
|
||||
}
|
||||
}
|
||||
|
@ -737,7 +737,7 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst
|
|||
}
|
||||
}
|
||||
|
||||
void FramebufferManagerCommon::NotifyBlockTransferAfter(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int width, int height, int bpp) {
|
||||
void FramebufferManagerCommon::NotifyBlockTransferAfter(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int width, int height, int bpp, u32 skipDrawReason) {
|
||||
// A few games use this INSTEAD of actually drawing the video image to the screen, they just blast it to
|
||||
// the backbuffer. Detect this and have the framebuffermanager draw the pixels.
|
||||
|
||||
|
@ -773,7 +773,7 @@ void FramebufferManagerCommon::NotifyBlockTransferAfter(u32 dstBasePtr, int dstS
|
|||
int dstBpp = dstBuffer->format == GE_FORMAT_8888 ? 4 : 2;
|
||||
float dstXFactor = (float)bpp / dstBpp;
|
||||
DrawPixels(dstBuffer, static_cast<int>(dstX * dstXFactor), dstY, srcBase, dstBuffer->format, static_cast<int>(srcStride * dstXFactor), static_cast<int>(dstWidth * dstXFactor), dstHeight);
|
||||
SetColorUpdated(dstBuffer, gstate_c.skipDrawReason);
|
||||
SetColorUpdated(dstBuffer, skipDrawReason);
|
||||
RebindFramebuffer();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ public:
|
|||
void BeginFrame();
|
||||
void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format);
|
||||
|
||||
VirtualFramebuffer *DoSetRenderFrameBuffer(const FramebufferHeuristicParams ¶ms);
|
||||
VirtualFramebuffer *DoSetRenderFrameBuffer(const FramebufferHeuristicParams ¶ms, u32 skipDrawReason);
|
||||
VirtualFramebuffer *SetRenderFrameBuffer(bool framebufChanged, int skipDrawReason) {
|
||||
// Inlining this part since it's so frequent.
|
||||
if (!framebufChanged && currentRenderVfb_) {
|
||||
|
@ -138,19 +138,19 @@ public:
|
|||
// that come from elsewhere than gstate.
|
||||
FramebufferHeuristicParams inputs;
|
||||
GetFramebufferHeuristicInputs(&inputs, gstate);
|
||||
return DoSetRenderFrameBuffer(inputs);
|
||||
return DoSetRenderFrameBuffer(inputs, skipDrawReason);
|
||||
}
|
||||
}
|
||||
virtual void RebindFramebuffer() = 0;
|
||||
|
||||
bool NotifyFramebufferCopy(u32 src, u32 dest, int size, bool isMemset = false);
|
||||
bool NotifyFramebufferCopy(u32 src, u32 dest, int size, bool isMemset, u32 skipDrawReason);
|
||||
void UpdateFromMemory(u32 addr, int size, bool safe);
|
||||
virtual bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) = 0;
|
||||
// Returns true if it's sure this is a direct FBO->FBO transfer and it has already handle it.
|
||||
// In that case we hardly need to actually copy the bytes in VRAM, they will be wrong anyway (unless
|
||||
// read framebuffers is on, in which case this should always return false).
|
||||
bool NotifyBlockTransferBefore(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int w, int h, int bpp);
|
||||
void NotifyBlockTransferAfter(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int w, int h, int bpp);
|
||||
bool NotifyBlockTransferBefore(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int w, int h, int bpp, u32 skipDrawReason);
|
||||
void NotifyBlockTransferAfter(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int w, int h, int bpp, u32 skipDrawReason);
|
||||
|
||||
virtual void ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h) = 0;
|
||||
virtual void MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) = 0;
|
||||
|
|
|
@ -1481,8 +1481,8 @@ void DIRECTX9_GPU::Execute_Generic(u32 op, u32 diff) {
|
|||
{
|
||||
// TODO: Here we should check if the transfer overlaps a framebuffer or any textures,
|
||||
// and take appropriate action. This is a block transfer between RAM and VRAM, or vice versa.
|
||||
// Can we skip this on SkipDraw?
|
||||
DoBlockTransfer();
|
||||
// Can we skip this entirely on SkipDraw? It skips some things internally.
|
||||
DoBlockTransfer(gstate_c.skipDrawReason);
|
||||
|
||||
// Fixes Gran Turismo's funky text issue, since it overwrites the current texture.
|
||||
gstate_c.textureChanged = TEXCHANGE_UPDATED;
|
||||
|
@ -1820,7 +1820,7 @@ void DIRECTX9_GPU::UpdateStats() {
|
|||
gpuStats.numFBOs = (int)framebufferManager_.NumVFBs();
|
||||
}
|
||||
|
||||
void DIRECTX9_GPU::DoBlockTransfer() {
|
||||
void DIRECTX9_GPU::DoBlockTransfer(u32 skipDrawReason) {
|
||||
// TODO: This is used a lot to copy data around between render targets and textures,
|
||||
// and also to quickly load textures from RAM to VRAM. So we should do checks like the following:
|
||||
// * Does dstBasePtr point to an existing texture? If so maybe reload it immediately.
|
||||
|
@ -1874,7 +1874,7 @@ void DIRECTX9_GPU::DoBlockTransfer() {
|
|||
}
|
||||
|
||||
// Tell the framebuffer manager to take action if possible. If it does the entire thing, let's just return.
|
||||
if (!framebufferManager_.NotifyBlockTransferBefore(dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, width, height, bpp)) {
|
||||
if (!framebufferManager_.NotifyBlockTransferBefore(dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, width, height, bpp, skipDrawReason)) {
|
||||
// Do the copy! (Hm, if we detect a drawn video frame (see below) then we could maybe skip this?)
|
||||
// Can use GetPointerUnchecked because we checked the addresses above. We could also avoid them
|
||||
// entirely by walking a couple of pointers...
|
||||
|
@ -1897,7 +1897,7 @@ void DIRECTX9_GPU::DoBlockTransfer() {
|
|||
}
|
||||
|
||||
textureCache_.Invalidate(dstBasePtr + (dstY * dstStride + dstX) * bpp, height * dstStride * bpp, GPU_INVALIDATE_HINT);
|
||||
framebufferManager_.NotifyBlockTransferAfter(dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, width, height, bpp);
|
||||
framebufferManager_.NotifyBlockTransferAfter(dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, width, height, bpp, skipDrawReason);
|
||||
}
|
||||
|
||||
CBreakPoints::ExecMemCheck(srcBasePtr + (srcY * srcStride + srcX) * bpp, false, height * srcStride * bpp, currentMIPS->pc);
|
||||
|
@ -1931,7 +1931,7 @@ void DIRECTX9_GPU::InvalidateCacheInternal(u32 addr, int size, GPUInvalidationTy
|
|||
}
|
||||
|
||||
void DIRECTX9_GPU::PerformMemoryCopyInternal(u32 dest, u32 src, int size) {
|
||||
if (!framebufferManager_.NotifyFramebufferCopy(src, dest, size)) {
|
||||
if (!framebufferManager_.NotifyFramebufferCopy(src, dest, size, false, gstate_c.skipDrawReason)) {
|
||||
// We use a little hack for Download/Upload using a VRAM mirror.
|
||||
// Since they're identical we don't need to copy.
|
||||
if (!Memory::IsVRAMAddress(dest) || (dest ^ 0x00400000) != src) {
|
||||
|
@ -1942,7 +1942,7 @@ void DIRECTX9_GPU::PerformMemoryCopyInternal(u32 dest, u32 src, int size) {
|
|||
}
|
||||
|
||||
void DIRECTX9_GPU::PerformMemorySetInternal(u32 dest, u8 v, int size) {
|
||||
if (!framebufferManager_.NotifyFramebufferCopy(dest, dest, size, true)) {
|
||||
if (!framebufferManager_.NotifyFramebufferCopy(dest, dest, size, true, gstate_c.skipDrawReason)) {
|
||||
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ private:
|
|||
void Flush() {
|
||||
transformDraw_.Flush();
|
||||
}
|
||||
void DoBlockTransfer();
|
||||
void DoBlockTransfer(u32 skipDrawReason);
|
||||
void ApplyDrawState(int prim);
|
||||
void CheckFlushOp(int cmd, u32 diff);
|
||||
void BuildReportingInfo();
|
||||
|
|
|
@ -671,7 +671,7 @@ void TransformDrawEngineDX9::ApplyDrawState(int prim) {
|
|||
renderHeightFactor = renderHeight / 272.0f;
|
||||
}
|
||||
|
||||
renderX += gstate_c.cutRTOffsetX * renderWidthFactor;
|
||||
renderX += gstate_c.curRTOffsetX * renderWidthFactor;
|
||||
|
||||
bool throughmode = gstate.isModeThrough();
|
||||
|
||||
|
|
|
@ -247,7 +247,7 @@ void FramebufferManager::CompileDraw2DProgram() {
|
|||
usePostShader_ = true;
|
||||
}
|
||||
} else {
|
||||
postShaderProgram_ = 0;
|
||||
postShaderProgram_ = nullptr;
|
||||
usePostShader_ = false;
|
||||
}
|
||||
|
||||
|
@ -258,36 +258,36 @@ void FramebufferManager::CompileDraw2DProgram() {
|
|||
void FramebufferManager::DestroyDraw2DProgram() {
|
||||
if (draw2dprogram_) {
|
||||
glsl_destroy(draw2dprogram_);
|
||||
draw2dprogram_ = 0;
|
||||
draw2dprogram_ = nullptr;
|
||||
}
|
||||
if (plainColorProgram_) {
|
||||
glsl_destroy(plainColorProgram_);
|
||||
plainColorProgram_ = 0;
|
||||
plainColorProgram_ = nullptr;
|
||||
}
|
||||
if (postShaderProgram_) {
|
||||
glsl_destroy(postShaderProgram_);
|
||||
postShaderProgram_ = 0;
|
||||
postShaderProgram_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
FramebufferManager::FramebufferManager() :
|
||||
drawPixelsTex_(0),
|
||||
drawPixelsTexFormat_(GE_FORMAT_INVALID),
|
||||
convBuf_(0),
|
||||
draw2dprogram_(0),
|
||||
postShaderProgram_(0),
|
||||
stencilUploadProgram_(0),
|
||||
convBuf_(nullptr),
|
||||
draw2dprogram_(nullptr),
|
||||
postShaderProgram_(nullptr),
|
||||
stencilUploadProgram_(nullptr),
|
||||
plainColorLoc_(-1),
|
||||
timeLoc_(-1),
|
||||
textureCache_(0),
|
||||
shaderManager_(0),
|
||||
textureCache_(nullptr),
|
||||
shaderManager_(nullptr),
|
||||
usePostShader_(false),
|
||||
postShaderAtOutputResolution_(false),
|
||||
resized_(false),
|
||||
gameUsesSequentialCopies_(false)
|
||||
#ifndef USING_GLES2
|
||||
,
|
||||
pixelBufObj_(0),
|
||||
pixelBufObj_(nullptr),
|
||||
currentPBO_(0)
|
||||
#endif
|
||||
{
|
||||
|
@ -703,7 +703,7 @@ void FramebufferManager::NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb)
|
|||
ClearBuffer();
|
||||
|
||||
// ugly...
|
||||
if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) {
|
||||
if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height && shaderManager_) {
|
||||
shaderManager_->DirtyUniform(DIRTY_PROJTHROUGHMATRIX);
|
||||
}
|
||||
}
|
||||
|
@ -764,7 +764,7 @@ void FramebufferManager::NotifyRenderFramebufferSwitched(VirtualFramebuffer *pre
|
|||
}
|
||||
|
||||
// ugly...
|
||||
if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) {
|
||||
if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height && shaderManager_) {
|
||||
shaderManager_->DirtyUniform(DIRTY_PROJTHROUGHMATRIX);
|
||||
}
|
||||
}
|
||||
|
@ -778,7 +778,7 @@ void FramebufferManager::NotifyRenderFramebufferUpdated(VirtualFramebuffer *vfb,
|
|||
}
|
||||
|
||||
// ugly...
|
||||
if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) {
|
||||
if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height && shaderManager_) {
|
||||
shaderManager_->DirtyUniform(DIRTY_PROJTHROUGHMATRIX);
|
||||
}
|
||||
}
|
||||
|
@ -875,7 +875,7 @@ FBO *FramebufferManager::GetTempFBO(u16 w, u16 h, FBOColorDepth depth) {
|
|||
return fbo;
|
||||
}
|
||||
|
||||
void FramebufferManager::BindFramebufferColor(int stage, VirtualFramebuffer *framebuffer, bool skipCopy) {
|
||||
void FramebufferManager::BindFramebufferColor(int stage, u32 fbRawAddress, VirtualFramebuffer *framebuffer, bool skipCopy) {
|
||||
if (framebuffer == NULL) {
|
||||
framebuffer = currentRenderVfb_;
|
||||
}
|
||||
|
@ -896,7 +896,7 @@ void FramebufferManager::BindFramebufferColor(int stage, VirtualFramebuffer *fra
|
|||
if (GPUStepping::IsStepping() || g_Config.bDisableSlowFramebufEffects) {
|
||||
skipCopy = true;
|
||||
}
|
||||
if (!skipCopy && currentRenderVfb_ && framebuffer->fb_address == gstate.getFrameBufRawAddress()) {
|
||||
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);
|
||||
if (renderCopy) {
|
||||
|
@ -1862,11 +1862,7 @@ void FramebufferManager::Resized() {
|
|||
resized_ = true;
|
||||
}
|
||||
|
||||
bool FramebufferManager::GetCurrentFramebuffer(GPUDebugBuffer &buffer) {
|
||||
u32 fb_address = gstate.getFrameBufRawAddress();
|
||||
int fb_stride = gstate.FrameBufStride();
|
||||
GEBufferFormat format = gstate.FrameBufFormat();
|
||||
|
||||
bool FramebufferManager::GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer) {
|
||||
VirtualFramebuffer *vfb = currentRenderVfb_;
|
||||
if (!vfb) {
|
||||
vfb = GetVFBAt(fb_address);
|
||||
|
@ -1898,13 +1894,7 @@ bool FramebufferManager::GetDisplayFramebuffer(GPUDebugBuffer &buffer) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FramebufferManager::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
|
||||
u32 fb_address = gstate.getFrameBufRawAddress();
|
||||
int fb_stride = gstate.FrameBufStride();
|
||||
|
||||
u32 z_address = gstate.getDepthBufRawAddress();
|
||||
int z_stride = gstate.DepthBufStride();
|
||||
|
||||
bool FramebufferManager::GetDepthbuffer(u32 fb_address, int fb_stride, u32 z_address, int z_stride, GPUDebugBuffer &buffer) {
|
||||
VirtualFramebuffer *vfb = currentRenderVfb_;
|
||||
if (!vfb) {
|
||||
vfb = GetVFBAt(fb_address);
|
||||
|
@ -1930,10 +1920,7 @@ bool FramebufferManager::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
|
|||
#endif
|
||||
}
|
||||
|
||||
bool FramebufferManager::GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
|
||||
u32 fb_address = gstate.getFrameBufRawAddress();
|
||||
int fb_stride = gstate.FrameBufStride();
|
||||
|
||||
bool FramebufferManager::GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer) {
|
||||
VirtualFramebuffer *vfb = currentRenderVfb_;
|
||||
if (!vfb) {
|
||||
vfb = GetVFBAt(fb_address);
|
||||
|
|
|
@ -101,7 +101,7 @@ public:
|
|||
void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst);
|
||||
|
||||
// For use when texturing from a framebuffer. May create a duplicate if target.
|
||||
void BindFramebufferColor(int stage, VirtualFramebuffer *framebuffer, bool skipCopy = false);
|
||||
void BindFramebufferColor(int stage, u32 fbRawAddress, VirtualFramebuffer *framebuffer, bool skipCopy = false);
|
||||
|
||||
// Reads a rectangular subregion of a framebuffer to the right position in its backing memory.
|
||||
virtual void ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h) override;
|
||||
|
@ -113,9 +113,9 @@ public:
|
|||
void DestroyFramebuf(VirtualFramebuffer *vfb);
|
||||
void ResizeFramebufFBO(VirtualFramebuffer *vfb, u16 w, u16 h, bool force = false);
|
||||
|
||||
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer);
|
||||
bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer);
|
||||
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer);
|
||||
bool GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer);
|
||||
bool GetDepthbuffer(u32 fb_address, int fb_stride, u32 z_address, int z_stride, GPUDebugBuffer &buffer);
|
||||
bool GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer);
|
||||
static bool GetDisplayFramebuffer(GPUDebugBuffer &buffer);
|
||||
|
||||
virtual void RebindFramebuffer() override;
|
||||
|
|
|
@ -1396,7 +1396,7 @@ void GLES_GPU::Execute_BlockTransferStart(u32 op, u32 diff) {
|
|||
// TODO: Here we should check if the transfer overlaps a framebuffer or any textures,
|
||||
// and take appropriate action. This is a block transfer between RAM and VRAM, or vice versa.
|
||||
// Can we skip this on SkipDraw?
|
||||
DoBlockTransfer();
|
||||
DoBlockTransfer(gstate_c.skipDrawReason);
|
||||
|
||||
// Fixes Gran Turismo's funky text issue, since it overwrites the current texture.
|
||||
gstate_c.textureChanged = TEXCHANGE_UPDATED;
|
||||
|
@ -1959,7 +1959,7 @@ void GLES_GPU::UpdateStats() {
|
|||
gpuStats.numFBOs = (int)framebufferManager_.NumVFBs();
|
||||
}
|
||||
|
||||
void GLES_GPU::DoBlockTransfer() {
|
||||
void GLES_GPU::DoBlockTransfer(u32 skipDrawReason) {
|
||||
// TODO: This is used a lot to copy data around between render targets and textures,
|
||||
// and also to quickly load textures from RAM to VRAM. So we should do checks like the following:
|
||||
// * Does dstBasePtr point to an existing texture? If so maybe reload it immediately.
|
||||
|
@ -2013,7 +2013,7 @@ void GLES_GPU::DoBlockTransfer() {
|
|||
}
|
||||
|
||||
// Tell the framebuffer manager to take action if possible. If it does the entire thing, let's just return.
|
||||
if (!framebufferManager_.NotifyBlockTransferBefore(dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, width, height, bpp)) {
|
||||
if (!framebufferManager_.NotifyBlockTransferBefore(dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, width, height, bpp, skipDrawReason)) {
|
||||
// Do the copy! (Hm, if we detect a drawn video frame (see below) then we could maybe skip this?)
|
||||
// Can use GetPointerUnchecked because we checked the addresses above. We could also avoid them
|
||||
// entirely by walking a couple of pointers...
|
||||
|
@ -2036,7 +2036,7 @@ void GLES_GPU::DoBlockTransfer() {
|
|||
}
|
||||
|
||||
textureCache_.Invalidate(dstBasePtr + (dstY * dstStride + dstX) * bpp, height * dstStride * bpp, GPU_INVALIDATE_HINT);
|
||||
framebufferManager_.NotifyBlockTransferAfter(dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, width, height, bpp);
|
||||
framebufferManager_.NotifyBlockTransferAfter(dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, width, height, bpp, skipDrawReason);
|
||||
}
|
||||
|
||||
#ifndef MOBILE_DEVICE
|
||||
|
@ -2072,7 +2072,7 @@ void GLES_GPU::InvalidateCacheInternal(u32 addr, int size, GPUInvalidationType t
|
|||
}
|
||||
|
||||
void GLES_GPU::PerformMemoryCopyInternal(u32 dest, u32 src, int size) {
|
||||
if (!framebufferManager_.NotifyFramebufferCopy(src, dest, size)) {
|
||||
if (!framebufferManager_.NotifyFramebufferCopy(src, dest, size, false, gstate_c.skipDrawReason)) {
|
||||
// We use a little hack for Download/Upload using a VRAM mirror.
|
||||
// Since they're identical we don't need to copy.
|
||||
if (!Memory::IsVRAMAddress(dest) || (dest ^ 0x00400000) != src) {
|
||||
|
@ -2083,7 +2083,7 @@ void GLES_GPU::PerformMemoryCopyInternal(u32 dest, u32 src, int size) {
|
|||
}
|
||||
|
||||
void GLES_GPU::PerformMemorySetInternal(u32 dest, u8 v, int size) {
|
||||
if (!framebufferManager_.NotifyFramebufferCopy(dest, dest, size, true)) {
|
||||
if (!framebufferManager_.NotifyFramebufferCopy(dest, dest, size, true, gstate_c.skipDrawReason)) {
|
||||
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
|
||||
}
|
||||
}
|
||||
|
@ -2213,15 +2213,27 @@ void GLES_GPU::DoState(PointerWrap &p) {
|
|||
}
|
||||
|
||||
bool GLES_GPU::GetCurrentFramebuffer(GPUDebugBuffer &buffer) {
|
||||
return framebufferManager_.GetCurrentFramebuffer(buffer);
|
||||
u32 fb_address = gstate.getFrameBufRawAddress();
|
||||
int fb_stride = gstate.FrameBufStride();
|
||||
GEBufferFormat format = gstate.FrameBufFormat();
|
||||
return framebufferManager_.GetFramebuffer(fb_address, fb_stride, format, buffer);
|
||||
}
|
||||
|
||||
bool GLES_GPU::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
|
||||
return framebufferManager_.GetCurrentDepthbuffer(buffer);
|
||||
u32 fb_address = gstate.getFrameBufRawAddress();
|
||||
int fb_stride = gstate.FrameBufStride();
|
||||
|
||||
u32 z_address = gstate.getDepthBufRawAddress();
|
||||
int z_stride = gstate.DepthBufStride();
|
||||
|
||||
return framebufferManager_.GetDepthbuffer(fb_address, fb_stride, z_address, z_stride, buffer);
|
||||
}
|
||||
|
||||
bool GLES_GPU::GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
|
||||
return framebufferManager_.GetCurrentStencilbuffer(buffer);
|
||||
u32 fb_address = gstate.getFrameBufRawAddress();
|
||||
int fb_stride = gstate.FrameBufStride();
|
||||
|
||||
return framebufferManager_.GetStencilbuffer(fb_address, fb_stride, buffer);
|
||||
}
|
||||
|
||||
bool GLES_GPU::GetCurrentTexture(GPUDebugBuffer &buffer, int level) {
|
||||
|
|
|
@ -155,7 +155,7 @@ private:
|
|||
void Flush() {
|
||||
transformDraw_.Flush();
|
||||
}
|
||||
void DoBlockTransfer();
|
||||
void DoBlockTransfer(u32 skipDrawReason);
|
||||
void ApplyDrawState(int prim);
|
||||
void CheckFlushOp(int cmd, u32 diff);
|
||||
void BuildReportingInfo();
|
||||
|
|
|
@ -190,7 +190,7 @@ bool TransformDrawEngine::ApplyShaderBlending() {
|
|||
return false;
|
||||
}
|
||||
|
||||
framebufferManager_->BindFramebufferColor(GL_TEXTURE1, NULL);
|
||||
framebufferManager_->BindFramebufferColor(GL_TEXTURE1, gstate.getFrameBufRawAddress(), nullptr);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
// If we are rendering at a higher resolution, linear is probably best for the dest color.
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
@ -743,7 +743,7 @@ void TransformDrawEngine::ApplyDrawState(int prim) {
|
|||
renderHeightFactor = renderHeight / 272.0f;
|
||||
}
|
||||
|
||||
renderX += gstate_c.cutRTOffsetX * renderWidthFactor;
|
||||
renderX += gstate_c.curRTOffsetX * renderWidthFactor;
|
||||
|
||||
// Scissor
|
||||
int scissorX1 = gstate.getScissorX1();
|
||||
|
|
|
@ -1016,7 +1016,7 @@ void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffe
|
|||
glBindTexture(GL_TEXTURE_2D, clutTexture);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
framebufferManager_->BindFramebufferColor(GL_TEXTURE0, framebuffer, true);
|
||||
framebufferManager_->BindFramebufferColor(GL_TEXTURE0, gstate.getFrameBufRawAddress(), framebuffer, true);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
|
@ -1049,7 +1049,7 @@ void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffe
|
|||
gstate_c.textureSimpleAlpha = alphaStatus == TexCacheEntry::STATUS_ALPHA_SIMPLE;
|
||||
} else {
|
||||
entry->status &= ~TexCacheEntry::STATUS_DEPALETTIZE;
|
||||
framebufferManager_->BindFramebufferColor(GL_TEXTURE0, framebuffer);
|
||||
framebufferManager_->BindFramebufferColor(GL_TEXTURE0, gstate.getFrameBufRawAddress(), framebuffer);
|
||||
|
||||
gstate_c.textureFullAlpha = gstate.getTextureFormat() == GE_TFMT_5650;
|
||||
gstate_c.textureSimpleAlpha = gstate_c.textureFullAlpha;
|
||||
|
|
|
@ -482,11 +482,12 @@ struct GPUStateCache {
|
|||
float vpWidthScale;
|
||||
float vpHeightScale;
|
||||
|
||||
// TODO: These should be accessed from the current VFB object directly.
|
||||
u32 curRTWidth;
|
||||
u32 curRTHeight;
|
||||
u32 curRTRenderWidth;
|
||||
u32 curRTRenderHeight;
|
||||
u32 cutRTOffsetX;
|
||||
u32 curRTOffsetX;
|
||||
|
||||
u32 getRelativeAddress(u32 data) const;
|
||||
void DoState(PointerWrap &p);
|
||||
|
|
Loading…
Add table
Reference in a new issue