diff options
| author | JMC47 <JMC4789@gmail.com> | 2021-12-20 14:27:14 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-12-20 14:27:14 -0500 |
| commit | 32fed91b0d35f06c46281f55c9f0fa4694c5334a (patch) | |
| tree | 6e47451f525329e5ba57fc615c491b0ca06088d8 /Source/Core/VideoCommon/VertexLoaderManager.cpp | |
| parent | 1714dc64bb1cc01aee9d9b52763f20aa6a44a674 (diff) | |
| parent | ffa512f5e7d24d9d9e93366bb596b9473d26d61b (diff) | |
Merge pull request #9718 from Pokechu22/better-fifo-analyzer-part-3
Fifo analyzer improvements, part 3
Diffstat (limited to 'Source/Core/VideoCommon/VertexLoaderManager.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/VertexLoaderManager.cpp | 219 |
1 files changed, 43 insertions, 176 deletions
diff --git a/Source/Core/VideoCommon/VertexLoaderManager.cpp b/Source/Core/VideoCommon/VertexLoaderManager.cpp index 33af56762f..b0922e5a6e 100644 --- a/Source/Core/VideoCommon/VertexLoaderManager.cpp +++ b/Source/Core/VideoCommon/VertexLoaderManager.cpp @@ -12,16 +12,14 @@ #include <utility> #include <vector> -#include "Common/Assert.h" #include "Common/CommonTypes.h" +#include "Common/EnumMap.h" #include "Common/Logging/Log.h" -#include "Core/DolphinAnalytics.h" #include "Core/HW/Memmap.h" #include "VideoCommon/BPMemory.h" #include "VideoCommon/CPMemory.h" -#include "VideoCommon/CommandProcessor.h" #include "VideoCommon/DataReader.h" #include "VideoCommon/IndexGenerator.h" #include "VideoCommon/NativeVertexFormat.h" @@ -48,14 +46,21 @@ static std::mutex s_vertex_loader_map_lock; static VertexLoaderMap s_vertex_loader_map; // TODO - change into array of pointers. Keep a map of all seen so far. -u8* cached_arraybases[NUM_VERTEX_COMPONENT_ARRAYS]; +Common::EnumMap<u8*, CPArray::TexCoord7> cached_arraybases; + +BitSet8 g_main_vat_dirty; +BitSet8 g_preprocess_vat_dirty; +bool g_bases_dirty; // Main only +u8 g_current_vat; // Main only +std::array<VertexLoaderBase*, CP_NUM_VAT_REG> g_main_vertex_loaders; +std::array<VertexLoaderBase*, CP_NUM_VAT_REG> g_preprocess_vertex_loaders; void Init() { MarkAllDirty(); - for (auto& map_entry : g_main_cp_state.vertex_loaders) + for (auto& map_entry : g_main_vertex_loaders) map_entry = nullptr; - for (auto& map_entry : g_preprocess_cp_state.vertex_loaders) + for (auto& map_entry : g_preprocess_vertex_loaders) map_entry = nullptr; SETSTAT(g_stats.num_vertex_loaders, 0); } @@ -70,7 +75,7 @@ void Clear() void UpdateVertexArrayPointers() { // Anything to update? - if (!g_main_cp_state.bases_dirty) + if (!g_bases_dirty) return; // Some games such as Burnout 2 can put invalid addresses into @@ -80,27 +85,28 @@ void UpdateVertexArrayPointers() // 12 through 15 are used for loading data into xfmem. // We also only update the array base if the vertex description states we are going to use it. if (IsIndexed(g_main_cp_state.vtx_desc.low.Position)) - cached_arraybases[ARRAY_POSITION] = - Memory::GetPointer(g_main_cp_state.array_bases[ARRAY_POSITION]); + cached_arraybases[CPArray::Position] = + Memory::GetPointer(g_main_cp_state.array_bases[CPArray::Position]); if (IsIndexed(g_main_cp_state.vtx_desc.low.Normal)) - cached_arraybases[ARRAY_NORMAL] = Memory::GetPointer(g_main_cp_state.array_bases[ARRAY_NORMAL]); + cached_arraybases[CPArray::Normal] = + Memory::GetPointer(g_main_cp_state.array_bases[CPArray::Normal]); - for (size_t i = 0; i < g_main_cp_state.vtx_desc.low.Color.Size(); i++) + for (u8 i = 0; i < g_main_cp_state.vtx_desc.low.Color.Size(); i++) { if (IsIndexed(g_main_cp_state.vtx_desc.low.Color[i])) - cached_arraybases[ARRAY_COLOR0 + i] = - Memory::GetPointer(g_main_cp_state.array_bases[ARRAY_COLOR0 + i]); + cached_arraybases[CPArray::Color0 + i] = + Memory::GetPointer(g_main_cp_state.array_bases[CPArray::Color0 + i]); } - for (size_t i = 0; i < g_main_cp_state.vtx_desc.high.TexCoord.Size(); i++) + for (u8 i = 0; i < g_main_cp_state.vtx_desc.high.TexCoord.Size(); i++) { if (IsIndexed(g_main_cp_state.vtx_desc.high.TexCoord[i])) - cached_arraybases[ARRAY_TEXCOORD0 + i] = - Memory::GetPointer(g_main_cp_state.array_bases[ARRAY_TEXCOORD0 + i]); + cached_arraybases[CPArray::TexCoord0 + i] = + Memory::GetPointer(g_main_cp_state.array_bases[CPArray::TexCoord0 + i]); } - g_main_cp_state.bases_dirty = false; + g_bases_dirty = false; } namespace @@ -115,8 +121,8 @@ struct entry void MarkAllDirty() { - g_main_cp_state.attr_dirty = BitSet32::AllTrue(8); - g_preprocess_cp_state.attr_dirty = BitSet32::AllTrue(8); + g_main_vat_dirty = BitSet8::AllTrue(8); + g_preprocess_vat_dirty = BitSet8::AllTrue(8); } NativeVertexFormat* GetOrCreateMatchingFormat(const PortableVertexDeclaration& decl) @@ -140,7 +146,8 @@ NativeVertexFormat* GetUberVertexFormat(const PortableVertexDeclaration& decl) std::memset(&new_decl, 0, sizeof(new_decl)); new_decl.stride = decl.stride; - auto MakeDummyAttribute = [](AttributeFormat& attr, VarType type, int components, bool integer) { + auto MakeDummyAttribute = [](AttributeFormat& attr, ComponentFormat type, int components, + bool integer) { attr.type = type; attr.components = components; attr.offset = 0; @@ -158,32 +165,32 @@ NativeVertexFormat* GetUberVertexFormat(const PortableVertexDeclaration& decl) if (decl.position.enable) CopyAttribute(new_decl.position, decl.position); else - MakeDummyAttribute(new_decl.position, VAR_FLOAT, 1, false); + MakeDummyAttribute(new_decl.position, ComponentFormat::Float, 1, false); for (size_t i = 0; i < std::size(new_decl.normals); i++) { if (decl.normals[i].enable) CopyAttribute(new_decl.normals[i], decl.normals[i]); else - MakeDummyAttribute(new_decl.normals[i], VAR_FLOAT, 1, false); + MakeDummyAttribute(new_decl.normals[i], ComponentFormat::Float, 1, false); } for (size_t i = 0; i < std::size(new_decl.colors); i++) { if (decl.colors[i].enable) CopyAttribute(new_decl.colors[i], decl.colors[i]); else - MakeDummyAttribute(new_decl.colors[i], VAR_UNSIGNED_BYTE, 4, false); + MakeDummyAttribute(new_decl.colors[i], ComponentFormat::UByte, 4, false); } for (size_t i = 0; i < std::size(new_decl.texcoords); i++) { if (decl.texcoords[i].enable) CopyAttribute(new_decl.texcoords[i], decl.texcoords[i]); else - MakeDummyAttribute(new_decl.texcoords[i], VAR_FLOAT, 1, false); + MakeDummyAttribute(new_decl.texcoords[i], ComponentFormat::Float, 1, false); } if (decl.posmtx.enable) CopyAttribute(new_decl.posmtx, decl.posmtx); else - MakeDummyAttribute(new_decl.posmtx, VAR_UNSIGNED_BYTE, 1, true); + MakeDummyAttribute(new_decl.posmtx, ComponentFormat::UByte, 1, true); return GetOrCreateMatchingFormat(new_decl); } @@ -191,10 +198,12 @@ NativeVertexFormat* GetUberVertexFormat(const PortableVertexDeclaration& decl) static VertexLoaderBase* RefreshLoader(int vtx_attr_group, bool preprocess = false) { CPState* state = preprocess ? &g_preprocess_cp_state : &g_main_cp_state; - state->last_id = vtx_attr_group; + BitSet8& attr_dirty = preprocess ? g_preprocess_vat_dirty : g_main_vat_dirty; + auto& vertex_loaders = preprocess ? g_main_vertex_loaders : g_preprocess_vertex_loaders; + g_current_vat = vtx_attr_group; VertexLoaderBase* loader; - if (state->attr_dirty[vtx_attr_group]) + if (attr_dirty[vtx_attr_group]) { // We are not allowed to create a native vertex format on preprocessing as this is on the wrong // thread @@ -224,12 +233,12 @@ static VertexLoaderBase* RefreshLoader(int vtx_attr_group, bool preprocess = fal native = g_renderer->CreateNativeVertexFormat(format); loader->m_native_vertex_format = native.get(); } - state->vertex_loaders[vtx_attr_group] = loader; - state->attr_dirty[vtx_attr_group] = false; + vertex_loaders[vtx_attr_group] = loader; + attr_dirty[vtx_attr_group] = false; } else { - loader = state->vertex_loaders[vtx_attr_group]; + loader = vertex_loaders[vtx_attr_group]; } // Lookup pointers for any vertex arrays. @@ -239,7 +248,8 @@ static VertexLoaderBase* RefreshLoader(int vtx_attr_group, bool preprocess = fal return loader; } -int RunVertices(int vtx_attr_group, int primitive, int count, DataReader src, bool is_preprocess) +int RunVertices(int vtx_attr_group, OpcodeDecoder::Primitive primitive, int count, DataReader src, + bool is_preprocess) { if (!count) return 0; @@ -266,7 +276,8 @@ int RunVertices(int vtx_attr_group, int primitive, int count, DataReader src, bo // if cull mode is CULL_ALL, tell VertexManager to skip triangles and quads. // They still need to go through vertex loading, because we need to calculate a zfreeze refrence // slope. - bool cullall = (bpmem.genMode.cullmode == CullMode::All && primitive < 5); + bool cullall = (bpmem.genMode.cullmode == CullMode::All && + primitive < OpcodeDecoder::Primitive::GX_DRAW_LINES); DataReader dst = g_vertex_manager->PrepareForAdditionalData( primitive, count, loader->m_native_vtx_decl.stride, cullall); @@ -287,147 +298,3 @@ NativeVertexFormat* GetCurrentVertexFormat() } } // namespace VertexLoaderManager - -void LoadCPReg(u32 sub_cmd, u32 value, bool is_preprocess) -{ - bool update_global_state = !is_preprocess; - CPState* state = is_preprocess ? &g_preprocess_cp_state : &g_main_cp_state; - switch (sub_cmd & CP_COMMAND_MASK) - { - case UNKNOWN_00: - case UNKNOWN_10: - case UNKNOWN_20: - if (!(sub_cmd == UNKNOWN_20 && value == 0)) - { - // All titles using libogc or the official SDK issue 0x20 with value=0 on startup - DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_CP_PERF_COMMAND); - DEBUG_LOG_FMT(VIDEO, "Unknown CP command possibly relating to perf queries used: {:02x}", - sub_cmd); - } - break; - - case MATINDEX_A: - if (sub_cmd != MATINDEX_A) - { - DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_MAYBE_INVALID_CP_COMMAND); - WARN_LOG_FMT(VIDEO, - "CP MATINDEX_A: an exact value of {:02x} was expected " - "but instead a value of {:02x} was seen", - MATINDEX_A, sub_cmd); - } - - if (update_global_state) - VertexShaderManager::SetTexMatrixChangedA(value); - break; - - case MATINDEX_B: - if (sub_cmd != MATINDEX_B) - { - DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_MAYBE_INVALID_CP_COMMAND); - WARN_LOG_FMT(VIDEO, - "CP MATINDEX_B: an exact value of {:02x} was expected " - "but instead a value of {:02x} was seen", - MATINDEX_B, sub_cmd); - } - - if (update_global_state) - VertexShaderManager::SetTexMatrixChangedB(value); - break; - - case VCD_LO: - if (sub_cmd != VCD_LO) // Stricter than YAGCD - { - DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_MAYBE_INVALID_CP_COMMAND); - WARN_LOG_FMT(VIDEO, - "CP VCD_LO: an exact value of {:02x} was expected " - "but instead a value of {:02x} was seen", - VCD_LO, sub_cmd); - } - - state->vtx_desc.low.Hex = value; - state->attr_dirty = BitSet32::AllTrue(CP_NUM_VAT_REG); - state->bases_dirty = true; - break; - - case VCD_HI: - if (sub_cmd != VCD_HI) // Stricter than YAGCD - { - DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_MAYBE_INVALID_CP_COMMAND); - WARN_LOG_FMT(VIDEO, - "CP VCD_HI: an exact value of {:02x} was expected " - "but instead a value of {:02x} was seen", - VCD_HI, sub_cmd); - } - - state->vtx_desc.high.Hex = value; - state->attr_dirty = BitSet32::AllTrue(CP_NUM_VAT_REG); - state->bases_dirty = true; - break; - - case CP_VAT_REG_A: - if ((sub_cmd - CP_VAT_REG_A) >= CP_NUM_VAT_REG) - { - DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_MAYBE_INVALID_CP_COMMAND); - WARN_LOG_FMT(VIDEO, "CP_VAT_REG_A: Invalid VAT {}", sub_cmd - CP_VAT_REG_A); - } - state->vtx_attr[sub_cmd & CP_VAT_MASK].g0.Hex = value; - state->attr_dirty[sub_cmd & CP_VAT_MASK] = true; - break; - - case CP_VAT_REG_B: - if ((sub_cmd - CP_VAT_REG_B) >= CP_NUM_VAT_REG) - { - DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_MAYBE_INVALID_CP_COMMAND); - WARN_LOG_FMT(VIDEO, "CP_VAT_REG_B: Invalid VAT {}", sub_cmd - CP_VAT_REG_B); - } - state->vtx_attr[sub_cmd & CP_VAT_MASK].g1.Hex = value; - state->attr_dirty[sub_cmd & CP_VAT_MASK] = true; - break; - - case CP_VAT_REG_C: - if ((sub_cmd - CP_VAT_REG_C) >= CP_NUM_VAT_REG) - { - DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_MAYBE_INVALID_CP_COMMAND); - WARN_LOG_FMT(VIDEO, "CP_VAT_REG_C: Invalid VAT {}", sub_cmd - CP_VAT_REG_C); - } - state->vtx_attr[sub_cmd & CP_VAT_MASK].g2.Hex = value; - state->attr_dirty[sub_cmd & CP_VAT_MASK] = true; - break; - - // Pointers to vertex arrays in GC RAM - case ARRAY_BASE: - state->array_bases[sub_cmd & CP_ARRAY_MASK] = - value & CommandProcessor::GetPhysicalAddressMask(); - state->bases_dirty = true; - break; - - case ARRAY_STRIDE: - state->array_strides[sub_cmd & CP_ARRAY_MASK] = value & 0xFF; - break; - - default: - DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_UNKNOWN_CP_COMMAND); - WARN_LOG_FMT(VIDEO, "Unknown CP register {:02x} set to {:08x}", sub_cmd, value); - } -} - -void FillCPMemoryArray(u32* memory) -{ - memory[MATINDEX_A] = g_main_cp_state.matrix_index_a.Hex; - memory[MATINDEX_B] = g_main_cp_state.matrix_index_b.Hex; - memory[VCD_LO] = g_main_cp_state.vtx_desc.low.Hex; - memory[VCD_HI] = g_main_cp_state.vtx_desc.high.Hex; - - for (int i = 0; i < CP_NUM_VAT_REG; ++i) - { - memory[CP_VAT_REG_A + i] = g_main_cp_state.vtx_attr[i].g0.Hex; - memory[CP_VAT_REG_B + i] = g_main_cp_state.vtx_attr[i].g1.Hex; - memory[CP_VAT_REG_C + i] = g_main_cp_state.vtx_attr[i].g2.Hex; - } - - for (int i = 0; i < CP_NUM_ARRAYS; ++i) - { - memory[ARRAY_BASE + i] = g_main_cp_state.array_bases[i]; - memory[ARRAY_STRIDE + i] = g_main_cp_state.array_strides[i]; - } -} |
