240 lines
9.6 KiB
C
240 lines
9.6 KiB
C
/*
|
|
* 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
|