Refactor: Even more getting rid of gstate access in the framebuffer manager.

This commit is contained in:
Henrik Rydgard 2015-08-05 12:13:14 +02:00
parent d7c76cb1da
commit d7f4c47c22
12 changed files with 79 additions and 79 deletions

View file

@ -248,7 +248,7 @@ void GetFramebufferHeuristicInputs(FramebufferHeuristicParams *params, const GPU
params->scissorHeight = gstate.getScissorY2() + 1;
}
VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const FramebufferHeuristicParams &params) {
VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const FramebufferHeuristicParams &params, 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();
}
}

View file

@ -124,7 +124,7 @@ public:
void BeginFrame();
void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format);
VirtualFramebuffer *DoSetRenderFrameBuffer(const FramebufferHeuristicParams &params);
VirtualFramebuffer *DoSetRenderFrameBuffer(const FramebufferHeuristicParams &params, 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;

View file

@ -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);
}
}

View file

@ -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();

View file

@ -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();

View file

@ -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);

View file

@ -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;

View file

@ -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) {

View file

@ -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();

View file

@ -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();

View file

@ -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;

View file

@ -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);