1 // Copyright 2010 Dolphin Emulator Project 2 // Licensed under GPLv2+ 3 // Refer to the license.txt file included. 4 5 #pragma once 6 7 #include <memory> 8 #include <vector> 9 10 #include "Common/CommonTypes.h" 11 #include "Common/MathUtil.h" 12 #include "VideoCommon/IndexGenerator.h" 13 #include "VideoCommon/RenderState.h" 14 #include "VideoCommon/ShaderCache.h" 15 16 class DataReader; 17 class NativeVertexFormat; 18 class PointerWrap; 19 struct PortableVertexDeclaration; 20 21 struct Slope 22 { 23 float dfdx; 24 float dfdy; 25 float f0; 26 bool dirty; 27 }; 28 29 // View format of the input data to the texture decoding shader. 30 enum TexelBufferFormat : u32 31 { 32 TEXEL_BUFFER_FORMAT_R8_UINT, 33 TEXEL_BUFFER_FORMAT_R16_UINT, 34 TEXEL_BUFFER_FORMAT_RGBA8_UINT, 35 TEXEL_BUFFER_FORMAT_R32G32_UINT, 36 NUM_TEXEL_BUFFER_FORMATS 37 }; 38 39 class VertexManagerBase 40 { 41 private: 42 // 3 pos 43 static constexpr u32 SMALLEST_POSSIBLE_VERTEX = sizeof(float) * 3; 44 // 3 pos, 3*3 normal, 2*u32 color, 8*4 tex, 1 posMat 45 static constexpr u32 LARGEST_POSSIBLE_VERTEX = sizeof(float) * 45 + sizeof(u32) * 2; 46 47 static constexpr u32 MAX_PRIMITIVES_PER_COMMAND = 65535; 48 49 // Used for 16:9 anamorphic widescreen heuristic. 50 struct FlushStatistics 51 { 52 struct ProjectionCounts 53 { 54 size_t normal_flush_count; 55 size_t anamorphic_flush_count; 56 size_t other_flush_count; 57 58 size_t normal_vertex_count; 59 size_t anamorphic_vertex_count; 60 size_t other_vertex_count; 61 GetTotalFlushCountFlushStatistics::ProjectionCounts62 size_t GetTotalFlushCount() const 63 { 64 return normal_flush_count + anamorphic_flush_count + other_flush_count; 65 } 66 GetTotalVertexCountFlushStatistics::ProjectionCounts67 size_t GetTotalVertexCount() const 68 { 69 return normal_vertex_count + anamorphic_vertex_count + other_vertex_count; 70 } 71 }; 72 73 ProjectionCounts perspective; 74 ProjectionCounts orthographic; 75 }; 76 77 public: 78 static constexpr u32 MAXVBUFFERSIZE = 79 MathUtil::NextPowerOf2(MAX_PRIMITIVES_PER_COMMAND * LARGEST_POSSIBLE_VERTEX); 80 81 // We may convert triangle-fans to triangle-lists, almost 3x as many indices. 82 static constexpr u32 MAXIBUFFERSIZE = MathUtil::NextPowerOf2(MAX_PRIMITIVES_PER_COMMAND * 3); 83 84 // Streaming buffer sizes. 85 // Texel buffer will fit the maximum size of an encoded GX texture. 1024x1024, RGBA8 = 4MB. 86 static constexpr u32 VERTEX_STREAM_BUFFER_SIZE = 48 * 1024 * 1024; 87 static constexpr u32 INDEX_STREAM_BUFFER_SIZE = 8 * 1024 * 1024; 88 static constexpr u32 UNIFORM_STREAM_BUFFER_SIZE = 32 * 1024 * 1024; 89 static constexpr u32 TEXEL_STREAM_BUFFER_SIZE = 16 * 1024 * 1024; 90 91 VertexManagerBase(); 92 virtual ~VertexManagerBase(); 93 94 virtual bool Initialize(); 95 GetCurrentPrimitiveType()96 PrimitiveType GetCurrentPrimitiveType() const { return m_current_primitive_type; } 97 void AddIndices(int primitive, u32 num_vertices); 98 DataReader PrepareForAdditionalData(int primitive, u32 count, u32 stride, bool cullall); 99 void FlushData(u32 count, u32 stride); 100 101 void Flush(); 102 103 void DoState(PointerWrap& p); 104 105 FlushStatistics ResetFlushAspectRatioCount(); 106 107 // State setters, called from register update functions. SetRasterizationStateChanged()108 void SetRasterizationStateChanged() { m_rasterization_state_changed = true; } SetDepthStateChanged()109 void SetDepthStateChanged() { m_depth_state_changed = true; } SetBlendingStateChanged()110 void SetBlendingStateChanged() { m_blending_state_changed = true; } InvalidatePipelineObject()111 void InvalidatePipelineObject() 112 { 113 m_current_pipeline_object = nullptr; 114 m_pipeline_config_changed = true; 115 } 116 117 // Utility pipeline drawing (e.g. EFB copies, post-processing, UI). 118 virtual void UploadUtilityUniforms(const void* uniforms, u32 uniforms_size); 119 void UploadUtilityVertices(const void* vertices, u32 vertex_stride, u32 num_vertices, 120 const u16* indices, u32 num_indices, u32* out_base_vertex, 121 u32* out_base_index); 122 123 // Determine how many bytes there are in each element of the texel buffer. 124 // Needed for alignment and stride calculations. 125 static u32 GetTexelBufferElementSize(TexelBufferFormat buffer_format); 126 127 // Texel buffer, used for palette conversion. 128 virtual bool UploadTexelBuffer(const void* data, u32 data_size, TexelBufferFormat format, 129 u32* out_offset); 130 131 // The second set of parameters uploads a second blob in the same buffer, used for GPU texture 132 // decoding for palette textures, as both the texture data and palette must be uploaded. 133 virtual bool UploadTexelBuffer(const void* data, u32 data_size, TexelBufferFormat format, 134 u32* out_offset, const void* palette_data, u32 palette_size, 135 TexelBufferFormat palette_format, u32* out_palette_offset); 136 137 // CPU access tracking - call after a draw call is made. 138 void OnDraw(); 139 140 // Call after CPU access is requested. 141 void OnCPUEFBAccess(); 142 143 // Call after an EFB copy to RAM. If true, the current command buffer should be executed. 144 void OnEFBCopyToRAM(); 145 146 // Call at the end of a frame. 147 void OnEndFrame(); 148 149 protected: 150 // When utility uniforms are used, the GX uniforms need to be re-written afterwards. 151 static void InvalidateConstants(); 152 153 // Prepares the buffer for the next batch of vertices. 154 virtual void ResetBuffer(u32 vertex_stride); 155 156 // Commits/uploads the current batch of vertices. 157 virtual void CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices, 158 u32* out_base_vertex, u32* out_base_index); 159 160 // Uploads uniform buffers for GX draws. 161 virtual void UploadUniforms(); 162 163 // Issues the draw call for the current batch in the backend. 164 virtual void DrawCurrentBatch(u32 base_index, u32 num_indices, u32 base_vertex); 165 166 u32 GetRemainingSize() const; 167 u32 GetRemainingIndices(int primitive) const; 168 169 void CalculateZSlope(NativeVertexFormat* format); 170 void LoadTextures(); 171 172 u8* m_cur_buffer_pointer = nullptr; 173 u8* m_base_buffer_pointer = nullptr; 174 u8* m_end_buffer_pointer = nullptr; 175 176 // Alternative buffers in CPU memory for primitives we are going to discard. 177 std::vector<u8> m_cpu_vertex_buffer; 178 std::vector<u16> m_cpu_index_buffer; 179 180 Slope m_zslope = {}; 181 182 VideoCommon::GXPipelineUid m_current_pipeline_config; 183 VideoCommon::GXUberPipelineUid m_current_uber_pipeline_config; 184 const AbstractPipeline* m_current_pipeline_object = nullptr; 185 PrimitiveType m_current_primitive_type = PrimitiveType::Points; 186 bool m_pipeline_config_changed = true; 187 bool m_rasterization_state_changed = true; 188 bool m_depth_state_changed = true; 189 bool m_blending_state_changed = true; 190 bool m_cull_all = false; 191 192 IndexGenerator m_index_generator; 193 194 private: 195 // Minimum number of draws per command buffer when attempting to preempt a readback operation. 196 static constexpr u32 MINIMUM_DRAW_CALLS_PER_COMMAND_BUFFER_FOR_READBACK = 10; 197 198 void UpdatePipelineConfig(); 199 void UpdatePipelineObject(); 200 201 bool m_is_flushed = true; 202 FlushStatistics m_flush_statistics = {}; 203 204 // CPU access tracking 205 u32 m_draw_counter = 0; 206 u32 m_last_efb_copy_draw_counter = 0; 207 std::vector<u32> m_cpu_accesses_this_frame; 208 std::vector<u32> m_scheduled_command_buffer_kicks; 209 bool m_allow_background_execution = true; 210 }; 211 212 extern std::unique_ptr<VertexManagerBase> g_vertex_manager; 213