1 // Copyright 2018 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 <memory> 8 #include <glad/glad.h> 9 #include "video_core/rasterizer_interface.h" 10 #include "video_core/regs_lighting.h" 11 #include "video_core/renderer_opengl/gl_resource_manager.h" 12 #include "video_core/renderer_opengl/gl_shader_gen.h" 13 #include "video_core/renderer_opengl/gl_state.h" 14 #include "video_core/renderer_opengl/pica_to_gl.h" 15 16 namespace Core { 17 class System; 18 } 19 20 namespace OpenGL { 21 22 enum class UniformBindings : GLuint { Common, VS, GS }; 23 24 struct LightSrc { 25 alignas(16) GLvec3 specular_0; 26 alignas(16) GLvec3 specular_1; 27 alignas(16) GLvec3 diffuse; 28 alignas(16) GLvec3 ambient; 29 alignas(16) GLvec3 position; 30 alignas(16) GLvec3 spot_direction; // negated 31 GLfloat dist_atten_bias; 32 GLfloat dist_atten_scale; 33 }; 34 35 /// Uniform structure for the Uniform Buffer Object, all vectors must be 16-byte aligned 36 // NOTE: Always keep a vec4 at the end. The GL spec is not clear wether the alignment at 37 // the end of a uniform block is included in UNIFORM_BLOCK_DATA_SIZE or not. 38 // Not following that rule will cause problems on some AMD drivers. 39 struct UniformData { 40 GLint framebuffer_scale; 41 GLint alphatest_ref; 42 GLfloat depth_scale; 43 GLfloat depth_offset; 44 GLfloat shadow_bias_constant; 45 GLfloat shadow_bias_linear; 46 GLint scissor_x1; 47 GLint scissor_y1; 48 GLint scissor_x2; 49 GLint scissor_y2; 50 GLint fog_lut_offset; 51 GLint proctex_noise_lut_offset; 52 GLint proctex_color_map_offset; 53 GLint proctex_alpha_map_offset; 54 GLint proctex_lut_offset; 55 GLint proctex_diff_lut_offset; 56 GLfloat proctex_bias; 57 GLint shadow_texture_bias; 58 alignas(16) GLivec4 lighting_lut_offset[Pica::LightingRegs::NumLightingSampler / 4]; 59 alignas(16) GLvec3 fog_color; 60 alignas(8) GLvec2 proctex_noise_f; 61 alignas(8) GLvec2 proctex_noise_a; 62 alignas(8) GLvec2 proctex_noise_p; 63 alignas(16) GLvec3 lighting_global_ambient; 64 LightSrc light_src[8]; 65 alignas(16) GLvec4 const_color[6]; // A vec4 color for each of the six tev stages 66 alignas(16) GLvec4 tev_combiner_buffer_color; 67 alignas(16) GLvec4 clip_coef; 68 }; 69 70 static_assert( 71 sizeof(UniformData) == 0x4F0, 72 "The size of the UniformData structure has changed, update the structure in the shader"); 73 static_assert(sizeof(UniformData) < 16384, 74 "UniformData structure must be less than 16kb as per the OpenGL spec"); 75 76 /// Uniform struct for the Uniform Buffer Object that contains PICA vertex/geometry shader uniforms. 77 // NOTE: the same rule from UniformData also applies here. 78 struct PicaUniformsData { 79 void SetFromRegs(const Pica::ShaderRegs& regs, const Pica::Shader::ShaderSetup& setup); 80 81 struct BoolAligned { 82 alignas(16) GLint b; 83 }; 84 85 std::array<BoolAligned, 16> bools; 86 alignas(16) std::array<GLuvec4, 4> i; 87 alignas(16) std::array<GLvec4, 96> f; 88 }; 89 90 struct VSUniformData { 91 PicaUniformsData uniforms; 92 }; 93 static_assert( 94 sizeof(VSUniformData) == 1856, 95 "The size of the VSUniformData structure has changed, update the structure in the shader"); 96 static_assert(sizeof(VSUniformData) < 16384, 97 "VSUniformData structure must be less than 16kb as per the OpenGL spec"); 98 99 /// A class that manage different shader stages and configures them with given config data. 100 class ShaderProgramManager { 101 public: 102 ShaderProgramManager(bool separable, bool is_amd); 103 ~ShaderProgramManager(); 104 105 void LoadDiskCache(const std::atomic_bool& stop_loading, 106 const VideoCore::DiskResourceLoadCallback& callback); 107 108 bool UseProgrammableVertexShader(const Pica::Regs& config, Pica::Shader::ShaderSetup& setup); 109 110 void UseTrivialVertexShader(); 111 112 void UseFixedGeometryShader(const Pica::Regs& regs); 113 114 void UseTrivialGeometryShader(); 115 116 void UseFragmentShader(const Pica::Regs& config); 117 118 void ApplyTo(OpenGLState& state); 119 120 private: 121 class Impl; 122 std::unique_ptr<Impl> impl; 123 }; 124 } // namespace OpenGL 125