diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index d773ec0a8b96..5b4f494b25dd 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -119,7 +119,8 @@ FramebufferManagerCommon::FramebufferManagerCommon() : frameLastFramebufUsed_(0), currentRenderVfb_(0), framebufRangeEnd_(0), - hackForce04154000Download_(false) { + hackForce04154000Download_(false), + updateVRAM_(false) { UpdateSize(); } @@ -795,7 +796,7 @@ void FramebufferManagerCommon::NotifyBlockTransferAfter(u32 dstBasePtr, int dstS (displayBuffer != 0 && dstBasePtr == displayBuffer)) && dstStride == 512 && height == 272 && !useBufferedRendering_) { FlushBeforeCopy(); - DrawFramebuffer(Memory::GetPointerUnchecked(dstBasePtr), displayFormat_, 512, false); + DrawFramebufferToOutput(Memory::GetPointerUnchecked(dstBasePtr), displayFormat_, 512, false); } if (MayIntersectFramebuffer(srcBasePtr) || MayIntersectFramebuffer(dstBasePtr)) { diff --git a/GPU/Common/FramebufferCommon.h b/GPU/Common/FramebufferCommon.h index 4017ecb3fd79..e8cd87212294 100644 --- a/GPU/Common/FramebufferCommon.h +++ b/GPU/Common/FramebufferCommon.h @@ -162,7 +162,7 @@ class FramebufferManagerCommon { 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; virtual void DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) = 0; - virtual void DrawFramebuffer(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) = 0; + virtual void DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) = 0; size_t NumVFBs() const { return vfbs_.size(); } @@ -220,7 +220,7 @@ class FramebufferManagerCommon { virtual void DecimateFBOs() = 0; // Used by ReadFramebufferToMemory and later framebuffer block copies - virtual void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, bool flip = false) = 0; + virtual void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) = 0; void EstimateDrawingSize(u32 fb_address, GEBufferFormat fb_format, int viewport_width, int viewport_height, int region_width, int region_height, int scissor_width, int scissor_height, int fb_stride, int &drawing_width, int &drawing_height); u32 FramebufferByteSize(const VirtualFramebuffer *vfb) const; diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index b6183e93d716..ecabfd848adb 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -23,7 +23,6 @@ std::string VertexShaderDesc(const ShaderID &id) { if (id.Bit(VS_BIT_NORM_REVERSE)) desc << "RevN "; if (id.Bit(VS_BIT_DO_TEXTURE)) desc << "Tex "; if (id.Bit(VS_BIT_DO_TEXTURE_PROJ)) desc << "TexProj "; - if (id.Bit(VS_BIT_FLIP_TEXTURE)) desc << "Flip "; int uvgMode = id.Bits(VS_BIT_UVGEN_MODE, 2); const char *uvgModes[4] = { "UV ", "UVMtx ", "UVEnv ", "UVUnk " }; int ls0 = id.Bits(VS_BIT_LS0, 2); @@ -72,7 +71,6 @@ void ComputeVertexShaderID(ShaderID *id_out, u32 vertType, bool useHWTransform) if (doTexture) { id.SetBit(VS_BIT_DO_TEXTURE); - id.SetBit(VS_BIT_FLIP_TEXTURE, gstate_c.flipTexture); id.SetBit(VS_BIT_DO_TEXTURE_PROJ, doTextureProjection); } @@ -138,7 +136,6 @@ std::string FragmentShaderDesc(const ShaderID &id) { if (id.Bit(FS_BIT_CLEARMODE)) desc << "Clear "; if (id.Bit(FS_BIT_DO_TEXTURE)) desc << "Tex "; if (id.Bit(FS_BIT_DO_TEXTURE_PROJ)) desc << "TexProj "; - if (id.Bit(FS_BIT_FLIP_TEXTURE)) desc << "Flip "; if (id.Bit(FS_BIT_TEXALPHA)) desc << "TexAlpha "; if (id.Bit(FS_BIT_TEXTURE_AT_OFFSET)) desc << "TexOffs "; if (id.Bit(FS_BIT_LMODE)) desc << "LM "; @@ -223,7 +220,6 @@ void ComputeFragmentShaderID(ShaderID *id_out, uint32_t vertType) { id.SetBit(FS_BIT_DO_TEXTURE); id.SetBits(FS_BIT_TEXFUNC, 3, gstate.getTextureFunction()); id.SetBit(FS_BIT_TEXALPHA, doTextureAlpha & 1); // rgb or rgba - id.SetBit(FS_BIT_FLIP_TEXTURE, gstate_c.flipTexture); if (gstate_c.needShaderTexClamp) { bool textureAtOffset = gstate_c.curTextureXOffset != 0 || gstate_c.curTextureYOffset != 0; // 4 bits total. diff --git a/GPU/Common/ShaderId.h b/GPU/Common/ShaderId.h index 14c9b39d8468..1983ab8551fd 100644 --- a/GPU/Common/ShaderId.h +++ b/GPU/Common/ShaderId.h @@ -11,7 +11,6 @@ enum { VS_BIT_ENABLE_FOG = 2, VS_BIT_HAS_COLOR = 3, VS_BIT_DO_TEXTURE = 4, - VS_BIT_FLIP_TEXTURE = 5, VS_BIT_DO_TEXTURE_PROJ = 6, VS_BIT_USE_HW_TRANSFORM = 8, VS_BIT_HAS_NORMAL = 9, // conditioned on hw transform @@ -49,7 +48,6 @@ enum { FS_BIT_DO_TEXTURE = 1, FS_BIT_TEXFUNC = 2, // 3 bits FS_BIT_TEXALPHA = 5, - FS_BIT_FLIP_TEXTURE = 6, FS_BIT_SHADER_TEX_CLAMP = 7, FS_BIT_CLAMP_S = 8, FS_BIT_CLAMP_T = 9, diff --git a/GPU/Common/SoftwareTransformCommon.cpp b/GPU/Common/SoftwareTransformCommon.cpp index 69e4d4e3112e..5b31e7316392 100644 --- a/GPU/Common/SoftwareTransformCommon.cpp +++ b/GPU/Common/SoftwareTransformCommon.cpp @@ -176,8 +176,6 @@ void SoftwareTransform( } VertexReader reader(decoded, decVtxFormat, vertType); - // We flip in the fragment shader for GE_TEXMAP_TEXTURE_MATRIX. - const bool flipV = gstate_c.flipTexture && gstate.getUVGenMode() != GE_TEXMAP_TEXTURE_MATRIX; if (throughmode) { for (int index = 0; index < maxIndex; index++) { // Do not touch the coordinates or the colors. No lighting. @@ -201,11 +199,6 @@ void SoftwareTransform( vert.u = 0.0f; vert.v = 0.0f; } - // Scale UV? - - if (flipV) { - vert.v = 1.0f - vert.v; - } // Ignore color1 and fog, never used in throughmode anyway. // The w of uv is also never used (hardcoded to 1.0.) @@ -397,9 +390,6 @@ void SoftwareTransform( memcpy(&transformed[index].x, v, 3 * sizeof(float)); transformed[index].fog = fogCoef; memcpy(&transformed[index].u, uv, 3 * sizeof(float)); - if (flipV) { - transformed[index].v = 1.0f - transformed[index].v; - } transformed[index].color0_32 = c0.ToRGBA(); transformed[index].color1_32 = c1.ToRGBA(); @@ -431,21 +421,14 @@ void SoftwareTransform( bool tlOutside; bool tlAlmostOutside; bool brOutside; - if (gstate_c.flipTexture) { - // This is flipped for OpenGL, but the same logic as unflipped, so look there. - tlOutside = transformed[0].v < -invTexH && transformed[0].v >= 1.0f - heightFactor; - brOutside = transformed[1].v < -invTexH && transformed[1].v >= 1.0f - heightFactor; - tlAlmostOutside = transformed[0].v <= 0.5f && transformed[0].v >= 1.0f - heightFactor; - } else { - // If we're outside heightFactor, then v must be wrapping or clamping. Avoid this workaround. - // If we're <= 1.0f, we're inside the framebuffer (workaround not needed.) - // We buffer that 1.0f a little more with a texel to avoid some false positives. - tlOutside = transformed[0].v <= heightFactor && transformed[0].v > 1.0f + invTexH; - brOutside = transformed[1].v <= heightFactor && transformed[1].v > 1.0f + invTexH; - // Careful: if br is outside, but tl is well inside, this workaround still doesn't make sense. - // We go with halfway, since we overestimate framebuffer heights sometimes but not by much. - tlAlmostOutside = transformed[0].v <= heightFactor && transformed[0].v >= 0.5f; - } + // If we're outside heightFactor, then v must be wrapping or clamping. Avoid this workaround. + // If we're <= 1.0f, we're inside the framebuffer (workaround not needed.) + // We buffer that 1.0f a little more with a texel to avoid some false positives. + tlOutside = transformed[0].v <= heightFactor && transformed[0].v > 1.0f + invTexH; + brOutside = transformed[1].v <= heightFactor && transformed[1].v > 1.0f + invTexH; + // Careful: if br is outside, but tl is well inside, this workaround still doesn't make sense. + // We go with halfway, since we overestimate framebuffer heights sometimes but not by much. + tlAlmostOutside = transformed[0].v <= heightFactor && transformed[0].v >= 0.5f; if (tlOutside || (brOutside && tlAlmostOutside)) { // Okay, so we're texturing from outside the framebuffer, but inside the texture height. // Breath of Fire 3 does this to access a render surface at an offset. @@ -464,13 +447,7 @@ void SoftwareTransform( for (int index = 0; index < maxIndex; ++index) { transformed[index].u *= widthFactor / oldWidthFactor; // Inverse it back to scale to the new FBO, and add 1.0f to account for old FBO. - if (gstate_c.flipTexture) { - transformed[index].v = (1.0f - transformed[index].v) / oldHeightFactor; - transformed[index].v -= yDiff; - transformed[index].v = 1.0f - (transformed[index].v * heightFactor); - } else { - transformed[index].v = (transformed[index].v / oldHeightFactor - yDiff) * heightFactor; - } + transformed[index].v = (transformed[index].v / oldHeightFactor - yDiff) * heightFactor; } } } @@ -486,18 +463,26 @@ void SoftwareTransform( numTrans = vertexCount; drawIndexed = true; } else { + bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; + if (useBufferedRendering) + ySign = -ySign; + float flippedMatrix[16]; if (!throughmode) { memcpy(&flippedMatrix, gstate.projMatrix, 16 * sizeof(float)); - const bool invertedY = gstate_c.vpHeight < 0; + const bool invertedY = useBufferedRendering ? (gstate_c.vpHeight > 0) : (gstate_c.vpHeight < 0); if (invertedY) { + flippedMatrix[1] = -flippedMatrix[1]; flippedMatrix[5] = -flippedMatrix[5]; + flippedMatrix[9] = -flippedMatrix[9]; flippedMatrix[13] = -flippedMatrix[13]; } const bool invertedX = gstate_c.vpWidth < 0; if (invertedX) { flippedMatrix[0] = -flippedMatrix[0]; + flippedMatrix[4] = -flippedMatrix[4]; + flippedMatrix[8] = -flippedMatrix[8]; flippedMatrix[12] = -flippedMatrix[12]; } } diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferDX9.cpp index 9c5c7f72fcc7..b86237592325 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferDX9.cpp @@ -183,21 +183,21 @@ namespace DX9 { } void FramebufferManagerDX9::DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) { - if (useBufferedRendering_ && vfb->fbo) { + if (useBufferedRendering_ && vfb && vfb->fbo) { fbo_bind_as_render_target(vfb->fbo); dxstate.viewport.set(0, 0, vfb->renderWidth, vfb->renderHeight); } else { float x, y, w, h; - CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, false, false); + CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, ROTATION_LOCKED_HORIZONTAL, false); dxstate.viewport.set(x, y, w, h); } MakePixelTexture(srcPixels, srcPixelFormat, srcStride, width, height); DisableState(); - DrawActiveTexture(drawPixelsTex_, dstX, dstY, width, height, vfb->bufferWidth, vfb->bufferHeight, false, 0.0f, 0.0f, 1.0f, 1.0f); + DrawActiveTexture(drawPixelsTex_, dstX, dstY, width, height, vfb->bufferWidth, vfb->bufferHeight, 0.0f, 0.0f, 1.0f, 1.0f, ROTATION_LOCKED_HORIZONTAL); textureCache_->ForgetLastTexture(); } - void FramebufferManagerDX9::DrawFramebuffer(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) { + void FramebufferManagerDX9::DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) { MakePixelTexture(srcPixels, srcPixelFormat, srcStride, 512, 272); DisableState(); @@ -208,14 +208,10 @@ namespace DX9 { float x, y, w, h; int uvRotation = (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) ? g_Config.iInternalScreenRotation : ROTATION_LOCKED_HORIZONTAL; CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, uvRotation, false); - DrawActiveTexture(drawPixelsTex_, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, false, 0.0f, 0.0f, 480.0f / 512.0f, uvRotation); + DrawActiveTexture(drawPixelsTex_, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, 0.0f, 0.0f, 480.0f / 512.0f, 1.0f, uvRotation); } - void FramebufferManagerDX9::DrawActiveTexture(LPDIRECT3DTEXTURE9 tex, float x, float y, float w, float h, float destW, float destH, bool flip, float u0, float v0, float u1, float v1, int uvRotation) { - if (flip) { - std::swap(v0, v1); - } - + void FramebufferManagerDX9::DrawActiveTexture(LPDIRECT3DTEXTURE9 tex, float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation) { // TODO: StretchRect instead? float coord[20] = { x,y,0, u0,v0, @@ -658,7 +654,7 @@ namespace DX9 { } } - BlitFramebuffer(©Info, x, y, framebuffer, x, y, w, h, 0, false); + BlitFramebuffer(©Info, x, y, framebuffer, x, y, w, h, 0); RebindFramebuffer(); pD3Ddevice->SetTexture(stage, fbo_get_color_texture(renderCopy)); @@ -732,7 +728,7 @@ namespace DX9 { if (!vfb) { // Just a pointer to plain memory to draw. Draw it. - DrawFramebuffer(Memory::GetPointer(displayFramebufPtr_), displayFormat_, displayStride_, true); + DrawFramebufferToOutput(Memory::GetPointer(displayFramebufPtr_), displayFormat_, displayStride_, true); return; } } else { @@ -794,7 +790,7 @@ namespace DX9 { } dxstate.texMipFilter.set(D3DTEXF_NONE); dxstate.texMipLodBias.set(0); - DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, false, u0, v0, u1, v1, uvRotation); + DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, u0, v0, u1, v1, uvRotation); } } /* @@ -837,7 +833,7 @@ namespace DX9 { #endif if (vfb) { - // We'll pseudo-blit framebuffers here to get a resized and flipped version of vfb. + // We'll pseudo-blit framebuffers here to get a resized version of vfb. // For now we'll keep these on the same struct as the ones that can get displayed // (and blatantly copy work already done above while at it). VirtualFramebuffer *nvfb = 0; @@ -935,22 +931,22 @@ namespace DX9 { gameUsesSequentialCopies_ = true; } } - BlitFramebuffer(nvfb, x, y, vfb, x, y, w, h, 0, false); + BlitFramebuffer(nvfb, x, y, vfb, x, y, w, h, 0); PackFramebufferDirectx9_(nvfb, x, y, w, h); RebindFramebuffer(); } } - void FramebufferManagerDX9::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, bool flip) { + void FramebufferManagerDX9::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) { if (!dst->fbo || !src->fbo || !useBufferedRendering_) { // This can happen if they recently switched from non-buffered. fbo_unbind(); return; } - float srcXFactor = flip ? 1.0f : (float)src->renderWidth / (float)src->bufferWidth; - float srcYFactor = flip ? 1.0f : (float)src->renderHeight / (float)src->bufferHeight; + float srcXFactor = (float)src->renderWidth / (float)src->bufferWidth; + float srcYFactor = (float)src->renderHeight / (float)src->bufferHeight; const int srcBpp = src->format == GE_FORMAT_8888 ? 4 : 2; if (srcBpp != bpp && bpp != 0) { srcXFactor = (srcXFactor * bpp) / srcBpp; @@ -960,8 +956,8 @@ namespace DX9 { int srcY1 = srcY * srcYFactor; int srcY2 = (srcY + h) * srcYFactor; - float dstXFactor = flip ? 1.0f : (float)dst->renderWidth / (float)dst->bufferWidth; - float dstYFactor = flip ? 1.0f : (float)dst->renderHeight / (float)dst->bufferHeight; + float dstXFactor = (float)dst->renderWidth / (float)dst->bufferWidth; + float dstYFactor = (float)dst->renderHeight / (float)dst->bufferHeight; const int dstBpp = dst->format == GE_FORMAT_8888 ? 4 : 2; if (dstBpp != bpp && bpp != 0) { dstXFactor = (dstXFactor * bpp) / dstBpp; @@ -971,50 +967,33 @@ namespace DX9 { int dstY1 = dstY * dstYFactor; int dstY2 = (dstY + h) * dstYFactor; - if (flip) { - fbo_bind_as_render_target(dst->fbo); - dxstate.viewport.set(0, 0, dst->renderWidth, dst->renderHeight); - DisableState(); - - fbo_bind_color_as_texture(src->fbo, 0); - - float srcW = src->bufferWidth; - float srcH = src->bufferHeight; - DrawActiveTexture(0, dstX1, dstY, w * dstXFactor, h, dst->bufferWidth, dst->bufferHeight, flip, srcX1 / srcW, srcY / srcH, srcX2 / srcW, (srcY + h) / srcH); - pD3Ddevice->SetTexture(0, NULL); - textureCache_->ForgetLastTexture(); - dxstate.viewport.restore(); - - RebindFramebuffer(); - } else { - LPDIRECT3DSURFACE9 srcSurf = fbo_get_color_for_read(src->fbo); - LPDIRECT3DSURFACE9 dstSurf = fbo_get_color_for_write(dst->fbo); - RECT srcRect = {srcX1, srcY1, srcX2, srcY2}; - RECT dstRect = {dstX1, dstY1, dstX2, dstY2}; - - D3DSURFACE_DESC desc; - srcSurf->GetDesc(&desc); - srcRect.right = std::min(srcRect.right, (LONG)desc.Width); - srcRect.bottom = std::min(srcRect.bottom, (LONG)desc.Height); + LPDIRECT3DSURFACE9 srcSurf = fbo_get_color_for_read(src->fbo); + LPDIRECT3DSURFACE9 dstSurf = fbo_get_color_for_write(dst->fbo); + RECT srcRect = {srcX1, srcY1, srcX2, srcY2}; + RECT dstRect = {dstX1, dstY1, dstX2, dstY2}; - dstSurf->GetDesc(&desc); - dstRect.right = std::min(dstRect.right, (LONG)desc.Width); - dstRect.bottom = std::min(dstRect.bottom, (LONG)desc.Height); - - // Direct3D 9 doesn't support rect -> self. - FBO *srcFBO = src->fbo; - if (src == dst) { - FBO *tempFBO = GetTempFBO(src->renderWidth, src->renderHeight, (FBOColorDepth)src->colorDepth); - HRESULT hr = fbo_blit_color(src->fbo, &srcRect, tempFBO, &srcRect, D3DTEXF_POINT); - if (SUCCEEDED(hr)) { - srcFBO = tempFBO; - } + D3DSURFACE_DESC desc; + srcSurf->GetDesc(&desc); + srcRect.right = std::min(srcRect.right, (LONG)desc.Width); + srcRect.bottom = std::min(srcRect.bottom, (LONG)desc.Height); + + dstSurf->GetDesc(&desc); + dstRect.right = std::min(dstRect.right, (LONG)desc.Width); + dstRect.bottom = std::min(dstRect.bottom, (LONG)desc.Height); + + // Direct3D 9 doesn't support rect -> self. + FBO *srcFBO = src->fbo; + if (src == dst) { + FBO *tempFBO = GetTempFBO(src->renderWidth, src->renderHeight, (FBOColorDepth)src->colorDepth); + HRESULT hr = fbo_blit_color(src->fbo, &srcRect, tempFBO, &srcRect, D3DTEXF_POINT); + if (SUCCEEDED(hr)) { + srcFBO = tempFBO; } + } - HRESULT hr = fbo_blit_color(srcFBO, &srcRect, dst->fbo, &dstRect, D3DTEXF_POINT); - if (FAILED(hr)) { - ERROR_LOG_REPORT(G3D, "fbo_blit_color failed in blit: %08x (%08x -> %08x)", hr, src->fb_address, dst->fb_address); - } + HRESULT hr = fbo_blit_color(srcFBO, &srcRect, dst->fbo, &dstRect, D3DTEXF_POINT); + if (FAILED(hr)) { + ERROR_LOG_REPORT(G3D, "fbo_blit_color failed in blit: %08x (%08x -> %08x)", hr, src->fb_address, dst->fb_address); } } @@ -1377,7 +1356,7 @@ namespace DX9 { GPUDebugBufferFormat fmt = GPU_DBG_FORMAT_24BIT_8X; int pixelSize = 4; - buffer.Allocate(locked.Pitch / pixelSize, desc.Height, fmt, gstate_c.flipTexture); + buffer.Allocate(locked.Pitch / pixelSize, desc.Height, fmt, false); memcpy(buffer.GetData(), locked.pBits, locked.Pitch * desc.Height); success = true; tex->UnlockRect(0); @@ -1418,7 +1397,7 @@ namespace DX9 { GPUDebugBufferFormat fmt = GPU_DBG_FORMAT_24X_8BIT; int pixelSize = 4; - buffer.Allocate(locked.Pitch / pixelSize, desc.Height, fmt, gstate_c.flipTexture); + buffer.Allocate(locked.Pitch / pixelSize, desc.Height, fmt, false); memcpy(buffer.GetData(), locked.pBits, locked.Pitch * desc.Height); success = true; tex->UnlockRect(0); diff --git a/GPU/Directx9/FramebufferDX9.h b/GPU/Directx9/FramebufferDX9.h index 0c18190e17ce..2fef208fa60a 100644 --- a/GPU/Directx9/FramebufferDX9.h +++ b/GPU/Directx9/FramebufferDX9.h @@ -57,9 +57,9 @@ class FramebufferManagerDX9 : public FramebufferManagerCommon { virtual void MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) override; virtual void DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) override; - virtual void DrawFramebuffer(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) override; + virtual void DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) override; - void DrawActiveTexture(LPDIRECT3DTEXTURE9 texture, float x, float y, float w, float h, float destW, float destH, bool flip = false, float u0 = 0.0f, float v0 = 0.0f, float u1 = 1.0f, float v1 = 1.0f, int uvRotation = ROTATION_LOCKED_HORIZONTAL); + void DrawActiveTexture(LPDIRECT3DTEXTURE9 texture, float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation); void DestroyAllFBOs(); @@ -100,7 +100,7 @@ class FramebufferManagerDX9 : public FramebufferManagerCommon { virtual void DecimateFBOs() override; // Used by ReadFramebufferToMemory and later framebuffer block copies - virtual void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, bool flip = false) override; + virtual void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) override; virtual void NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb) override; virtual void NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) override; diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index dbbaca4bce0c..14782aa235c1 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -2157,7 +2157,7 @@ bool DIRECTX9_GPU::GetCurrentTexture(GPUDebugBuffer &buffer, int level) { } if (fmt != GPU_DBG_FORMAT_INVALID) { - buffer.Allocate(locked.Pitch / pixelSize, desc.Height, fmt, gstate_c.flipTexture); + buffer.Allocate(locked.Pitch / pixelSize, desc.Height, fmt, false); memcpy(buffer.GetData(), locked.pBits, locked.Pitch * desc.Height); success = true; } else { diff --git a/GPU/Directx9/PixelShaderGeneratorDX9.cpp b/GPU/Directx9/PixelShaderGeneratorDX9.cpp index 9ef95682e85a..750d2b795f9b 100644 --- a/GPU/Directx9/PixelShaderGeneratorDX9.cpp +++ b/GPU/Directx9/PixelShaderGeneratorDX9.cpp @@ -151,11 +151,8 @@ bool GenerateFragmentShaderDX9(const ShaderID &id, char *buffer) { std::string ucoord = "In.v_texcoord.x"; std::string vcoord = "In.v_texcoord.y"; if (doTextureProjection) { - ucoord += " / In.v_texcoord.z"; + ucoord = "(In.v_texcoord.x / In.v_texcoord.z)"; vcoord = "(In.v_texcoord.y / In.v_texcoord.z)"; - // Vertex texcoords are NOT flipped when projecting despite gstate_c.flipTexture. - } else if (gstate_c.flipTexture) { - vcoord = "1.0 - " + vcoord; } if (id.Bit(FS_BIT_CLAMP_S)) { @@ -173,19 +170,10 @@ bool GenerateFragmentShaderDX9(const ShaderID &id, char *buffer) { vcoord = "(" + vcoord + " + u_texclampoff.y)"; } - if (gstate_c.flipTexture) { - vcoord = "1.0 - " + vcoord; - } - WRITE(p, " float2 fixedcoord = float2(%s, %s);\n", ucoord.c_str(), vcoord.c_str()); texcoord = "fixedcoord"; // We already projected it. doTextureProjection = false; - } else if (doTextureProjection && gstate_c.flipTexture) { - // Since we need to flip v, we project manually. - WRITE(p, " float2 fixedcoord = float2(v_texcoord.x / v_texcoord.z, 1.0 - (v_texcoord.y / v_texcoord.z));\n"); - texcoord = "fixedcoord"; - doTextureProjection = false; } if (doTextureProjection) { diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index 5562961adc26..9ed8b42af602 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -766,13 +766,13 @@ void TransformDrawEngineDX9::ApplyDrawState(int prim) { float overageTop = std::max(-top, 0.0f); float overageBottom = std::max(bottom - renderHeight, 0.0f); // Our center drifted by the difference in overages. - float drift = overageBottom - overageTop; + float drift = overageTop - overageBottom; top += overageTop; bottom -= overageBottom; hScale = vpHeight / (bottom - top); - yOffset = -drift / (bottom - top); + yOffset = drift / (bottom - top); } depthRangeMin = std::max(0.0f, depthRangeMin); diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index d3ddcd9866a8..408072a54298 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -893,7 +893,6 @@ void TextureCacheDX9::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebu // We need to force it, since we may have set it on a texture before attaching. gstate_c.curTextureWidth = framebuffer->bufferWidth; gstate_c.curTextureHeight = framebuffer->bufferHeight; - gstate_c.flipTexture = false; gstate_c.bgraTexture = false; gstate_c.curTextureXOffset = fbTexInfo_[entry->addr].xOffset; gstate_c.curTextureYOffset = fbTexInfo_[entry->addr].yOffset; @@ -1012,8 +1011,8 @@ void TextureCacheDX9::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFrame // And also the UVs, same order. const float uvleft = u1 * invWidth; const float uvright = u2 * invWidth; - const float uvtop = 1.0f - v1 * invHeight; - const float uvbottom = 1.0f - v2 * invHeight; + const float uvtop = v1 * invHeight; // TODO: Seems we should ditch the "1.0f - " + const float uvbottom = v2 * invHeight; verts[0].uv = UV(uvleft, uvbottom); verts[1].uv = UV(uvright, uvbottom); verts[2].uv = UV(uvright, uvtop); @@ -1161,7 +1160,6 @@ void TextureCacheDX9::SetTexture(bool force) { TexCache::iterator iter = cache.find(cachekey); TexCacheEntry *entry = NULL; - gstate_c.flipTexture = false; gstate_c.needShaderTexClamp = false; gstate_c.bgraTexture = true; gstate_c.skipDrawReason &= ~SKIPDRAW_BAD_FB_TEXTURE; diff --git a/GPU/Directx9/VertexShaderGeneratorDX9.cpp b/GPU/Directx9/VertexShaderGeneratorDX9.cpp index 32421e51f505..83d3202ded60 100644 --- a/GPU/Directx9/VertexShaderGeneratorDX9.cpp +++ b/GPU/Directx9/VertexShaderGeneratorDX9.cpp @@ -76,7 +76,6 @@ void GenerateVertexShaderDX9(const ShaderID &id, char *buffer) { bool hasTexcoord = id.Bit(VS_BIT_HAS_TEXCOORD) || !useHWTransform; bool enableFog = id.Bit(VS_BIT_ENABLE_FOG); bool throughmode = id.Bit(VS_BIT_IS_THROUGH); - bool flipV = id.Bit(VS_BIT_FLIP_TEXTURE); // This also means that we are texturing from a render target bool flipNormal = id.Bit(VS_BIT_NORM_REVERSE); int ls0 = id.Bits(VS_BIT_LS0, 2); int ls1 = id.Bits(VS_BIT_LS1, 2); @@ -135,7 +134,7 @@ void GenerateVertexShaderDX9(const ShaderID &id, char *buffer) { } #endif } - if (doTexture && (flipV || !prescale || uvGenMode == GE_TEXMAP_ENVIRONMENT_MAP || uvGenMode == GE_TEXMAP_TEXTURE_MATRIX)) { + if (doTexture && (!prescale || uvGenMode == GE_TEXMAP_ENVIRONMENT_MAP || uvGenMode == GE_TEXMAP_TEXTURE_MATRIX)) { WRITE(p, "float4 u_uvscaleoffset : register(c%i);\n", CONST_VS_UVSCALEOFFSET); } for (int i = 0; i < 4; i++) { @@ -505,7 +504,7 @@ void GenerateVertexShaderDX9(const ShaderID &id, char *buffer) { switch (uvGenMode) { case GE_TEXMAP_TEXTURE_COORDS: // Scale-offset. Easy. case GE_TEXMAP_UNKNOWN: // Not sure what this is, but Riviera uses it. Treating as coords works. - if (prescale && !flipV) { + if (prescale) { if (hasTexcoord) { WRITE(p, " Out.v_texcoord = In.texcoord;\n"); } else { @@ -562,10 +561,6 @@ void GenerateVertexShaderDX9(const ShaderID &id, char *buffer) { // ILLEGAL break; } - - // Will flip in the fragment for GE_TEXMAP_TEXTURE_MATRIX. - if (flipV && uvGenMode != GE_TEXMAP_TEXTURE_MATRIX) - WRITE(p, " Out.v_texcoord.y = 1.0 - Out.v_texcoord.y;\n"); } // Compute fogdepth diff --git a/GPU/GLES/FragmentShaderGenerator.cpp b/GPU/GLES/FragmentShaderGenerator.cpp index f592f8434873..440b98908e7d 100644 --- a/GPU/GLES/FragmentShaderGenerator.cpp +++ b/GPU/GLES/FragmentShaderGenerator.cpp @@ -147,7 +147,6 @@ bool GenerateFragmentShader(const ShaderID &id, char *buffer) { bool doTextureProjection = id.Bit(FS_BIT_DO_TEXTURE_PROJ); bool doTextureAlpha = id.Bit(FS_BIT_TEXALPHA); bool doFlatShading = id.Bit(FS_BIT_FLATSHADE); - bool flipTexture = id.Bit(FS_BIT_FLIP_TEXTURE); GEComparison alphaTestFunc = (GEComparison)id.Bits(FS_BIT_ALPHA_TEST_FUNC, 3); GEComparison colorTestFunc = (GEComparison)id.Bits(FS_BIT_COLOR_TEST_FUNC, 2); @@ -285,11 +284,8 @@ bool GenerateFragmentShader(const ShaderID &id, char *buffer) { std::string ucoord = "v_texcoord.x"; std::string vcoord = "v_texcoord.y"; if (doTextureProjection) { - ucoord += " / v_texcoord.z"; + ucoord = "(v_texcoord.x / v_texcoord.z)"; vcoord = "(v_texcoord.y / v_texcoord.z)"; - // Vertex texcoords are NOT flipped when projecting despite flipTexture. - } else if (flipTexture) { - vcoord = "1.0 - " + vcoord; } std::string modulo = (gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_BAD) ? "mymod" : "mod"; @@ -309,19 +305,10 @@ bool GenerateFragmentShader(const ShaderID &id, char *buffer) { vcoord = "(" + vcoord + " + u_texclampoff.y)"; } - if (flipTexture) { - vcoord = "1.0 - " + vcoord; - } - WRITE(p, " vec2 fixedcoord = vec2(%s, %s);\n", ucoord.c_str(), vcoord.c_str()); texcoord = "fixedcoord"; // We already projected it. doTextureProjection = false; - } else if (doTextureProjection && flipTexture) { - // Since we need to flip v, we project manually. - WRITE(p, " vec2 fixedcoord = vec2(v_texcoord.x / v_texcoord.z, 1.0 - (v_texcoord.y / v_texcoord.z));\n"); - texcoord = "fixedcoord"; - doTextureProjection = false; } if (doTextureProjection) { diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index e4b21dfa4c50..3124ed125402 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -390,21 +390,27 @@ void FramebufferManager::MakePixelTexture(const u8 *srcPixels, GEBufferFormat sr } void FramebufferManager::DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) { - if (useBufferedRendering_ && vfb->fbo) { + float v0 = 0.0f, v1 = 1.0f; + if (useBufferedRendering_ && vfb && vfb->fbo) { fbo_bind_as_render_target(vfb->fbo); glViewport(0, 0, vfb->renderWidth, vfb->renderHeight); } else { + // We are drawing to the back buffer so need to flip. + v0 = 1.0f; + v1 = 0.0f; float x, y, w, h; - CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, false, false); + CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, ROTATION_LOCKED_HORIZONTAL, false); glViewport(x, y, w, h); } + MakePixelTexture(srcPixels, srcPixelFormat, srcStride, width, height); DisableState(); - DrawActiveTexture(0, dstX, dstY, width, height, vfb->bufferWidth, vfb->bufferHeight, false, 0.0f, 0.0f, 1.0f, 1.0f); + + DrawActiveTexture(0, dstX, dstY, width, height, vfb->bufferWidth, vfb->bufferHeight, 0.0f, v0, 1.0f, v1, nullptr, ROTATION_LOCKED_HORIZONTAL); textureCache_->ForgetLastTexture(); } -void FramebufferManager::DrawFramebuffer(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) { +void FramebufferManager::DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) { MakePixelTexture(srcPixels, srcPixelFormat, srcStride, 512, 272); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, g_Config.iTexFiltering == TEX_FILTER_NEAREST ? GL_NEAREST : GL_LINEAR); @@ -423,29 +429,35 @@ void FramebufferManager::DrawFramebuffer(const u8 *srcPixels, GEBufferFormat src glsl_bind(postShaderProgram_); UpdatePostShaderUniforms(renderWidth_, renderHeight_); } + float u0 = 0.0f, u1 = 480.0f / 512.0f; + float v0 = 0.0f, v1 = 1.0f; + + // We are drawing directly to the back buffer. + std::swap(v0, v1); + if (cardboardSettings.enabled) { // Left Eye Image glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); if (applyPostShader && usePostShader_ && useBufferedRendering_) { - DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, false, 0.0f, 0.0f, 480.0f / 512.0f, 1.0f, postShaderProgram_); + DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, postShaderProgram_, ROTATION_LOCKED_HORIZONTAL); } else { - DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, false, 0.0f, 0.0f, 480.0f / 512.0f, 1.0f); + DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL); } // Right Eye Image glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); if (applyPostShader && usePostShader_ && useBufferedRendering_) { - DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, false, 0.0f, 0.0f, 480.0f / 512.0f, 1.0f, postShaderProgram_); + DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, postShaderProgram_, ROTATION_LOCKED_HORIZONTAL); } else { - DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, false, 0.0f, 0.0f, 480.0f / 512.0f); + DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL); } } else { // Fullscreen Image glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_); if (applyPostShader && usePostShader_ && useBufferedRendering_) { - DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, false, 0.0f, 0.0f, 480.0f / 512.0f, 1.0f, postShaderProgram_, uvRotation); + DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, postShaderProgram_, uvRotation); } else { - DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, false, 0.0f, 0.0f, 480.0f / 512.0f, 1.0f, NULL, uvRotation); + DrawActiveTexture(0, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, uvRotation); } } } @@ -489,18 +501,12 @@ void FramebufferManager::DrawPlainColor(u32 color) { } // x, y, w, h are relative coordinates against destW/destH, which is not very intuitive. -void FramebufferManager::DrawActiveTexture(GLuint texture, float x, float y, float w, float h, float destW, float destH, bool flip, float u0, float v0, float u1, float v1, GLSLProgram *program, int uvRotation) { - if (flip) { - // We're flipping, so 0 is downward. Reverse everything from 1.0f. - v0 = 1.0f - v0; - v1 = 1.0f - v1; - } - +void FramebufferManager::DrawActiveTexture(GLuint texture, float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, GLSLProgram *program, int uvRotation) { float texCoords[8] = { u0,v0, u1,v0, u1,v1, - u0,v1 + u0,v1, }; static const GLushort indices[4] = {0,1,3,2}; @@ -535,7 +541,7 @@ void FramebufferManager::DrawActiveTexture(GLuint texture, float x, float y, flo float invDestH = 1.0f / (destH * 0.5f); for (int i = 0; i < 4; i++) { pos[i * 3] = pos[i * 3] * invDestW - 1.0f; - pos[i * 3 + 1] = -(pos[i * 3 + 1] * invDestH - 1.0f); + pos[i * 3 + 1] = pos[i * 3 + 1] * invDestH - 1.0f; } if (!program) { @@ -910,7 +916,7 @@ void FramebufferManager::BindFramebufferColor(int stage, u32 fbRawAddress, Virtu } } - BlitFramebuffer(©Info, x, y, framebuffer, x, y, w, h, 0, false); + BlitFramebuffer(©Info, x, y, framebuffer, x, y, w, h, 0); fbo_bind_color_as_texture(renderCopy, 0); } else { @@ -1015,7 +1021,7 @@ void FramebufferManager::CopyDisplayToOutput() { if (!vfb) { // Just a pointer to plain memory to draw. We should create a framebuffer, then draw to it. - DrawFramebuffer(Memory::GetPointer(displayFramebufPtr_), displayFormat_, displayStride_, true); + DrawFramebufferToOutput(Memory::GetPointer(displayFramebufPtr_), displayFormat_, displayStride_, true); return; } } else { @@ -1053,24 +1059,27 @@ void FramebufferManager::CopyDisplayToOutput() { // TODO ES3: Use glInvalidateFramebuffer to discard depth/stencil data at the end of frame. - const float u0 = offsetX / (float)vfb->bufferWidth; - const float v0 = offsetY / (float)vfb->bufferHeight; - const float u1 = (480.0f + offsetX) / (float)vfb->bufferWidth; - const float v1 = (272.0f + offsetY) / (float)vfb->bufferHeight; + float u0 = offsetX / (float)vfb->bufferWidth; + float v0 = offsetY / (float)vfb->bufferHeight; + float u1 = (480.0f + offsetX) / (float)vfb->bufferWidth; + float v1 = (272.0f + offsetY) / (float)vfb->bufferHeight; if (!usePostShader_) { + // We are doing the DrawActiveTexture call directly to the backbuffer here. Hence, we must + // flip V. + std::swap(v0, v1); if (cardboardSettings.enabled) { // Left Eye Image glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); - DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, true, u0, v0, u1, v1); + DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL); // Right Eye Image glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); - DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, true, u0, v0, u1, v1); + DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL); } else { // Fullscreen Image glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_); - DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, true, u0, v0, u1, v1, NULL, uvRotation); + DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, uvRotation); } } else if (usePostShader_ && extraFBOs_.size() == 1 && !postShaderAtOutputResolution_) { // An additional pass, post-processing shader to the extra FBO. @@ -1081,7 +1090,7 @@ void FramebufferManager::CopyDisplayToOutput() { shaderManager_->DirtyLastShader(); // dirty lastShader_ glsl_bind(postShaderProgram_); UpdatePostShaderUniforms(renderWidth_, renderHeight_); - DrawActiveTexture(colorTexture, 0, 0, fbo_w, fbo_h, fbo_w, fbo_h, true, 0.0f, 0.0f, 1.0f, 1.0f, postShaderProgram_); + DrawActiveTexture(colorTexture, 0, 0, fbo_w, fbo_h, fbo_w, fbo_h, 0.0f, 0.0f, 1.0f, 1.0f, postShaderProgram_, ROTATION_LOCKED_HORIZONTAL); fbo_unbind(); @@ -1093,18 +1102,22 @@ void FramebufferManager::CopyDisplayToOutput() { } colorTexture = fbo_get_color_texture(extraFBOs_[0]); + // We are doing the DrawActiveTexture call directly to the backbuffer after here. Hence, we must + // flip V. + std::swap(v0, v1); + if (g_Config.bEnableCardboard) { // Left Eye Image glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); - DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, true, u0, v0, u1, v1); + DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL); // Right Eye Image glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); - DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, true, u0, v0, u1, v1); + DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL); } else { // Fullscreen Image glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_); - DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, true, u0, v0, u1, v1, NULL, uvRotation); + DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, uvRotation); } if (gl_extensions.GLES3 && glInvalidateFramebuffer != nullptr) { @@ -1113,21 +1126,25 @@ void FramebufferManager::CopyDisplayToOutput() { glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, attachments); } } else { + // We are doing the DrawActiveTexture call directly to the backbuffer here. Hence, we must + // flip V. + std::swap(v0, v1); + shaderManager_->DirtyLastShader(); // dirty lastShader_ glsl_bind(postShaderProgram_); UpdatePostShaderUniforms(vfb->renderWidth, vfb->renderHeight); if (g_Config.bEnableCardboard) { // Left Eye Image glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); - DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, true, u0, v0, u1, v1); + DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL); // Right Eye Image glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); - DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, true, u0, v0, u1, v1); + DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, nullptr, ROTATION_LOCKED_HORIZONTAL); } else { // Fullscreen Image glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_); - DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, true, u0, v0, u1, v1, postShaderProgram_, uvRotation); + DrawActiveTexture(colorTexture, x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, postShaderProgram_, uvRotation); } } @@ -1139,13 +1156,15 @@ void FramebufferManager::ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool s PROFILE_THIS_SCOPE("gpu-readback"); #ifndef USING_GLES2 if (sync) { - PackFramebufferAsync_(NULL); // flush async just in case when we go for synchronous update + // flush async just in case when we go for synchronous update + // Doesn't actually pack when sent a null argument. + PackFramebufferAsync_(nullptr); } #endif if (vfb) { + // We'll pseudo-blit framebuffers here to get a resized version of vfb. - // We'll pseudo-blit framebuffers here to get a resized and flipped version of vfb. // For now we'll keep these on the same struct as the ones that can get displayed // (and blatantly copy work already done above while at it). VirtualFramebuffer *nvfb = 0; @@ -1262,7 +1281,7 @@ void FramebufferManager::ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool s gameUsesSequentialCopies_ = true; } } - BlitFramebuffer(nvfb, x, y, vfb, x, y, w, h, 0, true); + BlitFramebuffer(nvfb, x, y, vfb, x, y, w, h, 0); // PackFramebufferSync_() - Synchronous pixel data transfer using glReadPixels // PackFramebufferAsync_() - Asynchronous pixel data transfer using glReadPixels with PBOs @@ -1284,7 +1303,7 @@ void FramebufferManager::ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool s } // TODO: If dimensions are the same, we can use glCopyImageSubData. -void FramebufferManager::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, bool flip) { +void FramebufferManager::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) { if (!dst->fbo || !src->fbo || !useBufferedRendering_) { // This can happen if they recently switched from non-buffered. fbo_unbind(); @@ -1305,8 +1324,8 @@ void FramebufferManager::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int } int srcX1 = srcX * srcXFactor; int srcX2 = (srcX + w) * srcXFactor; - int srcY2 = src->renderHeight - (h + srcY) * srcYFactor; - int srcY1 = srcY2 + h * srcYFactor; + int srcY1 = srcY * srcYFactor; + int srcY2 = (srcY + h) * srcYFactor; float dstXFactor = useBlit ? (float)dst->renderWidth / (float)dst->bufferWidth : 1.0f; float dstYFactor = useBlit ? (float)dst->renderHeight / (float)dst->bufferHeight : 1.0f; @@ -1316,15 +1335,10 @@ void FramebufferManager::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int } int dstX1 = dstX * dstXFactor; int dstX2 = (dstX + w) * dstXFactor; - int dstY2 = dst->renderHeight - (h + dstY) * dstYFactor; - int dstY1 = dstY2 + h * dstYFactor; + int dstY1 = dstY * dstYFactor; + int dstY2 = (dstY + h) * dstYFactor; if (useBlit) { - if (flip) { - dstY1 = dst->renderHeight - dstY1; - dstY2 = dst->renderHeight - dstY2; - } - fbo_bind_for_read(src->fbo); if (!useNV) { glBlitFramebuffer(srcX1, srcY1, srcX2, srcY2, dstX1, dstY1, dstX2, dstY2, GL_COLOR_BUFFER_BIT, GL_NEAREST); @@ -1348,7 +1362,7 @@ void FramebufferManager::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int // Should maybe revamp that interface. float srcW = src->bufferWidth; float srcH = src->bufferHeight; - DrawActiveTexture(0, dstX1, dstY, w * dstXFactor, h, dst->bufferWidth, dst->bufferHeight, !flip, srcX1 / srcW, srcY / srcH, srcX2 / srcW, (srcY + h) / srcH, draw2dprogram_); + DrawActiveTexture(0, dstX1, dstY1, w * dstXFactor, h, dst->bufferWidth, dst->bufferHeight, srcX1 / srcW, srcY1 / srcH, srcX2 / srcW, srcY2 / srcH, draw2dprogram_, ROTATION_LOCKED_HORIZONTAL); glBindTexture(GL_TEXTURE_2D, 0); textureCache_->ForgetLastTexture(); glstate.viewport.restore(); @@ -1884,7 +1898,7 @@ bool FramebufferManager::GetFramebuffer(u32 fb_address, int fb_stride, GEBufferF return true; } - buffer.Allocate(vfb->renderWidth, vfb->renderHeight, GE_FORMAT_8888, true, true); + buffer.Allocate(vfb->renderWidth, vfb->renderHeight, GE_FORMAT_8888, false, true); if (vfb->fbo) fbo_bind_for_read(vfb->fbo); if (gl_extensions.GLES3 || !gl_extensions.IsGLES) @@ -1901,7 +1915,7 @@ bool FramebufferManager::GetDisplayFramebuffer(GPUDebugBuffer &buffer) { int pw = PSP_CoreParameter().pixelWidth; int ph = PSP_CoreParameter().pixelHeight; - buffer.Allocate(pw, ph, GPU_DBG_FORMAT_888_RGB, true); + buffer.Allocate(pw, ph, GPU_DBG_FORMAT_888_RGB, false); glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(0, 0, pw, ph, GL_RGB, GL_UNSIGNED_BYTE, buffer.GetData()); return true; @@ -1919,7 +1933,7 @@ bool FramebufferManager::GetDepthbuffer(u32 fb_address, int fb_stride, u32 z_add return true; } - buffer.Allocate(vfb->renderWidth, vfb->renderHeight, GPU_DBG_FORMAT_FLOAT, true); + buffer.Allocate(vfb->renderWidth, vfb->renderHeight, GPU_DBG_FORMAT_FLOAT, false); if (vfb->fbo) fbo_bind_for_read(vfb->fbo); if (gl_extensions.GLES3 || !gl_extensions.IsGLES) @@ -1944,7 +1958,7 @@ bool FramebufferManager::GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebu } #ifndef USING_GLES2 - buffer.Allocate(vfb->renderWidth, vfb->renderHeight, GPU_DBG_FORMAT_8BIT, true); + buffer.Allocate(vfb->renderWidth, vfb->renderHeight, GPU_DBG_FORMAT_8BIT, false); if (vfb->fbo) fbo_bind_for_read(vfb->fbo); glReadBuffer(GL_STENCIL_ATTACHMENT); diff --git a/GPU/GLES/Framebuffer.h b/GPU/GLES/Framebuffer.h index 3a8b3b3220b1..b1b53efb782f 100644 --- a/GPU/GLES/Framebuffer.h +++ b/GPU/GLES/Framebuffer.h @@ -77,11 +77,11 @@ class FramebufferManager : public FramebufferManagerCommon { void MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) override; void DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) override; - void DrawFramebuffer(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) override; + void DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) override; // If texture != 0, will bind it. // x,y,w,h are relative to destW, destH which fill out the target completely. - void DrawActiveTexture(GLuint texture, float x, float y, float w, float h, float destW, float destH, bool flip = false, float u0 = 0.0f, float v0 = 0.0f, float u1 = 1.0f, float v1 = 1.0f, GLSLProgram *program = 0, int uvRotation = ROTATION_LOCKED_HORIZONTAL); + void DrawActiveTexture(GLuint texture, float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, GLSLProgram *program, int uvRotation); void DrawPlainColor(u32 color); @@ -130,7 +130,7 @@ class FramebufferManager : public FramebufferManagerCommon { virtual void DecimateFBOs() override; // Used by ReadFramebufferToMemory and later framebuffer block copies - virtual void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, bool flip = false) override; + virtual void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) override; virtual void NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb) override; virtual void NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) override; diff --git a/GPU/GLES/GLES_GPU.cpp b/GPU/GLES/GLES_GPU.cpp index 9b3f7ce7e857..646bad60610d 100644 --- a/GPU/GLES/GLES_GPU.cpp +++ b/GPU/GLES/GLES_GPU.cpp @@ -2114,8 +2114,8 @@ void GLES_GPU::DoBlockTransfer(u32 skipDrawReason) { // Check that the last address of both source and dest are valid addresses - u32 srcLastAddr = srcBasePtr + ((height - 1 + srcY) * srcStride + (srcX + width - 1)) * bpp; - u32 dstLastAddr = dstBasePtr + ((height - 1 + dstY) * dstStride + (dstX + width - 1)) * bpp; + u32 srcLastAddr = srcBasePtr + ((srcY + height - 1) * srcStride + (srcX + width - 1)) * bpp; + u32 dstLastAddr = dstBasePtr + ((dstY + height - 1) * dstStride + (dstX + width - 1)) * bpp; if (!Memory::IsValidAddress(srcLastAddr)) { ERROR_LOG_REPORT(G3D, "Bottom-right corner of source of block transfer is at an invalid address: %08x", srcLastAddr); @@ -2377,7 +2377,7 @@ bool GLES_GPU::GetCurrentTexture(GPUDebugBuffer &buffer, int level) { gstate = saved; } - buffer.Allocate(w, h, GE_FORMAT_8888, gstate_c.flipTexture); + buffer.Allocate(w, h, GE_FORMAT_8888, false); glPixelStorei(GL_PACK_ALIGNMENT, 4); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.GetData()); diff --git a/GPU/GLES/ShaderManager.cpp b/GPU/GLES/ShaderManager.cpp index 440ee7750ea4..5580f816c4d5 100644 --- a/GPU/GLES/ShaderManager.cpp +++ b/GPU/GLES/ShaderManager.cpp @@ -408,14 +408,20 @@ void LinkedShader::UpdateUniforms(u32 vertType) { Matrix4x4 flippedMatrix; memcpy(&flippedMatrix, gstate.projMatrix, 16 * sizeof(float)); - const bool invertedY = gstate_c.vpHeight < 0; + bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; + + const bool invertedY = useBufferedRendering ? (gstate_c.vpHeight > 0) : (gstate_c.vpHeight < 0); if (invertedY) { + flippedMatrix[1] = -flippedMatrix[1]; flippedMatrix[5] = -flippedMatrix[5]; + flippedMatrix[9] = -flippedMatrix[9]; flippedMatrix[13] = -flippedMatrix[13]; } const bool invertedX = gstate_c.vpWidth < 0; if (invertedX) { flippedMatrix[0] = -flippedMatrix[0]; + flippedMatrix[4] = -flippedMatrix[4]; + flippedMatrix[8] = -flippedMatrix[8]; flippedMatrix[12] = -flippedMatrix[12]; } @@ -458,7 +464,12 @@ void LinkedShader::UpdateUniforms(u32 vertType) { if (dirty & DIRTY_PROJTHROUGHMATRIX) { Matrix4x4 proj_through; - proj_through.setOrtho(0.0f, gstate_c.curRTWidth, gstate_c.curRTHeight, 0, 0.0f, 1.0f); + bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; + if (useBufferedRendering) { + proj_through.setOrtho(0.0f, gstate_c.curRTWidth, 0.0f, gstate_c.curRTHeight, 0.0f, 1.0f); + } else { + proj_through.setOrtho(0.0f, gstate_c.curRTWidth, gstate_c.curRTHeight, 0.0f, 0.0f, 1.0f); + } glUniformMatrix4fv(u_proj_through, 1, GL_FALSE, proj_through.getReadPtr()); } if (dirty & DIRTY_TEXENV) { diff --git a/GPU/GLES/StateMapping.cpp b/GPU/GLES/StateMapping.cpp index 399663346c2d..a86f2b4ec44a 100644 --- a/GPU/GLES/StateMapping.cpp +++ b/GPU/GLES/StateMapping.cpp @@ -89,8 +89,8 @@ static const GLushort eqLookup[] = { }; static const GLushort cullingMode[] = { - GL_BACK, GL_FRONT, + GL_BACK, }; static const GLushort ztests[] = { @@ -592,6 +592,7 @@ void TransformDrawEngine::ApplyDrawState(int prim) { bool alwaysDepthWrite = g_Config.bAlwaysDepthWrite; bool enableStencilTest = !g_Config.bDisableStencilTest; + bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; // Dither if (gstate.isDitherEnabled()) { @@ -653,7 +654,7 @@ void TransformDrawEngine::ApplyDrawState(int prim) { bool cullEnabled = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled(); if (cullEnabled) { glstate.cullFace.enable(); - glstate.cullFaceMode.set(cullingMode[gstate.getCullMode()]); + glstate.cullFaceMode.set(cullingMode[gstate.getCullMode() ^ !useBufferedRendering]); } else { glstate.cullFace.disable(); } @@ -729,7 +730,6 @@ void TransformDrawEngine::ApplyDrawState(int prim) { float renderWidth, renderHeight; float renderX = 0.0f, renderY = 0.0f; float displayOffsetX, displayOffsetY; - bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; if (useBufferedRendering) { displayOffsetX = 0.0f; displayOffsetY = 0.0f; @@ -761,11 +761,21 @@ void TransformDrawEngine::ApplyDrawState(int prim) { glstate.scissorTest.disable(); } else { glstate.scissorTest.enable(); - glstate.scissorRect.set( - renderX + displayOffsetX + scissorX1 * renderWidthFactor, - renderY + displayOffsetY + renderHeight - (scissorY2 * renderHeightFactor), - (scissorX2 - scissorX1) * renderWidthFactor, - (scissorY2 - scissorY1) * renderHeightFactor); + + // Buffers are now in the GL coordinate system, so no flipping needed. + if (useBufferedRendering) { + glstate.scissorRect.set( + renderX + displayOffsetX + scissorX1 * renderWidthFactor, + renderY + displayOffsetY + scissorY1 * renderHeightFactor, + (scissorX2 - scissorX1) * renderWidthFactor, + (scissorY2 - scissorY1) * renderHeightFactor); + } else { + glstate.scissorRect.set( + renderX + displayOffsetX + scissorX1 * renderWidthFactor, + renderY + displayOffsetY + renderHeight - (scissorY2 * renderHeightFactor), + (scissorX2 - scissorX1) * renderWidthFactor, + (scissorY2 - scissorY1) * renderHeightFactor); + } } /* @@ -783,15 +793,22 @@ void TransformDrawEngine::ApplyDrawState(int prim) { float offsetY = gstate.getOffsetY(); if (throughmode) { - // If the buffer is too large, offset the viewport to the top. - renderY += renderHeight - framebufferManager_->GetTargetHeight() * renderHeightFactor; - // No viewport transform here. Let's experiment with using region. - glstate.viewport.set( - renderX + displayOffsetX + (0 + regionX1) * renderWidthFactor, - renderY + displayOffsetY + (0 - regionY1) * renderHeightFactor, - (regionX2 - regionX1) * renderWidthFactor, - (regionY2 - regionY1) * renderHeightFactor); + if (useBufferedRendering) { + // No flip needed + glstate.viewport.set( + renderX + displayOffsetX + (0 + regionX1) * renderWidthFactor, + renderY + displayOffsetY + (0 + regionY1) * renderHeightFactor, + (regionX2 - regionX1) * renderWidthFactor, + (regionY2 - regionY1) * renderHeightFactor); + } else { + renderY += renderHeight - framebufferManager_->GetTargetHeight() * renderHeightFactor; + glstate.viewport.set( + renderX + displayOffsetX + (0 + regionX1) * renderWidthFactor, + renderY + displayOffsetY + (0 - regionY1) * renderHeightFactor, + (regionX2 - regionX1) * renderWidthFactor, + (regionY2 - regionY1) * renderHeightFactor); + } glstate.depthRange.set(0.0f, 1.0f); } else { // These we can turn into a glViewport call, offset by offsetX and offsetY. Math after. @@ -826,9 +843,9 @@ void TransformDrawEngine::ApplyDrawState(int prim) { // This may mean some games won't work, or at least won't work at higher render resolutions. // So we apply it in the shader instead. float left = renderX + vpX0; - float bottom = renderY + vpY0; + float top = renderY + vpY0; float right = left + vpWidth; - float top = bottom + vpHeight; + float bottom = top + vpHeight; float wScale = 1.0f; float xOffset = 0.0f; @@ -849,17 +866,17 @@ void TransformDrawEngine::ApplyDrawState(int prim) { xOffset = drift / (right - left); } - if (bottom < 0.0f || top > renderHeight) { - float overageBottom = std::max(-bottom, 0.0f); - float overageTop = std::max(top - renderHeight, 0.0f); + if (top < 0.0f || bottom > renderHeight) { + float overageTop = std::max(-top, 0.0f); + float overageBottom = std::max(bottom - renderHeight, 0.0f); // Our center drifted by the difference in overages. float drift = overageTop - overageBottom; - bottom += overageBottom; - top -= overageTop; + top += overageTop; + bottom -= overageBottom; - hScale = vpHeight / (top - bottom); - yOffset = drift / (top - bottom); + hScale = vpHeight / (bottom - top); + yOffset = drift / (bottom - top); } bool scaleChanged = gstate_c.vpWidthScale != wScale || gstate_c.vpHeightScale != hScale; @@ -872,7 +889,11 @@ void TransformDrawEngine::ApplyDrawState(int prim) { shaderManager_->DirtyUniform(DIRTY_PROJMATRIX); } - glstate.viewport.set(left + displayOffsetX, bottom + displayOffsetY, right - left, top - bottom); + if (useBufferedRendering) { + glstate.viewport.set(left + displayOffsetX, displayOffsetY + top, right - left, bottom - top); + } else { + glstate.viewport.set(left + displayOffsetX, displayOffsetY + (renderHeight - bottom), right - left, bottom - top); + } float zScale = gstate.getViewportZScale(); float zCenter = gstate.getViewportZCenter(); diff --git a/GPU/GLES/StencilBuffer.cpp b/GPU/GLES/StencilBuffer.cpp index fe6b7cb70e33..5454876315bb 100644 --- a/GPU/GLES/StencilBuffer.cpp +++ b/GPU/GLES/StencilBuffer.cpp @@ -216,7 +216,7 @@ bool FramebufferManager::NotifyStencilUpload(u32 addr, int size, bool skipZero) glstate.stencilMask.set(i); glUniform1f(u_stencilValue, i * (1.0f / 255.0f)); } - DrawActiveTexture(0, 0, 0, dstBuffer->width, dstBuffer->height, dstBuffer->bufferWidth, dstBuffer->bufferHeight, false, 0.0f, 0.0f, 1.0f, 1.0f, stencilUploadProgram_); + DrawActiveTexture(0, 0, 0, dstBuffer->width, dstBuffer->height, dstBuffer->bufferWidth, dstBuffer->bufferHeight, 0.0f, 0.0f, 1.0f, 1.0f, stencilUploadProgram_, ROTATION_LOCKED_HORIZONTAL); } glstate.stencilMask.set(0xFF); diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index b28ccad0fba0..72901e2db81a 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -964,7 +964,6 @@ void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffe // We need to force it, since we may have set it on a texture before attaching. gstate_c.curTextureWidth = framebuffer->bufferWidth; gstate_c.curTextureHeight = framebuffer->bufferHeight; - gstate_c.flipTexture = true; gstate_c.curTextureXOffset = fbTexInfo_[entry->addr].xOffset; gstate_c.curTextureYOffset = fbTexInfo_[entry->addr].yOffset; gstate_c.needShaderTexClamp = gstate_c.curTextureWidth != (u32)gstate.getTextureWidth(0) || gstate_c.curTextureHeight != (u32)gstate.getTextureHeight(0); @@ -1069,8 +1068,8 @@ void TextureCache::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuf const float left = u1 * invHalfWidth - 1.0f; const float right = u2 * invHalfWidth - 1.0f; - const float top = -(v1 * invHalfHeight - 1.0f); - const float bottom = -(v2 * invHalfHeight - 1.0f); + const float top = v1 * invHalfHeight - 1.0f; + const float bottom = v2 * invHalfHeight - 1.0f; // Points are: BL, BR, TR, TL. pos[0] = Pos(left, bottom, -1.0f); pos[1] = Pos(right, bottom, -1.0f); @@ -1080,8 +1079,8 @@ void TextureCache::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuf // And also the UVs, same order. const float uvleft = u1 * invWidth; const float uvright = u2 * invWidth; - const float uvtop = 1.0f - v1 * invHeight; - const float uvbottom = 1.0f - v2 * invHeight; + const float uvtop = v1 * invHeight; + const float uvbottom = v2 * invHeight; uv[0] = UV(uvleft, uvbottom); uv[1] = UV(uvright, uvbottom); uv[2] = UV(uvright, uvtop); @@ -1225,7 +1224,6 @@ void TextureCache::SetTexture(bool force) { TexCache::iterator iter = cache.find(cachekey); TexCacheEntry *entry = NULL; - gstate_c.flipTexture = false; gstate_c.needShaderTexClamp = false; gstate_c.skipDrawReason &= ~SKIPDRAW_BAD_FB_TEXTURE; bool replaceImages = false; diff --git a/GPU/GLES/VertexShaderGenerator.cpp b/GPU/GLES/VertexShaderGenerator.cpp index c591404c7e28..f8976e3c1743 100644 --- a/GPU/GLES/VertexShaderGenerator.cpp +++ b/GPU/GLES/VertexShaderGenerator.cpp @@ -172,7 +172,6 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) { bool hasTexcoord = id.Bit(VS_BIT_HAS_TEXCOORD) || !useHWTransform; bool enableFog = id.Bit(VS_BIT_ENABLE_FOG); bool throughmode = id.Bit(VS_BIT_IS_THROUGH); - bool flipV = id.Bit(VS_BIT_FLIP_TEXTURE); // This also means that we are texturing from a render target bool flipNormal = id.Bit(VS_BIT_NORM_REVERSE); int ls0 = id.Bits(VS_BIT_LS0, 2); int ls1 = id.Bits(VS_BIT_LS1, 2); @@ -248,7 +247,7 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) { } #endif } - if (doTexture && (flipV || !prescale || uvGenMode == GE_TEXMAP_ENVIRONMENT_MAP || uvGenMode == GE_TEXMAP_TEXTURE_MATRIX)) { + if (doTexture && (!prescale || uvGenMode == GE_TEXMAP_ENVIRONMENT_MAP || uvGenMode == GE_TEXMAP_TEXTURE_MATRIX)) { WRITE(p, "uniform vec4 u_uvscaleoffset;\n"); } for (int i = 0; i < 4; i++) { @@ -594,7 +593,7 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) { switch (uvGenMode) { case GE_TEXMAP_TEXTURE_COORDS: // Scale-offset. Easy. case GE_TEXMAP_UNKNOWN: // Not sure what this is, but Riviera uses it. Treating as coords works. - if (prescale && !flipV) { + if (prescale) { if (hasTexcoord) { WRITE(p, " v_texcoord = texcoord;\n"); } else { @@ -654,10 +653,6 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) { // ILLEGAL break; } - - // Will flip in the fragment for GE_TEXMAP_TEXTURE_MATRIX. - if (flipV && uvGenMode != GE_TEXMAP_TEXTURE_MATRIX) - WRITE(p, " v_texcoord.y = 1.0 - v_texcoord.y;\n"); } // Compute fogdepth diff --git a/GPU/GPUState.cpp b/GPU/GPUState.cpp index 50320303b328..b1ff10a0c70a 100644 --- a/GPU/GPUState.cpp +++ b/GPU/GPUState.cpp @@ -205,7 +205,6 @@ void GPUStateCache::DoState(PointerWrap &p) { framebufChanged = old.framebufChanged; skipDrawReason = old.skipDrawReason; uv = old.uv; - flipTexture = old.flipTexture; } else { p.Do(vertexAddr); p.Do(indexAddr); @@ -219,7 +218,10 @@ void GPUStateCache::DoState(PointerWrap &p) { p.Do(skipDrawReason); p.Do(uv); - p.Do(flipTexture); + + // No longer relevant. Remove when creating the next version. + bool oldFlipTexture; + p.Do(oldFlipTexture); } // needShaderTexClamp and bgraTexture don't need to be saved. diff --git a/GPU/GPUState.h b/GPU/GPUState.h index e5d68333b333..56564145fc24 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -491,7 +491,6 @@ struct GPUStateCache { int skipDrawReason; UVScale uv; - bool flipTexture; bool bgraTexture; bool needShaderTexClamp;