From 6e3222363c6c8024b446329a9760608abe5ec49e Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 19 Mar 2018 23:00:59 -0400 Subject: renderer_gl: Port boilerplate rasterizer code over from Citra. --- src/video_core/renderer_opengl/gl_rasterizer.h | 162 +++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 src/video_core/renderer_opengl/gl_rasterizer.h (limited to 'src/video_core/renderer_opengl/gl_rasterizer.h') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h new file mode 100644 index 000000000..893fc530f --- /dev/null +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -0,0 +1,162 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#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 DrawTriangles() override; + void NotifyMaxwellRegisterChanged(u32 id) override; + void FlushAll() override; + void FlushRegion(PAddr addr, u32 size) override; + void InvalidateRegion(PAddr addr, u32 size) override; + void FlushAndInvalidateRegion(PAddr addr, u32 size) override; + bool AccelerateDisplayTransfer(const void* config) override; + bool AccelerateTextureCopy(const void* config) override; + bool AccelerateFill(const void* config) override; + bool AccelerateDisplay(const void* config, PAddr framebuffer_addr, u32 pixel_stride, + ScreenInfo& screen_info) override; + bool AccelerateDrawBatch(bool is_indexed) override; + + 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: + struct SamplerInfo {}; + + /// 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; + + struct { + UniformData data; + bool dirty; + } uniform_block_data = {}; + + OGLPipeline pipeline; + OGLVertexArray sw_vao; + OGLVertexArray hw_vao; + std::array hw_vao_enabled_attributes; + + std::array texture_samplers; + static constexpr size_t VERTEX_BUFFER_SIZE = 128 * 1024 * 1024; + std::unique_ptr vertex_buffer; + OGLBuffer uniform_buffer; + OGLFramebuffer framebuffer; + + static constexpr size_t STREAM_BUFFER_SIZE = 4 * 1024 * 1024; + std::unique_ptr stream_buffer; + + GLint vs_input_index_min; + GLint vs_input_index_max; + GLsizeiptr vs_input_size; + + void AnalyzeVertexArray(bool is_indexed); + void SetupVertexArray(u8* array_ptr, GLintptr buffer_offset); + + OGLBuffer vs_uniform_buffer; + std::unordered_map vs_shader_map; + std::unordered_map vs_shader_cache; + OGLShader vs_default_shader; + + void SetupVertexShader(VSUniformData* ub_ptr, GLintptr buffer_offset); + + OGLBuffer fs_uniform_buffer; + std::unordered_map fs_shader_map; + std::unordered_map fs_shader_cache; + OGLShader fs_default_shader; + + void SetupFragmentShader(FSUniformData* ub_ptr, GLintptr buffer_offset); + + enum class AccelDraw { Disabled, Arrays, Indexed }; + AccelDraw accelerate_draw; +}; -- cgit v1.2.3