mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Some work toward better FBO handling. Fixes some things, breaks some things..
This commit is contained in:
parent
7995d1418c
commit
28979e9250
8 changed files with 63 additions and 53 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -18,11 +18,12 @@
|
|||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
#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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -255,6 +255,7 @@ struct GPUStateCache
|
|||
|
||||
u32 curTextureWidth;
|
||||
u32 curTextureHeight;
|
||||
u32 actualTextureHeight;
|
||||
|
||||
float vpWidth;
|
||||
float vpHeight;
|
||||
|
|
Loading…
Add table
Reference in a new issue