1 // Copyright 2008 Dolphin Emulator Project
2 // Licensed under GPLv2+
3 // Refer to the license.txt file included.
4 
5 #pragma once
6 
7 #include <array>
8 #include <string>
9 
10 #include "Common/GL/GLContext.h"
11 #include "Common/GL/GLExtensions/GLExtensions.h"
12 #include "VideoCommon/RenderBase.h"
13 
14 namespace OGL
15 {
16 class OGLFramebuffer;
17 class OGLPipeline;
18 class OGLTexture;
19 
20 enum GlslVersion
21 {
22   Glsl130,
23   Glsl140,
24   Glsl150,
25   Glsl330,
26   Glsl400,  // and above
27   Glsl430,
28   GlslEs300,  // GLES 3.0
29   GlslEs310,  // GLES 3.1
30   GlslEs320,  // GLES 3.2
31 };
32 enum class EsTexbufType
33 {
34   TexbufNone,
35   TexbufCore,
36   TexbufOes,
37   TexbufExt
38 };
39 
40 enum class EsFbFetchType
41 {
42   FbFetchNone,
43   FbFetchExt,
44   FbFetchArm,
45 };
46 
47 // ogl-only config, so not in VideoConfig.h
48 struct VideoConfig
49 {
50   bool bIsES;
51   bool bSupportsGLPinnedMemory;
52   bool bSupportsGLSync;
53   bool bSupportsGLBaseVertex;
54   bool bSupportsGLBufferStorage;
55   bool bSupportsMSAA;
56   GlslVersion eSupportedGLSLVersion;
57   bool bSupportViewportFloat;
58   bool bSupportsAEP;
59   bool bSupportsDebug;
60   bool bSupportsCopySubImage;
61   u8 SupportedESPointSize;
62   EsTexbufType SupportedESTextureBuffer;
63   bool bSupportsTextureStorage;
64   bool bSupports2DTextureStorageMultisample;
65   bool bSupports3DTextureStorageMultisample;
66   bool bSupportsConservativeDepth;
67   bool bSupportsImageLoadStore;
68   bool bSupportsAniso;
69   bool bSupportsBitfield;
70   bool bSupportsTextureSubImage;
71   EsFbFetchType SupportedFramebufferFetch;
72   bool bSupportsShaderThreadShuffleNV;
73 
74   const char* gl_vendor;
75   const char* gl_renderer;
76   const char* gl_version;
77 
78   s32 max_samples;
79 };
80 extern VideoConfig g_ogl_config;
81 
82 class Renderer : public ::Renderer
83 {
84 public:
85   Renderer(std::unique_ptr<GLContext> main_gl_context, float backbuffer_scale);
86   ~Renderer() override;
87 
GetInstance()88   static Renderer* GetInstance() { return static_cast<Renderer*>(g_renderer.get()); }
89 
90   bool IsHeadless() const override;
91 
92   bool Initialize() override;
93   void Shutdown() override;
94 
95   std::unique_ptr<AbstractTexture> CreateTexture(const TextureConfig& config) override;
96   std::unique_ptr<AbstractStagingTexture>
97   CreateStagingTexture(StagingTextureType type, const TextureConfig& config) override;
98   std::unique_ptr<AbstractShader> CreateShaderFromSource(ShaderStage stage,
99                                                          std::string_view source) override;
100   std::unique_ptr<AbstractShader> CreateShaderFromBinary(ShaderStage stage, const void* data,
101                                                          size_t length) override;
102   std::unique_ptr<NativeVertexFormat>
103   CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) override;
104   std::unique_ptr<AbstractPipeline> CreatePipeline(const AbstractPipelineConfig& config,
105                                                    const void* cache_data = nullptr,
106                                                    size_t cache_data_length = 0) override;
107   std::unique_ptr<AbstractFramebuffer>
108   CreateFramebuffer(AbstractTexture* color_attachment, AbstractTexture* depth_attachment) override;
109 
110   void SetPipeline(const AbstractPipeline* pipeline) override;
111   void SetFramebuffer(AbstractFramebuffer* framebuffer) override;
112   void SetAndDiscardFramebuffer(AbstractFramebuffer* framebuffer) override;
113   void SetAndClearFramebuffer(AbstractFramebuffer* framebuffer, const ClearColor& color_value = {},
114                               float depth_value = 0.0f) override;
115   void SetScissorRect(const MathUtil::Rectangle<int>& rc) override;
116   void SetTexture(u32 index, const AbstractTexture* texture) override;
117   void SetSamplerState(u32 index, const SamplerState& state) override;
118   void SetComputeImageTexture(AbstractTexture* texture, bool read, bool write) override;
119   void UnbindTexture(const AbstractTexture* texture) override;
120   void SetViewport(float x, float y, float width, float height, float near_depth,
121                    float far_depth) override;
122   void Draw(u32 base_vertex, u32 num_vertices) override;
123   void DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex) override;
124   void DispatchComputeShader(const AbstractShader* shader, u32 groups_x, u32 groups_y,
125                              u32 groups_z) override;
126   void BindBackbuffer(const ClearColor& clear_color = {}) override;
127   void PresentBackbuffer() override;
128 
129   u16 BBoxRead(int index) override;
130   void BBoxWrite(int index, u16 value) override;
131 
132   void BeginUtilityDrawing() override;
133   void EndUtilityDrawing() override;
134 
135   void Flush() override;
136   void WaitForGPUIdle() override;
137   void RenderXFBToScreen(const MathUtil::Rectangle<int>& target_rc,
138                          const AbstractTexture* source_texture,
139                          const MathUtil::Rectangle<int>& source_rc) override;
140   void OnConfigChanged(u32 bits) override;
141 
142   void ClearScreen(const MathUtil::Rectangle<int>& rc, bool colorEnable, bool alphaEnable,
143                    bool zEnable, u32 color, u32 z) override;
144 
145   std::unique_ptr<VideoCommon::AsyncShaderCompiler> CreateAsyncShaderCompiler() override;
146 
147   // Only call methods from this on the GPU thread.
GetMainGLContext()148   GLContext* GetMainGLContext() const { return m_main_gl_context.get(); }
IsGLES()149   bool IsGLES() const { return m_main_gl_context->IsGLES(); }
150 
151   // Invalidates a cached texture binding. Required for texel buffers when they borrow the units.
InvalidateTextureBinding(u32 index)152   void InvalidateTextureBinding(u32 index) { m_bound_textures[index] = nullptr; }
153 
154   // The shared framebuffer exists for copying textures when extensions are not available. It is
155   // slower, but the only way to do these things otherwise.
GetSharedReadFramebuffer()156   GLuint GetSharedReadFramebuffer() const { return m_shared_read_framebuffer; }
GetSharedDrawFramebuffer()157   GLuint GetSharedDrawFramebuffer() const { return m_shared_draw_framebuffer; }
158   void BindSharedReadFramebuffer();
159   void BindSharedDrawFramebuffer();
160 
161   // Restores FBO binding after it's been changed.
162   void RestoreFramebufferBinding();
163 
164 private:
165   void CheckForSurfaceChange();
166   void CheckForSurfaceResize();
167 
168   void ApplyRasterizationState(const RasterizationState state);
169   void ApplyDepthState(const DepthState state);
170   void ApplyBlendingState(const BlendingState state);
171 
172   std::unique_ptr<GLContext> m_main_gl_context;
173   std::unique_ptr<OGLFramebuffer> m_system_framebuffer;
174   std::array<const OGLTexture*, 8> m_bound_textures{};
175   AbstractTexture* m_bound_image_texture = nullptr;
176   RasterizationState m_current_rasterization_state;
177   DepthState m_current_depth_state;
178   BlendingState m_current_blend_state;
179   GLuint m_shared_read_framebuffer = 0;
180   GLuint m_shared_draw_framebuffer = 0;
181 };
182 }  // namespace OGL
183