// Copyright 2014 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include #include #include #include #include "Common/CommonTypes.h" #include "Common/MathUtil.h" #include "Common/Timer.h" #include "VideoCommon/TextureConfig.h" class AbstractPipeline; class AbstractShader; class AbstractTexture; namespace VideoCommon { class PostProcessingConfiguration { public: struct ConfigurationOption { enum OptionType { OPTION_BOOL = 0, OPTION_FLOAT, OPTION_INTEGER, }; bool m_bool_value = false; std::vector m_float_values; std::vector m_integer_values; std::vector m_float_min_values; std::vector m_integer_min_values; std::vector m_float_max_values; std::vector m_integer_max_values; std::vector m_float_step_values; std::vector m_integer_step_values; OptionType m_type = OptionType::OPTION_BOOL; std::string m_gui_name; std::string m_option_name; std::string m_dependent_option; bool m_dirty = false; }; using ConfigMap = std::map; PostProcessingConfiguration(); virtual ~PostProcessingConfiguration(); // Loads the configuration with a shader // If the argument is "" the class will load the shader from the g_activeConfig option. // Returns the loaded shader source from file void LoadShader(const std::string& shader); void LoadDefaultShader(); void SaveOptionsConfiguration(); const std::string& GetShader() const { return m_current_shader; } const std::string& GetShaderCode() const { return m_current_shader_code; } bool IsDirty() const { return m_any_options_dirty; } void SetDirty(bool dirty) { m_any_options_dirty = dirty; } bool HasOptions() const { return m_options.size() > 0; } const ConfigMap& GetOptions() const { return m_options; } ConfigMap& GetOptions() { return m_options; } const ConfigurationOption& GetOption(const std::string& option) { return m_options[option]; } // For updating option's values void SetOptionf(const std::string& option, int index, float value); void SetOptioni(const std::string& option, int index, s32 value); void SetOptionb(const std::string& option, bool value); private: bool m_any_options_dirty = false; std::string m_current_shader; std::string m_current_shader_code; ConfigMap m_options; void LoadOptions(const std::string& code); void LoadOptionsConfiguration(); }; class PostProcessing { public: PostProcessing(); virtual ~PostProcessing(); static std::vector GetShaderList(); static std::vector GetPassiveShaderList(); static std::vector GetAnaglyphShaderList(); PostProcessingConfiguration* GetConfig() { return &m_config; } bool Initialize(AbstractTextureFormat format); void RecompileShader(); void RecompilePipeline(); void BlitFromTexture(const MathUtil::Rectangle& dst, const MathUtil::Rectangle& src, const AbstractTexture* src_tex, int src_layer); protected: std::string GetUniformBufferHeader() const; std::string GetHeader() const; std::string GetFooter() const; bool CompileVertexShader(); bool CompilePixelShader(); bool CompilePipeline(); size_t CalculateUniformsSize() const; void FillUniformBuffer(const MathUtil::Rectangle& src, const AbstractTexture* src_tex, int src_layer); // Timer for determining our time value Common::Timer m_timer; PostProcessingConfiguration m_config; std::unique_ptr m_vertex_shader; std::unique_ptr m_pixel_shader; std::unique_ptr m_pipeline; AbstractTextureFormat m_framebuffer_format = AbstractTextureFormat::Undefined; std::vector m_uniform_staging_buffer; }; } // namespace VideoCommon