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