1 // Copyright 2015 Citra Emulator Project 2 // Licensed under GPLv2 or any later version 3 // Refer to the license.txt file included. 4 5 #pragma once 6 7 #include <array> 8 #include <atomic> 9 #include <cstddef> 10 #include <map> 11 #include <memory> 12 #include <optional> 13 #include <tuple> 14 #include <utility> 15 16 #include <glad/glad.h> 17 18 #include "common/common_types.h" 19 #include "video_core/engines/const_buffer_info.h" 20 #include "video_core/engines/maxwell_3d.h" 21 #include "video_core/rasterizer_accelerated.h" 22 #include "video_core/rasterizer_interface.h" 23 #include "video_core/renderer_opengl/gl_buffer_cache.h" 24 #include "video_core/renderer_opengl/gl_device.h" 25 #include "video_core/renderer_opengl/gl_fence_manager.h" 26 #include "video_core/renderer_opengl/gl_framebuffer_cache.h" 27 #include "video_core/renderer_opengl/gl_query_cache.h" 28 #include "video_core/renderer_opengl/gl_resource_manager.h" 29 #include "video_core/renderer_opengl/gl_sampler_cache.h" 30 #include "video_core/renderer_opengl/gl_shader_cache.h" 31 #include "video_core/renderer_opengl/gl_shader_decompiler.h" 32 #include "video_core/renderer_opengl/gl_shader_manager.h" 33 #include "video_core/renderer_opengl/gl_state_tracker.h" 34 #include "video_core/renderer_opengl/gl_texture_cache.h" 35 #include "video_core/renderer_opengl/utils.h" 36 #include "video_core/shader/async_shaders.h" 37 #include "video_core/textures/texture.h" 38 39 namespace Core::Memory { 40 class Memory; 41 } 42 43 namespace Core::Frontend { 44 class EmuWindow; 45 } 46 47 namespace Tegra { 48 class MemoryManager; 49 } 50 51 namespace OpenGL { 52 53 struct ScreenInfo; 54 struct DrawParameters; 55 56 struct BindlessSSBO { 57 GLuint64EXT address; 58 GLsizei length; 59 GLsizei padding; 60 }; 61 static_assert(sizeof(BindlessSSBO) * CHAR_BIT == 128); 62 63 class RasterizerOpenGL : public VideoCore::RasterizerAccelerated { 64 public: 65 explicit RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_, 66 Core::Memory::Memory& cpu_memory_, const Device& device_, 67 ScreenInfo& screen_info_, ProgramManager& program_manager_, 68 StateTracker& state_tracker_); 69 ~RasterizerOpenGL() override; 70 71 void Draw(bool is_indexed, bool is_instanced) override; 72 void Clear() override; 73 void DispatchCompute(GPUVAddr code_addr) override; 74 void ResetCounter(VideoCore::QueryType type) override; 75 void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) override; 76 void FlushAll() override; 77 void FlushRegion(VAddr addr, u64 size) override; 78 bool MustFlushRegion(VAddr addr, u64 size) override; 79 void InvalidateRegion(VAddr addr, u64 size) override; 80 void OnCPUWrite(VAddr addr, u64 size) override; 81 void SyncGuestHost() override; 82 void SignalSemaphore(GPUVAddr addr, u32 value) override; 83 void SignalSyncPoint(u32 value) override; 84 void ReleaseFences() override; 85 void FlushAndInvalidateRegion(VAddr addr, u64 size) override; 86 void WaitForIdle() override; 87 void FlushCommands() override; 88 void TickFrame() override; 89 bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src, 90 const Tegra::Engines::Fermi2D::Regs::Surface& dst, 91 const Tegra::Engines::Fermi2D::Config& copy_config) override; 92 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, 93 u32 pixel_stride) override; 94 void LoadDiskResources(u64 title_id, const std::atomic_bool& stop_loading, 95 const VideoCore::DiskResourceLoadCallback& callback) override; 96 97 /// Returns true when there are commands queued to the OpenGL server. AnyCommandQueued()98 bool AnyCommandQueued() const { 99 return num_queued_commands > 0; 100 } 101 GetAsyncShaders()102 VideoCommon::Shader::AsyncShaders& GetAsyncShaders() { 103 return async_shaders; 104 } 105 GetAsyncShaders()106 const VideoCommon::Shader::AsyncShaders& GetAsyncShaders() const { 107 return async_shaders; 108 } 109 110 private: 111 /// Configures the color and depth framebuffer states. 112 void ConfigureFramebuffers(); 113 114 /// Configures the color and depth framebuffer for clearing. 115 void ConfigureClearFramebuffer(bool using_color, bool using_depth_stencil); 116 117 /// Configures the current constbuffers to use for the draw command. 118 void SetupDrawConstBuffers(std::size_t stage_index, Shader* shader); 119 120 /// Configures the current constbuffers to use for the kernel invocation. 121 void SetupComputeConstBuffers(Shader* kernel); 122 123 /// Configures a constant buffer. 124 void SetupConstBuffer(GLenum stage, u32 binding, const Tegra::Engines::ConstBufferInfo& buffer, 125 const ConstBufferEntry& entry, bool use_unified, 126 std::size_t unified_offset); 127 128 /// Configures the current global memory entries to use for the draw command. 129 void SetupDrawGlobalMemory(std::size_t stage_index, Shader* shader); 130 131 /// Configures the current global memory entries to use for the kernel invocation. 132 void SetupComputeGlobalMemory(Shader* kernel); 133 134 /// Configures a global memory buffer. 135 void SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& entry, GPUVAddr gpu_addr, 136 size_t size, BindlessSSBO* ssbo); 137 138 /// Configures the current textures to use for the draw command. 139 void SetupDrawTextures(std::size_t stage_index, Shader* shader); 140 141 /// Configures the textures used in a compute shader. 142 void SetupComputeTextures(Shader* kernel); 143 144 /// Configures a texture. 145 void SetupTexture(u32 binding, const Tegra::Texture::FullTextureInfo& texture, 146 const SamplerEntry& entry); 147 148 /// Configures images in a graphics shader. 149 void SetupDrawImages(std::size_t stage_index, Shader* shader); 150 151 /// Configures images in a compute shader. 152 void SetupComputeImages(Shader* shader); 153 154 /// Configures an image. 155 void SetupImage(u32 binding, const Tegra::Texture::TICEntry& tic, const ImageEntry& entry); 156 157 /// Syncs the viewport and depth range to match the guest state 158 void SyncViewport(); 159 160 /// Syncs the depth clamp state 161 void SyncDepthClamp(); 162 163 /// Syncs the clip enabled status to match the guest state 164 void SyncClipEnabled(u32 clip_mask); 165 166 /// Syncs the clip coefficients to match the guest state 167 void SyncClipCoef(); 168 169 /// Syncs the cull mode to match the guest state 170 void SyncCullMode(); 171 172 /// Syncs the primitve restart to match the guest state 173 void SyncPrimitiveRestart(); 174 175 /// Syncs the depth test state to match the guest state 176 void SyncDepthTestState(); 177 178 /// Syncs the stencil test state to match the guest state 179 void SyncStencilTestState(); 180 181 /// Syncs the blend state to match the guest state 182 void SyncBlendState(); 183 184 /// Syncs the LogicOp state to match the guest state 185 void SyncLogicOpState(); 186 187 /// Syncs the the color clamp state 188 void SyncFragmentColorClampState(); 189 190 /// Syncs the alpha coverage and alpha to one 191 void SyncMultiSampleState(); 192 193 /// Syncs the scissor test state to match the guest state 194 void SyncScissorTest(); 195 196 /// Syncs the point state to match the guest state 197 void SyncPointState(); 198 199 /// Syncs the line state to match the guest state 200 void SyncLineState(); 201 202 /// Syncs the rasterizer enable state to match the guest state 203 void SyncRasterizeEnable(); 204 205 /// Syncs polygon modes to match the guest state 206 void SyncPolygonModes(); 207 208 /// Syncs Color Mask 209 void SyncColorMask(); 210 211 /// Syncs the polygon offsets 212 void SyncPolygonOffset(); 213 214 /// Syncs the alpha test state to match the guest state 215 void SyncAlphaTest(); 216 217 /// Syncs the framebuffer sRGB state to match the guest state 218 void SyncFramebufferSRGB(); 219 220 /// Syncs transform feedback state to match guest state 221 /// @note Only valid on assembly shaders 222 void SyncTransformFeedback(); 223 224 /// Begin a transform feedback 225 void BeginTransformFeedback(GLenum primitive_mode); 226 227 /// End a transform feedback 228 void EndTransformFeedback(); 229 230 /// Check for extension that are not strictly required but are needed for correct emulation 231 void CheckExtensions(); 232 233 std::size_t CalculateVertexArraysSize() const; 234 235 std::size_t CalculateIndexBufferSize() const; 236 237 /// Updates the current vertex format 238 void SetupVertexFormat(); 239 240 void SetupVertexBuffer(); 241 void SetupVertexInstances(); 242 243 GLintptr SetupIndexBuffer(); 244 245 void SetupShaders(GLenum primitive_mode); 246 247 Tegra::GPU& gpu; 248 Tegra::Engines::Maxwell3D& maxwell3d; 249 Tegra::Engines::KeplerCompute& kepler_compute; 250 Tegra::MemoryManager& gpu_memory; 251 252 const Device& device; 253 ScreenInfo& screen_info; 254 ProgramManager& program_manager; 255 StateTracker& state_tracker; 256 257 TextureCacheOpenGL texture_cache; 258 ShaderCacheOpenGL shader_cache; 259 SamplerCacheOpenGL sampler_cache; 260 FramebufferCacheOpenGL framebuffer_cache; 261 QueryCache query_cache; 262 OGLBufferCache buffer_cache; 263 FenceManagerOpenGL fence_manager; 264 265 VideoCommon::Shader::AsyncShaders async_shaders; 266 267 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; 268 269 GLint vertex_binding = 0; 270 271 std::array<OGLBuffer, Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers> 272 transform_feedback_buffers; 273 std::bitset<Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers> 274 enabled_transform_feedback_buffers; 275 276 static constexpr std::size_t NUM_CONSTANT_BUFFERS = 277 Tegra::Engines::Maxwell3D::Regs::MaxConstBuffers * 278 Tegra::Engines::Maxwell3D::Regs::MaxShaderProgram; 279 std::array<GLuint, NUM_CONSTANT_BUFFERS> staging_cbufs{}; 280 std::size_t current_cbuf = 0; 281 OGLBuffer unified_uniform_buffer; 282 283 /// Number of commands queued to the OpenGL driver. Reseted on flush. 284 std::size_t num_queued_commands = 0; 285 286 u32 last_clip_distance_mask = 0; 287 }; 288 289 } // namespace OpenGL 290