VideoCommon: trigger mod calls in TextureCacheBase (efb/xfb calls), VertexManagerBase (draw calls), and VertexShaderManager (projection calls)

This commit is contained in:
iwubcode 2022-03-05 14:52:43 -06:00
parent 62c186e14b
commit 892678648e
10 changed files with 142 additions and 28 deletions

View File

@ -213,7 +213,7 @@ void HiresTexture::Prefetch()
10000);
}
std::string HiresTexture::GenBaseName(TextureInfo& texture_info, bool dump)
std::string HiresTexture::GenBaseName(const TextureInfo& texture_info, bool dump)
{
if (!dump && s_textureMap.empty())
return "";
@ -261,7 +261,7 @@ u32 HiresTexture::CalculateMipCount(u32 width, u32 height)
return mip_count;
}
std::shared_ptr<HiresTexture> HiresTexture::Search(TextureInfo& texture_info)
std::shared_ptr<HiresTexture> HiresTexture::Search(const TextureInfo& texture_info)
{
const std::string base_filename = GenBaseName(texture_info);

View File

@ -25,9 +25,9 @@ public:
static void Clear();
static void Shutdown();
static std::shared_ptr<HiresTexture> Search(TextureInfo& texture_info);
static std::shared_ptr<HiresTexture> Search(const TextureInfo& texture_info);
static std::string GenBaseName(TextureInfo& texture_info, bool dump = false);
static std::string GenBaseName(const TextureInfo& texture_info, bool dump = false);
static u32 CalculateMipCount(u32 width, u32 height);

View File

@ -67,6 +67,7 @@
#include "VideoCommon/FramebufferManager.h"
#include "VideoCommon/FramebufferShaderGen.h"
#include "VideoCommon/FreeLookCamera.h"
#include "VideoCommon/GraphicsModSystem/Config/GraphicsModGroup.h"
#include "VideoCommon/NetPlayChatUI.h"
#include "VideoCommon/NetPlayGolfUI.h"
#include "VideoCommon/OnScreenDisplay.h"
@ -1309,6 +1310,11 @@ void Renderer::Swap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u6
// behind the renderer.
FlushFrameDump();
if (g_ActiveConfig.bGraphicMods)
{
m_graphics_mod_manager.EndOfFrame();
}
if (xfb_addr && fb_width && fb_stride && fb_height)
{
// Get the current XFB from texture cache
@ -1830,3 +1836,8 @@ std::unique_ptr<VideoCommon::AsyncShaderCompiler> Renderer::CreateAsyncShaderCom
{
return std::make_unique<VideoCommon::AsyncShaderCompiler>();
}
const GraphicsModManager& Renderer::GetGraphicsModManager() const
{
return m_graphics_mod_manager;
}

View File

@ -30,6 +30,7 @@
#include "VideoCommon/BPMemory.h"
#include "VideoCommon/FPSCounter.h"
#include "VideoCommon/FrameDump.h"
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.h"
#include "VideoCommon/RenderState.h"
#include "VideoCommon/TextureConfig.h"
@ -268,6 +269,8 @@ public:
// Will forcibly reload all textures on the next swap
void ForceReloadTextures();
const GraphicsModManager& GetGraphicsModManager() const;
protected:
// Bitmask containing information about which configuration has changed for the backend.
enum ConfigChangeBits : u32
@ -447,6 +450,8 @@ private:
std::unique_ptr<NetPlayChatUI> m_netplay_chat_ui;
Common::Flag m_force_reload_textures;
GraphicsModManager m_graphics_mod_manager;
};
extern std::unique_ptr<Renderer> g_renderer;

View File

@ -36,6 +36,7 @@
#include "VideoCommon/AbstractStagingTexture.h"
#include "VideoCommon/BPMemory.h"
#include "VideoCommon/FramebufferManager.h"
#include "VideoCommon/GraphicsModSystem/Runtime/FBInfo.h"
#include "VideoCommon/HiresTextures.h"
#include "VideoCommon/OpcodeDecoding.h"
#include "VideoCommon/PixelShaderManager.h"
@ -255,6 +256,7 @@ void TextureCacheBase::SetBackupConfig(const VideoConfig& config)
backup_config.gpu_texture_decoding = config.bEnableGPUTextureDecoding;
backup_config.disable_vram_copies = config.bDisableCopyToVRAM;
backup_config.arbitrary_mipmap_detection = config.bArbitraryMipmapDetection;
backup_config.graphics_mods = config.bGraphicMods;
}
TextureCacheBase::TCacheEntry*
@ -1205,15 +1207,15 @@ private:
std::vector<Level> levels;
};
TextureCacheBase::TCacheEntry* TextureCacheBase::Load(const u32 stage)
TextureCacheBase::TCacheEntry* TextureCacheBase::Load(const TextureInfo& texture_info)
{
// if this stage was not invalidated by changes to texture registers, keep the current texture
if (TMEM::IsValid(stage) && bound_textures[stage])
if (TMEM::IsValid(texture_info.GetStage()) && bound_textures[texture_info.GetStage()])
{
TCacheEntry* entry = bound_textures[stage];
TCacheEntry* entry = bound_textures[texture_info.GetStage()];
// If the TMEM configuration is such that this texture is more or less guaranteed to still
// be in TMEM, then we know we can reuse the old entry without even hashing the memory
if (TMEM::IsCached(stage))
if (TMEM::IsCached(texture_info.GetStage()))
{
return entry;
}
@ -1226,26 +1228,29 @@ TextureCacheBase::TCacheEntry* TextureCacheBase::Load(const u32 stage)
}
}
TextureInfo texture_info = TextureInfo::FromStage(stage);
auto entry = GetTexture(g_ActiveConfig.iSafeTextureCache_ColorSamples, texture_info);
if (!entry)
return nullptr;
entry->frameCount = FRAMECOUNT_INVALID;
bound_textures[stage] = entry;
if (entry->texture_info_name.empty() && g_ActiveConfig.bGraphicMods)
{
entry->texture_info_name = texture_info.CalculateTextureName().GetFullName();
}
bound_textures[texture_info.GetStage()] = entry;
// We need to keep track of invalided textures until they have actually been replaced or
// re-loaded
TMEM::Bind(stage, entry->NumBlocksX(), entry->NumBlocksY(), entry->GetNumLevels() > 1,
entry->format == TextureFormat::RGBA8);
TMEM::Bind(texture_info.GetStage(), entry->NumBlocksX(), entry->NumBlocksY(),
entry->GetNumLevels() > 1, entry->format == TextureFormat::RGBA8);
return entry;
}
TextureCacheBase::TCacheEntry*
TextureCacheBase::GetTexture(const int textureCacheSafetyColorSampleSize, TextureInfo& texture_info)
TextureCacheBase::GetTexture(const int textureCacheSafetyColorSampleSize,
const TextureInfo& texture_info)
{
u32 expanded_width = texture_info.GetExpandedWidth();
u32 expanded_height = texture_info.GetExpandedHeight();
@ -2119,6 +2124,35 @@ void TextureCacheBase::CopyRenderTargetToTexture(
const u32 bytes_per_row = num_blocks_x * bytes_per_block;
const u32 covered_range = num_blocks_y * dstStride;
if (g_ActiveConfig.bGraphicMods)
{
FBInfo info;
info.m_width = tex_w;
info.m_height = tex_h;
info.m_texture_format = baseFormat;
if (is_xfb_copy)
{
for (const auto action : g_renderer->GetGraphicsModManager().GetXFBActions(info))
{
action->OnXFB();
}
}
else
{
bool skip = false;
for (const auto action : g_renderer->GetGraphicsModManager().GetEFBActions(info))
{
action->OnEFB(&skip, tex_w, tex_h, &scaled_tex_w, &scaled_tex_h);
}
if (skip == true)
{
if (copy_to_ram)
UninitializeEFBMemory(dst, dstStride, bytes_per_row, num_blocks_y);
return;
}
}
}
if (dstStride < bytes_per_row)
{
// This kind of efb copy results in a scrambled image.

View File

@ -155,6 +155,8 @@ public:
u32 pending_efb_copy_height = 0;
bool pending_efb_copy_invalidated = false;
std::string texture_info_name = "";
explicit TCacheEntry(std::unique_ptr<AbstractTexture> tex,
std::unique_ptr<AbstractFramebuffer> fb);
@ -239,8 +241,9 @@ public:
void Invalidate();
TCacheEntry* Load(const u32 stage);
TCacheEntry* GetTexture(const int textureCacheSafetyColorSampleSize, TextureInfo& texture_info);
TCacheEntry* Load(const TextureInfo& texture_info);
TCacheEntry* GetTexture(const int textureCacheSafetyColorSampleSize,
const TextureInfo& texture_info);
TCacheEntry* GetXFBTexture(u32 address, u32 width, u32 height, u32 stride,
MathUtil::Rectangle<int>* display_rect);
@ -374,6 +377,7 @@ private:
bool gpu_texture_decoding;
bool disable_vram_copies;
bool arbitrary_mipmap_detection;
bool graphics_mods;
};
BackupConfig backup_config = {};

View File

@ -7,7 +7,6 @@
#include <cmath>
#include <memory>
#include "Common/BitSet.h"
#include "Common/ChunkFile.h"
#include "Common/CommonTypes.h"
#include "Common/EnumMap.h"
@ -30,6 +29,7 @@
#include "VideoCommon/RenderBase.h"
#include "VideoCommon/Statistics.h"
#include "VideoCommon/TextureCacheBase.h"
#include "VideoCommon/TextureInfo.h"
#include "VideoCommon/VertexLoaderManager.h"
#include "VideoCommon/VertexShaderManager.h"
#include "VideoCommon/VideoBackendBase.h"
@ -337,7 +337,7 @@ bool VertexManagerBase::UploadTexelBuffer(const void* data, u32 data_size, Texel
return false;
}
void VertexManagerBase::LoadTextures()
BitSet32 VertexManagerBase::UsedTextures() const
{
BitSet32 usedtextures;
for (u32 i = 0; i < bpmem.genMode.numtevstages + 1u; ++i)
@ -349,10 +349,7 @@ void VertexManagerBase::LoadTextures()
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
usedtextures[bpmem.tevindref.getTexMap(bpmem.tevind[i].bt)] = true;
for (unsigned int i : usedtextures)
g_texture_cache->Load(i);
g_texture_cache->BindTextures(usedtextures);
return usedtextures;
}
void VertexManagerBase::Flush()
@ -455,7 +452,30 @@ void VertexManagerBase::Flush()
CalculateBinormals(VertexLoaderManager::GetCurrentVertexFormat());
// Calculate ZSlope for zfreeze
VertexShaderManager::SetConstants();
const auto used_textures = UsedTextures();
std::vector<std::string> texture_names;
if (!m_cull_all)
{
if (!g_ActiveConfig.bGraphicMods)
{
for (const u32 i : used_textures)
{
g_texture_cache->Load(TextureInfo::FromStage(i));
}
}
else
{
for (const u32 i : used_textures)
{
const auto cache_entry = g_texture_cache->Load(TextureInfo::FromStage(i));
if (cache_entry)
{
texture_names.push_back(cache_entry->texture_info_name);
}
}
}
}
VertexShaderManager::SetConstants(texture_names);
if (!bpmem.genMode.zfreeze)
{
// Must be done after VertexShaderManager::SetConstants()
@ -469,6 +489,18 @@ void VertexManagerBase::Flush()
if (!m_cull_all)
{
for (const auto& texture_name : texture_names)
{
bool skip = false;
for (const auto action :
g_renderer->GetGraphicsModManager().GetDrawStartedActions(texture_name))
{
action->OnDrawStarted(&skip);
}
if (skip == true)
return;
}
// Now the vertices can be flushed to the GPU. Everything following the CommitBuffer() call
// must be careful to not upload any utility vertices, as the binding will be lost otherwise.
const u32 num_indices = m_index_generator.GetIndexLen();
@ -480,7 +512,7 @@ void VertexManagerBase::Flush()
// Texture loading can cause palettes to be applied (-> uniforms -> draws).
// Palette application does not use vertices, only a full-screen quad, so this is okay.
// Same with GPU texture decoding, which uses compute shaders.
LoadTextures();
g_texture_cache->BindTextures(used_textures);
// Now we can upload uniforms, as nothing else will override them.
GeometryShaderManager::SetConstants();

View File

@ -6,6 +6,7 @@
#include <memory>
#include <vector>
#include "Common/BitSet.h"
#include "Common/CommonTypes.h"
#include "Common/MathUtil.h"
#include "VideoCommon/IndexGenerator.h"
@ -173,7 +174,8 @@ protected:
void CalculateZSlope(NativeVertexFormat* format);
void CalculateBinormals(NativeVertexFormat* format);
void LoadTextures();
BitSet32 UsedTextures() const;
u8* m_cur_buffer_pointer = nullptr;
u8* m_base_buffer_pointer = nullptr;

View File

@ -85,7 +85,7 @@ void VertexShaderManager::Dirty()
// Syncs the shader constant buffers with xfmem
// TODO: A cleaner way to control the matrices without making a mess in the parameters field
void VertexShaderManager::SetConstants()
void VertexShaderManager::SetConstants(const std::vector<std::string>& textures)
{
if (constants.missing_color_hex != g_ActiveConfig.iMissingColorValue)
{
@ -302,7 +302,27 @@ void VertexShaderManager::SetConstants()
g_stats.AddScissorRect();
}
if (bProjectionChanged || g_freelook_camera.GetController()->IsDirty())
std::vector<GraphicsModAction*> projection_actions;
if (g_ActiveConfig.bGraphicMods)
{
for (const auto action :
g_renderer->GetGraphicsModManager().GetProjectionActions(xfmem.projection.type))
{
projection_actions.push_back(action);
}
for (const auto& texture : textures)
{
for (const auto action : g_renderer->GetGraphicsModManager().GetProjectionTextureActions(
xfmem.projection.type, texture))
{
projection_actions.push_back(action);
}
}
}
if (bProjectionChanged || g_freelook_camera.GetController()->IsDirty() ||
!projection_actions.empty())
{
bProjectionChanged = false;
@ -384,6 +404,11 @@ void VertexShaderManager::SetConstants()
if (g_freelook_camera.IsActive() && xfmem.projection.type == ProjectionType::Perspective)
corrected_matrix *= g_freelook_camera.GetView();
for (auto action : projection_actions)
{
action->OnProjection(&corrected_matrix);
}
memcpy(constants.projection.data(), corrected_matrix.data.data(), 4 * sizeof(float4));
g_freelook_camera.GetController()->SetClean();

View File

@ -4,6 +4,7 @@
#pragma once
#include <string>
#include <vector>
#include "Common/CommonTypes.h"
#include "VideoCommon/ConstantManager.h"
@ -19,7 +20,7 @@ public:
static void DoState(PointerWrap& p);
// constant management
static void SetConstants();
static void SetConstants(const std::vector<std::string>& textures);
static void InvalidateXFRange(int start, int end);
static void SetTexMatrixChangedA(u32 value);