duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

postprocessing.h (4979B)


      1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
      2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
      3 
      4 #pragma once
      5 
      6 #include "gpu_device.h"
      7 
      8 #include <array>
      9 #include <memory>
     10 #include <mutex>
     11 #include <string_view>
     12 #include <vector>
     13 
     14 namespace Common {
     15 class Timer;
     16 }
     17 
     18 class GPUSampler;
     19 class GPUTexture;
     20 
     21 class Error;
     22 class SettingsInterface;
     23 class ProgressCallback;
     24 
     25 namespace PostProcessing {
     26 class Shader;
     27 
     28 struct ShaderOption
     29 {
     30   enum : u32
     31   {
     32     MAX_VECTOR_COMPONENTS = 4
     33   };
     34 
     35   enum class Type
     36   {
     37     Invalid,
     38     Bool,
     39     Int,
     40     Float
     41   };
     42 
     43   union Value
     44   {
     45     s32 int_value;
     46     float float_value;
     47   };
     48   static_assert(sizeof(Value) == sizeof(u32));
     49 
     50   using ValueVector = std::array<Value, MAX_VECTOR_COMPONENTS>;
     51   static_assert(sizeof(ValueVector) == sizeof(u32) * MAX_VECTOR_COMPONENTS);
     52 
     53   std::string name;
     54   std::string ui_name;
     55   std::string dependent_option;
     56   std::string category;
     57   std::string tooltip;
     58   Type type;
     59   u32 vector_size;
     60   u32 buffer_size;
     61   u32 buffer_offset;
     62   ValueVector default_value;
     63   ValueVector min_value;
     64   ValueVector max_value;
     65   ValueVector step_value;
     66   ValueVector value;
     67   std::vector<std::string> choice_options;
     68 
     69   static u32 ParseIntVector(std::string_view line, ValueVector* values);
     70   static u32 ParseFloatVector(std::string_view line, ValueVector* values);
     71 
     72   static constexpr ValueVector MakeIntVector(s32 x, s32 y = 0, s32 z = 0, s32 w = 0)
     73   {
     74     ValueVector ret = {};
     75     ret[0].int_value = x;
     76     ret[1].int_value = y;
     77     ret[2].int_value = z;
     78     ret[3].int_value = w;
     79     return ret;
     80   }
     81 
     82   static constexpr ValueVector MakeFloatVector(float x, float y = 0, float z = 0, float w = 0)
     83   {
     84     ValueVector ret = {};
     85     ret[0].float_value = x;
     86     ret[1].float_value = y;
     87     ret[2].float_value = z;
     88     ret[3].float_value = w;
     89     return ret;
     90   }
     91 };
     92 
     93 namespace Config {
     94 static constexpr const char* DISPLAY_CHAIN_SECTION = "PostProcessing";
     95 static constexpr const char* INTERNAL_CHAIN_SECTION = "InternalPostProcessing";
     96 
     97 u32 GetStageCount(const SettingsInterface& si, const char* section);
     98 std::string GetStageShaderName(const SettingsInterface& si, const char* section, u32 index);
     99 std::vector<ShaderOption> GetStageOptions(const SettingsInterface& si, const char* section, u32 index);
    100 std::vector<ShaderOption> GetShaderOptions(const std::string& shader_name, Error* error);
    101 
    102 bool AddStage(SettingsInterface& si, const char* section, const std::string& shader_name, Error* error);
    103 void RemoveStage(SettingsInterface& si, const char* section, u32 index);
    104 void MoveStageUp(SettingsInterface& si, const char* section, u32 index);
    105 void MoveStageDown(SettingsInterface& si, const char* section, u32 index);
    106 void SetStageOption(SettingsInterface& si, const char* section, u32 index, const ShaderOption& option);
    107 void UnsetStageOption(SettingsInterface& si, const char* section, u32 index, const ShaderOption& option);
    108 void ClearStages(SettingsInterface& si, const char* section);
    109 } // namespace Config
    110 
    111 class Chain
    112 {
    113 public:
    114   Chain(const char* section);
    115   ~Chain();
    116 
    117   ALWAYS_INLINE bool HasStages() const { return m_stages.empty(); }
    118   ALWAYS_INLINE bool NeedsDepthBuffer() const { return m_needs_depth_buffer; }
    119   ALWAYS_INLINE GPUTexture* GetInputTexture() const { return m_input_texture.get(); }
    120   ALWAYS_INLINE GPUTexture* GetOutputTexture() const { return m_output_texture.get(); }
    121 
    122   bool IsActive() const;
    123   bool IsInternalChain() const;
    124 
    125   void UpdateSettings(std::unique_lock<std::mutex>& settings_lock);
    126 
    127   void LoadStages();
    128   void ClearStages();
    129   void DestroyTextures();
    130 
    131   /// Temporarily toggles post-processing on/off.
    132   void Toggle();
    133 
    134   bool CheckTargets(GPUTexture::Format target_format, u32 target_width, u32 target_height,
    135                     ProgressCallback* progress = nullptr);
    136 
    137   bool Apply(GPUTexture* input_color, GPUTexture* input_depth, GPUTexture* final_target, const GSVector4i final_rect,
    138              s32 orig_width, s32 orig_height, s32 native_width, s32 native_height);
    139 
    140 private:
    141   void ClearStagesWithError(const Error& error);
    142 
    143   const char* m_section;
    144 
    145   GPUTexture::Format m_target_format = GPUTexture::Format::Unknown;
    146   u32 m_target_width = 0;
    147   u32 m_target_height = 0;
    148   bool m_enabled = false;
    149   bool m_wants_depth_buffer = false;
    150   bool m_needs_depth_buffer = false;
    151 
    152   std::vector<std::unique_ptr<PostProcessing::Shader>> m_stages;
    153   std::unique_ptr<GPUTexture> m_input_texture;
    154   std::unique_ptr<GPUTexture> m_output_texture;
    155 };
    156 
    157 // [display_name, filename]
    158 std::vector<std::pair<std::string, std::string>> GetAvailableShaderNames();
    159 
    160 void Initialize();
    161 
    162 /// Reloads configuration.
    163 void UpdateSettings();
    164 
    165 /// Reloads post processing shaders with the current configuration.
    166 bool ReloadShaders();
    167 
    168 void Shutdown();
    169 
    170 GPUSampler* GetSampler(const GPUSampler::Config& config);
    171 GPUTexture* GetDummyTexture();
    172 
    173 const Common::Timer& GetTimer();
    174 
    175 extern Chain DisplayChain;
    176 extern Chain InternalChain;
    177 
    178 }; // namespace PostProcessing