| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- // Copyright 2015 Citra Emulator Project
- // Licensed under GPLv2 or any later version
- // Refer to the license.txt file included.
- #pragma once
- #include <array>
- #include <cstddef>
- #include <cstring>
- #include <memory>
- #include <unordered_map>
- #include <vector>
- #include <glad/glad.h>
- #include "common/bit_field.h"
- #include "common/common_types.h"
- #include "common/hash.h"
- #include "common/vector_math.h"
- #include "video_core/rasterizer_interface.h"
- #include "video_core/renderer_opengl/gl_rasterizer_cache.h"
- #include "video_core/renderer_opengl/gl_resource_manager.h"
- #include "video_core/renderer_opengl/gl_shader_gen.h"
- #include "video_core/renderer_opengl/gl_state.h"
- #include "video_core/renderer_opengl/gl_stream_buffer.h"
- struct ScreenInfo;
- class RasterizerOpenGL : public VideoCore::RasterizerInterface {
- public:
- RasterizerOpenGL();
- ~RasterizerOpenGL() override;
- void DrawArrays() override;
- void NotifyMaxwellRegisterChanged(u32 id) override;
- void FlushAll() override;
- void FlushRegion(VAddr addr, u64 size) override;
- void InvalidateRegion(VAddr addr, u64 size) override;
- void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
- bool AccelerateDisplayTransfer(const void* config) override;
- bool AccelerateTextureCopy(const void* config) override;
- bool AccelerateFill(const void* config) override;
- bool AccelerateDisplay(const Tegra::FramebufferConfig& framebuffer, VAddr framebuffer_addr,
- u32 pixel_stride, ScreenInfo& screen_info) override;
- bool AccelerateDrawBatch(bool is_indexed) override;
- /// OpenGL shader generated for a given Maxwell register state
- struct MaxwellShader {
- /// OpenGL shader resource
- OGLProgram shader;
- };
- struct VertexShader {
- OGLShader shader;
- };
- struct FragmentShader {
- OGLShader shader;
- };
- /// Uniform structure for the Uniform Buffer Object, all vectors must be 16-byte aligned
- // NOTE: Always keep a vec4 at the end. The GL spec is not clear wether the alignment at
- // the end of a uniform block is included in UNIFORM_BLOCK_DATA_SIZE or not.
- // Not following that rule will cause problems on some AMD drivers.
- struct UniformData {};
- // static_assert(
- // sizeof(UniformData) == 0x460,
- // "The size of the UniformData structure has changed, update the structure in the shader");
- static_assert(sizeof(UniformData) < 16384,
- "UniformData structure must be less than 16kb as per the OpenGL spec");
- struct VSUniformData {};
- // static_assert(
- // sizeof(VSUniformData) == 1856,
- // "The size of the VSUniformData structure has changed, update the structure in the
- // shader");
- static_assert(sizeof(VSUniformData) < 16384,
- "VSUniformData structure must be less than 16kb as per the OpenGL spec");
- struct FSUniformData {};
- // static_assert(
- // sizeof(FSUniformData) == 1856,
- // "The size of the FSUniformData structure has changed, update the structure in the
- // shader");
- static_assert(sizeof(FSUniformData) < 16384,
- "FSUniformData structure must be less than 16kb as per the OpenGL spec");
- private:
- class SamplerInfo {
- public:
- OGLSampler sampler;
- /// Creates the sampler object, initializing its state so that it's in sync with the
- /// SamplerInfo struct.
- void Create();
- /// Syncs the sampler object with the config, updating any necessary state.
- void SyncWithConfig(const Tegra::Texture::TSCEntry& config);
- private:
- Tegra::Texture::TextureFilter mag_filter;
- Tegra::Texture::TextureFilter min_filter;
- Tegra::Texture::WrapMode wrap_u;
- Tegra::Texture::WrapMode wrap_v;
- u32 border_color_r;
- u32 border_color_g;
- u32 border_color_b;
- u32 border_color_a;
- };
- /// Binds the framebuffer color and depth surface
- void BindFramebufferSurfaces(const Surface& color_surface, const Surface& depth_surface,
- bool has_stencil);
- /// Binds the required textures to OpenGL before drawing a batch.
- void BindTextures();
- /// Syncs the viewport to match the guest state
- void SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect, u16 res_scale);
- /// Syncs the clip enabled status to match the guest state
- void SyncClipEnabled();
- /// Syncs the clip coefficients to match the guest state
- void SyncClipCoef();
- /// Sets the OpenGL shader in accordance with the current guest state
- void SetShader();
- /// Syncs the cull mode to match the guest state
- void SyncCullMode();
- /// Syncs the depth scale to match the guest state
- void SyncDepthScale();
- /// Syncs the depth offset to match the guest state
- void SyncDepthOffset();
- /// Syncs the blend enabled status to match the guest state
- void SyncBlendEnabled();
- /// Syncs the blend functions to match the guest state
- void SyncBlendFuncs();
- /// Syncs the blend color to match the guest state
- void SyncBlendColor();
- bool has_ARB_buffer_storage;
- bool has_ARB_direct_state_access;
- bool has_ARB_separate_shader_objects;
- bool has_ARB_vertex_attrib_binding;
- OpenGLState state;
- RasterizerCacheOpenGL res_cache;
- /// Shader used for test renderering - to be removed once we have emulated shaders
- MaxwellShader test_shader{};
- const MaxwellShader* current_shader{};
- bool shader_dirty{};
- struct {
- UniformData data;
- bool dirty;
- } uniform_block_data = {};
- OGLPipeline pipeline;
- OGLVertexArray sw_vao;
- OGLVertexArray hw_vao;
- std::array<bool, 16> hw_vao_enabled_attributes;
- std::array<SamplerInfo, 32> texture_samplers;
- static constexpr size_t VERTEX_BUFFER_SIZE = 128 * 1024 * 1024;
- std::unique_ptr<OGLStreamBuffer> vertex_buffer;
- OGLBuffer uniform_buffer;
- OGLFramebuffer framebuffer;
- static constexpr size_t STREAM_BUFFER_SIZE = 4 * 1024 * 1024;
- std::unique_ptr<OGLStreamBuffer> stream_buffer;
- GLsizeiptr vs_input_size;
- void AnalyzeVertexArray(bool is_indexed);
- void SetupVertexArray(u8* array_ptr, GLintptr buffer_offset);
- OGLBuffer vs_uniform_buffer;
- std::unordered_map<GLShader::MaxwellVSConfig, VertexShader*> vs_shader_map;
- std::unordered_map<std::string, VertexShader> vs_shader_cache;
- OGLShader vs_default_shader;
- void SetupVertexShader(VSUniformData* ub_ptr, GLintptr buffer_offset);
- OGLBuffer fs_uniform_buffer;
- std::unordered_map<GLShader::MaxwellFSConfig, FragmentShader*> fs_shader_map;
- std::unordered_map<std::string, FragmentShader> fs_shader_cache;
- OGLShader fs_default_shader;
- void SetupFragmentShader(FSUniformData* ub_ptr, GLintptr buffer_offset);
- enum class AccelDraw { Disabled, Arrays, Indexed };
- AccelDraw accelerate_draw;
- };
|