1 /*
2  * This file is part of libplacebo.
3  *
4  * libplacebo is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * libplacebo is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with libplacebo.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef LIBPLACEBO_SHADERS_H_
19 #define LIBPLACEBO_SHADERS_H_
20 
21 // This function defines the "direct" interface to libplacebo's GLSL shaders,
22 // suitable for use in contexts where the user controls GLSL shader compilation
23 // but wishes to include functions generated by libplacebo as part of their
24 // own rendering process. This API is normally not used for operation with
25 // libplacebo's higher-level constructs such as `pl_dispatch` or `pl_renderer`.
26 
27 #include <libplacebo/gpu.h>
28 
29 PL_API_BEGIN
30 
31 // Thread-safety: Unsafe
32 typedef PL_STRUCT(pl_shader) *pl_shader;
33 
34 struct pl_shader_params {
35     // The `id` represents an abstract identifier for the shader, to avoid
36     // collisions with other shaders being used as part of the same larger,
37     // overarching shader. This is relevant for users which want to combine
38     // multiple `pl_shader` objects together, in which case all `pl_shader`
39     // objects should have a unique `id`.
40     uint8_t id;
41 
42     // If `gpu` is non-NULL, then this `gpu` will be used to create objects
43     // such as textures and buffers, or check for required capabilities, for
44     // operations which depend on either of those. This is fully optional, i.e.
45     // these GLSL primitives are designed to be used without a dependency on
46     // `gpu` wherever possible - however, some features may not work, and will
47     // be disabled even if requested.
48     pl_gpu gpu;
49 
50     // The `index` represents an abstract frame index, which shaders may use
51     // internally to do things like temporal dithering or seeding PRNGs. If the
52     // user does not care about temporal dithering/debanding, or wants
53     // deterministic rendering, this may safely be left as 0. Otherwise, it
54     // should be incremented by 1 on successive frames.
55     uint8_t index;
56 
57     // If `glsl.version` is nonzero, then this structure will be used to
58     // determine the effective GLSL mode and capabilities. If `gpu` is also
59     // set, then this overrides `gpu->glsl`.
60     struct pl_glsl_version glsl;
61 
62     // If this is true, all constants in the shader will be replaced by
63     // dynaminic variables. This is mainly useful to avoid recompilation for
64     // shaders which expect to have their values change constantly.
65     bool dynamic_constants;
66 };
67 
68 // Creates a new, blank, mutable pl_shader object.
69 //
70 // Note: Rather than allocating and destroying many shaders, users are
71 // encouraged to reuse them (using `pl_shader_reset`) for efficiency.
72 pl_shader pl_shader_alloc(pl_log log, const struct pl_shader_params *params);
73 
74 // Frees a pl_shader and all resources associated with it.
75 void pl_shader_free(pl_shader *sh);
76 
77 // Resets a pl_shader to a blank slate, without releasing internal memory.
78 // If you're going to be re-generating shaders often, this function will let
79 // you skip the re-allocation overhead.
80 void pl_shader_reset(pl_shader sh, const struct pl_shader_params *params);
81 
82 // Returns whether or not a shader is in a "failed" state. Trying to modify a
83 // shader in illegal ways (e.g. signature mismatch) will result in the shader
84 // being marked as "failed". Since most pl_shader_ operations have a void
85 // return type, the user can use this function to figure out whether a specific
86 // shader operation has failed or not. This function is somewhat redundant
87 // since `pl_shader_finalize` will also return NULL in this case.
88 bool pl_shader_is_failed(const pl_shader sh);
89 
90 // Returns whether or not a pl_shader needs to be run as a compute shader. This
91 // will never be the case unless the `pl_glsl_version` this `pl_shader` was
92 // created using has `compute` support enabled.
93 bool pl_shader_is_compute(const pl_shader sh);
94 
95 // Returns whether or not the shader has any particular output size
96 // requirements. Some shaders, in particular those that sample from other
97 // textures, have specific output size requirements which need to be respected
98 // by the caller. If this is false, then the shader is compatible with every
99 // output size. If true, the size requirements are stored into *w and *h.
100 bool pl_shader_output_size(const pl_shader sh, int *w, int *h);
101 
102 // Indicates the type of signature that is associated with a shader result.
103 // Every shader result defines a function that may be called by the user, and
104 // this enum indicates the type of value that this function takes and/or
105 // returns.
106 //
107 // Which signature a shader ends up with depends on the type of operation being
108 // performed by a shader fragment, as determined by the user's calls. See below
109 // for more information.
110 enum pl_shader_sig {
111     PL_SHADER_SIG_NONE = 0, // no input / void output
112     PL_SHADER_SIG_COLOR,    // vec4 color (normalized so that 1.0 is the ref white)
113 
114     // The following are only valid as input signatures:
115     PL_SHADER_SIG_SAMPLER, // (gsampler* src_tex, vecN tex_coord) pair,
116                            // specifics depend on how the shader was generated
117 };
118 
119 // Represents a finalized shader fragment. This is not a complete shader, but a
120 // collection of raw shader text together with description of the input
121 // attributes, variables and vertices it expects to be available.
122 struct pl_shader_res {
123     // A copy of the parameters used to create the shader.
124     struct pl_shader_params params;
125 
126     // A list of friendly names for the semantic operations being performed by
127     // this shader, e.g. "color decoding" or "debanding".
128     const char **steps;
129     int num_steps;
130 
131     // As a convenience, this contains a pretty-printed version of the
132     // above list, with entries tallied and separated by commas
133     const char *description;
134 
135     // The shader text, as literal GLSL. This will always be a function
136     // definition, such that the the function with the indicated name and
137     // signature may be called by the user.
138     const char *glsl;
139     const char *name;
140     enum pl_shader_sig input;  // what the function expects
141     enum pl_shader_sig output; // what the function returns
142 
143     // For compute shaders (pl_shader_is_compute), this indicates the requested
144     // work group size. Otherwise, both fields are 0. The interpretation of
145     // these work groups is that they're tiled across the output image.
146     int compute_group_size[2];
147 
148     // If this pass is a compute shader, this field indicates the shared memory
149     // size requirements for this shader pass.
150     size_t compute_shmem;
151 
152     // A set of input vertex attributes needed by this shader fragment.
153     const struct pl_shader_va *vertex_attribs;
154     int num_vertex_attribs;
155 
156     // A set of input variables needed by this shader fragment.
157     const struct pl_shader_var *variables;
158     int num_variables;
159 
160     // A list of input descriptors needed by this shader fragment,
161     const struct pl_shader_desc *descriptors;
162     int num_descriptors;
163 
164     // A list of compile-time constants used by this shader fragment.
165     const struct pl_shader_const *constants;
166     int num_constants;
167 };
168 
169 // Represents a vertex attribute. The four values will be bound to the four
170 // corner vertices respectively, in row-wise order starting from the top left:
171 //   data[0] data[1]
172 //   data[2] data[3]
173 struct pl_shader_va {
174     struct pl_vertex_attrib attr; // VA type, excluding `offset` and `location`
175     const void *data[4];
176 };
177 
178 // Represents a bound shared variable / descriptor
179 struct pl_shader_var {
180     struct pl_var var;  // the underlying variable description
181     const void *data;   // the raw data (as per `pl_var_host_layout`)
182     bool dynamic;       // if true, the value is expected to change frequently
183 };
184 
185 struct pl_buffer_var {
186     struct pl_var var;
187     struct pl_var_layout layout;
188 };
189 
190 typedef uint16_t pl_memory_qualifiers;
191 enum {
192     PL_MEMORY_COHERENT  = 1 << 0, // supports synchronization across shader invocations
193     PL_MEMORY_VOLATILE  = 1 << 1, // all writes are synchronized automatically
194 
195     // Note: All descriptors are also implicitly assumed to have the 'restrict'
196     // memory qualifier. There is currently no way to override this behavior.
197 };
198 
199 struct pl_shader_desc {
200     struct pl_desc desc; // descriptor type, excluding `int binding`
201     struct pl_desc_binding binding; // contents of the descriptor binding
202 
203     // For PL_DESC_BUF_UNIFORM/STORAGE, this specifies the layout of the
204     // variables contained by a buffer. Ignored for the other descriptor types
205     struct pl_buffer_var *buffer_vars;
206     int num_buffer_vars;
207 
208     // For storage images and buffers, this specifies additional memory
209     // qualifiers on the descriptor. It's highly recommended to always use
210     // at least PL_MEMORY_RESTRICT. Ignored for other descriptor types.
211     pl_memory_qualifiers memory;
212 
213     // Deprecated. Moved to `binding.object`. Still used as a fallback.
214     const void *object PL_DEPRECATED;
215 };
216 
217 // Represents a compile-time constant. This can be lowered to a specialization
218 // constant to support cheaper recompilations.
219 struct pl_shader_const {
220     enum pl_var_type type;
221     const char *name;
222     const void *data;
223 
224     // If true, this constant *must* be a compile-time constant, which
225     // basically just overrides `pl_shader_params.dynamic_constants`. Useful
226     // for constants which will serve as inputs to e.g. array sizes.
227     bool compile_time;
228 };
229 
230 // Finalize a pl_shader. It is no longer mutable at this point, and any further
231 // attempts to modify it result in an error. (Functions which take a `const
232 // pl_shader` argument do not modify the shader and may be freely
233 // called on an already-finalized shader)
234 //
235 // The returned pl_shader_res is bound to the lifetime of the pl_shader - and
236 // will only remain valid until the pl_shader is freed or reset. This function
237 // may be called multiple times, and will produce the same result each time.
238 //
239 // This function will return NULL if the shader is considered to be in a
240 // "failed" state (see pl_shader_is_failed).
241 const struct pl_shader_res *pl_shader_finalize(pl_shader sh);
242 
243 // Shader objects represent abstract resources that shaders need to manage in
244 // order to ensure their operation. This could include shader storage buffers,
245 // generated lookup textures, or other sorts of configured state. The body
246 // of a shader object is fully opaque; but the user is in charge of cleaning up
247 // after them and passing them to the right shader passes.
248 //
249 // Note: pl_shader_obj objects must be initialized to NULL by the caller.
250 typedef PL_STRUCT(pl_shader_obj) *pl_shader_obj;
251 
252 void pl_shader_obj_destroy(pl_shader_obj *obj);
253 
254 PL_API_END
255 
256 #endif // LIBPLACEBO_SHADERS_H_
257