Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate framebuffers that are rendered onto themselves #5150

Merged
merged 5 commits into from
Jan 20, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions GPU/Directx9/GPU_DX9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -740,8 +740,10 @@ void DIRECTX9_GPU::ExecuteOp(u32 op, u32 diff) {

case GE_CMD_REGION1:
case GE_CMD_REGION2:
if (diff)
if (diff) {
gstate_c.framebufChanged = true;
gstate_c.textureChanged = true;
}
break;

case GE_CMD_CLIPENABLE:
Expand Down Expand Up @@ -830,8 +832,10 @@ void DIRECTX9_GPU::ExecuteOp(u32 op, u32 diff) {
case GE_CMD_FRAMEBUFPTR:
case GE_CMD_FRAMEBUFWIDTH:
case GE_CMD_FRAMEBUFPIXFORMAT:
if (diff)
if (diff) {
gstate_c.framebufChanged = true;
gstate_c.textureChanged = true;
}
break;

case GE_CMD_TEXADDR0:
Expand Down Expand Up @@ -1045,8 +1049,10 @@ void DIRECTX9_GPU::ExecuteOp(u32 op, u32 diff) {
case GE_CMD_VIEWPORTY2:
case GE_CMD_VIEWPORTZ1:
case GE_CMD_VIEWPORTZ2:
if (diff)
if (diff) {
gstate_c.framebufChanged = true;
gstate_c.textureChanged = true;
}
break;

case GE_CMD_LIGHTENABLE0:
Expand Down
51 changes: 51 additions & 0 deletions GPU/GLES/Framebuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ FramebufferManager::~FramebufferManager() {
}
SetNumExtraFBOs(0);

for (auto it = renderCopies_.begin(), end = renderCopies_.end(); it != end; ++it) {
fbo_destroy(it->second);
}

#ifndef USING_GLES2
delete [] pixelBufObj_;
#endif
Expand Down Expand Up @@ -907,6 +911,7 @@ void FramebufferManager::BindFramebufferDepth(VirtualFramebuffer *sourceframebuf
if (MaskedEqual(sourceframebuffer->z_address, targetframebuffer->z_address) &&
sourceframebuffer->renderWidth == targetframebuffer->renderWidth &&
sourceframebuffer->renderHeight == targetframebuffer->renderHeight) {

#ifndef USING_GLES2
if (gl_extensions.FBO_ARB) {
#else
Expand All @@ -922,7 +927,53 @@ void FramebufferManager::BindFramebufferDepth(VirtualFramebuffer *sourceframebuf
#endif
}
}
}

void FramebufferManager::BindFramebufferColor(VirtualFramebuffer *framebuffer) {
if (!framebuffer->fbo || !useBufferedRendering_) {
glBindTexture(GL_TEXTURE_2D, 0);
gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE;
return;
}

if (MaskedEqual(framebuffer->fb_address, gstate.getFrameBufRawAddress())) {
#ifndef USING_GLES2
if (gl_extensions.FBO_ARB) {
#else
if (gl_extensions.GLES3) {
#endif
#ifdef MAY_HAVE_GLES3

// TODO: Maybe merge with bvfbs_? Not sure if those could be packing, and they're created at a different size.
FBO *renderCopy = NULL;
std::pair<int, int> copySize = std::make_pair((int)framebuffer->renderWidth, (int)framebuffer->renderHeight);
for (auto it = renderCopies_.begin(), end = renderCopies_.end(); it != end; ++it) {
if (it->first == copySize) {
renderCopy = it->second;
break;
}
}
if (!renderCopy) {
renderCopy = fbo_create(framebuffer->renderWidth, framebuffer->renderHeight, 1, true, framebuffer->colorDepth);
renderCopies_[copySize] = renderCopy;
}

fbo_bind_as_render_target(renderCopy);
glViewport(0, 0, framebuffer->renderWidth, framebuffer->renderHeight);
fbo_bind_for_read(framebuffer->fbo);
glBlitFramebuffer(0, 0, framebuffer->renderWidth, framebuffer->renderHeight, 0, 0, framebuffer->renderWidth, framebuffer->renderHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);

fbo_bind_as_render_target(currentRenderVfb_->fbo);
if (gl_extensions.gpuVendor != GPU_VENDOR_POWERVR)
glstate.viewport.restore();
fbo_bind_color_as_texture(renderCopy, 0);
#endif
} else {
fbo_bind_color_as_texture(framebuffer->fbo, 0);
}
} else {
fbo_bind_color_as_texture(framebuffer->fbo, 0);
}
}

void FramebufferManager::CopyDisplayToOutput() {
Expand Down
6 changes: 5 additions & 1 deletion GPU/GLES/Framebuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,10 @@ class FramebufferManager {
void SetLineWidth();

void BindFramebufferDepth(VirtualFramebuffer *sourceframebuffer, VirtualFramebuffer *targetframebuffer);


// For use when texturing from a framebuffer. May create a duplicate if target.
void BindFramebufferColor(VirtualFramebuffer *framebuffer);

// Just for logging right now. Might remove/change.
void NotifyBlockTransfer(u32 dst, u32 src);

Expand Down Expand Up @@ -228,6 +231,7 @@ class FramebufferManager {
bool useBufferedRendering_;

std::vector<VirtualFramebuffer *> bvfbs_; // blitting FBOs
std::map<std::pair<int, int>, FBO *> renderCopies_;

std::set<std::pair<u32, u32>> knownFramebufferCopies_;

Expand Down
17 changes: 13 additions & 4 deletions GPU/GLES/GLES_GPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ GLES_GPU::GLES_GPU()
transformDraw_.SetFramebufferManager(&framebufferManager_);
framebufferManager_.SetTextureCache(&textureCache_);
framebufferManager_.SetShaderManager(shaderManager_);
textureCache_.SetFramebufferManager(&framebufferManager_);

// Sanity check gstate
if ((int *)&gstate.transferstart - (int *)&gstate != 0xEA) {
Expand Down Expand Up @@ -893,8 +894,10 @@ void GLES_GPU::ExecuteOpInternal(u32 op, u32 diff) {

case GE_CMD_REGION1:
case GE_CMD_REGION2:
if (diff)
if (diff) {
gstate_c.framebufChanged = true;
gstate_c.textureChanged = true;
}
break;

case GE_CMD_CLIPENABLE:
Expand Down Expand Up @@ -970,8 +973,10 @@ void GLES_GPU::ExecuteOpInternal(u32 op, u32 diff) {

case GE_CMD_SCISSOR1:
case GE_CMD_SCISSOR2:
if (diff)
if (diff) {
gstate_c.framebufChanged = true;
gstate_c.textureChanged = true;
}
break;

///
Expand All @@ -982,8 +987,10 @@ void GLES_GPU::ExecuteOpInternal(u32 op, u32 diff) {
case GE_CMD_FRAMEBUFPTR:
case GE_CMD_FRAMEBUFWIDTH:
case GE_CMD_FRAMEBUFPIXFORMAT:
if (diff)
if (diff) {
gstate_c.framebufChanged = true;
gstate_c.textureChanged = true;
}
break;

case GE_CMD_TEXADDR0:
Expand Down Expand Up @@ -1209,8 +1216,10 @@ void GLES_GPU::ExecuteOpInternal(u32 op, u32 diff) {
case GE_CMD_VIEWPORTY2:
case GE_CMD_VIEWPORTZ1:
case GE_CMD_VIEWPORTZ2:
if (diff)
if (diff) {
gstate_c.framebufChanged = true;
gstate_c.textureChanged = true;
}
break;

case GE_CMD_LIGHTENABLE0:
Expand Down
Loading