VideoCommon:VertexLoaderManager: Reduce CPConfig checks

A bit of a micro optimization:
CheckCPConfiguration is called 350 times instead of 35k times.
This commit is contained in:
Robin Kertels 2022-11-16 14:39:29 +01:00
parent 8a1c28be63
commit f179fd9c33
No known key found for this signature in database
GPG Key ID: 3824904F14D40757
4 changed files with 28 additions and 8 deletions

View File

@ -56,18 +56,26 @@ public:
if constexpr (!is_preprocess)
{
if (sub_command == MATINDEX_A)
{
VertexLoaderManager::g_needs_cp_xf_consistency_check = true;
VertexShaderManager::SetTexMatrixChangedA(value);
}
else if (sub_command == MATINDEX_B)
{
VertexLoaderManager::g_needs_cp_xf_consistency_check = true;
VertexShaderManager::SetTexMatrixChangedB(value);
}
else if (sub_command == VCD_LO || sub_command == VCD_HI)
{
VertexLoaderManager::g_main_vat_dirty = BitSet8::AllTrue(CP_NUM_VAT_REG);
VertexLoaderManager::g_bases_dirty = true;
VertexLoaderManager::g_needs_cp_xf_consistency_check = true;
}
else if (sub_command == CP_VAT_REG_A || sub_command == CP_VAT_REG_B ||
sub_command == CP_VAT_REG_C)
{
VertexLoaderManager::g_main_vat_dirty[command & CP_VAT_MASK] = true;
VertexLoaderManager::g_needs_cp_xf_consistency_check = true;
}
else if (sub_command == ARRAY_BASE)
{

View File

@ -56,6 +56,7 @@ BitSet8 g_preprocess_vat_dirty;
bool g_bases_dirty; // Main only
std::array<VertexLoaderBase*, CP_NUM_VAT_REG> g_main_vertex_loaders;
std::array<VertexLoaderBase*, CP_NUM_VAT_REG> g_preprocess_vertex_loaders;
bool g_needs_cp_xf_consistency_check;
void Init()
{
@ -126,6 +127,7 @@ void MarkAllDirty()
g_bases_dirty = true;
g_main_vat_dirty = BitSet8::AllTrue(8);
g_preprocess_vat_dirty = BitSet8::AllTrue(8);
g_needs_cp_xf_consistency_check = true;
}
NativeVertexFormat* GetOrCreateMatchingFormat(const PortableVertexDeclaration& decl)
@ -244,6 +246,11 @@ VertexLoaderBase* GetOrCreateLoader(int vtx_attr_group)
static void CheckCPConfiguration(int vtx_attr_group)
{
if (!g_needs_cp_xf_consistency_check) [[likely]]
return;
g_needs_cp_xf_consistency_check = false;
// Validate that the XF input configuration matches the CP configuration
u32 num_cp_colors = std::count_if(
g_main_cp_state.vtx_desc.low.Color.begin(), g_main_cp_state.vtx_desc.low.Color.end(),
@ -276,7 +283,7 @@ static void CheckCPConfiguration(int vtx_attr_group)
}
if (num_cp_colors != xfmem.invtxspec.numcolors || num_cp_normals != num_xf_normals ||
num_cp_tex_coords != xfmem.invtxspec.numtextures)
num_cp_tex_coords != xfmem.invtxspec.numtextures) [[unlikely]]
{
PanicAlertFmt("Mismatched configuration between CP and XF stages - {}/{} colors, {}/{} "
"normals, {}/{} texture coordinates. Please report on the issue tracker.\n\n"
@ -291,17 +298,17 @@ static void CheckCPConfiguration(int vtx_attr_group)
// Analytics reporting so we can discover which games have this problem, that way when we
// eventually simulate the behavior we have test cases for it.
if (num_cp_colors != xfmem.invtxspec.numcolors)
if (num_cp_colors != xfmem.invtxspec.numcolors) [[unlikely]]
{
DolphinAnalytics::Instance().ReportGameQuirk(
GameQuirk::MISMATCHED_GPU_COLORS_BETWEEN_CP_AND_XF);
}
if (num_cp_normals != num_xf_normals)
if (num_cp_normals != num_xf_normals) [[unlikely]]
{
DolphinAnalytics::Instance().ReportGameQuirk(
GameQuirk::MISMATCHED_GPU_NORMALS_BETWEEN_CP_AND_XF);
}
if (num_cp_tex_coords != xfmem.invtxspec.numtextures)
if (num_cp_tex_coords != xfmem.invtxspec.numtextures) [[unlikely]]
{
DolphinAnalytics::Instance().ReportGameQuirk(
GameQuirk::MISMATCHED_GPU_TEX_COORDS_BETWEEN_CP_AND_XF);
@ -312,7 +319,7 @@ static void CheckCPConfiguration(int vtx_attr_group)
}
if (g_main_cp_state.matrix_index_a.Hex != xfmem.MatrixIndexA.Hex ||
g_main_cp_state.matrix_index_b.Hex != xfmem.MatrixIndexB.Hex)
g_main_cp_state.matrix_index_b.Hex != xfmem.MatrixIndexB.Hex) [[unlikely]]
{
WARN_LOG_FMT(VIDEO,
"Mismatched matrix index configuration between CP and XF stages - "
@ -327,14 +334,14 @@ static void CheckCPConfiguration(int vtx_attr_group)
template <bool IsPreprocess>
int RunVertices(int vtx_attr_group, OpcodeDecoder::Primitive primitive, int count, DataReader src)
{
if (count == 0)
if (count == 0) [[unlikely]]
return 0;
ASSERT(count > 0);
VertexLoaderBase* loader = RefreshLoader<IsPreprocess>(vtx_attr_group);
int size = count * loader->m_vertex_size;
if ((int)src.size() < size)
if ((int)src.size() < size) [[unlikely]]
return -1;
if constexpr (!IsPreprocess)
@ -346,7 +353,7 @@ int RunVertices(int vtx_attr_group, OpcodeDecoder::Primitive primitive, int coun
// If the native vertex format changed, force a flush.
if (loader->m_native_vertex_format != s_current_vtx_fmt ||
loader->m_native_components != g_current_components)
loader->m_native_components != g_current_components) [[unlikely]]
{
g_vertex_manager->Flush();
}

View File

@ -76,6 +76,7 @@ extern BitSet8 g_preprocess_vat_dirty;
extern bool g_bases_dirty; // Main only
extern std::array<VertexLoaderBase*, CP_NUM_VAT_REG> g_main_vertex_loaders;
extern std::array<VertexLoaderBase*, CP_NUM_VAT_REG> g_preprocess_vertex_loaders;
extern bool g_needs_cp_xf_consistency_check;
template <bool IsPreprocess = false>
VertexLoaderBase* RefreshLoader(int vtx_attr_group)

View File

@ -15,6 +15,7 @@
#include "VideoCommon/Fifo.h"
#include "VideoCommon/GeometryShaderManager.h"
#include "VideoCommon/PixelShaderManager.h"
#include "VideoCommon/VertexLoaderManager.h"
#include "VideoCommon/VertexManagerBase.h"
#include "VideoCommon/VertexShaderManager.h"
#include "VideoCommon/XFMemory.h"
@ -53,6 +54,7 @@ static void XFRegWritten(u32 address, u32 value)
}
case XFMEM_VTXSPECS: //__GXXfVtxSpecs, wrote 0004
VertexLoaderManager::g_needs_cp_xf_consistency_check = true;
break;
case XFMEM_SETNUMCHAN:
@ -102,9 +104,11 @@ static void XFRegWritten(u32 address, u32 value)
case XFMEM_SETMATRIXINDA:
VertexShaderManager::SetTexMatrixChangedA(value);
VertexLoaderManager::g_needs_cp_xf_consistency_check = true;
break;
case XFMEM_SETMATRIXINDB:
VertexShaderManager::SetTexMatrixChangedB(value);
VertexLoaderManager::g_needs_cp_xf_consistency_check = true;
break;
case XFMEM_SETVIEWPORT: