summaryrefslogtreecommitdiffstats
path: root/src/include/libplacebo/dispatch.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/libplacebo/dispatch.h')
-rw-r--r--src/include/libplacebo/dispatch.h239
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