diff options
Diffstat (limited to 'src/include/libplacebo/dispatch.h')
-rw-r--r-- | src/include/libplacebo/dispatch.h | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/src/include/libplacebo/dispatch.h b/src/include/libplacebo/dispatch.h new file mode 100644 index 0000000..7d43794 --- /dev/null +++ b/src/include/libplacebo/dispatch.h @@ -0,0 +1,239 @@ +/* + * This file is part of libplacebo. + * + * libplacebo is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libplacebo is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libplacebo. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef LIBPLACEBO_DISPATCH_H_ +#define LIBPLACEBO_DISPATCH_H_ + +#include <libplacebo/shaders.h> +#include <libplacebo/gpu.h> + +PL_API_BEGIN + +// Thread-safety: Safe +typedef struct pl_dispatch_t *pl_dispatch; + +// Creates a new shader dispatch object. This object provides a translation +// layer between generated shaders (pl_shader) and the ra context such that it +// can be used to execute shaders. This dispatch object will also provide +// shader caching (for efficient re-use). +PL_API pl_dispatch pl_dispatch_create(pl_log log, pl_gpu gpu); +PL_API void pl_dispatch_destroy(pl_dispatch *dp); + +// Reset/increments the internal counters of the pl_dispatch. This must be +// called whenever the user is going to begin with a new frame, in order to +// perform garbage collection and advance the state of the internal PRNG. +// +// Note that shaders generated by `pl_dispatch` are therefore entirely +// deterministic, as long as the sequence of calls (and inputs to the shader) +// are the same. +PL_API void pl_dispatch_reset_frame(pl_dispatch dp); + +// Returns a blank pl_shader object, suitable for recording rendering commands. +// For more information, see the header documentation in `shaders/*.h`. +PL_API pl_shader pl_dispatch_begin(pl_dispatch dp); + +// Struct passed to `info_callback`. Only valid until that function returns. +struct pl_dispatch_info { + // Information about the shader for this shader execution, as well as a + // 64-bit signature uniquely identifying it. + pl_shader_info shader; + uint64_t signature; + + // A list of execution times for this pass, in nanoseconds. May be empty. + uint64_t samples[256]; + int num_samples; + + // As a convenience, this contains the last, average and peak of the above + // list of samples. If `num_samples` is 0, these values are also 0. + uint64_t last; + uint64_t peak; + uint64_t average; +}; + +// Helper function to make a copy of `pl_dispatch_info`, while overriding +// (and dereferencing) whatever was previously stored there. +static inline void pl_dispatch_info_move(struct pl_dispatch_info *dst, + const struct pl_dispatch_info *src) +{ + pl_shader_info_deref(&dst->shader); + *dst = *src; + dst->shader = pl_shader_info_ref(src->shader); +} + +// Set up a dispatch callback for this `pl_dispatch` object. The given callback +// will be run for every successfully dispatched shader. Call this again with +// `cb == NULL` to disable. +PL_API void pl_dispatch_callback(pl_dispatch dp, void *priv, + void (*cb)(void *priv, + const struct pl_dispatch_info *)); + +struct pl_dispatch_params { + // The shader to execute. The pl_dispatch will take over ownership + // of this shader, and return it back to the internal pool. + // + // This shader must have a compatible signature, i.e. inputs + // `PL_SHADER_SIG_NONE` and outputs `PL_SHADER_SIG_COLOR`. + pl_shader *shader; + + // The texture to render to. This must have params compatible with the + // shader, i.e. `target->params.renderable` for fragment shaders and + // `target->params.storable` for compute shaders. + // + // Note: Even when not using compute shaders, users are advised to always + // set `target->params.storable` if permitted by the `pl_fmt`, since this + // allows the use of compute shaders instead of full-screen quads, which is + // faster on some platforms. + pl_tex target; + + // The target rect to render to. Optional, if left as {0}, then the + // entire texture will be rendered to. + pl_rect2d rect; + + // If set, enables and controls the blending for this pass. Optional. When + // using this with fragment shaders, `target->params.fmt->caps` must + // include `PL_FMT_CAP_BLENDABLE`. + const struct pl_blend_params *blend_params; + + // If set, records the execution time of this dispatch into the given + // timer object. Optional. + // + // Note: If this is set, `pl_dispatch` cannot internally measure the + // execution time of the shader, which means `pl_dispatch_info.samples` may + // be empty as a result. + pl_timer timer; +}; + +#define pl_dispatch_params(...) (&(struct pl_dispatch_params) { __VA_ARGS__ }) + +// Dispatch a generated shader (via the pl_shader mechanism). Returns whether +// or not the dispatch was successful. +PL_API bool pl_dispatch_finish(pl_dispatch dp, const struct pl_dispatch_params *params); + +struct pl_dispatch_compute_params { + // The shader to execute. This must be a compute shader with the input + // set to PL_SHADER_SIG_NONE. The output, if it has any, is ignored. + pl_shader *shader; + + // The number of work groups to dispatch in each dimension. If this is left + // as [0} and `width/height` are both set, the number of work groups will + // be inferred from the shader's `compute_group_sizes`. + int dispatch_size[3]; + + // If set, simulate vertex attributes (similar to `pl_dispatch_finish`) + // according to the given dimensions. The first two components of the + // thread's global ID will be interpreted as the X and Y locations. + // + // Optional, ignored if either component is left as 0. + int width, height; + + // If set, records the execution time of this dispatch into the given + // timer object. Optional. + // + // Note: If this is set, `pl_dispatch` cannot internally measure the + // execution time of the shader, which means `pl_dispatch_info.samples` may + // be empty as a result. + pl_timer timer; +}; + +#define pl_dispatch_compute_params(...) (&(struct pl_dispatch_compute_params) { __VA_ARGS__ }) + +// A variant of `pl_dispatch_finish`, this one only dispatches a compute shader +// while ignoring its output (if it has one). It's only useful for shaders +// which have otherwise observable side effects (such as updating state +// objects). +PL_API bool pl_dispatch_compute(pl_dispatch dp, const struct pl_dispatch_compute_params *params); + +enum pl_vertex_coords { + PL_COORDS_ABSOLUTE, // Absolute/integer `target` coordinates + PL_COORDS_RELATIVE, // Relative `target` coordinates in range [0, 1] + PL_COORDS_NORMALIZED, // GL-normalized coordinates in range [-1, 1] +}; + +struct pl_dispatch_vertex_params { + // The shader to execute. This must be a raster shader with the input set + // to `PL_SHADER_SIG_NONE` and the output set to `PL_SHADER_SIG_COLOR`. + // + // Additionally, the shader must not have any attached vertex attributes. + pl_shader *shader; + + // The texture to render to. Requires `target->params.renderable`. + pl_tex target; + + // The target rect to clip the rendering to. (Optional) + pl_rect2d scissors; + + // If set, enables and controls the blending for this pass. Optional. When + // enabled, `target->params.fmt->caps` must include `PL_FMT_CAP_BLENDABLE`. + const struct pl_blend_params *blend_params; + + // The description of the vertex format, including offsets. + // + // Note: `location` is ignored and can safely be left unset. + const struct pl_vertex_attrib *vertex_attribs; + int num_vertex_attribs; + size_t vertex_stride; + + // The index of the vertex position in `vertex_attribs`, as well as the + // interpretation of its contents. + int vertex_position_idx; + enum pl_vertex_coords vertex_coords; + bool vertex_flipped; // flip all vertex y coordinates + + // Type and number of vertices to render. + enum pl_prim_type vertex_type; + int vertex_count; + + // Vertex data. See `pl_pass_run_params.vertex_data`. + const void *vertex_data; + pl_buf vertex_buf; + size_t buf_offset; + + // Index data. See `pl_pass_run_params.index_data`. Optional. + const void *index_data; + enum pl_index_format index_fmt; + pl_buf index_buf; + size_t index_offset; + + // If set, records the execution time of this dispatch into the given + // timer object. Optional. + // + // Note: If this is set, `pl_dispatch` cannot internally measure the + // execution time of the shader, which means `pl_dispatch_info.samples` may + // be empty as a result. + pl_timer timer; +}; + +#define pl_dispatch_vertex_params(...) (&(struct pl_dispatch_vertex_params) { __VA_ARGS__ }) + +// Dispatch a generated shader using custom vertices, rather than using a quad +// generated by the dispatch. This allows the use of e.g. custom fragment +// shaders for things like rendering custom UI elements, or possibly doing +// advanced things like sampling from a cube map or spherical video. +PL_API bool pl_dispatch_vertex(pl_dispatch dp, const struct pl_dispatch_vertex_params *params); + +// Cancel an active shader without submitting anything. Useful, for example, +// if the shader was instead merged into a different shader. +PL_API void pl_dispatch_abort(pl_dispatch dp, pl_shader *sh); + +// Deprecated in favor of `pl_cache_save/pl_cache_load` on the `pl_cache` +// associated with the `pl_gpu` this dispatch is using. +PL_DEPRECATED PL_API size_t pl_dispatch_save(pl_dispatch dp, uint8_t *out_cache); +PL_DEPRECATED PL_API void pl_dispatch_load(pl_dispatch dp, const uint8_t *cache); + +PL_API_END + +#endif // LIBPLACEBO_DISPATCH_H |