diff options
| author | Pokechu22 <Pokechu022@gmail.com> | 2021-04-30 14:57:12 -0700 |
|---|---|---|
| committer | Pokechu22 <Pokechu022@gmail.com> | 2021-12-18 12:51:56 -0800 |
| commit | 3aaeb2b9ef3f6b9cde69c77ecdf96e8defc996d5 (patch) | |
| tree | bacb645dba78c7acb3165407ef904a3a890eeb12 /Source/Core/VideoCommon | |
| parent | 3fc12431c5ed7a0df1e9bd4c538405a44f6561de (diff) | |
Convert OpcodeDecoder::Opcode and OpcodeDecoder::Primitive to enum class
Diffstat (limited to 'Source/Core/VideoCommon')
| -rw-r--r-- | Source/Core/VideoCommon/IndexGenerator.cpp | 30 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/IndexGenerator.h | 7 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/OpcodeDecoding.cpp | 33 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/OpcodeDecoding.h | 32 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VertexLoaderManager.cpp | 6 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VertexLoaderManager.h | 8 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VertexManagerBase.cpp | 51 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VertexManagerBase.h | 12 |
8 files changed, 107 insertions, 72 deletions
diff --git a/Source/Core/VideoCommon/IndexGenerator.cpp b/Source/Core/VideoCommon/IndexGenerator.cpp index d71f6c8292..be2dc99e3a 100644 --- a/Source/Core/VideoCommon/IndexGenerator.cpp +++ b/Source/Core/VideoCommon/IndexGenerator.cpp @@ -202,25 +202,27 @@ u16* AddPoints(u16* index_ptr, u32 num_verts, u32 index) void IndexGenerator::Init() { + using OpcodeDecoder::Primitive; + if (g_Config.backend_info.bSupportsPrimitiveRestart) { - m_primitive_table[OpcodeDecoder::GX_DRAW_QUADS] = AddQuads<true>; - m_primitive_table[OpcodeDecoder::GX_DRAW_QUADS_2] = AddQuads_nonstandard<true>; - m_primitive_table[OpcodeDecoder::GX_DRAW_TRIANGLES] = AddList<true>; - m_primitive_table[OpcodeDecoder::GX_DRAW_TRIANGLE_STRIP] = AddStrip<true>; - m_primitive_table[OpcodeDecoder::GX_DRAW_TRIANGLE_FAN] = AddFan<true>; + m_primitive_table[Primitive::GX_DRAW_QUADS] = AddQuads<true>; + m_primitive_table[Primitive::GX_DRAW_QUADS_2] = AddQuads_nonstandard<true>; + m_primitive_table[Primitive::GX_DRAW_TRIANGLES] = AddList<true>; + m_primitive_table[Primitive::GX_DRAW_TRIANGLE_STRIP] = AddStrip<true>; + m_primitive_table[Primitive::GX_DRAW_TRIANGLE_FAN] = AddFan<true>; } else { - m_primitive_table[OpcodeDecoder::GX_DRAW_QUADS] = AddQuads<false>; - m_primitive_table[OpcodeDecoder::GX_DRAW_QUADS_2] = AddQuads_nonstandard<false>; - m_primitive_table[OpcodeDecoder::GX_DRAW_TRIANGLES] = AddList<false>; - m_primitive_table[OpcodeDecoder::GX_DRAW_TRIANGLE_STRIP] = AddStrip<false>; - m_primitive_table[OpcodeDecoder::GX_DRAW_TRIANGLE_FAN] = AddFan<false>; + m_primitive_table[Primitive::GX_DRAW_QUADS] = AddQuads<false>; + m_primitive_table[Primitive::GX_DRAW_QUADS_2] = AddQuads_nonstandard<false>; + m_primitive_table[Primitive::GX_DRAW_TRIANGLES] = AddList<false>; + m_primitive_table[Primitive::GX_DRAW_TRIANGLE_STRIP] = AddStrip<false>; + m_primitive_table[Primitive::GX_DRAW_TRIANGLE_FAN] = AddFan<false>; } - m_primitive_table[OpcodeDecoder::GX_DRAW_LINES] = AddLineList; - m_primitive_table[OpcodeDecoder::GX_DRAW_LINE_STRIP] = AddLineStrip; - m_primitive_table[OpcodeDecoder::GX_DRAW_POINTS] = AddPoints; + m_primitive_table[Primitive::GX_DRAW_LINES] = AddLineList; + m_primitive_table[Primitive::GX_DRAW_LINE_STRIP] = AddLineStrip; + m_primitive_table[Primitive::GX_DRAW_POINTS] = AddPoints; } void IndexGenerator::Start(u16* index_ptr) @@ -230,7 +232,7 @@ void IndexGenerator::Start(u16* index_ptr) m_base_index = 0; } -void IndexGenerator::AddIndices(int primitive, u32 num_vertices) +void IndexGenerator::AddIndices(OpcodeDecoder::Primitive primitive, u32 num_vertices) { m_index_buffer_current = m_primitive_table[primitive](m_index_buffer_current, num_vertices, m_base_index); diff --git a/Source/Core/VideoCommon/IndexGenerator.h b/Source/Core/VideoCommon/IndexGenerator.h index 00c8f73132..32cf21e207 100644 --- a/Source/Core/VideoCommon/IndexGenerator.h +++ b/Source/Core/VideoCommon/IndexGenerator.h @@ -6,8 +6,9 @@ #pragma once -#include <array> #include "Common/CommonTypes.h" +#include "Common/EnumMap.h" +#include "VideoCommon/OpcodeDecoding.h" class IndexGenerator { @@ -15,7 +16,7 @@ public: void Init(); void Start(u16* index_ptr); - void AddIndices(int primitive, u32 num_vertices); + void AddIndices(OpcodeDecoder::Primitive primitive, u32 num_vertices); void AddExternalIndices(const u16* indices, u32 num_indices, u32 num_vertices); @@ -30,5 +31,5 @@ private: u32 m_base_index = 0; using PrimitiveFunction = u16* (*)(u16*, u32, u32); - std::array<PrimitiveFunction, 8> m_primitive_table{}; + Common::EnumMap<PrimitiveFunction, OpcodeDecoder::Primitive::GX_DRAW_POINTS> m_primitive_table{}; }; diff --git a/Source/Core/VideoCommon/OpcodeDecoding.cpp b/Source/Core/VideoCommon/OpcodeDecoding.cpp index a1abacc4c6..362afd6a7a 100644 --- a/Source/Core/VideoCommon/OpcodeDecoding.cpp +++ b/Source/Core/VideoCommon/OpcodeDecoding.cpp @@ -102,18 +102,18 @@ u8* Run(DataReader src, u32* cycles, bool in_display_list) return finish_up(); const u8 cmd_byte = src.Read<u8>(); - switch (cmd_byte) + switch (static_cast<Opcode>(cmd_byte)) { - case GX_NOP: + case Opcode::GX_NOP: total_cycles += 6; // Hm, this means that we scan over nop streams pretty slowly... break; - case GX_UNKNOWN_RESET: + case Opcode::GX_UNKNOWN_RESET: total_cycles += 6; // Datel software uses this command DEBUG_LOG_FMT(VIDEO, "GX Reset?: {:08x}", cmd_byte); break; - case GX_LOAD_CP_REG: + case Opcode::GX_LOAD_CP_REG: { if (src.size() < 1 + 4) return finish_up(); @@ -128,7 +128,7 @@ u8* Run(DataReader src, u32* cycles, bool in_display_list) } break; - case GX_LOAD_XF_REG: + case Opcode::GX_LOAD_XF_REG: { if (src.size() < 4) return finish_up(); @@ -151,10 +151,10 @@ u8* Run(DataReader src, u32* cycles, bool in_display_list) } break; - case GX_LOAD_INDX_A: // Used for position matrices - case GX_LOAD_INDX_B: // Used for normal matrices - case GX_LOAD_INDX_C: // Used for postmatrices - case GX_LOAD_INDX_D: // Used for lights + case Opcode::GX_LOAD_INDX_A: // Used for position matrices + case Opcode::GX_LOAD_INDX_B: // Used for normal matrices + case Opcode::GX_LOAD_INDX_C: // Used for postmatrices + case Opcode::GX_LOAD_INDX_D: // Used for lights { if (src.size() < 4) return finish_up(); @@ -175,7 +175,7 @@ u8* Run(DataReader src, u32* cycles, bool in_display_list) } break; - case GX_CMD_CALL_DL: + case Opcode::GX_CMD_CALL_DL: { if (src.size() < 8) return finish_up(); @@ -198,18 +198,18 @@ u8* Run(DataReader src, u32* cycles, bool in_display_list) } break; - case GX_CMD_UNKNOWN_METRICS: // zelda 4 swords calls it and checks the metrics registers after - // that + case Opcode::GX_CMD_UNKNOWN_METRICS: // zelda 4 swords calls it and checks the metrics + // registers after that total_cycles += 6; DEBUG_LOG_FMT(VIDEO, "GX 0x44: {:08x}", cmd_byte); break; - case GX_CMD_INVL_VC: // Invalidate Vertex Cache + case Opcode::GX_CMD_INVL_VC: // Invalidate Vertex Cache total_cycles += 6; DEBUG_LOG_FMT(VIDEO, "Invalidate (vertex cache?)"); break; - case GX_LOAD_BP_REG: + case Opcode::GX_LOAD_BP_REG: // In skipped_frame case: We have to let BP writes through because they set // tokens and stuff. TODO: Call a much simplified LoadBPReg instead. { @@ -242,7 +242,8 @@ u8* Run(DataReader src, u32* cycles, bool in_display_list) const u16 num_vertices = src.Read<u16>(); const int bytes = VertexLoaderManager::RunVertices( cmd_byte & GX_VAT_MASK, // Vertex loader index (0 - 7) - (cmd_byte & GX_PRIMITIVE_MASK) >> GX_PRIMITIVE_SHIFT, num_vertices, src, is_preprocess); + static_cast<Primitive>((cmd_byte & GX_PRIMITIVE_MASK) >> GX_PRIMITIVE_SHIFT), + num_vertices, src, is_preprocess); if (bytes < 0) return finish_up(); @@ -267,7 +268,7 @@ u8* Run(DataReader src, u32* cycles, bool in_display_list) // Display lists get added directly into the FIFO stream if constexpr (!is_preprocess) { - if (g_record_fifo_data && cmd_byte != GX_CMD_CALL_DL) + if (g_record_fifo_data && static_cast<Opcode>(cmd_byte) != Opcode::GX_CMD_CALL_DL) { const u8* const opcode_end = src.GetPointer(); FifoRecorder::GetInstance().WriteGPCommand(opcode_start, u32(opcode_end - opcode_start)); diff --git a/Source/Core/VideoCommon/OpcodeDecoding.h b/Source/Core/VideoCommon/OpcodeDecoding.h index 98e5a292de..df1059f221 100644 --- a/Source/Core/VideoCommon/OpcodeDecoding.h +++ b/Source/Core/VideoCommon/OpcodeDecoding.h @@ -4,6 +4,7 @@ #pragma once #include "Common/CommonTypes.h" +#include "Common/EnumFormatter.h" class DataReader; @@ -12,7 +13,7 @@ namespace OpcodeDecoder // Global flag to signal if FifoRecorder is active. extern bool g_record_fifo_data; -enum +enum class Opcode { GX_NOP = 0x00, GX_UNKNOWN_RESET = 0x01, @@ -27,20 +28,20 @@ enum GX_CMD_CALL_DL = 0x40, GX_CMD_UNKNOWN_METRICS = 0x44, - GX_CMD_INVL_VC = 0x48 -}; + GX_CMD_INVL_VC = 0x48, -enum -{ - GX_PRIMITIVE_MASK = 0x78, - GX_PRIMITIVE_SHIFT = 3, - GX_VAT_MASK = 0x07 + GX_PRIMITIVE_START = 0x80, + GX_PRIMITIVE_END = 0xbf, }; +constexpr u8 GX_PRIMITIVE_MASK = 0x78; +constexpr u32 GX_PRIMITIVE_SHIFT = 3; +constexpr u8 GX_VAT_MASK = 0x07; + // These values are the values extracted using GX_PRIMITIVE_MASK // and GX_PRIMITIVE_SHIFT. // GX_DRAW_QUADS_2 behaves the same way as GX_DRAW_QUADS. -enum +enum class Primitive : u8 { GX_DRAW_QUADS = 0x0, // 0x80 GX_DRAW_QUADS_2 = 0x1, // 0x88 @@ -58,3 +59,16 @@ template <bool is_preprocess = false> u8* Run(DataReader src, u32* cycles, bool in_display_list); } // namespace OpcodeDecoder + +template <> +struct fmt::formatter<OpcodeDecoder::Primitive> + : EnumFormatter<OpcodeDecoder::Primitive::GX_DRAW_POINTS> +{ + static constexpr array_type names = { + "GX_DRAW_QUADS", "GX_DRAW_QUADS_2 (nonstandard)", + "GX_DRAW_TRIANGLES", "GX_DRAW_TRIANGLE_STRIP", + "GX_DRAW_TRIANGLE_FAN", "GX_DRAW_LINES", + "GX_DRAW_LINE_STRIP", "GX_DRAW_POINTS", + }; + formatter() : EnumFormatter(names) {} +}; diff --git a/Source/Core/VideoCommon/VertexLoaderManager.cpp b/Source/Core/VideoCommon/VertexLoaderManager.cpp index 33af56762f..b794c5dfc0 100644 --- a/Source/Core/VideoCommon/VertexLoaderManager.cpp +++ b/Source/Core/VideoCommon/VertexLoaderManager.cpp @@ -239,7 +239,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 +267,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); diff --git a/Source/Core/VideoCommon/VertexLoaderManager.h b/Source/Core/VideoCommon/VertexLoaderManager.h index b43f0d919f..bd9066c5bb 100644 --- a/Source/Core/VideoCommon/VertexLoaderManager.h +++ b/Source/Core/VideoCommon/VertexLoaderManager.h @@ -14,6 +14,11 @@ class DataReader; class NativeVertexFormat; struct PortableVertexDeclaration; +namespace OpcodeDecoder +{ +enum class Primitive : u8; +}; + namespace VertexLoaderManager { using NativeVertexFormatMap = @@ -35,7 +40,8 @@ NativeVertexFormat* GetOrCreateMatchingFormat(const PortableVertexDeclaration& d NativeVertexFormat* GetUberVertexFormat(const PortableVertexDeclaration& decl); // Returns -1 if buf_size is insufficient, else the amount of bytes consumed -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); NativeVertexFormat* GetCurrentVertexFormat(); diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp index 63213edd3a..5fa85b2761 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/VertexManagerBase.cpp @@ -10,6 +10,7 @@ #include "Common/BitSet.h" #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" +#include "Common/EnumMap.h" #include "Common/Logging/Log.h" #include "Common/MathUtil.h" @@ -38,8 +39,10 @@ std::unique_ptr<VertexManagerBase> g_vertex_manager; +using OpcodeDecoder::Primitive; + // GX primitive -> RenderState primitive, no primitive restart -constexpr std::array<PrimitiveType, 8> primitive_from_gx{{ +constexpr Common::EnumMap<PrimitiveType, Primitive::GX_DRAW_POINTS> primitive_from_gx{ PrimitiveType::Triangles, // GX_DRAW_QUADS PrimitiveType::Triangles, // GX_DRAW_QUADS_2 PrimitiveType::Triangles, // GX_DRAW_TRIANGLES @@ -48,10 +51,10 @@ constexpr std::array<PrimitiveType, 8> primitive_from_gx{{ PrimitiveType::Lines, // GX_DRAW_LINES PrimitiveType::Lines, // GX_DRAW_LINE_STRIP PrimitiveType::Points, // GX_DRAW_POINTS -}}; +}; // GX primitive -> RenderState primitive, using primitive restart -constexpr std::array<PrimitiveType, 8> primitive_from_gx_pr{{ +constexpr Common::EnumMap<PrimitiveType, Primitive::GX_DRAW_POINTS> primitive_from_gx_pr{ PrimitiveType::TriangleStrip, // GX_DRAW_QUADS PrimitiveType::TriangleStrip, // GX_DRAW_QUADS_2 PrimitiveType::TriangleStrip, // GX_DRAW_TRIANGLES @@ -60,7 +63,7 @@ constexpr std::array<PrimitiveType, 8> primitive_from_gx_pr{{ PrimitiveType::Lines, // GX_DRAW_LINES PrimitiveType::Lines, // GX_DRAW_LINE_STRIP PrimitiveType::Points, // GX_DRAW_POINTS -}}; +}; // Due to the BT.601 standard which the GameCube is based on being a compromise // between PAL and NTSC, neither standard gets square pixels. They are each off @@ -107,13 +110,13 @@ u32 VertexManagerBase::GetRemainingSize() const return static_cast<u32>(m_end_buffer_pointer - m_cur_buffer_pointer); } -void VertexManagerBase::AddIndices(int primitive, u32 num_vertices) +void VertexManagerBase::AddIndices(OpcodeDecoder::Primitive primitive, u32 num_vertices) { m_index_generator.AddIndices(primitive, num_vertices); } -DataReader VertexManagerBase::PrepareForAdditionalData(int primitive, u32 count, u32 stride, - bool cullall) +DataReader VertexManagerBase::PrepareForAdditionalData(OpcodeDecoder::Primitive primitive, + u32 count, u32 stride, bool cullall) { // Flush all EFB pokes. Since the buffer is shared, we can't draw pokes+primitives concurrently. g_framebuffer_manager->FlushEFBPokes(); @@ -185,7 +188,7 @@ void VertexManagerBase::FlushData(u32 count, u32 stride) m_cur_buffer_pointer += count * stride; } -u32 VertexManagerBase::GetRemainingIndices(int primitive) const +u32 VertexManagerBase::GetRemainingIndices(OpcodeDecoder::Primitive primitive) const { const u32 index_len = MAXIBUFFERSIZE - m_index_generator.GetIndexLen(); @@ -193,22 +196,22 @@ u32 VertexManagerBase::GetRemainingIndices(int primitive) const { switch (primitive) { - case OpcodeDecoder::GX_DRAW_QUADS: - case OpcodeDecoder::GX_DRAW_QUADS_2: + case Primitive::GX_DRAW_QUADS: + case Primitive::GX_DRAW_QUADS_2: return index_len / 5 * 4; - case OpcodeDecoder::GX_DRAW_TRIANGLES: + case Primitive::GX_DRAW_TRIANGLES: return index_len / 4 * 3; - case OpcodeDecoder::GX_DRAW_TRIANGLE_STRIP: + case Primitive::GX_DRAW_TRIANGLE_STRIP: return index_len / 1 - 1; - case OpcodeDecoder::GX_DRAW_TRIANGLE_FAN: + case Primitive::GX_DRAW_TRIANGLE_FAN: return index_len / 6 * 4 + 1; - case OpcodeDecoder::GX_DRAW_LINES: + case Primitive::GX_DRAW_LINES: return index_len; - case OpcodeDecoder::GX_DRAW_LINE_STRIP: + case Primitive::GX_DRAW_LINE_STRIP: return index_len / 2 + 1; - case OpcodeDecoder::GX_DRAW_POINTS: + case Primitive::GX_DRAW_POINTS: return index_len; default: @@ -219,22 +222,22 @@ u32 VertexManagerBase::GetRemainingIndices(int primitive) const { switch (primitive) { - case OpcodeDecoder::GX_DRAW_QUADS: - case OpcodeDecoder::GX_DRAW_QUADS_2: + case Primitive::GX_DRAW_QUADS: + case Primitive::GX_DRAW_QUADS_2: return index_len / 6 * 4; - case OpcodeDecoder::GX_DRAW_TRIANGLES: + case Primitive::GX_DRAW_TRIANGLES: return index_len; - case OpcodeDecoder::GX_DRAW_TRIANGLE_STRIP: + case Primitive::GX_DRAW_TRIANGLE_STRIP: return index_len / 3 + 2; - case OpcodeDecoder::GX_DRAW_TRIANGLE_FAN: + case Primitive::GX_DRAW_TRIANGLE_FAN: return index_len / 3 + 2; - case OpcodeDecoder::GX_DRAW_LINES: + case Primitive::GX_DRAW_LINES: return index_len; - case OpcodeDecoder::GX_DRAW_LINE_STRIP: + case Primitive::GX_DRAW_LINE_STRIP: return index_len / 2 + 1; - case OpcodeDecoder::GX_DRAW_POINTS: + case Primitive::GX_DRAW_POINTS: return index_len; default: diff --git a/Source/Core/VideoCommon/VertexManagerBase.h b/Source/Core/VideoCommon/VertexManagerBase.h index f41be70836..b3dd49aa61 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.h +++ b/Source/Core/VideoCommon/VertexManagerBase.h @@ -35,6 +35,11 @@ enum TexelBufferFormat : u32 NUM_TEXEL_BUFFER_FORMATS }; +namespace OpcodeDecoder +{ +enum class Primitive : u8; +}; + class VertexManagerBase { private: @@ -93,8 +98,9 @@ public: virtual bool Initialize(); PrimitiveType GetCurrentPrimitiveType() const { return m_current_primitive_type; } - void AddIndices(int primitive, u32 num_vertices); - DataReader PrepareForAdditionalData(int primitive, u32 count, u32 stride, bool cullall); + void AddIndices(OpcodeDecoder::Primitive primitive, u32 num_vertices); + DataReader PrepareForAdditionalData(OpcodeDecoder::Primitive primitive, u32 count, u32 stride, + bool cullall); void FlushData(u32 count, u32 stride); void Flush(); @@ -163,7 +169,7 @@ protected: virtual void DrawCurrentBatch(u32 base_index, u32 num_indices, u32 base_vertex); u32 GetRemainingSize() const; - u32 GetRemainingIndices(int primitive) const; + u32 GetRemainingIndices(OpcodeDecoder::Primitive primitive) const; void CalculateZSlope(NativeVertexFormat* format); void LoadTextures(); |
