1 #pragma once
2 
3 #include "common/common.h"
4 #include "misc/bstr.h"
5 
6 // Handle for a rendering API backend.
7 struct ra {
8     struct ra_fns *fns;
9     void *priv;
10 
11     int glsl_version;       // GLSL version (e.g. 300 => 3.0)
12     bool glsl_es;           // use ES dialect
13     bool glsl_vulkan;       // use vulkan dialect
14 
15     struct mp_log *log;
16 
17     // RA_CAP_* bit field. The RA backend must set supported features at init
18     // time.
19     uint64_t caps;
20 
21     // Maximum supported width and height of a 2D texture. Set by the RA backend
22     // at init time.
23     int max_texture_wh;
24 
25     // Maximum shared memory for compute shaders. Set by the RA backend at init
26     // time.
27     size_t max_shmem;
28 
29     // Maximum push constant size. Set by the RA backend at init time.
30     size_t max_pushc_size;
31 
32     // Set of supported texture formats. Must be added by RA backend at init time.
33     // If there are equivalent formats with different caveats, the preferred
34     // formats should have a lower index. (E.g. GLES3 should put rg8 before la.)
35     struct ra_format **formats;
36     int num_formats;
37 
38     // Accelerate texture uploads via an extra PBO even when
39     // RA_CAP_DIRECT_UPLOAD is supported. This is basically only relevant for
40     // OpenGL. Set by the RA user.
41     bool use_pbo;
42 
43     // Array of native resources. For the most part an "escape" mechanism, and
44     // usually does not contain parameters required for basic functionality.
45     struct ra_native_resource *native_resources;
46     int num_native_resources;
47 };
48 
49 // For passing through windowing system specific parameters and such. The
50 // names are always internal (except for legacy opengl-cb uses; the libmpv
51 // render API uses mpv_render_param_type and maps them to names internally).
52 // For example, a name="x11" entry has a X11 display as (Display*)data.
53 struct ra_native_resource {
54     const char *name;
55     void *data;
56 };
57 
58 // Add a ra_native_resource entry. Both name and data pointers must stay valid
59 // until ra termination.
60 void ra_add_native_resource(struct ra *ra, const char *name, void *data);
61 
62 // Search ra->native_resources, returns NULL on failure.
63 void *ra_get_native_resource(struct ra *ra, const char *name);
64 
65 enum {
66     RA_CAP_TEX_1D         = 1 << 0, // supports 1D textures (as shader inputs)
67     RA_CAP_TEX_3D         = 1 << 1, // supports 3D textures (as shader inputs)
68     RA_CAP_BLIT           = 1 << 2, // supports ra_fns.blit
69     RA_CAP_COMPUTE        = 1 << 3, // supports compute shaders
70     RA_CAP_DIRECT_UPLOAD  = 1 << 4, // supports tex_upload without ra_buf
71     RA_CAP_BUF_RO         = 1 << 5, // supports RA_VARTYPE_BUF_RO
72     RA_CAP_BUF_RW         = 1 << 6, // supports RA_VARTYPE_BUF_RW
73     RA_CAP_NESTED_ARRAY   = 1 << 7, // supports nested arrays
74     RA_CAP_GLOBAL_UNIFORM = 1 << 8, // supports using "naked" uniforms (not UBO)
75     RA_CAP_GATHER         = 1 << 9, // supports textureGather in GLSL
76     RA_CAP_FRAGCOORD      = 1 << 10, // supports reading from gl_FragCoord
77     RA_CAP_PARALLEL_COMPUTE  = 1 << 11, // supports parallel compute shaders
78     RA_CAP_NUM_GROUPS     = 1 << 12, // supports gl_NumWorkGroups
79 };
80 
81 enum ra_ctype {
82     RA_CTYPE_UNKNOWN = 0,   // also used for inconsistent multi-component formats
83     RA_CTYPE_UNORM,         // unsigned normalized integer (fixed point) formats
84     RA_CTYPE_UINT,          // full integer formats
85     RA_CTYPE_FLOAT,         // float formats (signed, any bit size)
86 };
87 
88 // All formats must be useable as texture formats. All formats must be byte
89 // aligned (all pixels start and end on a byte boundary), at least as far CPU
90 // transfers are concerned.
91 struct ra_format {
92     // All fields are read-only after creation.
93     const char *name;       // symbolic name for user interaction/debugging
94     void *priv;
95     enum ra_ctype ctype;    // data type of each component
96     bool ordered;           // components are sequential in memory, and returned
97                             // by the shader in memory order (the shader can
98                             // return arbitrary values for unused components)
99     int num_components;     // component count, 0 if not applicable, max. 4
100     int component_size[4];  // in bits, all entries 0 if not applicable
101     int component_depth[4]; // bits in use for each component, 0 if not applicable
102                             // (_must_ be set if component_size[] includes padding,
103                             //  and the real procession as seen by shader is lower)
104     int pixel_size;         // in bytes, total pixel size (0 if opaque)
105     bool luminance_alpha;   // pre-GL_ARB_texture_rg hack for 2 component textures
106                             // if this is set, shader must use .ra instead of .rg
107                             // only applies to 2-component textures
108     bool linear_filter;     // linear filtering available from shader
109     bool renderable;        // can be used for render targets
110     bool storable;          // can be used for storage images
111     bool dummy_format;      // is not a real ra_format but a fake one (e.g. FBO).
112                             // dummy formats cannot be used to create textures
113 
114     // If not 0, the format represents some sort of packed fringe format, whose
115     // shader representation is given by the special_imgfmt_desc pointer.
116     int special_imgfmt;
117     const struct ra_imgfmt_desc *special_imgfmt_desc;
118 
119     // This gives the GLSL image format corresponding to the format, if any.
120     // (e.g. rgba16ui)
121     const char *glsl_format;
122 };
123 
124 struct ra_tex_params {
125     int dimensions;         // 1-3 for 1D-3D textures
126     // Size of the texture. 1D textures require h=d=1, 2D textures require d=1.
127     int w, h, d;
128     const struct ra_format *format;
129     bool render_src;        // must be useable as source texture in a shader
130     bool render_dst;        // must be useable as target texture in a shader
131     bool storage_dst;       // must be usable as a storage image (RA_VARTYPE_IMG_W)
132     bool blit_src;          // must be usable as a blit source
133     bool blit_dst;          // must be usable as a blit destination
134     bool host_mutable;      // texture may be updated with tex_upload
135     bool downloadable;      // texture can be read with tex_download
136     // When used as render source texture.
137     bool src_linear;        // if false, use nearest sampling (whether this can
138                             // be true depends on ra_format.linear_filter)
139     bool src_repeat;        // if false, clamp texture coordinates to edge
140                             // if true, repeat texture coordinates
141     bool non_normalized;    // hack for GL_TEXTURE_RECTANGLE OSX idiocy
142                             // always set to false, except in OSX code
143     bool external_oes;      // hack for GL_TEXTURE_EXTERNAL_OES idiocy
144     // If non-NULL, the texture will be created with these contents. Using
145     // this does *not* require setting host_mutable. Otherwise, the initial
146     // data is undefined.
147     void *initial_data;
148 };
149 
150 // Conflates the following typical GPU API concepts:
151 // - texture itself
152 // - sampler state
153 // - staging buffers for texture upload
154 // - framebuffer objects
155 // - wrappers for swapchain framebuffers
156 // - synchronization needed for upload/rendering/etc.
157 struct ra_tex {
158     // All fields are read-only after creation.
159     struct ra_tex_params params;
160     void *priv;
161 };
162 
163 struct ra_tex_upload_params {
164     struct ra_tex *tex; // Texture to upload to
165     bool invalidate;    // Discard pre-existing data not in the region uploaded
166     // Uploading from buffer:
167     struct ra_buf *buf; // Buffer to upload from (mutually exclusive with `src`)
168     size_t buf_offset;  // Start of data within buffer (bytes)
169     // Uploading directly: (Note: If RA_CAP_DIRECT_UPLOAD is not set, then this
170     // will be internally translated to a tex_upload buffer by the RA)
171     const void *src;    // Address of data
172     // For 2D textures only:
173     struct mp_rect *rc; // Region to upload. NULL means entire image
174     ptrdiff_t stride;   // The size of a horizontal line in bytes (*not* texels!)
175 };
176 
177 struct ra_tex_download_params {
178     struct ra_tex *tex; // Texture to download from
179     // Downloading directly (set by caller, data written to by callee):
180     void *dst;          // Address of data (packed with no alignment)
181     ptrdiff_t stride;   // The size of a horizontal line in bytes (*not* texels!)
182 };
183 
184 // Buffer usage type. This restricts what types of operations may be performed
185 // on a buffer.
186 enum ra_buf_type {
187     RA_BUF_TYPE_INVALID,
188     RA_BUF_TYPE_TEX_UPLOAD,     // texture upload buffer (pixel buffer object)
189     RA_BUF_TYPE_SHADER_STORAGE, // shader buffer (SSBO), for RA_VARTYPE_BUF_RW
190     RA_BUF_TYPE_UNIFORM,        // uniform buffer (UBO), for RA_VARTYPE_BUF_RO
191     RA_BUF_TYPE_VERTEX,         // not publicly usable (RA-internal usage)
192     RA_BUF_TYPE_SHARED_MEMORY,  // device memory for sharing with external API
193 };
194 
195 struct ra_buf_params {
196     enum ra_buf_type type;
197     size_t size;
198     bool host_mapped;  // create a read-writable persistent mapping (ra_buf.data)
199     bool host_mutable; // contents may be updated via buf_update()
200     // If non-NULL, the buffer will be created with these contents. Otherwise,
201     // the initial data is undefined.
202     void *initial_data;
203 };
204 
205 // A generic buffer, which can be used for many purposes (texture upload,
206 // storage buffer, uniform buffer, etc.)
207 struct ra_buf {
208     // All fields are read-only after creation.
209     struct ra_buf_params params;
210     void *data; // for persistently mapped buffers, points to the first byte
211     void *priv;
212 };
213 
214 // Type of a shader uniform variable, or a vertex attribute. In all cases,
215 // vectors are matrices are done by having more than 1 value.
216 enum ra_vartype {
217     RA_VARTYPE_INVALID,
218     RA_VARTYPE_INT,             // C: int, GLSL: int, ivec*
219     RA_VARTYPE_FLOAT,           // C: float, GLSL: float, vec*, mat*
220     RA_VARTYPE_TEX,             // C: ra_tex*, GLSL: various sampler types
221                                 // ra_tex.params.render_src must be true
222     RA_VARTYPE_IMG_W,           // C: ra_tex*, GLSL: various image types
223                                 // write-only (W) image for compute shaders
224                                 // ra_tex.params.storage_dst must be true
225     RA_VARTYPE_BYTE_UNORM,      // C: uint8_t, GLSL: int, vec* (vertex data only)
226     RA_VARTYPE_BUF_RO,          // C: ra_buf*, GLSL: uniform buffer block
227                                 // buf type must be RA_BUF_TYPE_UNIFORM
228     RA_VARTYPE_BUF_RW,          // C: ra_buf*, GLSL: shader storage buffer block
229                                 // buf type must be RA_BUF_TYPE_SHADER_STORAGE
230     RA_VARTYPE_COUNT
231 };
232 
233 // Returns the host size of a ra_vartype, or 0 for abstract vartypes (e.g. tex)
234 size_t ra_vartype_size(enum ra_vartype type);
235 
236 // Represents a uniform, texture input parameter, and similar things.
237 struct ra_renderpass_input {
238     const char *name;       // name as used in the shader
239     enum ra_vartype type;
240     // The total number of values is given by dim_v * dim_m.
241     int dim_v;              // vector dimension (1 for non-vector and non-matrix)
242     int dim_m;              // additional matrix dimension (dim_v x dim_m)
243     // Vertex data: byte offset of the attribute into the vertex struct
244     size_t offset;
245     // RA_VARTYPE_TEX: texture unit
246     // RA_VARTYPE_IMG_W: image unit
247     // RA_VARTYPE_BUF_* buffer binding point
248     // Other uniforms: unused
249     // Bindings must be unique within each namespace, as specified by
250     // desc_namespace()
251     int binding;
252 };
253 
254 // Represents the layout requirements of an input value
255 struct ra_layout {
256     size_t align;  // the alignment requirements (always a power of two)
257     size_t stride; // the delta between two rows of an array/matrix
258     size_t size;   // the total size of the input
259 };
260 
261 // Returns the host layout of a render pass input. Returns {0} for renderpass
262 // inputs without a corresponding host representation (e.g. textures/buffers)
263 struct ra_layout ra_renderpass_input_layout(struct ra_renderpass_input *input);
264 
265 enum ra_blend {
266     RA_BLEND_ZERO,
267     RA_BLEND_ONE,
268     RA_BLEND_SRC_ALPHA,
269     RA_BLEND_ONE_MINUS_SRC_ALPHA,
270 };
271 
272 enum ra_renderpass_type {
273     RA_RENDERPASS_TYPE_INVALID,
274     RA_RENDERPASS_TYPE_RASTER,  // vertex+fragment shader
275     RA_RENDERPASS_TYPE_COMPUTE, // compute shader
276 };
277 
278 // Static part of a rendering pass. It conflates the following:
279 //  - compiled shader and its list of uniforms
280 //  - vertex attributes and its shader mappings
281 //  - blending parameters
282 // (For Vulkan, this would be shader module + pipeline state.)
283 // Upon creation, the values of dynamic values such as uniform contents (whose
284 // initial values are not provided here) are required to be 0.
285 struct ra_renderpass_params {
286     enum ra_renderpass_type type;
287 
288     // Uniforms, including texture/sampler inputs.
289     struct ra_renderpass_input *inputs;
290     int num_inputs;
291     size_t push_constants_size; // must be <= ra.max_pushc_size and a multiple of 4
292 
293     // Highly implementation-specific byte array storing a compiled version
294     // of the program. Can be used to speed up shader compilation. A backend
295     // xan read this in renderpass_create, or set this on the newly created
296     // ra_renderpass params field.
297     bstr cached_program;
298 
299     // --- type==RA_RENDERPASS_TYPE_RASTER only
300 
301     // Describes the format of the vertex data. When using ra.glsl_vulkan,
302     // the order of this array must match the vertex attribute locations.
303     struct ra_renderpass_input *vertex_attribs;
304     int num_vertex_attribs;
305     int vertex_stride;
306 
307     // Format of the target texture
308     const struct ra_format *target_format;
309 
310     // Shader text, in GLSL. (Yes, you need a GLSL compiler.)
311     // These are complete shaders, including prelude and declarations.
312     const char *vertex_shader;
313     const char *frag_shader;
314 
315     // Target blending mode. If enable_blend is false, the blend_ fields can
316     // be ignored.
317     bool enable_blend;
318     enum ra_blend blend_src_rgb;
319     enum ra_blend blend_dst_rgb;
320     enum ra_blend blend_src_alpha;
321     enum ra_blend blend_dst_alpha;
322 
323     // If true, the contents of `target` not written to will become undefined
324     bool invalidate_target;
325 
326     // --- type==RA_RENDERPASS_TYPE_COMPUTE only
327 
328     // Shader text, like vertex_shader/frag_shader.
329     const char *compute_shader;
330 };
331 
332 struct ra_renderpass_params *ra_renderpass_params_copy(void *ta_parent,
333         const struct ra_renderpass_params *params);
334 
335 // Conflates the following typical GPU API concepts:
336 // - various kinds of shaders
337 // - rendering pipelines
338 // - descriptor sets, uniforms, other bindings
339 // - all synchronization necessary
340 // - the current values of all uniforms (this one makes it relatively stateful
341 //   from an API perspective)
342 struct ra_renderpass {
343     // All fields are read-only after creation.
344     struct ra_renderpass_params params;
345     void *priv;
346 };
347 
348 // An input value (see ra_renderpass_input).
349 struct ra_renderpass_input_val {
350     int index;  // index into ra_renderpass_params.inputs[]
351     void *data; // pointer to data according to ra_renderpass_input
352                 // (e.g. type==RA_VARTYPE_FLOAT+dim_v=3,dim_m=3 => float[9])
353 };
354 
355 // Parameters for performing a rendering pass (basically the dynamic params).
356 // These change potentially every time.
357 struct ra_renderpass_run_params {
358     struct ra_renderpass *pass;
359 
360     // Generally this lists parameters only which changed since the last
361     // invocation and need to be updated. The ra_renderpass instance is
362     // supposed to keep unchanged values from the previous run.
363     // For non-primitive types like textures, these entries are always added,
364     // even if they do not change.
365     struct ra_renderpass_input_val *values;
366     int num_values;
367     void *push_constants; // must be set if params.push_constants_size > 0
368 
369     // --- pass->params.type==RA_RENDERPASS_TYPE_RASTER only
370 
371     // target->params.render_dst must be true, and target->params.format must
372     // match pass->params.target_format.
373     struct ra_tex *target;
374     struct mp_rect viewport;
375     struct mp_rect scissors;
376 
377     // (The primitive type is always a triangle list.)
378     void *vertex_data;
379     int vertex_count;   // number of vertex elements, not bytes
380 
381     // --- pass->params.type==RA_RENDERPASS_TYPE_COMPUTE only
382 
383     // Number of work groups to be run in X/Y/Z dimensions.
384     int compute_groups[3];
385 };
386 
387 // This is an opaque type provided by the implementation, but we want to at
388 // least give it a saner name than void* for code readability purposes.
389 typedef void ra_timer;
390 
391 // Rendering API entrypoints. (Note: there are some additional hidden features
392 // you need to take care of. For example, hwdec mapping will be provided
393 // separately from ra, but might need to call into ra private code.)
394 struct ra_fns {
395     void (*destroy)(struct ra *ra);
396 
397     // Create a texture (with undefined contents). Return NULL on failure.
398     // This is a rare operation, and normally textures and even FBOs for
399     // temporary rendering intermediate data are cached.
400     struct ra_tex *(*tex_create)(struct ra *ra,
401                                  const struct ra_tex_params *params);
402 
403     void (*tex_destroy)(struct ra *ra, struct ra_tex *tex);
404 
405     // Upload data to a texture. This is an extremely common operation. When
406     // using a buffer, the contants of the buffer must exactly match the image
407     // - conversions between bit depth etc. are not supported. The buffer *may*
408     // be marked as "in use" while this operation is going on, and the contents
409     // must not be touched again by the API user until buf_poll returns true.
410     // Returns whether successful.
411     bool (*tex_upload)(struct ra *ra, const struct ra_tex_upload_params *params);
412 
413     // Copy data from the texture to memory. ra_tex_params.downloadable must
414     // have been set to true on texture creation.
415     bool (*tex_download)(struct ra *ra, struct ra_tex_download_params *params);
416 
417     // Create a buffer. This can be used as a persistently mapped buffer,
418     // a uniform buffer, a shader storage buffer or possibly others.
419     // Not all usage types must be supported; may return NULL if unavailable.
420     struct ra_buf *(*buf_create)(struct ra *ra,
421                                  const struct ra_buf_params *params);
422 
423     void (*buf_destroy)(struct ra *ra, struct ra_buf *buf);
424 
425     // Update the contents of a buffer, starting at a given offset (*must* be a
426     // multiple of 4) and up to a given size, with the contents of *data. This
427     // is an extremely common operation. Calling this while the buffer is
428     // considered "in use" is an error. (See: buf_poll)
429     void (*buf_update)(struct ra *ra, struct ra_buf *buf, ptrdiff_t offset,
430                        const void *data, size_t size);
431 
432     // Returns if a buffer is currently "in use" or not. Updating the contents
433     // of a buffer (via buf_update or writing to buf->data) while it is still
434     // in use is an error and may result in graphical corruption. Optional, if
435     // NULL then all buffers are always usable.
436     bool (*buf_poll)(struct ra *ra, struct ra_buf *buf);
437 
438     // Returns the layout requirements of a uniform buffer element. Optional,
439     // but must be implemented if RA_CAP_BUF_RO is supported.
440     struct ra_layout (*uniform_layout)(struct ra_renderpass_input *inp);
441 
442     // Returns the layout requirements of a push constant element. Optional,
443     // but must be implemented if ra.max_pushc_size > 0.
444     struct ra_layout (*push_constant_layout)(struct ra_renderpass_input *inp);
445 
446     // Returns an abstract namespace index for a given renderpass input type.
447     // This will always be a value >= 0 and < RA_VARTYPE_COUNT. This is used to
448     // figure out which inputs may share the same value of `binding`.
449     int (*desc_namespace)(struct ra *ra, enum ra_vartype type);
450 
451     // Clear the dst with the given color (rgba) and within the given scissor.
452     // dst must have dst->params.render_dst==true. Content outside of the
453     // scissor is preserved.
454     void (*clear)(struct ra *ra, struct ra_tex *dst, float color[4],
455                   struct mp_rect *scissor);
456 
457     // Copy a sub-rectangle from one texture to another. The source/dest region
458     // is always within the texture bounds. Areas outside the dest region are
459     // preserved. The formats of the textures must be losely compatible. The
460     // dst texture can be a swapchain framebuffer, but src can not. Only 2D
461     // textures are supported.
462     // The textures must have blit_src and blit_dst set, respectively.
463     // Rectangles with negative width/height lead to flipping, different src/dst
464     // sizes lead to point scaling. Coordinates are always in pixels.
465     // Optional. Only available if RA_CAP_BLIT is set (if it's not set, it must
466     // not be called, even if it's non-NULL).
467     void (*blit)(struct ra *ra, struct ra_tex *dst, struct ra_tex *src,
468                  struct mp_rect *dst_rc, struct mp_rect *src_rc);
469 
470     // Compile a shader and create a pipeline. This is a rare operation.
471     // The params pointer and anything it points to must stay valid until
472     // renderpass_destroy.
473     struct ra_renderpass *(*renderpass_create)(struct ra *ra,
474                                     const struct ra_renderpass_params *params);
475 
476     void (*renderpass_destroy)(struct ra *ra, struct ra_renderpass *pass);
477 
478     // Perform a render pass, basically drawing a list of triangles to a FBO.
479     // This is an extremely common operation.
480     void (*renderpass_run)(struct ra *ra,
481                            const struct ra_renderpass_run_params *params);
482 
483     // Create a timer object. Returns NULL on failure, or if timers are
484     // unavailable for some reason. Optional.
485     ra_timer *(*timer_create)(struct ra *ra);
486 
487     void (*timer_destroy)(struct ra *ra, ra_timer *timer);
488 
489     // Start recording a timer. Note that valid usage requires you to pair
490     // every start with a stop. Trying to start a timer twice, or trying to
491     // stop a timer before having started it, consistutes invalid usage.
492     void (*timer_start)(struct ra *ra, ra_timer *timer);
493 
494     // Stop recording a timer. This also returns any results that have been
495     // measured since the last usage of this ra_timer. It's important to note
496     // that GPU timer measurement are asynchronous, so this function does not
497     // always produce a value - and the values it does produce are typically
498     // delayed by a few frames. When no value is available, this returns 0.
499     uint64_t (*timer_stop)(struct ra *ra, ra_timer *timer);
500 
501     // Associates a marker with any past error messages, for debugging
502     // purposes. Optional.
503     void (*debug_marker)(struct ra *ra, const char *msg);
504 };
505 
506 struct ra_tex *ra_tex_create(struct ra *ra, const struct ra_tex_params *params);
507 void ra_tex_free(struct ra *ra, struct ra_tex **tex);
508 
509 struct ra_buf *ra_buf_create(struct ra *ra, const struct ra_buf_params *params);
510 void ra_buf_free(struct ra *ra, struct ra_buf **buf);
511 
512 void ra_free(struct ra **ra);
513 
514 const struct ra_format *ra_find_unorm_format(struct ra *ra,
515                                              int bytes_per_component,
516                                              int n_components);
517 const struct ra_format *ra_find_uint_format(struct ra *ra,
518                                             int bytes_per_component,
519                                             int n_components);
520 const struct ra_format *ra_find_float16_format(struct ra *ra, int n_components);
521 const struct ra_format *ra_find_named_format(struct ra *ra, const char *name);
522 
523 struct ra_imgfmt_desc {
524     int num_planes;
525     const struct ra_format *planes[4];
526     // Chroma pixel size (1x1 is 4:4:4)
527     uint8_t chroma_w, chroma_h;
528     // Component storage size in bits (possibly padded). For formats with
529     // different sizes per component, this is arbitrary. For padded formats
530     // like P010 or YUV420P10, padding is included.
531     int component_bits;
532     // Like mp_regular_imgfmt.component_pad.
533     int component_pad;
534     // == planes[n].ctype (RA_CTYPE_UNKNOWN if not applicable)
535     enum ra_ctype component_type;
536     // For each texture and each texture output (rgba order) describe what
537     // component it returns.
538     // The values are like the values in mp_regular_imgfmt_plane.components[].
539     // Access as components[plane_nr][component_index]. Set unused items to 0.
540     // For ra_format.luminance_alpha, this returns 1/2 ("rg") instead of 1/4
541     // ("ra"). the logic is that the texture format has 2 channels, thus the
542     // data must be returned in the first two components. The renderer fixes
543     // this later.
544     uint8_t components[4][4];
545 };
546 
547 const char *ra_fmt_glsl_format(const struct ra_format *fmt);
548 
549 bool ra_get_imgfmt_desc(struct ra *ra, int imgfmt, struct ra_imgfmt_desc *out);
550 
551 void ra_dump_tex_formats(struct ra *ra, int msgl);
552 void ra_dump_imgfmt_desc(struct ra *ra, const struct ra_imgfmt_desc *desc,
553                          int msgl);
554 void ra_dump_img_formats(struct ra *ra, int msgl);
555