Branch data Line data Source code
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 : : #pragma once 19 : : 20 : : #include "common.h" 21 : : #include "log.h" 22 : : 23 : : #include <libplacebo/gpu.h> 24 : : #include <libplacebo/dispatch.h> 25 : : 26 : : // To avoid having to include drm_fourcc.h 27 : : #ifndef DRM_FORMAT_MOD_LINEAR 28 : : #define DRM_FORMAT_MOD_LINEAR UINT64_C(0x0) 29 : : #define DRM_FORMAT_MOD_INVALID ((UINT64_C(1) << 56) - 1) 30 : : #endif 31 : : 32 : : // This struct must be the first member of the gpu's priv struct. The `pl_gpu` 33 : : // helpers will cast the priv struct to this struct! 34 : : 35 : : #define GPU_PFN(name) __typeof__(pl_##name) *name 36 : : struct pl_gpu_fns { 37 : : // This is a pl_dispatch used (on the pl_gpu itself!) for the purposes of 38 : : // dispatching compute shaders for performing various emulation tasks (e.g. 39 : : // partial clears, blits or emulated texture transfers, see below). 40 : : // 41 : : // Warning: Care must be taken to avoid recursive calls. 42 : : pl_dispatch dp; 43 : : 44 : : // Internal cache, or NULL. Set by the user (via pl_gpu_set_cache). 45 : : _Atomic(pl_cache) cache; 46 : : 47 : : // Destructors: These also free the corresponding objects, but they 48 : : // must not be called on NULL. (The NULL checks are done by the pl_*_destroy 49 : : // wrappers) 50 : : void (*destroy)(pl_gpu gpu); 51 : : void (*tex_destroy)(pl_gpu, pl_tex); 52 : : void (*buf_destroy)(pl_gpu, pl_buf); 53 : : void (*pass_destroy)(pl_gpu, pl_pass); 54 : : void (*timer_destroy)(pl_gpu, pl_timer); 55 : : 56 : : GPU_PFN(tex_create); 57 : : GPU_PFN(tex_invalidate); // optional 58 : : GPU_PFN(tex_clear_ex); // optional if no blittable formats 59 : : GPU_PFN(tex_blit); // optional if no blittable formats 60 : : GPU_PFN(tex_upload); 61 : : GPU_PFN(tex_download); 62 : : GPU_PFN(tex_poll); // optional: if NULL, textures are always free to use 63 : : GPU_PFN(buf_create); 64 : : GPU_PFN(buf_write); 65 : : GPU_PFN(buf_read); 66 : : GPU_PFN(buf_copy); 67 : : GPU_PFN(buf_export); // optional if !gpu->export_caps.buf 68 : : GPU_PFN(buf_poll); // optional: if NULL, buffers are always free to use 69 : : GPU_PFN(desc_namespace); 70 : : GPU_PFN(pass_create); 71 : : GPU_PFN(pass_run); 72 : : GPU_PFN(timer_create); // optional 73 : : GPU_PFN(timer_query); // optional 74 : : GPU_PFN(gpu_flush); // optional 75 : : GPU_PFN(gpu_finish); 76 : : GPU_PFN(gpu_is_failed); // optional 77 : : }; 78 : : #undef GPU_PFN 79 : : 80 : : // All resources such as textures and buffers allocated from the GPU must be 81 : : // destroyed before calling pl_destroy. 82 : : void pl_gpu_destroy(pl_gpu gpu); 83 : : 84 : : // Returns true if the device supports interop. This is considered to be 85 : : // the case if at least one of `gpu->export/import_caps` is nonzero. 86 : : static inline bool pl_gpu_supports_interop(pl_gpu gpu) 87 : : { 88 : 14 : return gpu->export_caps.tex || 89 [ - + ]: 2 : gpu->import_caps.tex || 90 [ - + ]: 2 : gpu->export_caps.buf || 91 [ - + # # ]: 2 : gpu->import_caps.buf || 92 [ + + - + ]: 14 : gpu->export_caps.sync || 93 [ - + ]: 2 : gpu->import_caps.sync; 94 : : } 95 : : 96 : : // Returns the GPU-internal `pl_dispatch` and `pl_cache` objects. 97 : : pl_dispatch pl_gpu_dispatch(pl_gpu gpu); 98 : : pl_cache pl_gpu_cache(pl_gpu gpu); 99 : : 100 : : // GPU-internal helpers: these should not be used outside of GPU implementations 101 : : 102 : : // This performs several tasks. It sorts the format list, logs GPU metadata, 103 : : // performs verification and fixes up backwards compatibility fields. This 104 : : // should be returned as the last step when creating a `pl_gpu`. 105 : : pl_gpu pl_gpu_finalize(struct pl_gpu_t *gpu); 106 : : 107 : : // Look up the right GLSL image format qualifier from a partially filled-in 108 : : // pl_fmt, or NULL if the format does not have a legal matching GLSL name. 109 : : // 110 : : // `components` may differ from fmt->num_components (for emulated formats) 111 : : const char *pl_fmt_glsl_format(pl_fmt fmt, int components); 112 : : 113 : : // Look up the right fourcc from a partially filled-in pl_fmt, or 0 if the 114 : : // format does not have a legal matching fourcc format. 115 : : uint32_t pl_fmt_fourcc(pl_fmt fmt); 116 : : 117 : : // Compute the total size (in bytes) of a texture transfer operation 118 : : size_t pl_tex_transfer_size(const struct pl_tex_transfer_params *par); 119 : : 120 : : // Split a tex transfer into slices. For emulated formats, `texel_fmt` gives 121 : : // the format of the underlying texel buffer. 122 : : // 123 : : // Returns the number of slices, or 0 on error (e.g. no SSBOs available). 124 : : // `out_slices` must be freed by caller (on success). 125 : : int pl_tex_transfer_slices(pl_gpu gpu, pl_fmt texel_fmt, 126 : : const struct pl_tex_transfer_params *params, 127 : : struct pl_tex_transfer_params **out_slices); 128 : : 129 : : // Helper that wraps pl_tex_upload/download using texture upload buffers to 130 : : // ensure that params->buf is always set. 131 : : bool pl_tex_upload_pbo(pl_gpu gpu, const struct pl_tex_transfer_params *params); 132 : : bool pl_tex_download_pbo(pl_gpu gpu, const struct pl_tex_transfer_params *params); 133 : : 134 : : // This requires that params.buf has been set and is of type PL_BUF_TEXEL_* 135 : : bool pl_tex_upload_texel(pl_gpu gpu, const struct pl_tex_transfer_params *params); 136 : : bool pl_tex_download_texel(pl_gpu gpu, const struct pl_tex_transfer_params *params); 137 : : 138 : : // Both `src` and `dst must be storable. `src` must also be sampleable, if the 139 : : // blit requires linear sampling. Returns false if these conditions are unmet. 140 : : bool pl_tex_blit_compute(pl_gpu gpu, const struct pl_tex_blit_params *params); 141 : : 142 : : // Helper to do a 2D blit with stretch and scale using a raster pass 143 : : void pl_tex_blit_raster(pl_gpu gpu, const struct pl_tex_blit_params *params); 144 : : 145 : : // Helper for GPU-accelerated endian swapping 146 : : // 147 : : // Note: `src` and `dst` can be the same buffer, for an in-place operation. In 148 : : // this case, `src_offset` and `dst_offset` must be the same. 149 : : struct pl_buf_copy_swap_params { 150 : : // Source of the copy operation. Must be `storable`. 151 : : pl_buf src; 152 : : size_t src_offset; 153 : : 154 : : // Destination of the copy operation. Must be `storable`. 155 : : pl_buf dst; 156 : : size_t dst_offset; 157 : : 158 : : // Number of bytes to copy. Must be a multiple of 4. 159 : : size_t size; 160 : : 161 : : // Underlying word size. Must be 2 (for 16-bit swap) or 4 (for 32-bit swap) 162 : : int wordsize; 163 : : }; 164 : : 165 : : bool pl_buf_copy_swap(pl_gpu gpu, const struct pl_buf_copy_swap_params *params); 166 : : 167 : : void pl_pass_run_vbo(pl_gpu gpu, const struct pl_pass_run_params *params); 168 : : 169 : : // Make a deep-copy of the pass params. Note: cached_program etc. are not 170 : : // copied, but cleared explicitly. 171 : : struct pl_pass_params pl_pass_params_copy(void *alloc, const struct pl_pass_params *params); 172 : : 173 : : // Helper to compute the size of an index buffer 174 : 23 : static inline size_t pl_index_buf_size(const struct pl_pass_run_params *params) 175 : : { 176 [ + - - ]: 23 : switch (params->index_fmt) { 177 : 23 : case PL_INDEX_UINT16: return params->vertex_count * sizeof(uint16_t); 178 : 0 : case PL_INDEX_UINT32: return params->vertex_count * sizeof(uint32_t); 179 : : case PL_INDEX_FORMAT_COUNT: break; 180 : : } 181 : : 182 : 0 : pl_unreachable(); 183 : : } 184 : : 185 : : // Helper to compute the size of a vertex buffer required to fit all indices 186 : : size_t pl_vertex_buf_size(const struct pl_pass_run_params *params); 187 : : 188 : : // Utility function for pretty-printing UUIDs 189 : : #define UUID_SIZE 16 190 : : #define PRINT_UUID(uuid) (print_uuid((char[3 * UUID_SIZE]){0}, (uuid))) 191 : : const char *print_uuid(char buf[3 * UUID_SIZE], const uint8_t uuid[UUID_SIZE]); 192 : : 193 : : // Helper to pretty-print fourcc codes 194 : : #define PRINT_FOURCC(fcc) \ 195 : : (!(fcc) ? "" : (char[5]) { \ 196 : : (fcc) & 0xFF, \ 197 : : ((fcc) >> 8) & 0xFF, \ 198 : : ((fcc) >> 16) & 0xFF, \ 199 : : ((fcc) >> 24) & 0xFF \ 200 : : }) 201 : : 202 : : #define DRM_MOD_SIZE 26 203 : : #define PRINT_DRM_MOD(mod) (print_drm_mod((char[DRM_MOD_SIZE]){0}, (mod))) 204 : : const char *print_drm_mod(char buf[DRM_MOD_SIZE], uint64_t mod);