diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index 54783dcde3..ed3d624ed0 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -235,7 +235,7 @@ void FramebufferManager::DrawActiveTexture(float x, float y, float w, float h, b glsl_unbind(); } -FramebufferManager::VirtualFramebuffer *FramebufferManager::GetDisplayFBO() { +VirtualFramebuffer *FramebufferManager::GetDisplayFBO() { for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter) { VirtualFramebuffer *v = *iter; if (MaskedEqual(v->fb_address, displayFramebufPtr_) && v->format == displayFormat_) { @@ -325,6 +325,7 @@ void FramebufferManager::SetRenderFrameBuffer() { vfb->renderWidth = (u16)(drawing_width * renderWidthFactor); vfb->renderHeight = (u16)(drawing_height * renderHeightFactor); vfb->format = fmt; + vfb->usageFlags = FB_USAGE_RENDERTARGET; switch (fmt) { case GE_FORMAT_4444: vfb->colorDepth = FBO_4444; break; @@ -342,7 +343,7 @@ void FramebufferManager::SetRenderFrameBuffer() { //#endif vfb->fbo = fbo_create(vfb->renderWidth, vfb->renderHeight, 1, true, vfb->colorDepth); - textureCache_->NotifyFramebuffer(vfb->fb_address, vfb->fbo); + textureCache_->NotifyFramebuffer(vfb->fb_address, vfb); vfb->last_frame_used = gpuStats.numFrames; vfbs_.push_back(vfb); @@ -368,7 +369,7 @@ void FramebufferManager::SetRenderFrameBuffer() { fbo_bind_as_render_target(vfb->fbo); - textureCache_->NotifyFramebuffer(vfb->fb_address, vfb->fbo); + textureCache_->NotifyFramebuffer(vfb->fb_address, vfb); #ifdef USING_GLES2 // Some tiled mobile GPUs benefit IMMENSELY from clearing an FBO before rendering // to it. This broke stuff before, so now it only clears on the first use of an @@ -482,7 +483,7 @@ void FramebufferManager::DecimateFBOs() { } if ((*iter)->last_frame_used + FBO_OLD_AGE < gpuStats.numFrames) { INFO_LOG(HLE, "Destroying FBO for %08x (%i x %i x %i)", vfb->fb_address, vfb->width, vfb->height, vfb->format) - textureCache_->NotifyFramebufferDestroyed(vfb->fb_address, vfb->fbo); + textureCache_->NotifyFramebufferDestroyed(vfb->fb_address, vfb); fbo_destroy(vfb->fbo); delete vfb; vfbs_.erase(iter++); @@ -495,7 +496,7 @@ void FramebufferManager::DecimateFBOs() { void FramebufferManager::DestroyAllFBOs() { for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter) { VirtualFramebuffer *vfb = *iter; - textureCache_->NotifyFramebufferDestroyed(vfb->fb_address, vfb->fbo); + textureCache_->NotifyFramebufferDestroyed(vfb->fb_address, vfb); fbo_destroy(vfb->fbo); delete vfb; } diff --git a/GPU/GLES/Framebuffer.h b/GPU/GLES/Framebuffer.h index c5a86426c9..c40fcc7c24 100644 --- a/GPU/GLES/Framebuffer.h +++ b/GPU/GLES/Framebuffer.h @@ -38,6 +38,34 @@ enum PspDisplayPixelFormat { PSP_DISPLAY_PIXEL_FORMAT_8888 = 3, }; +enum { + FB_USAGE_RENDERTARGET = 1, + FB_USAGE_TEXTURE = 2, +}; + + +struct VirtualFramebuffer { + int last_frame_used; + + u32 fb_address; + u32 z_address; + int fb_stride; + int z_stride; + + // There's also a top left of the drawing region, but meh... + u16 width; + u16 height; + u16 renderWidth; + u16 renderHeight; + + u16 usageFlags; + + int format; // virtual, right now they are all RGBA8888 + FBOColorDepth colorDepth; + FBO *fbo; +}; + + class FramebufferManager { public: FramebufferManager(); @@ -47,25 +75,6 @@ public: textureCache_ = tc; } - struct VirtualFramebuffer { - int last_frame_used; - - u32 fb_address; - u32 z_address; - int fb_stride; - int z_stride; - - // There's also a top left of the drawing region, but meh... - u16 width; - u16 height; - u16 renderWidth; - u16 renderHeight; - - int format; // virtual, right now they are all RGBA8888 - FBOColorDepth colorDepth; - FBO *fbo; - }; - void DrawPixels(const u8 *framebuf, int pixelFormat, int linesize); void DrawActiveTexture(float x, float y, float w, float h, bool flip = false); diff --git a/GPU/GLES/ShaderManager.cpp b/GPU/GLES/ShaderManager.cpp index 30c294b780..4471a48e86 100644 --- a/GPU/GLES/ShaderManager.cpp +++ b/GPU/GLES/ShaderManager.cpp @@ -243,7 +243,7 @@ void LinkedShader::updateUniforms() { if (u_proj_through != -1 && (dirtyUniforms & DIRTY_PROJTHROUGHMATRIX)) { Matrix4x4 proj_through; - proj_through.setOrtho(0.0f, 480, 272, 0, 1, 0); + proj_through.setOrtho(0.0f, 480, 272, 0, 0, 1); glUniformMatrix4fv(u_proj_through, 1, GL_FALSE, proj_through.getReadPtr()); } if (u_texenv != -1 && (dirtyUniforms & DIRTY_TEXENV)) { diff --git a/GPU/GLES/StateMapping.cpp b/GPU/GLES/StateMapping.cpp index 9d9deca257..d6bf5b57ab 100644 --- a/GPU/GLES/StateMapping.cpp +++ b/GPU/GLES/StateMapping.cpp @@ -236,7 +236,7 @@ void TransformDrawEngine::UpdateViewportAndProjection() { if (throughmode) { // No viewport transform here. Let's experiment with using region. glstate.viewport.set((0 + regionX1) * renderWidthFactor, (0 - regionY1) * renderHeightFactor, (regionX2 - regionX1) * renderWidthFactor, (regionY2 - regionY1) * renderHeightFactor); - glstate.depthRange.set(1.0, 0.0); + glstate.depthRange.set(0.0, 1.0); } else { // These we can turn into a glViewport call, offset by offsetX and offsetY. Math after. float vpXa = getFloat24(gstate.viewportx1); diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index 96ccc7768b..7ea3c85bcc 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -18,11 +18,12 @@ #include #include -#include "../../Core/MemMap.h" -#include "../ge_constants.h" -#include "../GPUState.h" -#include "TextureCache.h" -#include "../Core/Config.h" +#include "Core/MemMap.h" +#include "GPU/ge_constants.h" +#include "GPU/GPUState.h" +#include "GPU/GLES/TextureCache.h" +#include "GPU/GLES/Framebuffer.h" +#include "Core/Config.h" // If a texture hasn't been seen for this many frames, get rid of it. #define TEXTURE_KILL_AGE 200 @@ -131,21 +132,21 @@ TextureCache::TexCacheEntry *TextureCache::GetEntryAt(u32 texaddr) { return 0; } -void TextureCache::NotifyFramebuffer(u32 address, FBO *fbo) { +void TextureCache::NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffer) { // Must be in VRAM so | 0x04000000 it is. TexCacheEntry *entry = GetEntryAt(address | 0x04000000); if (entry) { DEBUG_LOG(HLE, "Render to texture detected at %08x!", address); - if (!entry->fbo) - entry->fbo = fbo; + if (!entry->framebuffer) + entry->framebuffer= framebuffer; // TODO: Delete the original non-fbo texture too. } } -void TextureCache::NotifyFramebufferDestroyed(u32 address, FBO *fbo) { +void TextureCache::NotifyFramebufferDestroyed(u32 address, VirtualFramebuffer *fbo) { TexCacheEntry *entry = GetEntryAt(address | 0x04000000); - if (entry && entry->fbo) { - entry->fbo = 0; + if (entry && entry->framebuffer) { + entry->framebuffer = 0; } } @@ -699,19 +700,15 @@ void TextureCache::SetTexture() { if (iter != cache.end()) { entry = &iter->second; // Check for FBO - slow! - if (entry->fbo) { - int w = 1 << (gstate.texsize[0] & 0xf); - int h = 1 << ((gstate.texsize[0] >> 8) & 0xf); - - fbo_bind_color_as_texture(entry->fbo, 0); + if (entry->framebuffer) { + fbo_bind_color_as_texture(entry->framebuffer->fbo, 0); UpdateSamplingParams(*entry, false); - int fbow, fboh; - fbo_get_dimensions(entry->fbo, &fbow, &fboh); - // This isn't right. - gstate_c.curTextureWidth = w; //w; //RoundUpToPowerOf2(fbow); - gstate_c.curTextureHeight = h; // RoundUpToPowerOf2(fboh); + gstate_c.curTextureWidth = entry->framebuffer->width; + gstate_c.curTextureHeight = entry->framebuffer->height; + int h = 1 << ((gstate.texsize[0] >> 8) & 0xf); + gstate_c.actualTextureHeight = h; gstate_c.flipTexture = true; entry->lastFrame = gpuStats.numFrames; return; @@ -807,7 +804,7 @@ void TextureCache::SetTexture() { entry->hash = texhash; entry->format = format; entry->lastFrame = gpuStats.numFrames; - entry->fbo = 0; + entry->framebuffer = 0; entry->maxLevel = maxLevel; entry->lodBias = 0.0f; diff --git a/GPU/GLES/TextureCache.h b/GPU/GLES/TextureCache.h index 65c64b4eb3..62008ec0dd 100644 --- a/GPU/GLES/TextureCache.h +++ b/GPU/GLES/TextureCache.h @@ -21,6 +21,8 @@ #include "gfx_es2/fbo.h" #include "GPU/GPUState.h" +struct VirtualFramebuffer; + class TextureCache { public: @@ -36,16 +38,16 @@ public: // FramebufferManager keeps TextureCache updated about what regions of memory // are being rendered to. This is barebones so far. - void NotifyFramebuffer(u32 address, FBO *fbo); - void NotifyFramebufferDestroyed(u32 address, FBO *fbo); + void NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffer); + void NotifyFramebufferDestroyed(u32 address, VirtualFramebuffer *framebuffer); size_t NumLoadedTextures() const { return cache.size(); } bool DecodeTexture(u8 *output, GPUgstate state); + private: - struct TexCacheEntry { // After marking STATUS_UNRELIABLE, if it stays the same this many frames we'll trust it again. const static int FRAMES_REGAIN_TRUST = 1000; @@ -60,7 +62,7 @@ private: int status; u32 addr; u32 hash; - FBO *fbo; // if null, not sourced from an FBO. + VirtualFramebuffer *framebuffer; // if null, not sourced from an FBO. u32 sizeInRAM; int lastFrame; int numFrames; diff --git a/GPU/GLES/TransformPipeline.cpp b/GPU/GLES/TransformPipeline.cpp index 72b2066c57..87153a40f2 100644 --- a/GPU/GLES/TransformPipeline.cpp +++ b/GPU/GLES/TransformPipeline.cpp @@ -640,7 +640,7 @@ void TransformDrawEngine::SoftwareTransformAndDraw( transformed[index].fog = fogCoef; memcpy(&transformed[index].u, uv, 2 * sizeof(float)); if (gstate_c.flipTexture) - transformed[index].v = 1.0f - transformed[index].v * 2.0f; + transformed[index].v = 1.0f - transformed[index].v; //(float)gstate_c.actualTextureHeight / gstate_c.curTextureHeight - transformed[index].v; for (int i = 0; i < 4; i++) { transformed[index].color0[i] = c0[i] * 255.0f; } diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 8f12c7d045..6522ae567f 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -255,6 +255,7 @@ struct GPUStateCache u32 curTextureWidth; u32 curTextureHeight; + u32 actualTextureHeight; float vpWidth; float vpHeight;