mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
Make un-buffered rendering much smarter, removing flicker.
This turns it into a very viable option for many games. You do lose some FX but it can as a result even be used as a workaround for the massive glow in Wipeout...
This commit is contained in:
parent
fa11e4971b
commit
bc15617392
@ -1085,8 +1085,8 @@ void ARMXEmitter::VMOV(ARMReg Dest, ARMReg Src)
|
||||
|
||||
void ARMXEmitter::VCVT(ARMReg Sd, ARMReg Sm, int flags)
|
||||
{
|
||||
bool op = (flags & TO_INT) ? (flags & ROUND_TO_ZERO) : (flags & IS_SIGNED);
|
||||
bool op2 = (flags & TO_INT) ? (flags & IS_SIGNED) : 0;
|
||||
int op = ((flags & TO_INT) ? (flags & ROUND_TO_ZERO) : (flags & IS_SIGNED)) ? 1 : 0;
|
||||
int op2 = ((flags & TO_INT) ? (flags & IS_SIGNED) : 0) ? 1 : 0;
|
||||
Sd = SubBase(Sd);
|
||||
Sm = SubBase(Sm);
|
||||
|
||||
|
@ -210,7 +210,7 @@ void CalculateFPS()
|
||||
}
|
||||
|
||||
char stats[50];
|
||||
sprintf(stats, "%0.1f", fps);
|
||||
sprintf(stats, "VPS: %0.1f", fps);
|
||||
|
||||
#ifdef USING_GLES2
|
||||
float zoom = 0.7f; /// g_Config.iWindowZoom;
|
||||
@ -285,13 +285,12 @@ void DebugStats()
|
||||
}
|
||||
|
||||
// Let's collect all the throttling and frameskipping logic here.
|
||||
void DoFrameTiming(bool &throttle, bool &skipFrame, bool &skipFlip) {
|
||||
void DoFrameTiming(bool &throttle, bool &skipFrame) {
|
||||
#ifdef _WIN32
|
||||
throttle = !GetAsyncKeyState(VK_TAB);
|
||||
#else
|
||||
throttle = false;
|
||||
throttle = true;
|
||||
#endif
|
||||
skipFlip = false;
|
||||
skipFrame = false;
|
||||
if (PSP_CoreParameter().headLess)
|
||||
throttle = false;
|
||||
@ -311,7 +310,6 @@ void DoFrameTiming(bool &throttle, bool &skipFrame, bool &skipFlip) {
|
||||
if (curFrameTime > nextFrameTime && doFrameSkip) {
|
||||
// Argh, we are falling behind! Let's skip a frame and see if we catch up.
|
||||
skipFrame = true;
|
||||
skipFlip = true;
|
||||
INFO_LOG(HLE,"FRAMESKIP %i", numSkippedFrames);
|
||||
}
|
||||
|
||||
@ -339,10 +337,10 @@ void DoFrameTiming(bool &throttle, bool &skipFrame, bool &skipFlip) {
|
||||
nextFrameTime = nextFrameTime + 1.0 / 60.0;
|
||||
}
|
||||
|
||||
// Max 6 skipped frames in a row - 10 fps is really the bare minimum for playability.
|
||||
if (numSkippedFrames >= 4) {
|
||||
// Max 4 skipped frames in a row - 15 fps is really the bare minimum for playability.
|
||||
// We check for 3 here so it's 3 skipped frames, 1 non skipped, 3 skipped, etc.
|
||||
if (numSkippedFrames >= 3) {
|
||||
skipFrame = false;
|
||||
skipFlip = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -389,17 +387,23 @@ void hleEnterVblank(u64 userdata, int cyclesLate) {
|
||||
CalculateFPS();
|
||||
}
|
||||
|
||||
bool skipFlip = false;
|
||||
|
||||
// This frame was skipped, so no need to flip.
|
||||
if (gstate_c.skipDrawReason & SKIPDRAW_SKIPFRAME) {
|
||||
skipFlip = true;
|
||||
}
|
||||
|
||||
// Draw screen overlays before blitting. Saves and restores the Ge context.
|
||||
// Yeah, this has to be the right moment to end the frame. Give the graphics backend opportunity
|
||||
// to blit the framebuffer, in order to support half-framerate games that otherwise wouldn't have
|
||||
// anything to draw here.
|
||||
gstate_c.skipDrawReason &= ~SKIPDRAW_SKIPFRAME;
|
||||
|
||||
bool throttle, skipFrame, skipFlip;
|
||||
bool throttle, skipFrame;
|
||||
|
||||
DoFrameTiming(throttle, skipFrame, skipFlip);
|
||||
DoFrameTiming(throttle, skipFrame);
|
||||
|
||||
// Setting CORE_NEXTFRAME causes a swap.
|
||||
if (skipFrame) {
|
||||
gstate_c.skipDrawReason |= SKIPDRAW_SKIPFRAME;
|
||||
numSkippedFrames++;
|
||||
@ -408,11 +412,11 @@ void hleEnterVblank(u64 userdata, int cyclesLate) {
|
||||
}
|
||||
|
||||
if (!skipFlip) {
|
||||
// Might've just quit / been paused.
|
||||
if (coreState == CORE_RUNNING) {
|
||||
// Setting CORE_NEXTFRAME causes a swap.
|
||||
// Check first though, might've just quit / been paused.
|
||||
if (coreState == CORE_RUNNING && gpu->FramebufferDirty()) {
|
||||
coreState = CORE_NEXTFRAME;
|
||||
}
|
||||
CoreTiming::ScheduleEvent(0 - cyclesLate, afterFlipEvent, 0);
|
||||
|
||||
gpu->CopyDisplayToOutput();
|
||||
}
|
||||
@ -420,6 +424,7 @@ void hleEnterVblank(u64 userdata, int cyclesLate) {
|
||||
// Returning here with coreState == CORE_NEXTFRAME causes a buffer flip to happen (next frame).
|
||||
// Right after, we regain control for a little bit in hleAfterFlip. I think that's a great
|
||||
// place to do housekeeping.
|
||||
CoreTiming::ScheduleEvent(0 - cyclesLate, afterFlipEvent, 0);
|
||||
}
|
||||
|
||||
void hleAfterFlip(u64 userdata, int cyclesLate)
|
||||
|
@ -355,7 +355,7 @@ void ArmJitBlockCache::DestroyBlock(int block_num, bool invalidate)
|
||||
// checkedEntry is the only "linked" entrance so it's enough to overwrite that.
|
||||
ARMXEmitter emit((u8 *)b.checkedEntry);
|
||||
emit.MOVI2R(R0, b.originalAddress);
|
||||
emit.STR(R10, R0, offsetof(MIPSState, pc));
|
||||
emit.STR(CTXREG, R0, offsetof(MIPSState, pc));
|
||||
emit.B(MIPSComp::jit->dispatcher);
|
||||
emit.FlushIcache();
|
||||
}
|
||||
|
@ -251,15 +251,23 @@ void GLES_GPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, int format) {
|
||||
framebufferManager_.SetDisplayFramebuffer(framebuf, stride, format);
|
||||
}
|
||||
|
||||
bool GLES_GPU::FramebufferDirty() {
|
||||
if (!g_Config.bBufferedRendering) {
|
||||
VirtualFramebuffer *vfb = framebufferManager_.GetDisplayFBO();
|
||||
if (vfb)
|
||||
return vfb->dirtyAfterDisplay;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLES_GPU::CopyDisplayToOutput() {
|
||||
glstate.colorMask.set(true, true, true, true);
|
||||
transformDraw_.Flush();
|
||||
if (!g_Config.bBufferedRendering)
|
||||
return;
|
||||
|
||||
EndDebugDraw();
|
||||
|
||||
framebufferManager_.CopyDisplayToOutput();
|
||||
framebufferManager_.EndFrame();
|
||||
|
||||
shaderManager_->DirtyShader();
|
||||
shaderManager_->DirtyUniform(DIRTY_ALL);
|
||||
@ -313,10 +321,16 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) {
|
||||
|
||||
case GE_CMD_PRIM:
|
||||
{
|
||||
if (gstate_c.skipDrawReason)
|
||||
return;
|
||||
// This drives all drawing. All other state we just buffer up, then we apply it only
|
||||
// when it's time to draw. As most PSP games set state redundantly ALL THE TIME, this is a huge optimization.
|
||||
|
||||
// This also make skipping drawing very effective.
|
||||
|
||||
if (gstate_c.skipDrawReason & SKIPDRAW_SKIPFRAME)
|
||||
return;
|
||||
framebufferManager_.SetRenderFrameBuffer();
|
||||
if (gstate_c.skipDrawReason & SKIPDRAW_NON_DISPLAYED_FB)
|
||||
return;
|
||||
|
||||
u32 count = data & 0xFFFF;
|
||||
u32 type = data >> 16;
|
||||
@ -650,6 +664,7 @@ void GLES_GPU::ExecuteOp(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();
|
||||
break;
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ public:
|
||||
{
|
||||
return textureCache_.DecodeTexture(dest, state);
|
||||
}
|
||||
virtual bool FramebufferDirty();
|
||||
|
||||
std::vector<FramebufferInfo> GetFramebufferList();
|
||||
|
||||
|
@ -88,7 +88,7 @@ void GenerateFragmentShader(char *buffer)
|
||||
bool enableFog = gstate.isFogEnabled() && !gstate.isModeThrough() && !gstate.isModeClear();
|
||||
bool enableAlphaTest = (gstate.alphaTestEnable & 1) && !gstate.isModeClear();
|
||||
bool enableColorTest = (gstate.colorTestEnable & 1) && !gstate.isModeClear();
|
||||
bool enableColorDoubling = gstate.texfunc & 0x10000;
|
||||
bool enableColorDoubling = (gstate.texfunc & 0x10000) != 0;
|
||||
|
||||
|
||||
if (doTexture)
|
||||
|
@ -266,8 +266,6 @@ void GetViewportDimensions(int *w, int *h) {
|
||||
}
|
||||
|
||||
void FramebufferManager::SetRenderFrameBuffer() {
|
||||
if (!g_Config.bBufferedRendering)
|
||||
return;
|
||||
// Get parameters
|
||||
u32 fb_address = (gstate.fbptr & 0xFFE000) | ((gstate.fbwidth & 0xFF0000) << 8);
|
||||
int fb_stride = gstate.fbwidth & 0x3C0;
|
||||
@ -328,6 +326,7 @@ void FramebufferManager::SetRenderFrameBuffer() {
|
||||
vfb->renderHeight = (u16)(drawing_height * renderHeightFactor);
|
||||
vfb->format = fmt;
|
||||
vfb->usageFlags = FB_USAGE_RENDERTARGET;
|
||||
vfb->dirtyAfterDisplay = true;
|
||||
|
||||
switch (fmt) {
|
||||
case GE_FORMAT_4444: vfb->colorDepth = FBO_4444; break;
|
||||
@ -344,13 +343,26 @@ void FramebufferManager::SetRenderFrameBuffer() {
|
||||
// vfb->colorDepth = FBO_8888;
|
||||
//#endif
|
||||
|
||||
vfb->fbo = fbo_create(vfb->renderWidth, vfb->renderHeight, 1, true, vfb->colorDepth);
|
||||
if (g_Config.bBufferedRendering)
|
||||
{
|
||||
vfb->fbo = fbo_create(vfb->renderWidth, vfb->renderHeight, 1, true, vfb->colorDepth);
|
||||
}
|
||||
else
|
||||
vfb->fbo = 0;
|
||||
|
||||
textureCache_->NotifyFramebuffer(vfb->fb_address, vfb);
|
||||
|
||||
vfb->last_frame_used = gpuStats.numFrames;
|
||||
vfbs_.push_back(vfb);
|
||||
|
||||
fbo_bind_as_render_target(vfb->fbo);
|
||||
if (g_Config.bBufferedRendering) {
|
||||
fbo_bind_as_render_target(vfb->fbo);
|
||||
} else {
|
||||
fbo_unbind();
|
||||
// Let's ignore rendering to targets that have not (yet) been displayed.
|
||||
gstate_c.skipDrawReason |= SKIPDRAW_NON_DISPLAYED_FB;
|
||||
}
|
||||
|
||||
glEnable(GL_DITHER);
|
||||
glstate.viewport.set(0, 0, vfb->renderWidth, vfb->renderHeight);
|
||||
currentRenderVfb_ = vfb;
|
||||
@ -359,21 +371,39 @@ void FramebufferManager::SetRenderFrameBuffer() {
|
||||
glClearColor(0,0,0,1);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
INFO_LOG(HLE, "Creating FBO for %08x : %i x %i x %i", vfb->fb_address, vfb->width, vfb->height, vfb->format);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vfb != currentRenderVfb_) {
|
||||
// We already have it!
|
||||
} else if (vfb != currentRenderVfb_) {
|
||||
// Use it as a render target.
|
||||
DEBUG_LOG(HLE, "Switching render target to FBO for %08x", vfb->fb_address);
|
||||
vfb->usageFlags |= FB_USAGE_RENDERTARGET;
|
||||
gstate_c.textureChanged = true;
|
||||
if (vfb->last_frame_used != gpuStats.numFrames) {
|
||||
// Android optimization
|
||||
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
vfb->last_frame_used = gpuStats.numFrames;
|
||||
|
||||
fbo_bind_as_render_target(vfb->fbo);
|
||||
vfb->dirtyAfterDisplay = true;
|
||||
|
||||
if (g_Config.bBufferedRendering && vfb->fbo) {
|
||||
fbo_bind_as_render_target(vfb->fbo);
|
||||
} else {
|
||||
fbo_unbind();
|
||||
|
||||
// Let's ignore rendering to targets that have not (yet) been displayed.
|
||||
if (vfb->usageFlags & FB_USAGE_DISPLAYED_FRAMEBUFFER)
|
||||
gstate_c.skipDrawReason &= ~SKIPDRAW_NON_DISPLAYED_FB;
|
||||
else
|
||||
gstate_c.skipDrawReason |= SKIPDRAW_NON_DISPLAYED_FB;
|
||||
|
||||
/*
|
||||
if (drawing_width == 480 && drawing_height == 272) {
|
||||
gstate_c.skipDrawReason &= ~SKIPDRAW_SKIPNONFB;
|
||||
// OK!
|
||||
} else {
|
||||
gstate_c.skipDrawReason |= ~SKIPDRAW_SKIPNONFB;
|
||||
}*/
|
||||
}
|
||||
textureCache_->NotifyFramebuffer(vfb->fb_address, vfb);
|
||||
|
||||
#ifdef USING_GLES2
|
||||
@ -394,7 +424,6 @@ void FramebufferManager::SetRenderFrameBuffer() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FramebufferManager::CopyDisplayToOutput() {
|
||||
fbo_unbind();
|
||||
|
||||
@ -409,22 +438,31 @@ void FramebufferManager::CopyDisplayToOutput() {
|
||||
return;
|
||||
}
|
||||
|
||||
vfb->usageFlags |= FB_USAGE_DISPLAYED_FRAMEBUFFER;
|
||||
vfb->dirtyAfterDisplay = false;
|
||||
|
||||
prevPrevDisplayFramebuf_ = prevDisplayFramebuf_;
|
||||
prevDisplayFramebuf_ = displayFramebuf_;
|
||||
displayFramebuf_ = vfb;
|
||||
|
||||
glstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
|
||||
|
||||
currentRenderVfb_ = 0;
|
||||
|
||||
DEBUG_LOG(HLE, "Displaying FBO %08x", vfb->fb_address);
|
||||
glstate.blend.disable();
|
||||
glstate.cullFace.disable();
|
||||
glstate.depthTest.disable();
|
||||
glstate.scissorTest.disable();
|
||||
glstate.stencilTest.disable();
|
||||
if (vfb->fbo) {
|
||||
glstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
|
||||
DEBUG_LOG(HLE, "Displaying FBO %08x", vfb->fb_address);
|
||||
glstate.blend.disable();
|
||||
glstate.cullFace.disable();
|
||||
glstate.depthTest.disable();
|
||||
glstate.scissorTest.disable();
|
||||
glstate.stencilTest.disable();
|
||||
|
||||
fbo_bind_color_as_texture(vfb->fbo, 0);
|
||||
|
||||
fbo_bind_color_as_texture(vfb->fbo, 0);
|
||||
// These are in the output display coordinates
|
||||
float x, y, w, h;
|
||||
CenterRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight);
|
||||
DrawActiveTexture(x, y, w, h, true);
|
||||
}
|
||||
|
||||
if (resized_) {
|
||||
glstate.depthWrite.set(GL_TRUE);
|
||||
@ -432,11 +470,9 @@ void FramebufferManager::CopyDisplayToOutput() {
|
||||
glClearColor(0,0,0,1);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
// These are in the output display coordinates
|
||||
float x, y, w, h;
|
||||
CenterRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight);
|
||||
DrawActiveTexture(x, y, w, h, true);
|
||||
}
|
||||
|
||||
void FramebufferManager::EndFrame() {
|
||||
if (resized_) {
|
||||
DestroyAllFBOs();
|
||||
glstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
|
||||
@ -472,8 +508,7 @@ void FramebufferManager::SetDisplayFramebuffer(u32 framebuf, u32 stride, int for
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<FramebufferInfo> FramebufferManager::GetFramebufferList()
|
||||
{
|
||||
std::vector<FramebufferInfo> FramebufferManager::GetFramebufferList() {
|
||||
std::vector<FramebufferInfo> list;
|
||||
|
||||
for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter) {
|
||||
@ -501,8 +536,11 @@ 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_destroy(vfb->fbo);
|
||||
if (vfb->fbo) {
|
||||
textureCache_->NotifyFramebufferDestroyed(vfb->fb_address, vfb);
|
||||
fbo_destroy(vfb->fbo);
|
||||
vfb->fbo = 0;
|
||||
}
|
||||
delete vfb;
|
||||
vfbs_.erase(iter++);
|
||||
}
|
||||
@ -515,7 +553,8 @@ void FramebufferManager::DestroyAllFBOs() {
|
||||
for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter) {
|
||||
VirtualFramebuffer *vfb = *iter;
|
||||
textureCache_->NotifyFramebufferDestroyed(vfb->fb_address, vfb);
|
||||
fbo_destroy(vfb->fbo);
|
||||
if (vfb->fbo)
|
||||
fbo_destroy(vfb->fbo);
|
||||
delete vfb;
|
||||
}
|
||||
vfbs_.clear();
|
||||
|
@ -39,8 +39,9 @@ enum PspDisplayPixelFormat {
|
||||
};
|
||||
|
||||
enum {
|
||||
FB_USAGE_RENDERTARGET = 1,
|
||||
FB_USAGE_TEXTURE = 2,
|
||||
FB_USAGE_DISPLAYED_FRAMEBUFFER = 1,
|
||||
FB_USAGE_RENDERTARGET = 2,
|
||||
FB_USAGE_TEXTURE = 4,
|
||||
};
|
||||
|
||||
|
||||
@ -63,6 +64,8 @@ struct VirtualFramebuffer {
|
||||
int format; // virtual, right now they are all RGBA8888
|
||||
FBOColorDepth colorDepth;
|
||||
FBO *fbo;
|
||||
|
||||
bool dirtyAfterDisplay;
|
||||
};
|
||||
|
||||
|
||||
@ -82,6 +85,7 @@ public:
|
||||
void DecimateFBOs();
|
||||
|
||||
void BeginFrame();
|
||||
void EndFrame();
|
||||
void Resized();
|
||||
void CopyDisplayToOutput();
|
||||
void SetRenderFrameBuffer(); // Uses parameters computed from gstate
|
||||
|
@ -376,8 +376,7 @@ void ShaderManager::DirtyShader()
|
||||
}
|
||||
|
||||
|
||||
LinkedShader *ShaderManager::ApplyShader(int prim)
|
||||
{
|
||||
LinkedShader *ShaderManager::ApplyShader(int prim) {
|
||||
if (globalDirty) {
|
||||
if (lastShader)
|
||||
lastShader->dirtyUniforms |= globalDirty;
|
||||
|
@ -138,7 +138,7 @@ void TextureCache::NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffe
|
||||
if (entry) {
|
||||
DEBUG_LOG(HLE, "Render to texture detected at %08x!", address);
|
||||
if (!entry->framebuffer)
|
||||
entry->framebuffer= framebuffer;
|
||||
entry->framebuffer = framebuffer;
|
||||
// TODO: Delete the original non-fbo texture too.
|
||||
}
|
||||
}
|
||||
@ -695,12 +695,22 @@ void TextureCache::SetTexture() {
|
||||
TexCache::iterator iter = cache.find(cachekey);
|
||||
TexCacheEntry *entry = NULL;
|
||||
gstate_c.flipTexture = false;
|
||||
gstate_c.skipDrawReason &= ~SKIPDRAW_BAD_FB_TEXTURE;
|
||||
|
||||
if (iter != cache.end()) {
|
||||
entry = &iter->second;
|
||||
// Check for FBO - slow!
|
||||
if (entry->framebuffer) {
|
||||
fbo_bind_color_as_texture(entry->framebuffer->fbo, 0);
|
||||
entry->framebuffer->usageFlags |= FB_USAGE_TEXTURE;
|
||||
if (entry->framebuffer->fbo)
|
||||
{
|
||||
fbo_bind_color_as_texture(entry->framebuffer->fbo, 0);
|
||||
}
|
||||
else {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE;
|
||||
}
|
||||
|
||||
UpdateSamplingParams(*entry, false);
|
||||
|
||||
// This isn't right.
|
||||
|
@ -23,6 +23,7 @@ public:
|
||||
virtual u32 EnqueueList(u32 listpc, u32 stall, int subIntrBase, bool head);
|
||||
virtual int listStatus(int listid);
|
||||
virtual void DoState(PointerWrap &p);
|
||||
virtual bool FramebufferDirty() { return true; }
|
||||
|
||||
protected:
|
||||
typedef std::deque<DisplayList> DisplayListQueue;
|
||||
|
@ -102,6 +102,7 @@ public:
|
||||
|
||||
// Called by the window system if the window size changed. This will be reflected in PSPCoreParam.pixel*.
|
||||
virtual void Resized() = 0;
|
||||
virtual bool FramebufferDirty() = 0;
|
||||
|
||||
// Debugging
|
||||
virtual void DumpNextFrame() = 0;
|
||||
|
@ -229,6 +229,8 @@ struct GPUgstate
|
||||
|
||||
enum SkipDrawReasonFlags {
|
||||
SKIPDRAW_SKIPFRAME = 1,
|
||||
SKIPDRAW_NON_DISPLAYED_FB = 2, // Skip drawing to FBO:s that have not been displayed.
|
||||
SKIPDRAW_BAD_FB_TEXTURE = 4,
|
||||
};
|
||||
|
||||
// The rest is cached simplified/converted data for fast access.
|
||||
|
@ -339,6 +339,7 @@
|
||||
<None Include="..\android\jni\Application.mk" />
|
||||
<None Include="..\CMakeLists.txt" />
|
||||
<None Include="..\README.md" />
|
||||
<None Include="git-version-gen.cmd" />
|
||||
<None Include="ppsspp.ico" />
|
||||
<None Include="icon1.ico" />
|
||||
<None Include="rt_manif.bin" />
|
||||
|
@ -215,6 +215,7 @@
|
||||
<None Include="..\CMakeLists.txt">
|
||||
<Filter>Windows</Filter>
|
||||
</None>
|
||||
<None Include="git-version-gen.cmd" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="ppsspp.rc">
|
||||
|
@ -401,6 +401,8 @@ namespace MainWindow
|
||||
case ID_OPTIONS_BUFFEREDRENDERING:
|
||||
g_Config.bBufferedRendering = !g_Config.bBufferedRendering;
|
||||
UpdateMenus();
|
||||
if (gpu)
|
||||
gpu->Resized(); // easy way to force a clear...
|
||||
break;
|
||||
|
||||
case ID_OPTIONS_SHOWDEBUGSTATISTICS:
|
||||
@ -416,7 +418,8 @@ namespace MainWindow
|
||||
case ID_OPTIONS_STRETCHDISPLAY:
|
||||
g_Config.bStretchToDisplay = !g_Config.bStretchToDisplay;
|
||||
UpdateMenus();
|
||||
gpu->Resized(); // easy way to force a clear...
|
||||
if (gpu)
|
||||
gpu->Resized(); // easy way to force a clear...
|
||||
break;
|
||||
|
||||
case ID_OPTIONS_FRAMESKIP:
|
||||
@ -443,12 +446,12 @@ namespace MainWindow
|
||||
break;
|
||||
|
||||
case ID_DEBUG_DUMPNEXTFRAME:
|
||||
gpu->DumpNextFrame();
|
||||
if (gpu)
|
||||
gpu->DumpNextFrame();
|
||||
break;
|
||||
|
||||
case ID_DEBUG_LOADMAPFILE:
|
||||
if (W32Util::BrowseForFileName(true, hWnd, "Load .MAP",0,"Maps\0*.map\0All files\0*.*\0\0","map",fn))
|
||||
{
|
||||
if (W32Util::BrowseForFileName(true, hWnd, "Load .MAP",0,"Maps\0*.map\0All files\0*.*\0\0","map",fn)) {
|
||||
symbolMap.LoadSymbolMap(fn.c_str());
|
||||
// HLE_PatchFunctions();
|
||||
for (int i=0; i<numCPUs; i++)
|
||||
|
@ -314,10 +314,14 @@ void SettingsScreen::render() {
|
||||
int y = 30;
|
||||
int stride = 40;
|
||||
UICheckBox(GEN_ID, x, y += stride, "Sound Emulation", ALIGN_TOPLEFT, &g_Config.bEnableSound);
|
||||
UICheckBox(GEN_ID, x, y += stride, "Buffered Rendering", ALIGN_TOPLEFT, &g_Config.bBufferedRendering);
|
||||
if (UICheckBox(GEN_ID, x, y += stride, "Buffered Rendering", ALIGN_TOPLEFT, &g_Config.bBufferedRendering)) {
|
||||
gpu->Resized();
|
||||
}
|
||||
if (g_Config.bBufferedRendering) {
|
||||
bool doubleRes = g_Config.iWindowZoom == 2;
|
||||
UICheckBox(GEN_ID, x + 50, y += stride, "2x Render Resolution", ALIGN_TOPLEFT, &doubleRes);
|
||||
if (UICheckBox(GEN_ID, x + 50, y += stride, "2x Render Resolution", ALIGN_TOPLEFT, &doubleRes)) {
|
||||
gpu->Resized();
|
||||
}
|
||||
g_Config.iWindowZoom = doubleRes ? 2 : 1;
|
||||
}
|
||||
UICheckBox(GEN_ID, x, y += stride, "Hardware Transform", ALIGN_TOPLEFT, &g_Config.bHardwareTransform);
|
||||
@ -444,8 +448,7 @@ void CreditsScreen::update(InputState &input_state) {
|
||||
frames_++;
|
||||
}
|
||||
|
||||
const static char *credits[] =
|
||||
{
|
||||
static const char * credits[] = {
|
||||
"PPSSPP",
|
||||
"",
|
||||
"",
|
||||
|
Loading…
Reference in New Issue
Block a user