rend: get rid of globals for fog/palette updates & tex cache flush
Add state vars to Renderer Use events to detect loading a state and terminating the game. Don't present last rendered frame after game terminated.
This commit is contained in:
parent
825778445a
commit
d789b57412
|
@ -880,7 +880,7 @@ void Emulator::loadstate(Deserializer& deser)
|
|||
|
||||
mmu_set_state();
|
||||
getSh4Executor()->ResetCache();
|
||||
KillTex = true;
|
||||
EventManager::event(Event::LoadState);
|
||||
}
|
||||
|
||||
void Emulator::setNetworkState(bool online)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include "types.h"
|
||||
#include "ta_ctx.h"
|
||||
#include "emulator.h"
|
||||
#include <vector>
|
||||
|
||||
extern u32 FrameCount;
|
||||
|
@ -22,6 +23,8 @@ void rend_enable_renderer(bool enabled);
|
|||
bool rend_is_enabled();
|
||||
void rend_serialize(Serializer& ser);
|
||||
void rend_deserialize(Deserializer& deser);
|
||||
static void rend_updatePalette();
|
||||
static void rend_updateFogTable();
|
||||
|
||||
///////
|
||||
extern TA_context* _pvrrc;
|
||||
|
@ -54,7 +57,14 @@ struct FramebufferInfo
|
|||
|
||||
struct Renderer
|
||||
{
|
||||
virtual ~Renderer() = default;
|
||||
Renderer() {
|
||||
EventManager::listen(Event::Terminate, onEvent, this);
|
||||
EventManager::listen(Event::LoadState, onEvent, this);
|
||||
}
|
||||
virtual ~Renderer() {
|
||||
EventManager::unlisten(Event::Terminate, onEvent, this);
|
||||
EventManager::unlisten(Event::LoadState, onEvent, this);
|
||||
}
|
||||
|
||||
virtual bool Init() = 0;
|
||||
virtual void Term() = 0;
|
||||
|
@ -72,6 +82,25 @@ struct Renderer
|
|||
virtual bool Present() { return true; }
|
||||
|
||||
virtual BaseTextureCacheData *GetTexture(TSP tsp, TCW tcw) { return nullptr; }
|
||||
|
||||
protected:
|
||||
bool resetTextureCache = false;
|
||||
bool clearLastFrame = false;
|
||||
bool updatePalette = true;
|
||||
bool updateFogTable = true;
|
||||
|
||||
private:
|
||||
static void onEvent(Event event, void *arg)
|
||||
{
|
||||
Renderer *renderer = static_cast<Renderer*>(arg);
|
||||
renderer->resetTextureCache = true;
|
||||
renderer->updatePalette = true;
|
||||
renderer->updateFogTable = true;
|
||||
if (event == Event::Terminate)
|
||||
renderer->clearLastFrame = true;
|
||||
}
|
||||
friend void rend_updatePalette();
|
||||
friend void rend_updateFogTable();
|
||||
};
|
||||
|
||||
extern Renderer* renderer;
|
||||
|
@ -81,3 +110,11 @@ extern u32 fb_watch_addr_end;
|
|||
extern bool fb_dirty;
|
||||
|
||||
void check_framebuffer_write();
|
||||
static inline void rend_updatePalette() {
|
||||
if (renderer != nullptr)
|
||||
renderer->updatePalette = true;
|
||||
}
|
||||
static inline void rend_updateFogTable() {
|
||||
if (renderer != nullptr)
|
||||
renderer->updateFogTable = true;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ extern u8 ta_fsm[2049]; //[2048] stores the current state
|
|||
extern u32 ta_fsm_cl;
|
||||
extern u32 taRenderPass;
|
||||
// pvr_regs.cpp
|
||||
extern bool fog_needs_update;
|
||||
extern bool pal_needs_update;
|
||||
|
||||
namespace pvr
|
||||
|
@ -39,7 +38,6 @@ namespace pvr
|
|||
|
||||
void reset(bool hard)
|
||||
{
|
||||
KillTex = true;
|
||||
Regs_Reset(hard);
|
||||
spg_Reset(hard);
|
||||
if (hard)
|
||||
|
@ -92,7 +90,7 @@ void deserialize(Deserializer& deser)
|
|||
YUV_deserialize(deser);
|
||||
|
||||
deser >> pvr_regs;
|
||||
fog_needs_update = true;
|
||||
rend_updateFogTable();
|
||||
|
||||
spg_Deserialize(deser);
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <map>
|
||||
|
||||
bool pal_needs_update=true;
|
||||
bool fog_needs_update=true;
|
||||
|
||||
u8 pvr_regs[pvr_RegSize];
|
||||
|
||||
|
@ -221,7 +220,7 @@ void pvr_WriteReg(u32 paddr,u32 data)
|
|||
if (addr >= PALETTE_RAM_START_addr && PvrReg(addr,u32) != data)
|
||||
pal_needs_update = true;
|
||||
else if (addr >= FOG_TABLE_START_addr && addr <= FOG_TABLE_END_addr && PvrReg(addr,u32) != data)
|
||||
fog_needs_update = true;
|
||||
rend_updateFogTable();
|
||||
break;
|
||||
}
|
||||
PvrReg(addr, u32) = data;
|
||||
|
|
|
@ -281,7 +281,6 @@ void dc_loadstate(int index)
|
|||
}
|
||||
|
||||
free(data);
|
||||
EventManager::event(Event::LoadState);
|
||||
}
|
||||
|
||||
time_t dc_getStateCreationDate(int index)
|
||||
|
|
|
@ -14,12 +14,10 @@
|
|||
|
||||
const u8 *vq_codebook;
|
||||
u32 palette_index;
|
||||
bool KillTex=false;
|
||||
u32 palette16_ram[1024];
|
||||
u32 palette32_ram[1024];
|
||||
u32 pal_hash_256[4];
|
||||
u32 pal_hash_16[64];
|
||||
bool palette_updated;
|
||||
extern bool pal_needs_update;
|
||||
|
||||
// Rough approximation of LoD bias from D adjust param, only used to increase LoD
|
||||
|
@ -87,7 +85,7 @@ void palette_update()
|
|||
if (!pal_needs_update)
|
||||
return;
|
||||
pal_needs_update = false;
|
||||
palette_updated = true;
|
||||
rend_updatePalette();
|
||||
|
||||
if (!isDirectX(config::RendererType))
|
||||
{
|
||||
|
|
|
@ -16,11 +16,8 @@ constexpr int VQ_CODEBOOK_SIZE = 256 * 8;
|
|||
extern u32 palette_index;
|
||||
extern u32 palette16_ram[1024];
|
||||
extern u32 palette32_ram[1024];
|
||||
extern bool fog_needs_update;
|
||||
extern u32 pal_hash_256[4];
|
||||
extern u32 pal_hash_16[64];
|
||||
extern bool KillTex;
|
||||
extern bool palette_updated;
|
||||
|
||||
extern u32 detwiddle[2][11][1024];
|
||||
|
||||
|
@ -818,7 +815,6 @@ public:
|
|||
texture.Delete();
|
||||
|
||||
cache.clear();
|
||||
KillTex = false;
|
||||
INFO_LOG(RENDERER, "Texture cache cleared");
|
||||
}
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ bool DX11Renderer::Init()
|
|||
quad->init(device, deviceContext, shaders);
|
||||
n2Helper.init(device, deviceContext);
|
||||
|
||||
fog_needs_update = true;
|
||||
updateFogTable = true;
|
||||
|
||||
if (!success)
|
||||
{
|
||||
|
@ -318,8 +318,10 @@ BaseTextureCacheData *DX11Renderer::GetTexture(TSP tsp, TCW tcw)
|
|||
|
||||
void DX11Renderer::Process(TA_context* ctx)
|
||||
{
|
||||
if (KillTex)
|
||||
if (resetTextureCache) {
|
||||
texCache.Clear();
|
||||
resetTextureCache = false;
|
||||
}
|
||||
texCache.Cleanup();
|
||||
|
||||
ta_parse(ctx, true);
|
||||
|
@ -936,7 +938,7 @@ void DX11Renderer::drawStrips()
|
|||
|
||||
bool DX11Renderer::RenderLastFrame()
|
||||
{
|
||||
if (!frameRenderedOnce)
|
||||
if (!frameRenderedOnce || clearLastFrame)
|
||||
return false;
|
||||
displayFramebuffer();
|
||||
return true;
|
||||
|
@ -1222,9 +1224,9 @@ void DX11Renderer::readRttRenderTarget(u32 texAddress)
|
|||
|
||||
void DX11Renderer::updatePaletteTexture()
|
||||
{
|
||||
if (palette_updated)
|
||||
if (updatePalette)
|
||||
{
|
||||
palette_updated = false;
|
||||
updatePalette = false;
|
||||
deviceContext->UpdateSubresource(paletteTexture, 0, nullptr, palette32_ram, 32 * sizeof(u32), 32 * sizeof(u32) * 32);
|
||||
}
|
||||
deviceContext->PSSetShaderResources(1, 1, &paletteTextureView.get());
|
||||
|
@ -1235,9 +1237,9 @@ void DX11Renderer::updateFogTexture()
|
|||
{
|
||||
if (!config::Fog)
|
||||
return;
|
||||
if (fog_needs_update)
|
||||
if (updateFogTable)
|
||||
{
|
||||
fog_needs_update = false;
|
||||
updateFogTable = false;
|
||||
u8 temp_tex_buffer[256];
|
||||
MakeFogTexture(temp_tex_buffer);
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ struct DX11Renderer : public Renderer
|
|||
if (!frameRendered)
|
||||
return false;
|
||||
frameRendered = false;
|
||||
clearLastFrame = false;
|
||||
#ifndef LIBRETRO
|
||||
imguiDriver->setFrameRendered();
|
||||
#else
|
||||
|
|
|
@ -139,7 +139,7 @@ bool D3DRenderer::Init()
|
|||
success &= (bool)shaders.getVertexShader(true);
|
||||
success &= SUCCEEDED(device->CreateTexture(32, 32, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &paletteTexture.get(), 0));
|
||||
success &= SUCCEEDED(device->CreateTexture(128, 2, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8, D3DPOOL_DEFAULT, &fogTexture.get(), 0));
|
||||
fog_needs_update = true;
|
||||
updateFogTable = true;
|
||||
|
||||
if (!success)
|
||||
{
|
||||
|
@ -199,8 +199,8 @@ void D3DRenderer::postReset()
|
|||
verify(rc);
|
||||
rc = SUCCEEDED(device->CreateTexture(128, 2, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8, D3DPOOL_DEFAULT, &fogTexture.get(), 0));
|
||||
verify(rc);
|
||||
fog_needs_update = true;
|
||||
palette_updated = true;
|
||||
updateFogTable = true;
|
||||
updatePalette = true;
|
||||
}
|
||||
|
||||
void D3DRenderer::Term()
|
||||
|
@ -315,8 +315,10 @@ void D3DRenderer::Process(TA_context* ctx)
|
|||
if (settings.platform.isNaomi2())
|
||||
throw FlycastException("DirectX 9 doesn't support Naomi 2 games. Select a different graphics API");
|
||||
|
||||
if (KillTex)
|
||||
if (resetTextureCache) {
|
||||
texCache.Clear();
|
||||
resetTextureCache = false;
|
||||
}
|
||||
texCache.Cleanup();
|
||||
|
||||
ta_parse(ctx, false);
|
||||
|
@ -1279,7 +1281,7 @@ void D3DRenderer::displayFramebuffer()
|
|||
|
||||
bool D3DRenderer::RenderLastFrame()
|
||||
{
|
||||
if (!frameRenderedOnce || !theDXContext.isReady())
|
||||
if (clearLastFrame || !frameRenderedOnce || !theDXContext.isReady())
|
||||
return false;
|
||||
backbuffer.reset();
|
||||
bool rc = SUCCEEDED(device->GetRenderTarget(0, &backbuffer.get()));
|
||||
|
@ -1292,9 +1294,9 @@ bool D3DRenderer::RenderLastFrame()
|
|||
|
||||
void D3DRenderer::updatePaletteTexture()
|
||||
{
|
||||
if (!palette_updated)
|
||||
if (!updatePalette)
|
||||
return;
|
||||
palette_updated = false;
|
||||
updatePalette = false;
|
||||
|
||||
D3DLOCKED_RECT rect;
|
||||
bool rc = SUCCEEDED(paletteTexture->LockRect(0, &rect, nullptr, 0));
|
||||
|
@ -1316,9 +1318,9 @@ void D3DRenderer::updatePaletteTexture()
|
|||
|
||||
void D3DRenderer::updateFogTexture()
|
||||
{
|
||||
if (!fog_needs_update || !config::Fog)
|
||||
if (!updateFogTable || !config::Fog)
|
||||
return;
|
||||
fog_needs_update = false;
|
||||
updateFogTable = false;
|
||||
u8 temp_tex_buffer[256];
|
||||
MakeFogTexture(temp_tex_buffer);
|
||||
|
||||
|
|
|
@ -110,6 +110,7 @@ struct D3DRenderer : public Renderer
|
|||
return false;
|
||||
imguiDriver->setFrameRendered();
|
||||
frameRendered = false;
|
||||
clearLastFrame = false;
|
||||
return true;
|
||||
}
|
||||
BaseTextureCacheData *GetTexture(TSP tsp, TCW tcw) override;
|
||||
|
|
|
@ -763,7 +763,7 @@ bool OpenGL4Renderer::Init()
|
|||
u32 dst[16];
|
||||
UpscalexBRZ(2, src, dst, 2, 2, false);
|
||||
}
|
||||
fog_needs_update = true;
|
||||
updateFogTable = true;
|
||||
TextureCacheData::SetDirectXColorOrder(false);
|
||||
TextureCacheData::setUploadToGPUFlavor();
|
||||
|
||||
|
|
|
@ -982,7 +982,7 @@ bool OpenGLRenderer::Init()
|
|||
u32 dst[16];
|
||||
UpscalexBRZ(2, src, dst, 2, 2, false);
|
||||
}
|
||||
fog_needs_update = true;
|
||||
updateFogTable = true;
|
||||
TextureCacheData::SetDirectXColorOrder(false);
|
||||
TextureCacheData::setUploadToGPUFlavor();
|
||||
|
||||
|
@ -1049,19 +1049,19 @@ void OpenGLRenderer::Process(TA_context* ctx)
|
|||
if (gl.gl_major < 3 && settings.platform.isNaomi2())
|
||||
throw FlycastException("OpenGL ES 3.0+ required for Naomi 2");
|
||||
|
||||
if (KillTex)
|
||||
if (resetTextureCache) {
|
||||
TexCache.Clear();
|
||||
resetTextureCache = false;
|
||||
}
|
||||
TexCache.Cleanup();
|
||||
|
||||
if (fog_needs_update && config::Fog)
|
||||
{
|
||||
fog_needs_update = false;
|
||||
if (updateFogTable && config::Fog) {
|
||||
updateFogTable = false;
|
||||
updateFogTexture((u8 *)FOG_TABLE, getFogTextureSlot(), gl.single_channel_format);
|
||||
}
|
||||
if (palette_updated)
|
||||
{
|
||||
if (updatePalette) {
|
||||
updatePaletteTexture(getPaletteTextureSlot());
|
||||
palette_updated = false;
|
||||
updatePalette = false;
|
||||
}
|
||||
ta_parse(ctx, gl.prim_restart_fixed_supported || gl.prim_restart_supported);
|
||||
}
|
||||
|
|
|
@ -502,6 +502,8 @@ struct OpenGLRenderer : Renderer
|
|||
|
||||
bool RenderLastFrame() override
|
||||
{
|
||||
if (clearLastFrame)
|
||||
return false;
|
||||
saveCurrentFramebuffer();
|
||||
bool ret = renderLastFrame();
|
||||
restoreCurrentFramebuffer();
|
||||
|
@ -519,6 +521,7 @@ struct OpenGLRenderer : Renderer
|
|||
#ifndef LIBRETRO
|
||||
imguiDriver->setFrameRendered();
|
||||
#endif
|
||||
clearLastFrame = false;
|
||||
frameRendered = false;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -105,6 +105,7 @@ public:
|
|||
|
||||
bool Present() override
|
||||
{
|
||||
clearLastFrame = false;
|
||||
if (config::EmulateFramebuffer || framebufferRendered)
|
||||
return presentFramebuffer();
|
||||
else
|
||||
|
|
|
@ -56,7 +56,8 @@ public:
|
|||
if (!rendering || newFrameStarted)
|
||||
{
|
||||
context->BeginRenderPass();
|
||||
context->PresentLastFrame();
|
||||
if (renderer->RenderLastFrame())
|
||||
context->PresentLastFrame();
|
||||
}
|
||||
if (!justStarted)
|
||||
{
|
||||
|
|
|
@ -87,8 +87,10 @@ BaseTextureCacheData *BaseVulkanRenderer::GetTexture(TSP tsp, TCW tcw)
|
|||
void BaseVulkanRenderer::Process(TA_context* ctx)
|
||||
{
|
||||
framebufferRendered = false;
|
||||
if (KillTex)
|
||||
if (resetTextureCache) {
|
||||
textureCache.Clear();
|
||||
resetTextureCache = false;
|
||||
}
|
||||
|
||||
texCommandPool.BeginFrame();
|
||||
textureCache.SetCurrentIndex(texCommandPool.GetIndex());
|
||||
|
@ -184,11 +186,11 @@ void BaseVulkanRenderer::CheckFogTexture()
|
|||
{
|
||||
fogTexture = std::make_unique<Texture>();
|
||||
fogTexture->tex_type = TextureType::_8;
|
||||
fog_needs_update = true;
|
||||
updateFogTable = true;
|
||||
}
|
||||
if (!fog_needs_update || !config::Fog)
|
||||
if (!updateFogTable || !config::Fog)
|
||||
return;
|
||||
fog_needs_update = false;
|
||||
updateFogTable = false;
|
||||
u8 texData[256];
|
||||
MakeFogTexture(texData);
|
||||
|
||||
|
@ -199,15 +201,14 @@ void BaseVulkanRenderer::CheckFogTexture()
|
|||
|
||||
void BaseVulkanRenderer::CheckPaletteTexture()
|
||||
{
|
||||
if (!paletteTexture)
|
||||
{
|
||||
if (!paletteTexture) {
|
||||
paletteTexture = std::make_unique<Texture>();
|
||||
paletteTexture->tex_type = TextureType::_8888;
|
||||
palette_updated = true;
|
||||
}
|
||||
if (!palette_updated)
|
||||
else if (!updatePalette) {
|
||||
return;
|
||||
palette_updated = false;
|
||||
}
|
||||
updatePalette = false;
|
||||
|
||||
paletteTexture->SetCommandBuffer(texCommandBuffer);
|
||||
paletteTexture->UploadToGPU(1024, 1, (u8 *)palette32_ram, false);
|
||||
|
@ -299,6 +300,7 @@ public:
|
|||
|
||||
bool Present() override
|
||||
{
|
||||
clearLastFrame = false;
|
||||
if (config::EmulateFramebuffer || framebufferRendered)
|
||||
return presentFramebuffer();
|
||||
else
|
||||
|
|
|
@ -41,6 +41,9 @@ public:
|
|||
void RenderFramebuffer(const FramebufferInfo& info) override;
|
||||
void RenderVideoRouting();
|
||||
|
||||
bool RenderLastFrame() override {
|
||||
return !clearLastFrame;
|
||||
}
|
||||
bool GetLastFrame(std::vector<u8>& data, int& width, int& height) override {
|
||||
return GetContext()->GetLastFrame(data, width, height);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue