VertexLoaderManager.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Copyright 2008 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <array>
  5. #include <memory>
  6. #include <string>
  7. #include <unordered_map>
  8. #include "Common/CommonTypes.h"
  9. #include "Common/EnumMap.h"
  10. #include "VideoCommon/CPMemory.h"
  11. class NativeVertexFormat;
  12. struct PortableVertexDeclaration;
  13. namespace OpcodeDecoder
  14. {
  15. enum class Primitive : u8;
  16. }
  17. namespace VertexLoaderManager
  18. {
  19. using NativeVertexFormatMap =
  20. std::unordered_map<PortableVertexDeclaration, std::unique_ptr<NativeVertexFormat>>;
  21. void Init();
  22. void Clear();
  23. void MarkAllDirty();
  24. // Creates or obtains a pointer to a VertexFormat representing decl.
  25. // If this results in a VertexFormat being created, if the game later uses a matching vertex
  26. // declaration, the one that was previously created will be used.
  27. NativeVertexFormat* GetOrCreateMatchingFormat(const PortableVertexDeclaration& decl);
  28. // For vertex ubershaders, all attributes need to be present, even when the vertex
  29. // format does not contain them. This function returns a vertex format with dummy
  30. // offsets set to the unused attributes.
  31. NativeVertexFormat* GetUberVertexFormat(const PortableVertexDeclaration& decl);
  32. // Returns -1 if buf_size is insufficient, else the amount of bytes consumed
  33. template <bool IsPreprocess = false>
  34. int RunVertices(int vtx_attr_group, OpcodeDecoder::Primitive primitive, int count, const u8* src);
  35. namespace detail
  36. {
  37. // This will look for an existing loader in the global hashmap or create a new one if there is none.
  38. // It should not be used directly because RefreshLoaders() has another cache for fast lookups.
  39. template <bool IsPreprocess = false>
  40. VertexLoaderBase* GetOrCreateLoader(int vtx_attr_group);
  41. } // namespace detail
  42. NativeVertexFormat* GetCurrentVertexFormat();
  43. // Resolved pointers to array bases. Used by vertex loaders.
  44. extern Common::EnumMap<u8*, CPArray::TexCoord7> cached_arraybases;
  45. void UpdateVertexArrayPointers();
  46. // Position cache for zfreeze (3 vertices, 4 floats each to allow SIMD overwrite).
  47. // These arrays are in reverse order.
  48. extern std::array<std::array<float, 4>, 3> position_cache;
  49. extern std::array<u32, 3> position_matrix_index_cache;
  50. // Needed for the game "LIT", which has text that has lighting enabled, but doesn't have normal
  51. // vectors. The normals from the last drawn object are used instead.
  52. // See https://bugs.dolphin-emu.org/issues/13635
  53. extern std::array<float, 4> normal_cache;
  54. // Store the tangent and binormal vectors for games that use emboss texgens when the vertex format
  55. // doesn't include them (e.g. RS2 and RS3). These too are 4 floats each for SIMD overwrites.
  56. extern std::array<float, 4> tangent_cache;
  57. extern std::array<float, 4> binormal_cache;
  58. // VB_HAS_X. Bitmask telling what vertex components are present.
  59. extern u32 g_current_components;
  60. extern BitSet8 g_main_vat_dirty;
  61. extern BitSet8 g_preprocess_vat_dirty;
  62. extern bool g_bases_dirty; // Main only
  63. extern std::array<VertexLoaderBase*, CP_NUM_VAT_REG> g_main_vertex_loaders;
  64. extern std::array<VertexLoaderBase*, CP_NUM_VAT_REG> g_preprocess_vertex_loaders;
  65. extern bool g_needs_cp_xf_consistency_check;
  66. template <bool IsPreprocess = false>
  67. VertexLoaderBase* RefreshLoader(int vtx_attr_group)
  68. {
  69. constexpr const BitSet8& attr_dirty = IsPreprocess ? g_preprocess_vat_dirty : g_main_vat_dirty;
  70. constexpr const auto& vertex_loaders =
  71. IsPreprocess ? g_preprocess_vertex_loaders : g_main_vertex_loaders;
  72. VertexLoaderBase* loader;
  73. if (!attr_dirty[vtx_attr_group]) [[likely]]
  74. {
  75. loader = vertex_loaders[vtx_attr_group];
  76. }
  77. else [[unlikely]]
  78. {
  79. loader = detail::GetOrCreateLoader<IsPreprocess>(vtx_attr_group);
  80. }
  81. // Lookup pointers for any vertex arrays.
  82. if constexpr (!IsPreprocess)
  83. UpdateVertexArrayPointers();
  84. return loader;
  85. }
  86. } // namespace VertexLoaderManager