1 /*  RetroArch - A frontend for libretro.
2  *  Copyright (C) 2010-2014 - Hans-Kristian Arntzen
3  *  Copyright (C) 2011-2017 - Daniel De Matteis
4  *
5  *  RetroArch is free software: you can redistribute it and/or modify it under the terms
6  *  of the GNU General Public License as published by the Free Software Found-
7  *  ation, either version 3 of the License, or (at your option) any later version.
8  *
9  *  RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10  *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11  *  PURPOSE.  See the GNU General Public License for more details.
12  *
13  *  You should have received a copy of the GNU General Public License along with RetroArch.
14  *  If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 #ifndef __VIDEO_SHADER_PARSE_H
18 #define __VIDEO_SHADER_PARSE_H
19 
20 #include <boolean.h>
21 #include <retro_common_api.h>
22 #include <retro_miscellaneous.h>
23 #include <file/config_file.h>
24 #include <file/file_path.h>
25 
26 RETRO_BEGIN_DECLS
27 
28 #ifndef GFX_MAX_SHADERS
29 #define GFX_MAX_SHADERS 64
30 #endif
31 
32 #ifndef GFX_MAX_TEXTURES
33 #define GFX_MAX_TEXTURES 64
34 #endif
35 
36 #ifndef GFX_MAX_PARAMETERS
37 #define GFX_MAX_PARAMETERS 1024
38 #endif
39 
40 #ifndef GFX_MAX_FRAME_HISTORY
41 #define GFX_MAX_FRAME_HISTORY 128
42 #endif
43 
44 enum rarch_shader_type
45 {
46    RARCH_SHADER_NONE = 0,
47    RARCH_SHADER_CG,
48    RARCH_SHADER_HLSL,
49    RARCH_SHADER_GLSL,
50    RARCH_SHADER_SLANG,
51    RARCH_SHADER_METAL
52 };
53 
54 enum gfx_scale_type
55 {
56    RARCH_SCALE_INPUT = 0,
57    RARCH_SCALE_ABSOLUTE,
58    RARCH_SCALE_VIEWPORT
59 };
60 
61 enum
62 {
63    RARCH_FILTER_UNSPEC = 0,
64    RARCH_FILTER_LINEAR,
65    RARCH_FILTER_NEAREST,
66    RARCH_FILTER_MAX
67 };
68 
69 enum gfx_wrap_type
70 {
71    RARCH_WRAP_BORDER = 0, /* Kinda deprecated, but keep as default.
72                              Will be translated to EDGE in GLES. */
73    RARCH_WRAP_DEFAULT = RARCH_WRAP_BORDER,
74    RARCH_WRAP_EDGE,
75    RARCH_WRAP_REPEAT,
76    RARCH_WRAP_MIRRORED_REPEAT,
77    RARCH_WRAP_MAX
78 };
79 
80 struct gfx_fbo_scale
81 {
82    unsigned abs_x;
83    unsigned abs_y;
84    float scale_x;
85    float scale_y;
86    enum gfx_scale_type type_x;
87    enum gfx_scale_type type_y;
88    bool fp_fbo;
89    bool srgb_fbo;
90    bool valid;
91 };
92 
93 struct video_shader_parameter
94 {
95    int pass;
96    float current;
97    float minimum;
98    float initial;
99    float maximum;
100    float step;
101    char id[64];
102    char desc[64];
103 };
104 
105 struct video_shader_pass
106 {
107    struct gfx_fbo_scale fbo; /* unsigned alignment */
108    unsigned filter;
109    unsigned frame_count_mod;
110    enum gfx_wrap_type wrap;
111    struct
112    {
113       struct
114       {
115          char *vertex; /* Dynamically allocated. Must be free'd. */
116          char *fragment; /* Dynamically allocated. Must be free'd. */
117       } string;
118       char path[PATH_MAX_LENGTH];
119    } source;
120    char alias[64];
121    bool mipmap;
122    bool feedback;
123 };
124 
125 struct video_shader_lut
126 {
127    unsigned filter;
128    enum gfx_wrap_type wrap;
129    char id[64];
130    char path[PATH_MAX_LENGTH];
131    bool mipmap;
132 };
133 
134 /* This is pretty big, shouldn't be put on the stack.
135  * Avoid lots of allocation for convenience. */
136 struct video_shader
137 {
138    struct video_shader_parameter parameters[GFX_MAX_PARAMETERS]; /* int alignment */
139    /* If < 0, no feedback pass is used. Otherwise,
140     * the FBO after pass #N is passed a texture to next frame. */
141    int feedback_pass;
142    int history_size;
143 
144    struct video_shader_pass pass[GFX_MAX_SHADERS]; /* unsigned alignment */
145    struct video_shader_lut lut[GFX_MAX_TEXTURES];  /* unsigned alignment */
146    unsigned passes;
147    unsigned luts;
148    unsigned num_parameters;
149    unsigned variables;
150 
151    char prefix[64];
152 
153    /* Path to the root preset */
154    char path[PATH_MAX_LENGTH];
155 
156    /* Path to the original preset loaded, if this is a preset with the #reference
157     * directive then this will be different than the path*/
158    char loaded_preset_path[PATH_MAX_LENGTH];
159 
160    bool modern; /* Only used for XML shaders. */
161    /* indicative of whether shader was modified -
162     * for instance from the menus */
163    bool modified;
164 };
165 
166 
167 /**
168  * video_shader_resolve_parameters:
169  * @conf              : Preset file to read from.
170  * @shader            : Shader passes handle.
171  *
172  * Resolves all shader parameters belonging to shaders
173  * from the #pragma parameter lines in the shader for each pass.
174  *
175  * Returns: true (1) if successful, otherwise false (0).
176  **/
177 bool video_shader_resolve_parameters(struct video_shader *shader);
178 
179 
180 /**
181  * video_shader_load_current_parameter_values:
182  * @conf              : Preset file to read from.
183  * @shader            : Shader passes handle.
184  *
185  * Reads the current value for all parameters from config file.
186  *
187  * Returns: true (1) if successful, otherwise false (0).
188  **/
189 bool video_shader_load_current_parameter_values(config_file_t *conf, struct video_shader *shader);
190 
191 
192 /**
193  * video_shader_load_preset_into_shader:
194  * @path              : Path to preset file, could be a Simple Preset (including a #reference) or Full Preset
195  * @shader            : Shader
196  *
197  * Loads preset file to a shader including passes, textures and parameters
198  *
199  * Returns: true (1) if successful, otherwise false (0).
200  **/
201 bool video_shader_load_preset_into_shader(const char *path, struct video_shader *shader);
202 
203 
204 /**
205  * video_shader_write_preset:
206  * @path              : File to write to
207  * @shader            : Shader to write
208  * @reference         : Whether a simple preset should be written with the #reference to another preset in it
209  *
210  * Writes a preset to disk. Can be written as a simple preset (With the #reference directive in it) or a full preset.
211  **/
212 bool video_shader_write_preset(const char *path,
213                                  const char *shader_dir,
214                                  const struct video_shader *shader,
215                                  bool reference);
216 
217 
218 enum rarch_shader_type video_shader_get_type_from_ext(const char *ext, bool *is_preset);
219 
220 /**
221  * video_shader_parse_type:
222  * @path              : Shader path.
223  *
224  * Parses type of shader.
225  *
226  * Returns: value of shader type if it could be determined,
227  * otherwise RARCH_SHADER_NONE.
228  **/
229 #define video_shader_parse_type(path) video_shader_get_type_from_ext(path_get_extension((path)), NULL)
230 
231 bool video_shader_is_supported(enum rarch_shader_type type);
232 
233 bool video_shader_any_supported(void);
234 
235 bool video_shader_check_for_changes(void);
236 
237 const char *video_shader_type_to_str(enum rarch_shader_type type);
238 
239 const char *video_shader_get_preset_extension(enum rarch_shader_type type);
240 
241 RETRO_END_DECLS
242 
243 #endif
244