Cleanup: move public doc-strings into headers for 'gpu'

Ref T92709
This commit is contained in:
2021-12-09 20:01:47 +11:00
parent 9f546d6908
commit 7c76bdca1b
65 changed files with 596 additions and 387 deletions

View File

@@ -102,25 +102,48 @@ void GPU_batch_init_ex(GPUBatch *batch,
GPUVertBuf *vert, GPUVertBuf *vert,
GPUIndexBuf *elem, GPUIndexBuf *elem,
eGPUBatchFlag owns_flag); eGPUBatchFlag owns_flag);
/**
* This will share the VBOs with the new batch.
*/
void GPU_batch_copy(GPUBatch *batch_dst, GPUBatch *batch_src); void GPU_batch_copy(GPUBatch *batch_dst, GPUBatch *batch_src);
#define GPU_batch_create(prim, verts, elem) GPU_batch_create_ex(prim, verts, elem, 0) #define GPU_batch_create(prim, verts, elem) GPU_batch_create_ex(prim, verts, elem, 0)
#define GPU_batch_init(batch, prim, verts, elem) GPU_batch_init_ex(batch, prim, verts, elem, 0) #define GPU_batch_init(batch, prim, verts, elem) GPU_batch_init_ex(batch, prim, verts, elem, 0)
/* Same as discard but does not free. (does not call free callback). */ /**
* Same as discard but does not free. (does not call free callback).
*/
void GPU_batch_clear(GPUBatch *); void GPU_batch_clear(GPUBatch *);
void GPU_batch_discard(GPUBatch *); /* verts & elem are not discarded */ /**
* \note Verts & elem are not discarded.
*/
void GPU_batch_discard(GPUBatch *);
/**
* \note Override ONLY the first instance VBO (and free them if owned).
*/
void GPU_batch_instbuf_set(GPUBatch *, GPUVertBuf *, bool own_vbo); /* Instancing */ void GPU_batch_instbuf_set(GPUBatch *, GPUVertBuf *, bool own_vbo); /* Instancing */
/**
* \note Override any previously assigned elem (and free it if owned).
*/
void GPU_batch_elembuf_set(GPUBatch *batch, GPUIndexBuf *elem, bool own_ibo); void GPU_batch_elembuf_set(GPUBatch *batch, GPUIndexBuf *elem, bool own_ibo);
int GPU_batch_instbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo); int GPU_batch_instbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo);
/**
* Returns the index of verts in the batch.
*/
int GPU_batch_vertbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo); int GPU_batch_vertbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo);
#define GPU_batch_vertbuf_add(batch, verts) GPU_batch_vertbuf_add_ex(batch, verts, false) #define GPU_batch_vertbuf_add(batch, verts) GPU_batch_vertbuf_add_ex(batch, verts, false)
void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader); void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader);
/**
* Bind program bound to IMM to the batch.
*
* XXX Use this with much care. Drawing with the #GPUBatch API is not compatible with IMM.
* DO NOT DRAW WITH THE BATCH BEFORE CALLING #immUnbindProgram.
*/
void GPU_batch_program_set_imm_shader(GPUBatch *batch); void GPU_batch_program_set_imm_shader(GPUBatch *batch);
void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id); void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id);
void GPU_batch_program_set_builtin_with_config(GPUBatch *batch, void GPU_batch_program_set_builtin_with_config(GPUBatch *batch,
@@ -129,6 +152,7 @@ void GPU_batch_program_set_builtin_with_config(GPUBatch *batch,
/* Will only work after setting the batch program. */ /* Will only work after setting the batch program. */
/* TODO(fclem): These need to be replaced by GPU_shader_uniform_* with explicit shader. */ /* TODO(fclem): These need to be replaced by GPU_shader_uniform_* with explicit shader. */
#define GPU_batch_uniform_1i(batch, name, x) GPU_shader_uniform_1i((batch)->shader, name, x); #define GPU_batch_uniform_1i(batch, name, x) GPU_shader_uniform_1i((batch)->shader, name, x);
#define GPU_batch_uniform_1b(batch, name, x) GPU_shader_uniform_1b((batch)->shader, name, x); #define GPU_batch_uniform_1b(batch, name, x) GPU_shader_uniform_1b((batch)->shader, name, x);
#define GPU_batch_uniform_1f(batch, name, x) GPU_shader_uniform_1f((batch)->shader, name, x); #define GPU_batch_uniform_1f(batch, name, x) GPU_shader_uniform_1f((batch)->shader, name, x);
@@ -151,14 +175,19 @@ void GPU_batch_program_set_builtin_with_config(GPUBatch *batch,
void GPU_batch_draw(GPUBatch *batch); void GPU_batch_draw(GPUBatch *batch);
void GPU_batch_draw_range(GPUBatch *batch, int v_first, int v_count); void GPU_batch_draw_range(GPUBatch *batch, int v_first, int v_count);
/**
* Draw multiple instance of a batch without having any instance attributes.
*/
void GPU_batch_draw_instanced(GPUBatch *batch, int i_count); void GPU_batch_draw_instanced(GPUBatch *batch, int i_count);
/* This does not bind/unbind shader and does not call GPU_matrix_bind() */ /**
* This does not bind/unbind shader and does not call GPU_matrix_bind().
*/
void GPU_batch_draw_advanced(GPUBatch *, int v_first, int v_count, int i_first, int i_count); void GPU_batch_draw_advanced(GPUBatch *, int v_first, int v_count, int i_first, int i_count);
#if 0 /* future plans */ #if 0 /* future plans */
/* Can multiple batches share a GPUVertBuf? Use ref count? */ /* Can multiple batches share a #GPUVertBuf? Use ref count? */
/* We often need a batch with its own data, to be created and discarded together. */ /* We often need a batch with its own data, to be created and discarded together. */
/* WithOwn variants reduce number of system allocations. */ /* WithOwn variants reduce number of system allocations. */

View File

@@ -35,7 +35,8 @@ extern "C" {
/* gpu_batch_presets.c */ /* gpu_batch_presets.c */
/* Replacement for gluSphere */ /* Replacement for #gluSphere */
struct GPUBatch *GPU_batch_preset_sphere(int lod) ATTR_WARN_UNUSED_RESULT; struct GPUBatch *GPU_batch_preset_sphere(int lod) ATTR_WARN_UNUSED_RESULT;
struct GPUBatch *GPU_batch_preset_sphere_wire(int lod) ATTR_WARN_UNUSED_RESULT; struct GPUBatch *GPU_batch_preset_sphere_wire(int lod) ATTR_WARN_UNUSED_RESULT;
struct GPUBatch *GPU_batch_preset_panel_drag_widget(const float pixelsize, struct GPUBatch *GPU_batch_preset_panel_drag_widget(const float pixelsize,
@@ -43,6 +44,9 @@ struct GPUBatch *GPU_batch_preset_panel_drag_widget(const float pixelsize,
const float col_dark[4], const float col_dark[4],
const float width) ATTR_WARN_UNUSED_RESULT; const float width) ATTR_WARN_UNUSED_RESULT;
/**
* To be used with procedural placement inside shader.
*/
struct GPUBatch *GPU_batch_preset_quad(void); struct GPUBatch *GPU_batch_preset_quad(void);
void gpu_batch_presets_init(void); void gpu_batch_presets_init(void);

View File

@@ -30,6 +30,16 @@ extern "C" {
struct rctf; struct rctf;
/* gpu_batch_utils.c */ /* gpu_batch_utils.c */
/**
* Creates triangles from a byte-array of polygons.
*
* See 'make_shape_2d_from_blend.py' utility to create data to pass to this function.
*
* \param polys_flat: Pairs of X, Y coordinates (repeating to signify closing the polygon).
* \param polys_flat_len: Length of the array (must be an even number).
* \param rect: Optional region to map the byte 0..255 coords to. When not set use -1..1.
*/
struct GPUBatch *GPU_batch_tris_from_poly_2d_encoded( struct GPUBatch *GPU_batch_tris_from_poly_2d_encoded(
const uchar *polys_flat, uint polys_flat_len, const struct rctf *rect) ATTR_WARN_UNUSED_RESULT const uchar *polys_flat, uint polys_flat_len, const struct rctf *rect) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL(1); ATTR_NONNULL(1);
@@ -37,7 +47,11 @@ struct GPUBatch *GPU_batch_wire_from_poly_2d_encoded(
const uchar *polys_flat, uint polys_flat_len, const struct rctf *rect) ATTR_WARN_UNUSED_RESULT const uchar *polys_flat, uint polys_flat_len, const struct rctf *rect) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL(1); ATTR_NONNULL(1);
/* Only use by draw manager. Use the presets function instead for interface. */ /**
* Replacement for #gluSphere.
*
* \note Only use by draw manager. Use the presets function instead for interface.
*/
struct GPUBatch *gpu_batch_sphere(int lat_res, int lon_res) ATTR_WARN_UNUSED_RESULT; struct GPUBatch *gpu_batch_sphere(int lat_res, int lon_res) ATTR_WARN_UNUSED_RESULT;
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -44,11 +44,17 @@ struct Mesh;
struct PBVH; struct PBVH;
struct SubdivCCG; struct SubdivCCG;
/* Buffers for drawing from PBVH grids. */ /**
* Buffers for drawing from PBVH grids.
*/
typedef struct GPU_PBVH_Buffers GPU_PBVH_Buffers; typedef struct GPU_PBVH_Buffers GPU_PBVH_Buffers;
/* Build must be called once before using the other functions, used every time /**
* mesh topology changes. Threaded. */ * Build must be called once before using the other functions,
* used every time mesh topology changes.
*
* Threaded: do not call any functions that use OpenGL calls!
*/
GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const struct MPoly *mpoly, GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const struct MPoly *mpoly,
const struct MLoop *mloop, const struct MLoop *mloop,
const struct MLoopTri *looptri, const struct MLoopTri *looptri,
@@ -58,23 +64,36 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const struct MPoly *mpoly,
const int face_indices_len, const int face_indices_len,
const struct Mesh *mesh); const struct Mesh *mesh);
/**
* Threaded: do not call any functions that use OpenGL calls!
*/
GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(int totgrid, unsigned int **grid_hidden); GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(int totgrid, unsigned int **grid_hidden);
/**
* Threaded: do not call any functions that use OpenGL calls!
*/
GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading); GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading);
/* Free part of data for update. Not thread safe, must run in OpenGL main thread. */ /**
* Free part of data for update. Not thread safe, must run in OpenGL main thread.
*/
void GPU_pbvh_bmesh_buffers_update_free(GPU_PBVH_Buffers *buffers); void GPU_pbvh_bmesh_buffers_update_free(GPU_PBVH_Buffers *buffers);
void GPU_pbvh_grid_buffers_update_free(GPU_PBVH_Buffers *buffers, void GPU_pbvh_grid_buffers_update_free(GPU_PBVH_Buffers *buffers,
const struct DMFlagMat *grid_flag_mats, const struct DMFlagMat *grid_flag_mats,
const int *grid_indices); const int *grid_indices);
/* Update mesh buffers without topology changes. Threaded. */ /**
* Update mesh buffers without topology changes. Threaded.
*/
enum { enum {
GPU_PBVH_BUFFERS_SHOW_MASK = (1 << 1), GPU_PBVH_BUFFERS_SHOW_MASK = (1 << 1),
GPU_PBVH_BUFFERS_SHOW_VCOL = (1 << 2), GPU_PBVH_BUFFERS_SHOW_VCOL = (1 << 2),
GPU_PBVH_BUFFERS_SHOW_SCULPT_FACE_SETS = (1 << 3), GPU_PBVH_BUFFERS_SHOW_SCULPT_FACE_SETS = (1 << 3),
}; };
/**
* Threaded: do not call any functions that use OpenGL calls!
*/
void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers, void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
const struct MVert *mvert, const struct MVert *mvert,
const float *vmask, const float *vmask,
@@ -85,6 +104,11 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
const struct MPropCol *vtcol, const struct MPropCol *vtcol,
const int update_flags); const int update_flags);
/**
* Creates a vertex buffer (coordinate, normal, color) and,
* if smooth shading, an element index buffer.
* Threaded: do not call any functions that use OpenGL calls!
*/
void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers, void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
struct BMesh *bm, struct BMesh *bm,
struct GSet *bm_faces, struct GSet *bm_faces,
@@ -92,6 +116,9 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
struct GSet *bm_other_verts, struct GSet *bm_other_verts,
const int update_flags); const int update_flags);
/**
* Threaded: do not call any functions that use OpenGL calls!
*/
void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers, void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers,
struct SubdivCCG *subdiv_ccg, struct SubdivCCG *subdiv_ccg,
struct CCGElem **grids, struct CCGElem **grids,
@@ -104,13 +131,17 @@ void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers,
const struct CCGKey *key, const struct CCGKey *key,
const int update_flags); const int update_flags);
/* Finish update. Not thread safe, must run in OpenGL main thread. */ /**
* Finish update. Not thread safe, must run in OpenGL main thread.
*/
void GPU_pbvh_buffers_update_flush(GPU_PBVH_Buffers *buffers); void GPU_pbvh_buffers_update_flush(GPU_PBVH_Buffers *buffers);
/* Free buffers. Not thread safe, must run in OpenGL main thread. */ /**
* Free buffers. Not thread safe, must run in OpenGL main thread.
*/
void GPU_pbvh_buffers_free(GPU_PBVH_Buffers *buffers); void GPU_pbvh_buffers_free(GPU_PBVH_Buffers *buffers);
/* draw */ /** Draw. */
struct GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast, bool wires); struct GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast, bool wires);
short GPU_pbvh_buffers_material_index_get(GPU_PBVH_Buffers *buffers); short GPU_pbvh_buffers_material_index_get(GPU_PBVH_Buffers *buffers);

View File

@@ -64,6 +64,9 @@ bool GPU_shader_image_load_store_support(void);
bool GPU_mem_stats_supported(void); bool GPU_mem_stats_supported(void);
void GPU_mem_stats_get(int *totalmem, int *freemem); void GPU_mem_stats_get(int *totalmem, int *freemem);
/**
* Return support for the active context + window.
*/
bool GPU_stereo_quadbuffer_support(void); bool GPU_stereo_quadbuffer_support(void);
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -44,8 +44,14 @@ void GPU_backend_exit(void);
typedef struct GPUContext GPUContext; typedef struct GPUContext GPUContext;
GPUContext *GPU_context_create(void *ghost_window); GPUContext *GPU_context_create(void *ghost_window);
/**
* To be called after #GPU_context_active_set(ctx_to_destroy).
*/
void GPU_context_discard(GPUContext *); void GPU_context_discard(GPUContext *);
/**
* Ctx can be NULL.
*/
void GPU_context_active_set(GPUContext *); void GPU_context_active_set(GPUContext *);
GPUContext *GPU_context_active_get(void); GPUContext *GPU_context_active_get(void);

View File

@@ -33,7 +33,14 @@ extern "C" {
void GPU_debug_group_begin(const char *name); void GPU_debug_group_begin(const char *name);
void GPU_debug_group_end(void); void GPU_debug_group_end(void);
/**
* Return a formatted string showing the current group hierarchy in this format:
* "Group1 > Group 2 > Group3 > ... > GroupN : "
*/
void GPU_debug_get_groups_names(int name_buf_len, char *r_name_buf); void GPU_debug_get_groups_names(int name_buf_len, char *r_name_buf);
/**
* Return true if inside a debug group with the same name.
*/
bool GPU_debug_group_match(const char *ref); bool GPU_debug_group_match(const char *ref);
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -62,6 +62,9 @@ typedef struct GPUOffScreen GPUOffScreen;
GPUFrameBuffer *GPU_framebuffer_create(const char *name); GPUFrameBuffer *GPU_framebuffer_create(const char *name);
void GPU_framebuffer_free(GPUFrameBuffer *fb); void GPU_framebuffer_free(GPUFrameBuffer *fb);
void GPU_framebuffer_bind(GPUFrameBuffer *fb); void GPU_framebuffer_bind(GPUFrameBuffer *fb);
/**
* Workaround for binding a SRGB frame-buffer without doing the SRGB transform.
*/
void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *fb); void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *fb);
void GPU_framebuffer_restore(void); void GPU_framebuffer_restore(void);
@@ -69,6 +72,9 @@ bool GPU_framebuffer_bound(GPUFrameBuffer *fb);
bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256]); bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256]);
GPUFrameBuffer *GPU_framebuffer_active_get(void); GPUFrameBuffer *GPU_framebuffer_active_get(void);
/**
* Returns the default frame-buffer. Will always exists even if it's just a dummy.
*/
GPUFrameBuffer *GPU_framebuffer_back_get(void); GPUFrameBuffer *GPU_framebuffer_back_get(void);
#define GPU_FRAMEBUFFER_FREE_SAFE(fb) \ #define GPU_FRAMEBUFFER_FREE_SAFE(fb) \
@@ -113,6 +119,12 @@ void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, struct GPUTexture *tex);
GPU_framebuffer_config_array(*(_fb), config, (sizeof(config) / sizeof(GPUAttachment))); \ GPU_framebuffer_config_array(*(_fb), config, (sizeof(config) / sizeof(GPUAttachment))); \
} while (0) } while (0)
/**
* First #GPUAttachment in *config is always the depth/depth_stencil buffer.
* Following #GPUAttachments are color buffers.
* Setting #GPUAttachment.mip to -1 will leave the texture in this slot.
* Setting #GPUAttachment.tex to NULL will detach the texture in this slot.
*/
void GPU_framebuffer_config_array(GPUFrameBuffer *fb, const GPUAttachment *config, int config_len); void GPU_framebuffer_config_array(GPUFrameBuffer *fb, const GPUAttachment *config, int config_len);
#define GPU_ATTACHMENT_NONE \ #define GPU_ATTACHMENT_NONE \
@@ -156,8 +168,16 @@ void GPU_framebuffer_texture_cubeface_attach(
/* Frame-buffer operations. */ /* Frame-buffer operations. */
/**
* Viewport and scissor size is stored per frame-buffer.
* It is only reset to its original dimensions explicitly OR when binding the frame-buffer after
* modifying its attachments.
*/
void GPU_framebuffer_viewport_set(GPUFrameBuffer *fb, int x, int y, int w, int h); void GPU_framebuffer_viewport_set(GPUFrameBuffer *fb, int x, int y, int w, int h);
void GPU_framebuffer_viewport_get(GPUFrameBuffer *fb, int r_viewport[4]); void GPU_framebuffer_viewport_get(GPUFrameBuffer *fb, int r_viewport[4]);
/**
* Reset to its attachment(s) size.
*/
void GPU_framebuffer_viewport_reset(GPUFrameBuffer *fb); void GPU_framebuffer_viewport_reset(GPUFrameBuffer *fb);
void GPU_framebuffer_clear(GPUFrameBuffer *fb, void GPU_framebuffer_clear(GPUFrameBuffer *fb,
@@ -184,6 +204,9 @@ void GPU_framebuffer_clear(GPUFrameBuffer *fb,
#define GPU_framebuffer_clear_color_depth_stencil(fb, col, depth, stencil) \ #define GPU_framebuffer_clear_color_depth_stencil(fb, col, depth, stencil) \
GPU_framebuffer_clear(fb, GPU_COLOR_BIT | GPU_DEPTH_BIT | GPU_STENCIL_BIT, col, depth, stencil) GPU_framebuffer_clear(fb, GPU_COLOR_BIT | GPU_DEPTH_BIT | GPU_STENCIL_BIT, col, depth, stencil)
/**
* Clear all textures attached to this frame-buffer with a different color.
*/
void GPU_framebuffer_multi_clear(GPUFrameBuffer *fb, const float (*clear_cols)[4]); void GPU_framebuffer_multi_clear(GPUFrameBuffer *fb, const float (*clear_cols)[4]);
void GPU_framebuffer_read_depth( void GPU_framebuffer_read_depth(
@@ -198,6 +221,9 @@ void GPU_framebuffer_read_color(GPUFrameBuffer *fb,
eGPUDataFormat format, eGPUDataFormat format,
void *data); void *data);
/**
* Read_slot and write_slot are only used for color buffers.
*/
void GPU_framebuffer_blit(GPUFrameBuffer *fb_read, void GPU_framebuffer_blit(GPUFrameBuffer *fb_read,
int read_slot, int read_slot,
GPUFrameBuffer *fb_write, GPUFrameBuffer *fb_write,
@@ -233,6 +259,9 @@ int GPU_offscreen_width(const GPUOffScreen *ofs);
int GPU_offscreen_height(const GPUOffScreen *ofs); int GPU_offscreen_height(const GPUOffScreen *ofs);
struct GPUTexture *GPU_offscreen_color_texture(const GPUOffScreen *ofs); struct GPUTexture *GPU_offscreen_color_texture(const GPUOffScreen *ofs);
/**
* \note only to be used by viewport code!
*/
void GPU_offscreen_viewport_data_get(GPUOffScreen *ofs, void GPU_offscreen_viewport_data_get(GPUOffScreen *ofs,
GPUFrameBuffer **r_fb, GPUFrameBuffer **r_fb,
struct GPUTexture **r_color, struct GPUTexture **r_color,

View File

@@ -39,7 +39,7 @@ extern "C" {
/** Returns a cleared vertex format, ready for #add_attr. */ /** Returns a cleared vertex format, ready for #add_attr. */
GPUVertFormat *immVertexFormat(void); GPUVertFormat *immVertexFormat(void);
/** Every immBegin must have a program bound first. */ /** Every #immBegin must have a program bound first. */
void immBindShader(GPUShader *shader); void immBindShader(GPUShader *shader);
/** Call after your last immEnd, or before binding another program. */ /** Call after your last immEnd, or before binding another program. */
void immUnbindProgram(void); void immUnbindProgram(void);
@@ -50,10 +50,12 @@ void immBegin(GPUPrimType, uint vertex_len);
void immBeginAtMost(GPUPrimType, uint max_vertex_len); void immBeginAtMost(GPUPrimType, uint max_vertex_len);
void immEnd(void); /* finishes and draws. */ void immEnd(void); /* finishes and draws. */
/* immBegin a batch, then use standard immFunctions as usual. */ /* - #immBegin a batch, then use standard `imm*` functions as usual.
/* immEnd will finalize the batch instead of drawing. */ * - #immEnd will finalize the batch instead of drawing.
/* Then you can draw it as many times as you like! *
* Then you can draw it as many times as you like!
* Partially replaces the need for display lists. */ * Partially replaces the need for display lists. */
GPUBatch *immBeginBatch(GPUPrimType, uint vertex_len); GPUBatch *immBeginBatch(GPUPrimType, uint vertex_len);
GPUBatch *immBeginBatchAtMost(GPUPrimType, uint vertex_len); GPUBatch *immBeginBatchAtMost(GPUPrimType, uint vertex_len);
@@ -81,12 +83,14 @@ void immAttr4ub(uint attr_id, unsigned char r, unsigned char g, unsigned char b,
void immAttr3ubv(uint attr_id, const unsigned char data[3]); void immAttr3ubv(uint attr_id, const unsigned char data[3]);
void immAttr4ubv(uint attr_id, const unsigned char data[4]); void immAttr4ubv(uint attr_id, const unsigned char data[4]);
/* Explicitly skip an attribute. */ /* Explicitly skip an attribute.
/* This advanced option kills automatic value copying for this attr_id. */ * This advanced option kills automatic value copying for this attr_id. */
void immAttrSkip(uint attr_id); void immAttrSkip(uint attr_id);
/* Provide one last attribute value & end the current vertex. */ /* Provide one last attribute value & end the current vertex.
/* This is most often used for 2D or 3D position (similar to glVertex). */ * This is most often used for 2D or 3D position (similar to #glVertex). */
void immVertex2f(uint attr_id, float x, float y); void immVertex2f(uint attr_id, float x, float y);
void immVertex3f(uint attr_id, float x, float y, float z); void immVertex3f(uint attr_id, float x, float y, float z);
void immVertex4f(uint attr_id, float x, float y, float z, float w); void immVertex4f(uint attr_id, float x, float y, float z, float w);
@@ -101,6 +105,7 @@ void immVertex3fv(uint attr_id, const float data[3]);
void immVertex2iv(uint attr_id, const int data[2]); void immVertex2iv(uint attr_id, const int data[2]);
/* Provide uniform values that don't change for the entire draw call. */ /* Provide uniform values that don't change for the entire draw call. */
void immUniform1i(const char *name, int x); void immUniform1i(const char *name, int x);
void immUniform1f(const char *name, float x); void immUniform1f(const char *name, float x);
void immUniform2f(const char *name, float x, float y); void immUniform2f(const char *name, float x, float y);
@@ -109,6 +114,9 @@ void immUniform3f(const char *name, float x, float y, float z);
void immUniform3fv(const char *name, const float data[3]); void immUniform3fv(const char *name, const float data[3]);
void immUniform4f(const char *name, float x, float y, float z, float w); void immUniform4f(const char *name, float x, float y, float z, float w);
void immUniform4fv(const char *name, const float data[4]); void immUniform4fv(const char *name, const float data[4]);
/**
* Note array index is not supported for name (i.e: "array[0]").
*/
void immUniformArray4fv(const char *bare_name, const float *data, int count); void immUniformArray4fv(const char *bare_name, const float *data, int count);
void immUniformMatrix4fv(const char *name, const float data[4][4]); void immUniformMatrix4fv(const char *name, const float data[4][4]);
@@ -116,7 +124,8 @@ void immBindTexture(const char *name, GPUTexture *tex);
void immBindTextureSampler(const char *name, GPUTexture *tex, eGPUSamplerState state); void immBindTextureSampler(const char *name, GPUTexture *tex, eGPUSamplerState state);
/* Convenience functions for setting "uniform vec4 color". */ /* Convenience functions for setting "uniform vec4 color". */
/* The rgb functions have implicit alpha = 1.0. */ /* The RGB functions have implicit alpha = 1.0. */
void immUniformColor4f(float r, float g, float b, float a); void immUniformColor4f(float r, float g, float b, float a);
void immUniformColor4fv(const float rgba[4]); void immUniformColor4fv(const float rgba[4]);
void immUniformColor3f(float r, float g, float b); void immUniformColor3f(float r, float g, float b);
@@ -135,7 +144,7 @@ void immUniformColor4ubv(const unsigned char rgba[4]);
*/ */
void immBindBuiltinProgram(eGPUBuiltinShader shader_id); void immBindBuiltinProgram(eGPUBuiltinShader shader_id);
/* Extend immUniformColor to take Blender's themes */ /** Extend #immUniformColor to take Blender's themes. */
void immUniformThemeColor(int color_id); void immUniformThemeColor(int color_id);
void immUniformThemeColorAlpha(int color_id, float a); void immUniformThemeColorAlpha(int color_id, float a);
void immUniformThemeColor3(int color_id); void immUniformThemeColor3(int color_id);

View File

@@ -31,16 +31,50 @@ extern "C" {
void immRectf(uint pos, float x1, float y1, float x2, float y2); void immRectf(uint pos, float x1, float y1, float x2, float y2);
void immRecti(uint pos, int x1, int y1, int x2, int y2); void immRecti(uint pos, int x1, int y1, int x2, int y2);
/* Same as immRectf/immRecti but does not call immBegin/immEnd. To use with GPU_PRIM_TRIS. */ /**
* Same as #immRectf / #immRecti but does not call #immBegin / #immEnd.
* To use with #GPU_PRIM_TRIS.
*/
void immRectf_fast(uint pos, float x1, float y1, float x2, float y2); void immRectf_fast(uint pos, float x1, float y1, float x2, float y2);
void immRectf_fast_with_color( void immRectf_fast_with_color(
uint pos, uint col, float x1, float y1, float x2, float y2, const float color[4]); uint pos, uint col, float x1, float y1, float x2, float y2, const float color[4]);
void immRecti_fast_with_color( void immRecti_fast_with_color(
uint pos, uint col, int x1, int y1, int x2, int y2, const float color[4]); uint pos, uint col, int x1, int y1, int x2, int y2, const float color[4]);
/**
* Pack color into 3 bytes
*
* This define converts a numerical value to the equivalent 24-bit
* color, while not being endian-sensitive. On little-endian, this
* is the same as doing a 'naive' indexing, on big-endian, it is not!
*
* \note BGR format (i.e. 0xBBGGRR)...
*
* \param x: color.
*/
void imm_cpack(uint x); void imm_cpack(uint x);
/**
* Draw a circle outline with the given \a radius.
* The circle is centered at \a x, \a y and drawn in the XY plane.
*
* \param shdr_pos: The vertex attribute number for position.
* \param x: Horizontal center.
* \param y: Vertical center.
* \param rad: The circle's radius.
* \param nsegments: The number of segments to use in drawing (more = smoother).
*/
void imm_draw_circle_wire_2d(uint shdr_pos, float x, float y, float radius, int nsegments); void imm_draw_circle_wire_2d(uint shdr_pos, float x, float y, float radius, int nsegments);
/**
* Draw a filled circle with the given \a radius.
* The circle is centered at \a x, \a y and drawn in the XY plane.
*
* \param shdr_pos: The vertex attribute number for position.
* \param x: Horizontal center.
* \param y: Vertical center.
* \param rad: The circle's radius.
* \param nsegments: The number of segments to use in drawing (more = smoother).
*/
void imm_draw_circle_fill_2d(uint shdr_pos, float x, float y, float radius, int nsegments); void imm_draw_circle_fill_2d(uint shdr_pos, float x, float y, float radius, int nsegments);
void imm_draw_circle_wire_aspect_2d( void imm_draw_circle_wire_aspect_2d(
@@ -48,15 +82,34 @@ void imm_draw_circle_wire_aspect_2d(
void imm_draw_circle_fill_aspect_2d( void imm_draw_circle_fill_aspect_2d(
uint shdr_pos, float x, float y, float rad_x, float rad_y, int nsegments); uint shdr_pos, float x, float y, float rad_x, float rad_y, int nsegments);
/* use this version when GPUVertFormat has a vec3 position */ /**
* Use this version when #GPUVertFormat has a vec3 position.
*/
void imm_draw_circle_wire_3d(uint pos, float x, float y, float radius, int nsegments); void imm_draw_circle_wire_3d(uint pos, float x, float y, float radius, int nsegments);
void imm_draw_circle_dashed_3d(uint pos, float x, float y, float radius, int nsegments); void imm_draw_circle_dashed_3d(uint pos, float x, float y, float radius, int nsegments);
void imm_draw_circle_fill_3d(uint pos, float x, float y, float radius, int nsegments); void imm_draw_circle_fill_3d(uint pos, float x, float y, float radius, int nsegments);
/* same as 'imm_draw_disk_partial_fill_2d', except it draws a wire arc. */ /**
* Same as 'imm_draw_disk_partial_fill_2d', except it draws a wire arc.
*/
void imm_draw_circle_partial_wire_2d( void imm_draw_circle_partial_wire_2d(
uint pos, float x, float y, float radius, int nsegments, float start, float sweep); uint pos, float x, float y, float radius, int nsegments, float start, float sweep);
/**
* Draw a filled arc with the given inner and outer radius.
* The circle is centered at \a x, \a y and drawn in the XY plane.
*
* \note Arguments are `gluPartialDisk` compatible.
*
* \param pos: The vertex attribute number for position.
* \param x: Horizontal center.
* \param y: Vertical center.
* \param rad_inner: The inner circle's radius.
* \param rad_outer: The outer circle's radius (can be zero).
* \param nsegments: The number of segments to use in drawing (more = smoother).
* \param start: Specifies the starting angle, in degrees, of the disk portion.
* \param sweep: Specifies the sweep angle, in degrees, of the disk portion.
*/
void imm_draw_disk_partial_fill_2d(uint pos, void imm_draw_disk_partial_fill_2d(uint pos,
float x, float x,
float y, float y,
@@ -66,9 +119,21 @@ void imm_draw_disk_partial_fill_2d(uint pos,
float start, float start,
float sweep); float sweep);
/**
* Draw a lined box.
*
* \param pos: The vertex attribute number for position.
* \param x1: left.
* \param y1: bottom.
* \param x2: right.
* \param y2: top.
*/
void imm_draw_box_wire_2d(uint pos, float x1, float y1, float x2, float y2); void imm_draw_box_wire_2d(uint pos, float x1, float y1, float x2, float y2);
void imm_draw_box_wire_3d(uint pos, float x1, float y1, float x2, float y2); void imm_draw_box_wire_3d(uint pos, float x1, float y1, float x2, float y2);
/**
* Draw a standard checkerboard to indicate transparent backgrounds.
*/
void imm_draw_box_checker_2d_ex(float x1, void imm_draw_box_checker_2d_ex(float x1,
float y1, float y1,
float x2, float x2,
@@ -85,6 +150,18 @@ void imm_draw_cube_corners_3d(uint pos,
const float aspect[3], const float aspect[3],
const float factor); const float factor);
/**
* Draw a cylinder. Replacement for #gluCylinder.
* \warning Slow, better use it only if you no other choices.
*
* \param pos: The vertex attribute number for position.
* \param nor: The vertex attribute number for normal.
* \param base: Specifies the radius of the cylinder at z = 0.
* \param top: Specifies the radius of the cylinder at z = height.
* \param height: Specifies the height of the cylinder.
* \param slices: Specifies the number of subdivisions around the z axis.
* \param stacks: Specifies the number of subdivisions along the z axis.
*/
void imm_draw_cylinder_fill_normal_3d( void imm_draw_cylinder_fill_normal_3d(
uint pos, uint nor, float base, float top, float height, int slices, int stacks); uint pos, uint nor, float base, float top, float height, int slices, int stacks);
void imm_draw_cylinder_wire_3d( void imm_draw_cylinder_wire_3d(

View File

@@ -54,7 +54,7 @@ typedef struct GPUMaterial GPUMaterial;
typedef struct GPUNode GPUNode; typedef struct GPUNode GPUNode;
typedef struct GPUNodeLink GPUNodeLink; typedef struct GPUNodeLink GPUNodeLink;
/* Functions to create GPU Materials nodes */ /* Functions to create GPU Materials nodes. */
typedef enum eGPUType { typedef enum eGPUType {
/* Keep in sync with GPU_DATATYPE_STR */ /* Keep in sync with GPU_DATATYPE_STR */
@@ -180,10 +180,17 @@ struct GPUUniformBuf *GPU_material_sss_profile_get(GPUMaterial *material,
int sample_len, int sample_len,
struct GPUTexture **tex_profile); struct GPUTexture **tex_profile);
/* High level functions to create and use GPU materials */ /**
* High level functions to create and use GPU materials.
*/
GPUMaterial *GPU_material_from_nodetree_find(struct ListBase *gpumaterials, GPUMaterial *GPU_material_from_nodetree_find(struct ListBase *gpumaterials,
const void *engine_type, const void *engine_type,
int options); int options);
/**
* \note Caller must use #GPU_material_from_nodetree_find to re-use existing materials,
* This is enforced since constructing other arguments to this function may be expensive
* so only do this when they are needed.
*/
GPUMaterial *GPU_material_from_nodetree(struct Scene *scene, GPUMaterial *GPU_material_from_nodetree(struct Scene *scene,
struct Material *ma, struct Material *ma,
struct bNodeTree *ntree, struct bNodeTree *ntree,
@@ -205,10 +212,21 @@ void GPU_materials_free(struct Main *bmain);
struct Scene *GPU_material_scene(GPUMaterial *material); struct Scene *GPU_material_scene(GPUMaterial *material);
struct GPUPass *GPU_material_get_pass(GPUMaterial *material); struct GPUPass *GPU_material_get_pass(GPUMaterial *material);
struct GPUShader *GPU_material_get_shader(GPUMaterial *material); struct GPUShader *GPU_material_get_shader(GPUMaterial *material);
/**
* Return can be NULL if it's a world material.
*/
struct Material *GPU_material_get_material(GPUMaterial *material); struct Material *GPU_material_get_material(GPUMaterial *material);
/**
* Return true if the material compilation has not yet begin or begin.
*/
eGPUMaterialStatus GPU_material_status(GPUMaterial *mat); eGPUMaterialStatus GPU_material_status(GPUMaterial *mat);
struct GPUUniformBuf *GPU_material_uniform_buffer_get(GPUMaterial *material); struct GPUUniformBuf *GPU_material_uniform_buffer_get(GPUMaterial *material);
/**
* Create dynamic UBO from parameters
*
* \param inputs: Items are #LinkData, data is #GPUInput (`BLI_genericNodeN(GPUInput)`).
*/
void GPU_material_uniform_buffer_create(GPUMaterial *material, ListBase *inputs); void GPU_material_uniform_buffer_create(GPUMaterial *material, ListBase *inputs);
struct GPUUniformBuf *GPU_material_create_sss_profile_ubo(void); struct GPUUniformBuf *GPU_material_create_sss_profile_ubo(void);

View File

@@ -31,7 +31,10 @@ extern "C" {
struct GPUShader; struct GPUShader;
void GPU_matrix_reset(void); /* to Identity transform & empty stack */ /**
* To Identity transform & empty stack.
*/
void GPU_matrix_reset(void);
/* ModelView Matrix (2D or 3D) */ /* ModelView Matrix (2D or 3D) */
@@ -52,9 +55,13 @@ void GPU_matrix_translate_3fv(const float vec[3]);
void GPU_matrix_scale_3f(float x, float y, float z); void GPU_matrix_scale_3f(float x, float y, float z);
void GPU_matrix_scale_3fv(const float vec[3]); void GPU_matrix_scale_3fv(const float vec[3]);
/* Axis of rotation should be a unit vector. */ /**
* Axis of rotation should be a unit vector.
*/
void GPU_matrix_rotate_3f(float deg, float x, float y, float z); void GPU_matrix_rotate_3f(float deg, float x, float y, float z);
/* Axis of rotation should be a unit vector. */ /**
* Axis of rotation should be a unit vector.
*/
void GPU_matrix_rotate_3fv(float deg, const float axis[3]); void GPU_matrix_rotate_3fv(float deg, const float axis[3]);
void GPU_matrix_rotate_axis(float deg, char axis); /* TODO: enum for axis? */ void GPU_matrix_rotate_axis(float deg, char axis); /* TODO: enum for axis? */
@@ -78,12 +85,12 @@ void GPU_matrix_scale_2f(float x, float y);
void GPU_matrix_scale_2fv(const float vec[2]); void GPU_matrix_scale_2fv(const float vec[2]);
void GPU_matrix_rotate_2d(float deg); void GPU_matrix_rotate_2d(float deg);
/* Projection Matrix (2D or 3D) */ /* Projection Matrix (2D or 3D). */
void GPU_matrix_push_projection(void); void GPU_matrix_push_projection(void);
void GPU_matrix_pop_projection(void); void GPU_matrix_pop_projection(void);
/* 3D Projection Matrix */ /* 3D Projection Matrix. */
void GPU_matrix_identity_projection_set(void); void GPU_matrix_identity_projection_set(void);
void GPU_matrix_projection_set(const float m[4][4]); void GPU_matrix_projection_set(const float m[4][4]);
@@ -136,11 +143,12 @@ bool GPU_matrix_unproject_3fv(const float win[3],
const int view[4], const int view[4],
float r_world[3]); float r_world[3]);
/* 2D Projection Matrix */ /* 2D Projection Matrix. */
void GPU_matrix_ortho_2d_set(float left, float right, float bottom, float top); void GPU_matrix_ortho_2d_set(float left, float right, float bottom, float top);
/* functions to get matrix values */ /* Functions to get matrix values. */
const float (*GPU_matrix_model_view_get(float m[4][4]))[4]; const float (*GPU_matrix_model_view_get(float m[4][4]))[4];
const float (*GPU_matrix_projection_get(float m[4][4]))[4]; const float (*GPU_matrix_projection_get(float m[4][4]))[4];
const float (*GPU_matrix_model_view_projection_get(float m[4][4]))[4]; const float (*GPU_matrix_model_view_projection_get(float m[4][4]))[4];
@@ -148,12 +156,19 @@ const float (*GPU_matrix_model_view_projection_get(float m[4][4]))[4];
const float (*GPU_matrix_normal_get(float m[3][3]))[3]; const float (*GPU_matrix_normal_get(float m[3][3]))[3];
const float (*GPU_matrix_normal_inverse_get(float m[3][3]))[3]; const float (*GPU_matrix_normal_inverse_get(float m[3][3]))[3];
/* set uniform values for currently bound shader */ /**
* Set uniform values for currently bound shader.
*/
void GPU_matrix_bind(struct GPUShader *shader); void GPU_matrix_bind(struct GPUShader *shader);
bool GPU_matrix_dirty_get(void); /* since last bind */ bool GPU_matrix_dirty_get(void); /* since last bind */
/* own working polygon offset */ /**
* Own working polygon offset.
*/
float GPU_polygon_offset_calc(const float (*winmat)[4], float viewdist, float dist); float GPU_polygon_offset_calc(const float (*winmat)[4], float viewdist, float dist);
/**
* \note \a viewdist is only for orthographic projections at the moment.
*/
void GPU_polygon_offset(float viewdist, float dist); void GPU_polygon_offset(float viewdist, float dist);
/* Python API needs to be able to inspect the stack so errors raise exceptions /* Python API needs to be able to inspect the stack so errors raise exceptions

View File

@@ -66,7 +66,10 @@ typedef enum eGPUSupportLevel {
extern "C" { extern "C" {
#endif #endif
/* GPU Types */
bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver); bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver);
eGPUSupportLevel GPU_platform_support_level(void); eGPUSupportLevel GPU_platform_support_level(void);
const char *GPU_platform_vendor(void); const char *GPU_platform_vendor(void);
const char *GPU_platform_renderer(void); const char *GPU_platform_renderer(void);

View File

@@ -31,7 +31,7 @@ extern "C" {
struct rcti; struct rcti;
/* flags for mode of operation */ /** Flags for mode of operation. */
enum { enum {
GPU_SELECT_ALL = 1, GPU_SELECT_ALL = 1,
/* gpu_select_query */ /* gpu_select_query */
@@ -42,21 +42,48 @@ enum {
GPU_SELECT_PICK_NEAREST = 5, GPU_SELECT_PICK_NEAREST = 5,
}; };
/**
* Initialize and provide buffer for results.
*/
void GPU_select_begin( void GPU_select_begin(
unsigned int *buffer, unsigned int bufsize, const struct rcti *input, char mode, int oldhits); unsigned int *buffer, unsigned int bufsize, const struct rcti *input, char mode, int oldhits);
/**
* Loads a new selection id and ends previous query, if any.
* In second pass of selection it also returns
* if id has been hit on the first pass already.
* Thus we can skip drawing un-hit objects.
*
* \warning We rely on the order of object rendering on passes to be the same for this to work.
*/
bool GPU_select_load_id(unsigned int id); bool GPU_select_load_id(unsigned int id);
void GPU_select_finalize(void); void GPU_select_finalize(void);
/**
* Cleanup and flush selection results to buffer.
* Return number of hits and hits in buffer.
* if \a dopass is true, we will do a second pass with occlusion queries to get the closest hit.
*/
unsigned int GPU_select_end(void); unsigned int GPU_select_end(void);
/* cache selection region */ /* Cache selection region. */
bool GPU_select_is_cached(void); bool GPU_select_is_cached(void);
void GPU_select_cache_begin(void); void GPU_select_cache_begin(void);
void GPU_select_cache_load_id(void); void GPU_select_cache_load_id(void);
void GPU_select_cache_end(void); void GPU_select_cache_end(void);
/* utilities */ /* Utilities. */
/**
* Helper function, nothing special but avoids doing inline since hits aren't sorted by depth
* and purpose of 4x buffer indices isn't so clear.
*
* Note that comparing depth as uint is fine.
*/
const uint *GPU_select_buffer_near(const uint *buffer, int hits); const uint *GPU_select_buffer_near(const uint *buffer, int hits);
uint GPU_select_buffer_remove_by_id(uint *buffer, int hits, uint select_id); uint GPU_select_buffer_remove_by_id(uint *buffer, int hits, uint select_id);
/**
* Part of the solution copied from `rect_subregion_stride_calc`.
*/
void GPU_select_buffer_stride_realign(const struct rcti *src, const struct rcti *dst, uint *r_buf); void GPU_select_buffer_stride_realign(const struct rcti *src, const struct rcti *dst, uint *r_buf);
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -70,6 +70,26 @@ GPUShader *GPU_shader_create_ex(const char *vertcode,
struct GPU_ShaderCreateFromArray_Params { struct GPU_ShaderCreateFromArray_Params {
const char **vert, **geom, **frag, **defs; const char **vert, **geom, **frag, **defs;
}; };
/**
* Use via #GPU_shader_create_from_arrays macro (avoids passing in param).
*
* Similar to #DRW_shader_create_with_lib with the ability to include libs for each type of shader.
*
* It has the advantage that each item can be conditionally included
* without having to build the string inline, then free it.
*
* \param params: NULL terminated arrays of strings.
*
* Example:
* \code{.c}
* sh = GPU_shader_create_from_arrays({
* .vert = (const char *[]){shader_lib_glsl, shader_vert_glsl, NULL},
* .geom = (const char *[]){shader_geom_glsl, NULL},
* .frag = (const char *[]){shader_frag_glsl, NULL},
* .defs = (const char *[]){"#define DEFINE\n", test ? "#define OTHER_DEFINE\n" : "", NULL},
* });
* \endcode
*/
struct GPUShader *GPU_shader_create_from_arrays_impl( struct GPUShader *GPU_shader_create_from_arrays_impl(
const struct GPU_ShaderCreateFromArray_Params *params, const char *func, int line); const struct GPU_ShaderCreateFromArray_Params *params, const char *func, int line);
@@ -88,10 +108,13 @@ void GPU_shader_unbind(void);
const char *GPU_shader_get_name(GPUShader *shader); const char *GPU_shader_get_name(GPUShader *shader);
/* Returns true if transform feedback was successfully enabled. */ /**
* Returns true if transform feedback was successfully enabled.
*/
bool GPU_shader_transform_feedback_enable(GPUShader *shader, struct GPUVertBuf *vertbuf); bool GPU_shader_transform_feedback_enable(GPUShader *shader, struct GPUVertBuf *vertbuf);
void GPU_shader_transform_feedback_disable(GPUShader *shader); void GPU_shader_transform_feedback_disable(GPUShader *shader);
/** DEPRECATED: Kept only because of BGL API. */
int GPU_shader_get_program(GPUShader *shader); int GPU_shader_get_program(GPUShader *shader);
typedef enum { typedef enum {
@@ -134,6 +157,7 @@ void GPU_shader_set_srgb_uniform(GPUShader *shader);
int GPU_shader_get_uniform(GPUShader *shader, const char *name); int GPU_shader_get_uniform(GPUShader *shader, const char *name);
int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin); int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin);
int GPU_shader_get_builtin_block(GPUShader *shader, int builtin); int GPU_shader_get_builtin_block(GPUShader *shader, int builtin);
/** DEPRECATED: Kept only because of Python GPU API. */
int GPU_shader_get_uniform_block(GPUShader *shader, const char *name); int GPU_shader_get_uniform_block(GPUShader *shader, const char *name);
int GPU_shader_get_ssbo(GPUShader *shader, const char *name); int GPU_shader_get_ssbo(GPUShader *shader, const char *name);

View File

@@ -48,8 +48,8 @@ ENUM_OPERATORS(eGPUBarrier, GPU_BARRIER_SHADER_STORAGE)
* Defines the fixed pipeline blending equation. * Defines the fixed pipeline blending equation.
* SRC is the output color from the shader. * SRC is the output color from the shader.
* DST is the color from the frame-buffer. * DST is the color from the frame-buffer.
* The blending equation is : * The blending equation is:
* (SRC * A) + (DST * B). * `(SRC * A) + (DST * B)`.
* The blend mode will modify the A and B parameters. * The blend mode will modify the A and B parameters.
*/ */
typedef enum eGPUBlend { typedef enum eGPUBlend {
@@ -124,10 +124,23 @@ void GPU_front_facing(bool invert);
void GPU_depth_range(float near, float far); void GPU_depth_range(float near, float far);
void GPU_scissor_test(bool enable); void GPU_scissor_test(bool enable);
void GPU_line_smooth(bool enable); void GPU_line_smooth(bool enable);
/**
* \note By convention, this is set as needed and not reset back to 1.0.
* This means code that draws lines must always set the line width beforehand,
* but is not expected to restore it's previous value.
*/
void GPU_line_width(float width); void GPU_line_width(float width);
void GPU_logic_op_xor_set(bool enable); void GPU_logic_op_xor_set(bool enable);
void GPU_point_size(float size); void GPU_point_size(float size);
void GPU_polygon_smooth(bool enable); void GPU_polygon_smooth(bool enable);
/**
* Programmable point size:
* - Shaders set their own point size when enabled
* - Use GPU_point_size when disabled.
*
* TODO: remove and use program point size everywhere.
*/
void GPU_program_point_size(bool enable); void GPU_program_point_size(bool enable);
void GPU_scissor(int x, int y, int width, int height); void GPU_scissor(int x, int y, int width, int height);
void GPU_scissor_get(int coords[4]); void GPU_scissor_get(int coords[4]);
@@ -158,6 +171,9 @@ eGPUDepthTest GPU_depth_test_get(void);
eGPUWriteMask GPU_write_mask_get(void); eGPUWriteMask GPU_write_mask_get(void);
uint GPU_stencil_mask_get(void); uint GPU_stencil_mask_get(void);
eGPUStencilTest GPU_stencil_test_get(void); eGPUStencilTest GPU_stencil_test_get(void);
/**
* \note Already pre-multiplied by `U.pixelsize`.
*/
float GPU_line_width_get(void); float GPU_line_width_get(void);
void GPU_flush(void); void GPU_flush(void);
@@ -165,6 +181,10 @@ void GPU_finish(void);
void GPU_apply_state(void); void GPU_apply_state(void);
void GPU_bgl_start(void); void GPU_bgl_start(void);
/**
* Just turn off the `bgl` safeguard system. Can be called even without #GPU_bgl_start.
*/
void GPU_bgl_end(void); void GPU_bgl_end(void);
bool GPU_bgl_get(void); bool GPU_bgl_get(void);

View File

@@ -32,7 +32,8 @@ struct GPUVertBuf;
/** Opaque type hiding blender::gpu::Texture. */ /** Opaque type hiding blender::gpu::Texture. */
typedef struct GPUTexture GPUTexture; typedef struct GPUTexture GPUTexture;
/* GPU Samplers state /**
* GPU Samplers state
* - Specify the sampler state to bind a texture with. * - Specify the sampler state to bind a texture with.
* - Internally used by textures. * - Internally used by textures.
* - All states are created at startup to avoid runtime costs. * - All states are created at startup to avoid runtime costs.
@@ -60,8 +61,9 @@ typedef enum eGPUSamplerState {
} \ } \
} while (0) } while (0)
/* `GPU_SAMPLER_MAX` is not a valid enum value, but only a limit. /**
* It also creates a bad mask for the `NOT` operator in `ENUM_OPERATORS`. * #GPU_SAMPLER_MAX is not a valid enum value, but only a limit.
* It also creates a bad mask for the `NOT` operator in #ENUM_OPERATORS.
*/ */
static const int GPU_SAMPLER_MAX = (GPU_SAMPLER_ICON + 1); static const int GPU_SAMPLER_MAX = (GPU_SAMPLER_ICON + 1);
ENUM_OPERATORS(eGPUSamplerState, GPU_SAMPLER_ICON) ENUM_OPERATORS(eGPUSamplerState, GPU_SAMPLER_ICON)
@@ -70,6 +72,9 @@ ENUM_OPERATORS(eGPUSamplerState, GPU_SAMPLER_ICON)
extern "C" { extern "C" {
#endif #endif
/**
* Update user defined sampler states.
*/
void GPU_samplers_update(void); void GPU_samplers_update(void);
/* GPU Texture /* GPU Texture
@@ -84,11 +89,13 @@ void GPU_samplers_update(void);
* - if created with from_blender, will not free the texture * - if created with from_blender, will not free the texture
*/ */
/* Wrapper to supported OpenGL/Vulkan texture internal storage /**
* Wrapper to supported OpenGL/Vulkan texture internal storage
* If you need a type just un-comment it. Be aware that some formats * If you need a type just un-comment it. Be aware that some formats
* are not supported by render-buffers. All of the following formats * are not supported by render-buffers. All of the following formats
* are part of the OpenGL 3.3 core * are part of the OpenGL 3.3 core
* specification. */ * specification.
*/
typedef enum eGPUTextureFormat { typedef enum eGPUTextureFormat {
/* Formats texture & render-buffer. */ /* Formats texture & render-buffer. */
GPU_RGBA8UI, GPU_RGBA8UI,
@@ -221,12 +228,19 @@ GPUTexture *GPU_texture_create_cube_array(
const char *name, int w, int d, int mip_len, eGPUTextureFormat format, const float *data); const char *name, int w, int d, int mip_len, eGPUTextureFormat format, const float *data);
/* Special textures. */ /* Special textures. */
GPUTexture *GPU_texture_create_from_vertbuf(const char *name, struct GPUVertBuf *vert); GPUTexture *GPU_texture_create_from_vertbuf(const char *name, struct GPUVertBuf *vert);
/** /**
* \a data should hold all the data for all mipmaps. * \a data should hold all the data for all mipmaps.
*/ */
/**
* DDS texture loading. Return NULL if support is not available.
*/
GPUTexture *GPU_texture_create_compressed_2d( GPUTexture *GPU_texture_create_compressed_2d(
const char *name, int w, int h, int miplen, eGPUTextureFormat format, const void *data); const char *name, int w, int h, int miplen, eGPUTextureFormat format, const void *data);
/**
* Create an error texture that will bind an invalid texture (pink) at draw time.
*/
GPUTexture *GPU_texture_create_error(int dimension, bool array); GPUTexture *GPU_texture_create_error(int dimension, bool array);
void GPU_texture_update_mipmap(GPUTexture *tex, void GPU_texture_update_mipmap(GPUTexture *tex,
@@ -234,6 +248,9 @@ void GPU_texture_update_mipmap(GPUTexture *tex,
eGPUDataFormat gpu_data_format, eGPUDataFormat gpu_data_format,
const void *pixels); const void *pixels);
/**
* \note Updates only mip 0.
*/
void GPU_texture_update(GPUTexture *tex, eGPUDataFormat data_format, const void *data); void GPU_texture_update(GPUTexture *tex, eGPUDataFormat data_format, const void *data);
void GPU_texture_update_sub(GPUTexture *tex, void GPU_texture_update_sub(GPUTexture *tex,
eGPUDataFormat data_format, eGPUDataFormat data_format,
@@ -244,9 +261,20 @@ void GPU_texture_update_sub(GPUTexture *tex,
int width, int width,
int height, int height,
int depth); int depth);
/**
* Makes data interpretation aware of the source layout.
* Skipping pixels correctly when changing rows when doing partial update.
*/
void GPU_unpack_row_length_set(uint len); void GPU_unpack_row_length_set(uint len);
void *GPU_texture_read(GPUTexture *tex, eGPUDataFormat data_format, int miplvl); void *GPU_texture_read(GPUTexture *tex, eGPUDataFormat data_format, int miplvl);
/**
* Fills the whole texture with the same data for all pixels.
* \warning Only work for 2D texture for now.
* \warning Only clears the mip 0 of the texture.
* \param data_format: data format of the pixel data.
* \param data: 1 pixel worth of data to fill the texture with.
*/
void GPU_texture_clear(GPUTexture *tex, eGPUDataFormat data_format, const void *data); void GPU_texture_clear(GPUTexture *tex, eGPUDataFormat data_format, const void *data);
void GPU_texture_free(GPUTexture *tex); void GPU_texture_free(GPUTexture *tex);
@@ -261,6 +289,9 @@ void GPU_texture_image_bind(GPUTexture *tex, int unit);
void GPU_texture_image_unbind(GPUTexture *tex); void GPU_texture_image_unbind(GPUTexture *tex);
void GPU_texture_image_unbind_all(void); void GPU_texture_image_unbind_all(void);
/**
* Copy a texture content to a similar texture. Only MIP 0 is copied.
*/
void GPU_texture_copy(GPUTexture *dst, GPUTexture *src); void GPU_texture_copy(GPUTexture *dst, GPUTexture *src);
void GPU_texture_generate_mipmap(GPUTexture *tex); void GPU_texture_generate_mipmap(GPUTexture *tex);
@@ -292,7 +323,8 @@ int GPU_texture_opengl_bindcode(const GPUTexture *tex);
void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size); void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size);
/* utilities */ /* Utilities. */
size_t GPU_texture_component_len(eGPUTextureFormat format); size_t GPU_texture_component_len(eGPUTextureFormat format);
size_t GPU_texture_dataformat_size(eGPUDataFormat data_format); size_t GPU_texture_dataformat_size(eGPUDataFormat data_format);

View File

@@ -40,6 +40,12 @@ struct ListBase;
typedef struct GPUUniformBuf GPUUniformBuf; typedef struct GPUUniformBuf GPUUniformBuf;
GPUUniformBuf *GPU_uniformbuf_create_ex(size_t size, const void *data, const char *name); GPUUniformBuf *GPU_uniformbuf_create_ex(size_t size, const void *data, const char *name);
/**
* Create UBO from inputs list.
* Return NULL if failed to create or if \param inputs: is empty.
*
* \param inputs: ListBase of #BLI_genericNodeN(#GPUInput).
*/
GPUUniformBuf *GPU_uniformbuf_create_from_list(struct ListBase *inputs, const char *name); GPUUniformBuf *GPU_uniformbuf_create_from_list(struct ListBase *inputs, const char *name);
#define GPU_uniformbuf_create(size) GPU_uniformbuf_create_ex(size, NULL, __func__); #define GPU_uniformbuf_create(size) GPU_uniformbuf_create_ex(size, NULL, __func__);

View File

@@ -79,10 +79,13 @@ GPUVertBuf *GPU_vertbuf_create_with_format_ex(const GPUVertFormat *, GPUUsageTyp
*/ */
const void *GPU_vertbuf_read(GPUVertBuf *verts); const void *GPU_vertbuf_read(GPUVertBuf *verts);
void *GPU_vertbuf_unmap(const GPUVertBuf *verts, const void *mapped_data); void *GPU_vertbuf_unmap(const GPUVertBuf *verts, const void *mapped_data);
/** Same as discard but does not free. */
void GPU_vertbuf_clear(GPUVertBuf *verts); void GPU_vertbuf_clear(GPUVertBuf *verts);
void GPU_vertbuf_discard(GPUVertBuf *); void GPU_vertbuf_discard(GPUVertBuf *);
/* Avoid GPUVertBuf datablock being free but not its data. */ /**
* Avoid GPUVertBuf data-block being free but not its data.
*/
void GPU_vertbuf_handle_ref_add(GPUVertBuf *verts); void GPU_vertbuf_handle_ref_add(GPUVertBuf *verts);
void GPU_vertbuf_handle_ref_remove(GPUVertBuf *verts); void GPU_vertbuf_handle_ref_remove(GPUVertBuf *verts);
@@ -93,25 +96,42 @@ void GPU_vertbuf_init_with_format_ex(GPUVertBuf *, const GPUVertFormat *, GPUUsa
GPUVertBuf *GPU_vertbuf_duplicate(GPUVertBuf *verts); GPUVertBuf *GPU_vertbuf_duplicate(GPUVertBuf *verts);
/**
* Create a new allocation, discarding any existing data.
*/
void GPU_vertbuf_data_alloc(GPUVertBuf *, uint v_len); void GPU_vertbuf_data_alloc(GPUVertBuf *, uint v_len);
/**
* Resize buffer keeping existing data.
*/
void GPU_vertbuf_data_resize(GPUVertBuf *, uint v_len); void GPU_vertbuf_data_resize(GPUVertBuf *, uint v_len);
/**
* Set vertex count but does not change allocation.
* Only this many verts will be uploaded to the GPU and rendered.
* This is useful for streaming data.
*/
void GPU_vertbuf_data_len_set(GPUVertBuf *, uint v_len); void GPU_vertbuf_data_len_set(GPUVertBuf *, uint v_len);
/* The most important #set_attr variant is the untyped one. Get it right first. /**
* The most important #set_attr variant is the untyped one. Get it right first.
* It takes a void* so the app developer is responsible for matching their app data types * It takes a void* so the app developer is responsible for matching their app data types
* to the vertex attribute's type and component count. They're in control of both, so this * to the vertex attribute's type and component count. They're in control of both, so this
* should not be a problem. */ * should not be a problem.
*/
void GPU_vertbuf_attr_set(GPUVertBuf *, uint a_idx, uint v_idx, const void *data); void GPU_vertbuf_attr_set(GPUVertBuf *, uint a_idx, uint v_idx, const void *data);
/** Fills a whole vertex (all attributes). Data must match packed layout. */
void GPU_vertbuf_vert_set(GPUVertBuf *verts, uint v_idx, const void *data); void GPU_vertbuf_vert_set(GPUVertBuf *verts, uint v_idx, const void *data);
/* Tightly packed, non interleaved input data. */ /**
* Tightly packed, non interleaved input data.
*/
void GPU_vertbuf_attr_fill(GPUVertBuf *, uint a_idx, const void *data); void GPU_vertbuf_attr_fill(GPUVertBuf *, uint a_idx, const void *data);
void GPU_vertbuf_attr_fill_stride(GPUVertBuf *, uint a_idx, uint stride, const void *data); void GPU_vertbuf_attr_fill_stride(GPUVertBuf *, uint a_idx, uint stride, const void *data);
/* For low level access only */ /**
* For low level access only.
*/
typedef struct GPUVertBufRaw { typedef struct GPUVertBufRaw {
uint size; uint size;
uint stride; uint stride;
@@ -138,18 +158,32 @@ GPU_INLINE uint GPU_vertbuf_raw_used(GPUVertBufRaw *a)
void GPU_vertbuf_attr_get_raw_data(GPUVertBuf *, uint a_idx, GPUVertBufRaw *access); void GPU_vertbuf_attr_get_raw_data(GPUVertBuf *, uint a_idx, GPUVertBufRaw *access);
/**
* Returns the data buffer and set it to null internally to avoid freeing.
* \note Be careful when using this. The data needs to match the expected format.
*/
void *GPU_vertbuf_steal_data(GPUVertBuf *verts); void *GPU_vertbuf_steal_data(GPUVertBuf *verts);
/**
* \note Be careful when using this. The data needs to match the expected format.
*/
void *GPU_vertbuf_get_data(const GPUVertBuf *verts); void *GPU_vertbuf_get_data(const GPUVertBuf *verts);
const GPUVertFormat *GPU_vertbuf_get_format(const GPUVertBuf *verts); const GPUVertFormat *GPU_vertbuf_get_format(const GPUVertBuf *verts);
uint GPU_vertbuf_get_vertex_alloc(const GPUVertBuf *verts); uint GPU_vertbuf_get_vertex_alloc(const GPUVertBuf *verts);
uint GPU_vertbuf_get_vertex_len(const GPUVertBuf *verts); uint GPU_vertbuf_get_vertex_len(const GPUVertBuf *verts);
GPUVertBufStatus GPU_vertbuf_get_status(const GPUVertBuf *verts); GPUVertBufStatus GPU_vertbuf_get_status(const GPUVertBuf *verts);
/**
* Should be rename to #GPU_vertbuf_data_upload.
*/
void GPU_vertbuf_use(GPUVertBuf *); void GPU_vertbuf_use(GPUVertBuf *);
void GPU_vertbuf_bind_as_ssbo(struct GPUVertBuf *verts, int binding); void GPU_vertbuf_bind_as_ssbo(struct GPUVertBuf *verts, int binding);
/* XXX do not use. */ /**
* XXX: do not use!
* This is just a wrapper for the use of the Hair refine workaround.
* To be used with #GPU_vertbuf_use().
*/
void GPU_vertbuf_update_sub(GPUVertBuf *verts, uint start, uint len, void *data); void GPU_vertbuf_update_sub(GPUVertBuf *verts, uint start, uint len, void *data);
/* Metrics */ /* Metrics */

View File

@@ -113,8 +113,33 @@ uint GPU_vertformat_attr_add(
GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode); GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode);
void GPU_vertformat_alias_add(GPUVertFormat *, const char *alias); void GPU_vertformat_alias_add(GPUVertFormat *, const char *alias);
/**
* Makes vertex attribute from the next vertices to be accessible in the vertex shader.
* For an attribute named "attr" you can access the next nth vertex using "attr{number}".
* Use this function after specifying all the attributes in the format.
*
* NOTE: This does NOT work when using indexed rendering.
* NOTE: Only works for first attribute name. (this limitation can be changed if needed)
*
* WARNING: this function creates a lot of aliases/attributes, make sure to keep the attribute
* name short to avoid overflowing the name-buffer.
*/
void GPU_vertformat_multiload_enable(GPUVertFormat *format, int load_count); void GPU_vertformat_multiload_enable(GPUVertFormat *format, int load_count);
/**
* Make attribute layout non-interleaved.
* Warning! This does not change data layout!
* Use direct buffer access to fill the data.
* This is for advanced usage.
*
* De-interleaved data means all attribute data for each attribute
* is stored continuously like this:
* 000011112222
* instead of:
* 012012012012
*
* \note This is per attribute de-interleaving, NOT per component.
*/
void GPU_vertformat_deinterleave(GPUVertFormat *format); void GPU_vertformat_deinterleave(GPUVertFormat *format);
int GPU_vertformat_attr_id_get(const GPUVertFormat *, const char *name); int GPU_vertformat_attr_id_get(const GPUVertFormat *, const char *name);
@@ -126,10 +151,16 @@ BLI_INLINE const char *GPU_vertformat_attr_name_get(const GPUVertFormat *format,
return format->names + attr->names[n_idx]; return format->names + attr->names[n_idx];
} }
/* WARNING: Can only rename using a string with same character count. /**
* WARNING: This removes all other aliases of this attribute. */ * \warning Can only rename using a string with same character count.
* \warning This removes all other aliases of this attribute.
*/
void GPU_vertformat_attr_rename(GPUVertFormat *format, int attr, const char *new_name); void GPU_vertformat_attr_rename(GPUVertFormat *format, int attr, const char *new_name);
/**
* \warning Always add a prefix to the result of this function as
* the generated string can start with a number and not be a valid attribute name.
*/
void GPU_vertformat_safe_attr_name(const char *attr_name, char *r_safe_name, uint max_len); void GPU_vertformat_safe_attr_name(const char *attr_name, char *r_safe_name, uint max_len);
/* format conversion */ /* format conversion */

View File

@@ -49,12 +49,26 @@ GPUViewport *GPU_viewport_create(void);
GPUViewport *GPU_viewport_stereo_create(void); GPUViewport *GPU_viewport_stereo_create(void);
void GPU_viewport_bind(GPUViewport *viewport, int view, const rcti *rect); void GPU_viewport_bind(GPUViewport *viewport, int view, const rcti *rect);
void GPU_viewport_unbind(GPUViewport *viewport); void GPU_viewport_unbind(GPUViewport *viewport);
/**
* Merge and draw the buffers of \a viewport into the currently active framebuffer, performing
* color transform to display space.
*
* \param rect: Coordinates to draw into. By swapping min and max values, drawing can be done
* with inversed axis coordinates (upside down or sideways).
*/
void GPU_viewport_draw_to_screen(GPUViewport *viewport, int view, const rcti *rect); void GPU_viewport_draw_to_screen(GPUViewport *viewport, int view, const rcti *rect);
/**
* Version of #GPU_viewport_draw_to_screen() that lets caller decide if display colorspace
* transform should be performed.
*/
void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport, void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport,
int view, int view,
const rcti *rect, const rcti *rect,
bool display_colorspace, bool display_colorspace,
bool do_overlay_merge); bool do_overlay_merge);
/**
* Must be executed inside Draw-manager OpenGL Context.
*/
void GPU_viewport_free(GPUViewport *viewport); void GPU_viewport_free(GPUViewport *viewport);
void GPU_viewport_colorspace_set(GPUViewport *viewport, void GPU_viewport_colorspace_set(GPUViewport *viewport,
@@ -62,7 +76,13 @@ void GPU_viewport_colorspace_set(GPUViewport *viewport,
const ColorManagedDisplaySettings *display_settings, const ColorManagedDisplaySettings *display_settings,
float dither); float dither);
/**
* Should be called from DRW after DRW_opengl_context_enable.
*/
void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, struct GPUOffScreen *ofs); void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, struct GPUOffScreen *ofs);
/**
* Clear vars assigned from offscreen, so we don't free data owned by `GPUOffScreen`.
*/
void GPU_viewport_unbind_from_offscreen(GPUViewport *viewport, void GPU_viewport_unbind_from_offscreen(GPUViewport *viewport,
struct GPUOffScreen *ofs, struct GPUOffScreen *ofs,
bool display_colorspace, bool display_colorspace,
@@ -70,6 +90,9 @@ void GPU_viewport_unbind_from_offscreen(GPUViewport *viewport,
struct DRWData **GPU_viewport_data_get(GPUViewport *viewport); struct DRWData **GPU_viewport_data_get(GPUViewport *viewport);
/**
* Merge the stereo textures. `color` and `overlay` texture will be modified.
*/
void GPU_viewport_stereo_composite(GPUViewport *viewport, Stereo3dFormat *stereo_format); void GPU_viewport_stereo_composite(GPUViewport *viewport, Stereo3dFormat *stereo_format);
void GPU_viewport_tag_update(GPUViewport *viewport); void GPU_viewport_tag_update(GPUViewport *viewport);
@@ -82,6 +105,9 @@ GPUTexture *GPU_viewport_color_texture(GPUViewport *viewport, int view);
GPUTexture *GPU_viewport_overlay_texture(GPUViewport *viewport, int view); GPUTexture *GPU_viewport_overlay_texture(GPUViewport *viewport, int view);
GPUTexture *GPU_viewport_depth_texture(GPUViewport *viewport); GPUTexture *GPU_viewport_depth_texture(GPUViewport *viewport);
/**
* Overlay frame-buffer for drawing outside of DRW module.
*/
GPUFrameBuffer *GPU_viewport_framebuffer_overlay_get(GPUViewport *viewport); GPUFrameBuffer *GPU_viewport_framebuffer_overlay_get(GPUViewport *viewport);
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -90,7 +90,6 @@ void GPU_batch_init_ex(GPUBatch *batch,
batch->shader = nullptr; batch->shader = nullptr;
} }
/* This will share the VBOs with the new batch. */
void GPU_batch_copy(GPUBatch *batch_dst, GPUBatch *batch_src) void GPU_batch_copy(GPUBatch *batch_dst, GPUBatch *batch_src)
{ {
GPU_batch_init_ex( GPU_batch_init_ex(
@@ -137,7 +136,6 @@ void GPU_batch_discard(GPUBatch *batch)
/** \name Buffers Management /** \name Buffers Management
* \{ */ * \{ */
/* NOTE: Override ONLY the first instance vbo (and free them if owned). */
void GPU_batch_instbuf_set(GPUBatch *batch, GPUVertBuf *inst, bool own_vbo) void GPU_batch_instbuf_set(GPUBatch *batch, GPUVertBuf *inst, bool own_vbo)
{ {
BLI_assert(inst); BLI_assert(inst);
@@ -151,7 +149,6 @@ void GPU_batch_instbuf_set(GPUBatch *batch, GPUVertBuf *inst, bool own_vbo)
SET_FLAG_FROM_TEST(batch->flag, own_vbo, GPU_BATCH_OWNS_INST_VBO); SET_FLAG_FROM_TEST(batch->flag, own_vbo, GPU_BATCH_OWNS_INST_VBO);
} }
/* NOTE: Override any previously assigned elem (and free it if owned). */
void GPU_batch_elembuf_set(GPUBatch *batch, GPUIndexBuf *elem, bool own_ibo) void GPU_batch_elembuf_set(GPUBatch *batch, GPUIndexBuf *elem, bool own_ibo)
{ {
BLI_assert(elem); BLI_assert(elem);
@@ -188,7 +185,6 @@ int GPU_batch_instbuf_add_ex(GPUBatch *batch, GPUVertBuf *insts, bool own_vbo)
return -1; return -1;
} }
/* Returns the index of verts in the batch. */
int GPU_batch_vertbuf_add_ex(GPUBatch *batch, GPUVertBuf *verts, bool own_vbo) int GPU_batch_vertbuf_add_ex(GPUBatch *batch, GPUVertBuf *verts, bool own_vbo)
{ {
BLI_assert(verts); BLI_assert(verts);
@@ -243,7 +239,6 @@ void GPU_batch_draw_range(GPUBatch *batch, int v_first, int v_count)
GPU_batch_draw_advanced(batch, v_first, v_count, 0, 0); GPU_batch_draw_advanced(batch, v_first, v_count, 0, 0);
} }
/* Draw multiple instance of a batch without having any instance attributes. */
void GPU_batch_draw_instanced(GPUBatch *batch, int i_count) void GPU_batch_draw_instanced(GPUBatch *batch, int i_count)
{ {
BLI_assert(batch->inst[0] == nullptr); BLI_assert(batch->inst[0] == nullptr);
@@ -301,9 +296,6 @@ void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id)
GPU_batch_program_set_builtin_with_config(batch, shader_id, GPU_SHADER_CFG_DEFAULT); GPU_batch_program_set_builtin_with_config(batch, shader_id, GPU_SHADER_CFG_DEFAULT);
} }
/* Bind program bound to IMM to the batch.
* XXX Use this with much care. Drawing with the GPUBatch API is not compatible with IMM.
* DO NOT DRAW WITH THE BATCH BEFORE CALLING immUnbindProgram. */
void GPU_batch_program_set_imm_shader(GPUBatch *batch) void GPU_batch_program_set_imm_shader(GPUBatch *batch)
{ {
GPU_batch_set_shader(batch, immGetShader()); GPU_batch_set_shader(batch, immGetShader());

View File

@@ -154,7 +154,6 @@ GPUBatch *GPU_batch_preset_sphere_wire(int lod)
/** \name Create Sphere (3D) /** \name Create Sphere (3D)
* \{ */ * \{ */
/* Replacement for gluSphere */
GPUBatch *gpu_batch_sphere(int lat_res, int lon_res) GPUBatch *gpu_batch_sphere(int lat_res, int lon_res)
{ {
const float lon_inc = 2 * M_PI / lon_res; const float lon_inc = 2 * M_PI / lon_res;
@@ -331,7 +330,6 @@ GPUBatch *GPU_batch_preset_panel_drag_widget(const float pixelsize,
return g_presets_2d.batch.panel_drag_widget; return g_presets_2d.batch.panel_drag_widget;
} }
/* To be used with procedural placement inside shader. */
GPUBatch *GPU_batch_preset_quad(void) GPUBatch *GPU_batch_preset_quad(void)
{ {
if (!g_presets_2d.batch.quad) { if (!g_presets_2d.batch.quad) {

View File

@@ -33,15 +33,6 @@
/** \name Polygon Creation (2D) /** \name Polygon Creation (2D)
* \{ */ * \{ */
/**
* Creates triangles from a byte-array of polygons.
*
* See 'make_shape_2d_from_blend.py' utility to create data to pass to this function.
*
* \param polys_flat: Pairs of X, Y coordinates (repeating to signify closing the polygon).
* \param polys_flat_len: Length of the array (must be an even number).
* \param rect: Optional region to map the byte 0..255 coords to. When not set use -1..1.
*/
GPUBatch *GPU_batch_tris_from_poly_2d_encoded(const uchar *polys_flat, GPUBatch *GPU_batch_tris_from_poly_2d_encoded(const uchar *polys_flat,
uint polys_flat_len, uint polys_flat_len,
const rctf *rect) const rctf *rect)

View File

@@ -204,7 +204,6 @@ static bool gpu_pbvh_is_looptri_visible(const MLoopTri *lt,
sculpt_face_sets[lt->poly] > SCULPT_FACE_SET_NONE); sculpt_face_sets[lt->poly] > SCULPT_FACE_SET_NONE);
} }
/* Threaded - do not call any functions that use OpenGL calls! */
void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers, void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
const MVert *mvert, const MVert *mvert,
const float *vmask, const float *vmask,
@@ -337,7 +336,6 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
buffers->mvert = mvert; buffers->mvert = mvert;
} }
/* Threaded - do not call any functions that use OpenGL calls! */
GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const MPoly *mpoly, GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const MPoly *mpoly,
const MLoop *mloop, const MLoop *mloop,
const MLoopTri *looptri, const MLoopTri *looptri,
@@ -584,7 +582,6 @@ void GPU_pbvh_grid_buffers_update_free(GPU_PBVH_Buffers *buffers,
} }
} }
/* Threaded - do not call any functions that use OpenGL calls! */
void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers, void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers,
SubdivCCG *subdiv_ccg, SubdivCCG *subdiv_ccg,
CCGElem **grids, CCGElem **grids,
@@ -764,7 +761,6 @@ void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers,
buffers->show_overlay = !empty_mask || !default_face_set; buffers->show_overlay = !empty_mask || !default_face_set;
} }
/* Threaded - do not call any functions that use OpenGL calls! */
GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(int totgrid, BLI_bitmap **grid_hidden) GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(int totgrid, BLI_bitmap **grid_hidden)
{ {
GPU_PBVH_Buffers *buffers; GPU_PBVH_Buffers *buffers;
@@ -878,9 +874,6 @@ void GPU_pbvh_bmesh_buffers_update_free(GPU_PBVH_Buffers *buffers)
} }
} }
/* Creates a vertex buffer (coordinate, normal, color) and, if smooth
* shading, an element index buffer.
* Threaded - do not call any functions that use OpenGL calls! */
void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers, void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
BMesh *bm, BMesh *bm,
GSet *bm_faces, GSet *bm_faces,
@@ -1048,7 +1041,6 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
/** \name Generic /** \name Generic
* \{ */ * \{ */
/* Threaded - do not call any functions that use OpenGL calls! */
GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading) GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading)
{ {
GPU_PBVH_Buffers *buffers; GPU_PBVH_Buffers *buffers;

View File

@@ -189,7 +189,6 @@ void GPU_mem_stats_get(int *totalmem, int *freemem)
Context::get()->memory_statistics_get(totalmem, freemem); Context::get()->memory_statistics_get(totalmem, freemem);
} }
/* Return support for the active context + window. */
bool GPU_stereo_quadbuffer_support() bool GPU_stereo_quadbuffer_support()
{ {
return Context::get()->front_right != nullptr; return Context::get()->front_right != nullptr;

View File

@@ -109,7 +109,6 @@ GPUContext *GPU_context_create(void *ghost_window)
return wrap(ctx); return wrap(ctx);
} }
/* to be called after GPU_context_active_set(ctx_to_destroy) */
void GPU_context_discard(GPUContext *ctx_) void GPU_context_discard(GPUContext *ctx_)
{ {
Context *ctx = unwrap(ctx_); Context *ctx = unwrap(ctx_);
@@ -117,7 +116,6 @@ void GPU_context_discard(GPUContext *ctx_)
active_ctx = nullptr; active_ctx = nullptr;
} }
/* ctx can be NULL */
void GPU_context_active_set(GPUContext *ctx_) void GPU_context_active_set(GPUContext *ctx_)
{ {
Context *ctx = unwrap(ctx_); Context *ctx = unwrap(ctx_);

View File

@@ -55,10 +55,6 @@ void GPU_debug_group_end()
ctx->debug_group_end(); ctx->debug_group_end();
} }
/**
* Return a formatted string showing the current group hierarchy in this format:
* "Group1 > Group 2 > Group3 > ... > GroupN : "
*/
void GPU_debug_get_groups_names(int name_buf_len, char *r_name_buf) void GPU_debug_get_groups_names(int name_buf_len, char *r_name_buf)
{ {
Context *ctx = Context::get(); Context *ctx = Context::get();
@@ -77,7 +73,6 @@ void GPU_debug_get_groups_names(int name_buf_len, char *r_name_buf)
r_name_buf[sz - 3] = '\0'; r_name_buf[sz - 3] = '\0';
} }
/* Return true if inside a debug group with the same name. */
bool GPU_debug_group_match(const char *ref) bool GPU_debug_group_match(const char *ref)
{ {
/* Otherwise there will be no names. */ /* Otherwise there will be no names. */

View File

@@ -216,18 +216,12 @@ void GPU_framebuffer_bind(GPUFrameBuffer *gpu_fb)
unwrap(gpu_fb)->bind(enable_srgb); unwrap(gpu_fb)->bind(enable_srgb);
} }
/**
* Workaround for binding a SRGB frame-buffer without doing the SRGB transform.
*/
void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *gpu_fb) void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *gpu_fb)
{ {
const bool enable_srgb = false; const bool enable_srgb = false;
unwrap(gpu_fb)->bind(enable_srgb); unwrap(gpu_fb)->bind(enable_srgb);
} }
/**
* For stereo rendering.
*/
void GPU_backbuffer_bind(eGPUBackBuffer buffer) void GPU_backbuffer_bind(eGPUBackBuffer buffer)
{ {
Context *ctx = Context::get(); Context *ctx = Context::get();
@@ -251,7 +245,6 @@ GPUFrameBuffer *GPU_framebuffer_active_get()
return wrap(ctx ? ctx->active_fb : nullptr); return wrap(ctx ? ctx->active_fb : nullptr);
} }
/* Returns the default frame-buffer. Will always exists even if it's just a dummy. */
GPUFrameBuffer *GPU_framebuffer_back_get() GPUFrameBuffer *GPU_framebuffer_back_get()
{ {
Context *ctx = Context::get(); Context *ctx = Context::get();
@@ -302,12 +295,6 @@ void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex)
unwrap(tex)->detach_from(unwrap(fb)); unwrap(tex)->detach_from(unwrap(fb));
} }
/**
* First GPUAttachment in *config is always the depth/depth_stencil buffer.
* Following GPUAttachments are color buffers.
* Setting GPUAttachment.mip to -1 will leave the texture in this slot.
* Setting GPUAttachment.tex to NULL will detach the texture in this slot.
*/
void GPU_framebuffer_config_array(GPUFrameBuffer *gpu_fb, void GPU_framebuffer_config_array(GPUFrameBuffer *gpu_fb,
const GPUAttachment *config, const GPUAttachment *config,
int config_len) int config_len)
@@ -341,11 +328,6 @@ void GPU_framebuffer_config_array(GPUFrameBuffer *gpu_fb,
/* ---------- Viewport & Scissor Region ----------- */ /* ---------- Viewport & Scissor Region ----------- */
/**
* Viewport and scissor size is stored per frame-buffer.
* It is only reset to its original dimensions explicitly OR when binding the frame-buffer after
* modifying its attachments.
*/
void GPU_framebuffer_viewport_set(GPUFrameBuffer *gpu_fb, int x, int y, int width, int height) void GPU_framebuffer_viewport_set(GPUFrameBuffer *gpu_fb, int x, int y, int width, int height)
{ {
int viewport_rect[4] = {x, y, width, height}; int viewport_rect[4] = {x, y, width, height};
@@ -357,9 +339,6 @@ void GPU_framebuffer_viewport_get(GPUFrameBuffer *gpu_fb, int r_viewport[4])
unwrap(gpu_fb)->viewport_get(r_viewport); unwrap(gpu_fb)->viewport_get(r_viewport);
} }
/**
* Reset to its attachment(s) size.
*/
void GPU_framebuffer_viewport_reset(GPUFrameBuffer *gpu_fb) void GPU_framebuffer_viewport_reset(GPUFrameBuffer *gpu_fb)
{ {
unwrap(gpu_fb)->viewport_reset(); unwrap(gpu_fb)->viewport_reset();
@@ -376,9 +355,6 @@ void GPU_framebuffer_clear(GPUFrameBuffer *gpu_fb,
unwrap(gpu_fb)->clear(buffers, clear_col, clear_depth, clear_stencil); unwrap(gpu_fb)->clear(buffers, clear_col, clear_depth, clear_stencil);
} }
/**
* Clear all textures attached to this frame-buffer with a different color.
*/
void GPU_framebuffer_multi_clear(GPUFrameBuffer *gpu_fb, const float (*clear_cols)[4]) void GPU_framebuffer_multi_clear(GPUFrameBuffer *gpu_fb, const float (*clear_cols)[4])
{ {
unwrap(gpu_fb)->clear_multi(clear_cols); unwrap(gpu_fb)->clear_multi(clear_cols);
@@ -425,7 +401,6 @@ void GPU_frontbuffer_read_pixels(
Context::get()->front_left->read(GPU_COLOR_BIT, format, rect, channels, 0, data); Context::get()->front_left->read(GPU_COLOR_BIT, format, rect, channels, 0, data);
} }
/* read_slot and write_slot are only used for color buffers. */
/* TODO(fclem): port as texture operation. */ /* TODO(fclem): port as texture operation. */
void GPU_framebuffer_blit(GPUFrameBuffer *gpufb_read, void GPU_framebuffer_blit(GPUFrameBuffer *gpufb_read,
int read_slot, int read_slot,
@@ -466,11 +441,6 @@ void GPU_framebuffer_blit(GPUFrameBuffer *gpufb_read,
prev_fb->bind(true); prev_fb->bind(true);
} }
/**
* Use this if you need to custom down-sample your texture and use the previous mip-level as
* input. This function only takes care of the correct texture handling. It execute the callback
* for each texture level.
*/
void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *gpu_fb, void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *gpu_fb,
int max_lvl, int max_lvl,
void (*callback)(void *userData, int level), void (*callback)(void *userData, int level),
@@ -704,9 +674,6 @@ GPUTexture *GPU_offscreen_color_texture(const GPUOffScreen *ofs)
return ofs->color; return ofs->color;
} }
/**
* \note only to be used by viewport code!
*/
void GPU_offscreen_viewport_data_get(GPUOffScreen *ofs, void GPU_offscreen_viewport_data_get(GPUOffScreen *ofs,
GPUFrameBuffer **r_fb, GPUFrameBuffer **r_fb,
GPUTexture **r_color, GPUTexture **r_color,

View File

@@ -89,7 +89,6 @@ void immUnbindProgram()
imm->shader = nullptr; imm->shader = nullptr;
} }
/* XXX do not use it. Special hack to use OCIO with batch API. */
GPUShader *immGetShader() GPUShader *immGetShader()
{ {
return imm->shader; return imm->shader;
@@ -603,7 +602,6 @@ void immUniform4fv(const char *name, const float data[4])
GPU_shader_uniform_4fv(imm->shader, name, data); GPU_shader_uniform_4fv(imm->shader, name, data);
} }
/* Note array index is not supported for name (i.e: "array[0]"). */
void immUniformArray4fv(const char *name, const float *data, int count) void immUniformArray4fv(const char *name, const float *data, int count)
{ {
GPU_shader_uniform_4fv_array(imm->shader, name, count, (const float(*)[4])data); GPU_shader_uniform_4fv_array(imm->shader, name, count, (const float(*)[4])data);

View File

@@ -143,17 +143,6 @@ void immRecti_complete(int x1, int y1, int x2, int y2, const float color[4])
} }
#endif #endif
/**
* Pack color into 3 bytes
*
* This define converts a numerical value to the equivalent 24-bit
* color, while not being endian-sensitive. On little-endian, this
* is the same as doing a 'naive' indexing, on big-endian, it is not!
*
* \note BGR format (i.e. 0xBBGGRR)...
*
* \param x: color.
*/
void imm_cpack(uint x) void imm_cpack(uint x)
{ {
immUniformColor3ub(((x)&0xFF), (((x) >> 8) & 0xFF), (((x) >> 16) & 0xFF)); immUniformColor3ub(((x)&0xFF), (((x) >> 8) & 0xFF), (((x) >> 16) & 0xFF));
@@ -175,31 +164,11 @@ static void imm_draw_circle(GPUPrimType prim_type,
immEnd(); immEnd();
} }
/**
* Draw a circle outline with the given \a radius.
* The circle is centered at \a x, \a y and drawn in the XY plane.
*
* \param shdr_pos: The vertex attribute number for position.
* \param x: Horizontal center.
* \param y: Vertical center.
* \param rad: The circle's radius.
* \param nsegments: The number of segments to use in drawing (more = smoother).
*/
void imm_draw_circle_wire_2d(uint shdr_pos, float x, float y, float rad, int nsegments) void imm_draw_circle_wire_2d(uint shdr_pos, float x, float y, float rad, int nsegments)
{ {
imm_draw_circle(GPU_PRIM_LINE_LOOP, shdr_pos, x, y, rad, rad, nsegments); imm_draw_circle(GPU_PRIM_LINE_LOOP, shdr_pos, x, y, rad, rad, nsegments);
} }
/**
* Draw a filled circle with the given \a radius.
* The circle is centered at \a x, \a y and drawn in the XY plane.
*
* \param shdr_pos: The vertex attribute number for position.
* \param x: Horizontal center.
* \param y: Vertical center.
* \param rad: The circle's radius.
* \param nsegments: The number of segments to use in drawing (more = smoother).
*/
void imm_draw_circle_fill_2d(uint shdr_pos, float x, float y, float rad, int nsegments) void imm_draw_circle_fill_2d(uint shdr_pos, float x, float y, float rad, int nsegments)
{ {
imm_draw_circle(GPU_PRIM_TRI_FAN, shdr_pos, x, y, rad, rad, nsegments); imm_draw_circle(GPU_PRIM_TRI_FAN, shdr_pos, x, y, rad, rad, nsegments);
@@ -274,21 +243,6 @@ static void imm_draw_disk_partial(GPUPrimType prim_type,
immEnd(); immEnd();
} }
/**
* Draw a filled arc with the given inner and outer radius.
* The circle is centered at \a x, \a y and drawn in the XY plane.
*
* \note Arguments are `gluPartialDisk` compatible.
*
* \param pos: The vertex attribute number for position.
* \param x: Horizontal center.
* \param y: Vertical center.
* \param rad_inner: The inner circle's radius.
* \param rad_outer: The outer circle's radius (can be zero).
* \param nsegments: The number of segments to use in drawing (more = smoother).
* \param start: Specifies the starting angle, in degrees, of the disk portion.
* \param sweep: Specifies the sweep angle, in degrees, of the disk portion.
*/
void imm_draw_disk_partial_fill_2d(uint pos, void imm_draw_disk_partial_fill_2d(uint pos,
float x, float x,
float y, float y,
@@ -328,15 +282,6 @@ void imm_draw_circle_fill_3d(uint pos, float x, float y, float rad, int nsegment
imm_draw_circle_3D(GPU_PRIM_TRI_FAN, pos, x, y, rad, nsegments); imm_draw_circle_3D(GPU_PRIM_TRI_FAN, pos, x, y, rad, nsegments);
} }
/**
* Draw a lined box.
*
* \param pos: The vertex attribute number for position.
* \param x1: left.
* \param y1: bottom.
* \param x2: right.
* \param y2: top.
*/
void imm_draw_box_wire_2d(uint pos, float x1, float y1, float x2, float y2) void imm_draw_box_wire_2d(uint pos, float x1, float y1, float x2, float y2)
{ {
immBegin(GPU_PRIM_LINE_LOOP, 4); immBegin(GPU_PRIM_LINE_LOOP, 4);
@@ -358,9 +303,6 @@ void imm_draw_box_wire_3d(uint pos, float x1, float y1, float x2, float y2)
immEnd(); immEnd();
} }
/**
* Draw a standard checkerboard to indicate transparent backgrounds.
*/
void imm_draw_box_checker_2d_ex(float x1, void imm_draw_box_checker_2d_ex(float x1,
float y1, float y1,
float x2, float x2,
@@ -458,18 +400,6 @@ void imm_draw_cube_corners_3d(uint pos,
immEnd(); immEnd();
} }
/**
* Draw a cylinder. Replacement for gluCylinder.
* _warning_ : Slow, better use it only if you no other choices.
*
* \param pos: The vertex attribute number for position.
* \param nor: The vertex attribute number for normal.
* \param base: Specifies the radius of the cylinder at z = 0.
* \param top: Specifies the radius of the cylinder at z = height.
* \param height: Specifies the height of the cylinder.
* \param slices: Specifies the number of subdivisions around the z axis.
* \param stacks: Specifies the number of subdivisions along the z axis.
*/
void imm_draw_cylinder_fill_normal_3d( void imm_draw_cylinder_fill_normal_3d(
uint pos, uint nor, float base, float top, float height, int slices, int stacks) uint pos, uint nor, float base, float top, float height, int slices, int stacks)
{ {

View File

@@ -115,7 +115,6 @@ enum {
/* Functions */ /* Functions */
/* Returns the address of the future pointer to coba_tex */
GPUTexture **gpu_material_ramp_texture_row_set(GPUMaterial *mat, GPUTexture **gpu_material_ramp_texture_row_set(GPUMaterial *mat,
int size, int size,
float *pixels, float *pixels,
@@ -212,7 +211,6 @@ GPUShader *GPU_material_get_shader(GPUMaterial *material)
return material->pass ? GPU_pass_shader_get(material->pass) : NULL; return material->pass ? GPU_pass_shader_get(material->pass) : NULL;
} }
/* Return can be NULL if it's a world material. */
Material *GPU_material_get_material(GPUMaterial *material) Material *GPU_material_get_material(GPUMaterial *material)
{ {
return material->ma; return material->ma;
@@ -223,11 +221,6 @@ GPUUniformBuf *GPU_material_uniform_buffer_get(GPUMaterial *material)
return material->ubo; return material->ubo;
} }
/**
* Create dynamic UBO from parameters
*
* \param inputs: Items are #LinkData, data is #GPUInput (`BLI_genericNodeN(GPUInput)`).
*/
void GPU_material_uniform_buffer_create(GPUMaterial *material, ListBase *inputs) void GPU_material_uniform_buffer_create(GPUMaterial *material, ListBase *inputs)
{ {
#ifndef NDEBUG #ifndef NDEBUG
@@ -545,7 +538,6 @@ GSet *gpu_material_used_libraries(GPUMaterial *material)
return material->used_libraries; return material->used_libraries;
} }
/* Return true if the material compilation has not yet begin or begin. */
eGPUMaterialStatus GPU_material_status(GPUMaterial *mat) eGPUMaterialStatus GPU_material_status(GPUMaterial *mat)
{ {
return mat->status; return mat->status;
@@ -592,11 +584,6 @@ GPUMaterial *GPU_material_from_nodetree_find(ListBase *gpumaterials,
return NULL; return NULL;
} }
/**
* \note Caller must use #GPU_material_from_nodetree_find to re-use existing materials,
* This is enforced since constructing other arguments to this function may be expensive
* so only do this when they are needed.
*/
GPUMaterial *GPU_material_from_nodetree(Scene *scene, GPUMaterial *GPU_material_from_nodetree(Scene *scene,
struct Material *ma, struct Material *ma,
struct bNodeTree *ntree, struct bNodeTree *ntree,

View File

@@ -733,9 +733,6 @@ float GPU_polygon_offset_calc(const float (*winmat)[4], float viewdist, float di
return winmat[3][2] * -0.0025f * dist; return winmat[3][2] * -0.0025f * dist;
} }
/**
* \note \a viewdist is only for ortho at the moment.
*/
void GPU_polygon_offset(float viewdist, float dist) void GPU_polygon_offset(float viewdist, float dist)
{ {
static float winmat[4][4], offset = 0.0f; static float winmat[4][4], offset = 0.0f;

View File

@@ -791,7 +791,6 @@ static void gpu_node_free(GPUNode *node)
MEM_freeN(node); MEM_freeN(node);
} }
/* Free intermediate node graph. */
void gpu_node_graph_free_nodes(GPUNodeGraph *graph) void gpu_node_graph_free_nodes(GPUNodeGraph *graph)
{ {
GPUNode *node; GPUNode *node;
@@ -803,7 +802,6 @@ void gpu_node_graph_free_nodes(GPUNodeGraph *graph)
graph->outlink = NULL; graph->outlink = NULL;
} }
/* Free both node graph and requested attributes and textures. */
void gpu_node_graph_free(GPUNodeGraph *graph) void gpu_node_graph_free(GPUNodeGraph *graph)
{ {
BLI_freelistN(&graph->outlink_aovs); BLI_freelistN(&graph->outlink_aovs);

View File

@@ -167,12 +167,21 @@ typedef struct GPUNodeGraph {
void gpu_node_graph_prune_unused(GPUNodeGraph *graph); void gpu_node_graph_prune_unused(GPUNodeGraph *graph);
void gpu_node_graph_finalize_uniform_attrs(GPUNodeGraph *graph); void gpu_node_graph_finalize_uniform_attrs(GPUNodeGraph *graph);
/**
* Free intermediate node graph.
*/
void gpu_node_graph_free_nodes(GPUNodeGraph *graph); void gpu_node_graph_free_nodes(GPUNodeGraph *graph);
/**
* Free both node graph and requested attributes and textures.
*/
void gpu_node_graph_free(GPUNodeGraph *graph); void gpu_node_graph_free(GPUNodeGraph *graph);
/* Material calls */ /* Material calls */
struct GPUNodeGraph *gpu_material_node_graph(struct GPUMaterial *material); struct GPUNodeGraph *gpu_material_node_graph(struct GPUMaterial *material);
/**
* Returns the address of the future pointer to coba_tex.
*/
struct GPUTexture **gpu_material_ramp_texture_row_set(struct GPUMaterial *mat, struct GPUTexture **gpu_material_ramp_texture_row_set(struct GPUMaterial *mat,
int size, int size,
float *pixels, float *pixels,

View File

@@ -157,7 +157,6 @@ const char *GPU_platform_gpu_name()
return GPG.gpu_name; return GPG.gpu_name;
} }
/* GPU Types */
bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver) bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver)
{ {
BLI_assert(GPG.initialized); BLI_assert(GPG.initialized);

View File

@@ -71,9 +71,6 @@ static GPUSelectState g_select_state = {0};
/** \name Public API /** \name Public API
* \{ */ * \{ */
/**
* initialize and provide buffer for results
*/
void GPU_select_begin(uint *buffer, uint bufsize, const rcti *input, char mode, int oldhits) void GPU_select_begin(uint *buffer, uint bufsize, const rcti *input, char mode, int oldhits)
{ {
if (mode == GPU_SELECT_NEAREST_SECOND_PASS) { if (mode == GPU_SELECT_NEAREST_SECOND_PASS) {
@@ -107,14 +104,6 @@ void GPU_select_begin(uint *buffer, uint bufsize, const rcti *input, char mode,
} }
} }
/**
* loads a new selection id and ends previous query, if any.
* In second pass of selection it also returns
* if id has been hit on the first pass already.
* Thus we can skip drawing un-hit objects.
*
* \warning We rely on the order of object rendering on passes to be the same for this to work.
*/
bool GPU_select_load_id(uint id) bool GPU_select_load_id(uint id)
{ {
/* if no selection mode active, ignore */ /* if no selection mode active, ignore */
@@ -133,11 +122,6 @@ bool GPU_select_load_id(uint id)
} }
} }
/**
* Cleanup and flush selection results to buffer.
* Return number of hits and hits in buffer.
* if \a dopass is true, we will do a second pass with occlusion queries to get the closest hit.
*/
uint GPU_select_end(void) uint GPU_select_end(void)
{ {
uint hits = 0; uint hits = 0;
@@ -205,12 +189,6 @@ bool GPU_select_is_cached(void)
/** \name Utilities /** \name Utilities
* \{ */ * \{ */
/**
* Helper function, nothing special but avoids doing inline since hits aren't sorted by depth
* and purpose of 4x buffer indices isn't so clear.
*
* Note that comparing depth as uint is fine.
*/
const uint *GPU_select_buffer_near(const uint *buffer, int hits) const uint *GPU_select_buffer_near(const uint *buffer, int hits)
{ {
const uint *buffer_near = NULL; const uint *buffer_near = NULL;
@@ -244,7 +222,6 @@ uint GPU_select_buffer_remove_by_id(uint *buffer, int hits, uint select_id)
return hits_final; return hits_final;
} }
/* Part of the solution copied from `rect_subregion_stride_calc`. */
void GPU_select_buffer_stride_realign(const rcti *src, const rcti *dst, uint *r_buf) void GPU_select_buffer_stride_realign(const rcti *src, const rcti *dst, uint *r_buf)
{ {
const int x = dst->xmin - src->xmin; const int x = dst->xmin - src->xmin;

View File

@@ -730,7 +730,6 @@ void gpu_select_pick_cache_end(void)
BLI_freelistN(&g_pick_state.cache.bufs); BLI_freelistN(&g_pick_state.cache.bufs);
} }
/* is drawing needed? */
bool gpu_select_pick_is_cached(void) bool gpu_select_pick_is_cached(void)
{ {
return g_pick_state.is_cached; return g_pick_state.is_cached;

View File

@@ -30,16 +30,21 @@ extern "C" {
#endif #endif
/* gpu_select_pick */ /* gpu_select_pick */
void gpu_select_pick_begin(uint (*buffer)[4], uint bufsize, const rcti *input, char mode); void gpu_select_pick_begin(uint (*buffer)[4], uint bufsize, const rcti *input, char mode);
bool gpu_select_pick_load_id(uint id, bool end); bool gpu_select_pick_load_id(uint id, bool end);
uint gpu_select_pick_end(void); uint gpu_select_pick_end(void);
void gpu_select_pick_cache_begin(void); void gpu_select_pick_cache_begin(void);
void gpu_select_pick_cache_end(void); void gpu_select_pick_cache_end(void);
/**
* \return true if drawing is not needed.
*/
bool gpu_select_pick_is_cached(void); bool gpu_select_pick_is_cached(void);
void gpu_select_pick_cache_load_id(void); void gpu_select_pick_cache_load_id(void);
/* gpu_select_sample_query */ /* gpu_select_sample_query */
void gpu_select_query_begin( void gpu_select_query_begin(
uint (*buffer)[4], uint bufsize, const rcti *input, char mode, int oldhits); uint (*buffer)[4], uint bufsize, const rcti *input, char mode, int oldhits);
bool gpu_select_query_load_id(uint id); bool gpu_select_query_load_id(uint id);

View File

@@ -284,26 +284,6 @@ static const char *string_join_array_maybe_alloc(const char **str_arr, bool *r_i
return str_arr[0]; return str_arr[0];
} }
/**
* Use via #GPU_shader_create_from_arrays macro (avoids passing in param).
*
* Similar to #DRW_shader_create_with_lib with the ability to include libs for each type of shader.
*
* It has the advantage that each item can be conditionally included
* without having to build the string inline, then free it.
*
* \param params: NULL terminated arrays of strings.
*
* Example:
* \code{.c}
* sh = GPU_shader_create_from_arrays({
* .vert = (const char *[]){shader_lib_glsl, shader_vert_glsl, NULL},
* .geom = (const char *[]){shader_geom_glsl, NULL},
* .frag = (const char *[]){shader_frag_glsl, NULL},
* .defs = (const char *[]){"#define DEFINE\n", test ? "#define OTHER_DEFINE\n" : "", NULL},
* });
* \endcode
*/
struct GPUShader *GPU_shader_create_from_arrays_impl( struct GPUShader *GPU_shader_create_from_arrays_impl(
const struct GPU_ShaderCreateFromArray_Params *params, const char *func, int line) const struct GPU_ShaderCreateFromArray_Params *params, const char *func, int line)
{ {
@@ -431,7 +411,6 @@ int GPU_shader_get_ssbo(GPUShader *shader, const char *name)
return ssbo ? ssbo->location : -1; return ssbo ? ssbo->location : -1;
} }
/* DEPRECATED. */
int GPU_shader_get_uniform_block(GPUShader *shader, const char *name) int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
{ {
ShaderInterface *interface = unwrap(shader)->interface; ShaderInterface *interface = unwrap(shader)->interface;
@@ -466,7 +445,6 @@ int GPU_shader_get_attribute(GPUShader *shader, const char *name)
/** \name Getters /** \name Getters
* \{ */ * \{ */
/* DEPRECATED: Kept only because of BGL API */
int GPU_shader_get_program(GPUShader *shader) int GPU_shader_get_program(GPUShader *shader)
{ {
return unwrap(shader)->program_handle_get(); return unwrap(shader)->program_handle_get();

View File

@@ -65,11 +65,12 @@ static void sort_input_list(MutableSpan<ShaderInput> dst)
} }
} }
/* Sorts all inputs inside their respective array.
* This is to allow fast hash collision detection.
* See ShaderInterface::input_lookup for more details. */
void ShaderInterface::sort_inputs() void ShaderInterface::sort_inputs()
{ {
/* Sorts all inputs inside their respective array.
* This is to allow fast hash collision detection.
* See `ShaderInterface::input_lookup` for more details. */
sort_input_list(MutableSpan<ShaderInput>(inputs_, attr_len_)); sort_input_list(MutableSpan<ShaderInput>(inputs_, attr_len_));
sort_input_list(MutableSpan<ShaderInput>(inputs_ + attr_len_, ubo_len_)); sort_input_list(MutableSpan<ShaderInput>(inputs_ + attr_len_, ubo_len_));
sort_input_list(MutableSpan<ShaderInput>(inputs_ + attr_len_ + ubo_len_, uniform_len_)); sort_input_list(MutableSpan<ShaderInput>(inputs_ + attr_len_ + ubo_len_, uniform_len_));

View File

@@ -130,7 +130,9 @@ class ShaderInterface {
inline uint32_t set_input_name(ShaderInput *input, char *name, uint32_t name_len) const; inline uint32_t set_input_name(ShaderInput *input, char *name, uint32_t name_len) const;
/* Finalize interface construction by sorting the ShaderInputs for faster lookups. */ /**
* Finalize interface construction by sorting the #ShaderInputs for faster lookups.
*/
void sort_inputs(void); void sort_inputs(void);
private: private:

View File

@@ -165,11 +165,6 @@ void GPU_depth_range(float near, float far)
copy_v2_fl2(state.depth_range, near, far); copy_v2_fl2(state.depth_range, near, far);
} }
/**
* \note By convention, this is set as needed and not reset back to 1.0.
* This means code that draws lines must always set the line width beforehand,
* but is not expected to restore it's previous value.
*/
void GPU_line_width(float width) void GPU_line_width(float width)
{ {
width = max_ff(1.0f, width * PIXELSIZE); width = max_ff(1.0f, width * PIXELSIZE);
@@ -184,10 +179,6 @@ void GPU_point_size(float size)
state.point_size = size * ((state.point_size > 0.0) ? 1.0f : -1.0f); state.point_size = size * ((state.point_size > 0.0) ? 1.0f : -1.0f);
} }
/* Programmable point size
* - shaders set their own point size when enabled
* - use GPU_point_size when disabled */
/* TODO: remove and use program point size everywhere. */
void GPU_program_point_size(bool enable) void GPU_program_point_size(bool enable)
{ {
StateManager *stack = Context::get()->state_manager; StateManager *stack = Context::get()->state_manager;
@@ -264,7 +255,6 @@ eGPUStencilTest GPU_stencil_test_get()
return (eGPUStencilTest)state.stencil_test; return (eGPUStencilTest)state.stencil_test;
} }
/* NOTE: Already premultiplied by U.pixelsize. */
float GPU_line_width_get() float GPU_line_width_get()
{ {
const GPUStateMutable &state = Context::get()->state_manager->mutable_state; const GPUStateMutable &state = Context::get()->state_manager->mutable_state;
@@ -363,7 +353,6 @@ void GPU_bgl_start()
} }
} }
/* Just turn off the bgl safeguard system. Can be called even without GPU_bgl_start. */
void GPU_bgl_end() void GPU_bgl_end()
{ {
Context *ctx = Context::get(); Context *ctx = Context::get();

View File

@@ -298,7 +298,6 @@ GPUTexture *GPU_texture_create_cube_array(
name, w, w, d, GPU_TEXTURE_CUBE_ARRAY, mip_len, format, GPU_DATA_FLOAT, data); name, w, w, d, GPU_TEXTURE_CUBE_ARRAY, mip_len, format, GPU_DATA_FLOAT, data);
} }
/* DDS texture loading. Return NULL if support is not available. */
GPUTexture *GPU_texture_create_compressed_2d( GPUTexture *GPU_texture_create_compressed_2d(
const char *name, int w, int h, int miplen, eGPUTextureFormat tex_format, const void *data) const char *name, int w, int h, int miplen, eGPUTextureFormat tex_format, const void *data)
{ {
@@ -337,7 +336,6 @@ GPUTexture *GPU_texture_create_from_vertbuf(const char *name, GPUVertBuf *vert)
return reinterpret_cast<GPUTexture *>(tex); return reinterpret_cast<GPUTexture *>(tex);
} }
/* Create an error texture that will bind an invalid texture (pink) at draw time. */
GPUTexture *GPU_texture_create_error(int dimension, bool is_array) GPUTexture *GPU_texture_create_error(int dimension, bool is_array)
{ {
float pixel[4] = {1.0f, 0.0f, 1.0f, 1.0f}; float pixel[4] = {1.0f, 0.0f, 1.0f, 1.0f};
@@ -386,27 +384,17 @@ void *GPU_texture_read(GPUTexture *tex_, eGPUDataFormat data_format, int miplvl)
return tex->read(miplvl, data_format); return tex->read(miplvl, data_format);
} }
/**
* Fills the whole texture with the same data for all pixels.
* \warning Only work for 2D texture for now.
* \warning Only clears the mip 0 of the texture.
* \param data_format: data format of the pixel data.
* \param data: 1 pixel worth of data to fill the texture with.
*/
void GPU_texture_clear(GPUTexture *tex, eGPUDataFormat data_format, const void *data) void GPU_texture_clear(GPUTexture *tex, eGPUDataFormat data_format, const void *data)
{ {
BLI_assert(data != nullptr); /* Do not accept NULL as parameter. */ BLI_assert(data != nullptr); /* Do not accept NULL as parameter. */
reinterpret_cast<Texture *>(tex)->clear(data_format, data); reinterpret_cast<Texture *>(tex)->clear(data_format, data);
} }
/* NOTE: Updates only mip 0. */
void GPU_texture_update(GPUTexture *tex, eGPUDataFormat data_format, const void *data) void GPU_texture_update(GPUTexture *tex, eGPUDataFormat data_format, const void *data)
{ {
reinterpret_cast<Texture *>(tex)->update(data_format, data); reinterpret_cast<Texture *>(tex)->update(data_format, data);
} }
/* Makes data interpretation aware of the source layout.
* Skipping pixels correctly when changing rows when doing partial update. */
void GPU_unpack_row_length_set(uint len) void GPU_unpack_row_length_set(uint len)
{ {
Context::get()->state_manager->texture_unpack_row_length_set(len); Context::get()->state_manager->texture_unpack_row_length_set(len);
@@ -461,7 +449,6 @@ void GPU_texture_generate_mipmap(GPUTexture *tex)
reinterpret_cast<Texture *>(tex)->generate_mipmap(); reinterpret_cast<Texture *>(tex)->generate_mipmap();
} }
/* Copy a texture content to a similar texture. Only MIP 0 is copied. */
void GPU_texture_copy(GPUTexture *dst_, GPUTexture *src_) void GPU_texture_copy(GPUTexture *dst_, GPUTexture *src_)
{ {
Texture *src = reinterpret_cast<Texture *>(src_); Texture *src = reinterpret_cast<Texture *>(src_);
@@ -626,7 +613,6 @@ void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *r_size)
* Override texture sampler state for one sampler unit only. * Override texture sampler state for one sampler unit only.
* \{ */ * \{ */
/* Update user defined sampler states. */
void GPU_samplers_update(void) void GPU_samplers_update(void)
{ {
GPUBackend::get()->samplers_update(); GPUBackend::get()->samplers_update();

View File

@@ -201,12 +201,6 @@ GPUUniformBuf *GPU_uniformbuf_create_ex(size_t size, const void *data, const cha
return wrap(ubo); return wrap(ubo);
} }
/**
* Create UBO from inputs list.
* Return NULL if failed to create or if \param inputs: is empty.
*
* \param inputs: ListBase of #BLI_genericNodeN(#GPUInput).
*/
GPUUniformBuf *GPU_uniformbuf_create_from_list(ListBase *inputs, const char *name) GPUUniformBuf *GPU_uniformbuf_create_from_list(ListBase *inputs, const char *name)
{ {
/* There is no point on creating an UBO if there is no arguments. */ /* There is no point on creating an UBO if there is no arguments. */

View File

@@ -159,7 +159,6 @@ void *GPU_vertbuf_unmap(const GPUVertBuf *verts, const void *mapped_data)
return unwrap(verts)->unmap(mapped_data); return unwrap(verts)->unmap(mapped_data);
} }
/** Same as discard but does not free. */
void GPU_vertbuf_clear(GPUVertBuf *verts) void GPU_vertbuf_clear(GPUVertBuf *verts)
{ {
unwrap(verts)->clear(); unwrap(verts)->clear();
@@ -183,21 +182,16 @@ void GPU_vertbuf_handle_ref_remove(GPUVertBuf *verts)
/* -------- Data update -------- */ /* -------- Data update -------- */
/* create a new allocation, discarding any existing data */
void GPU_vertbuf_data_alloc(GPUVertBuf *verts, uint v_len) void GPU_vertbuf_data_alloc(GPUVertBuf *verts, uint v_len)
{ {
unwrap(verts)->allocate(v_len); unwrap(verts)->allocate(v_len);
} }
/* resize buffer keeping existing data */
void GPU_vertbuf_data_resize(GPUVertBuf *verts, uint v_len) void GPU_vertbuf_data_resize(GPUVertBuf *verts, uint v_len)
{ {
unwrap(verts)->resize(v_len); unwrap(verts)->resize(v_len);
} }
/* Set vertex count but does not change allocation.
* Only this many verts will be uploaded to the GPU and rendered.
* This is useful for streaming data. */
void GPU_vertbuf_data_len_set(GPUVertBuf *verts_, uint v_len) void GPU_vertbuf_data_len_set(GPUVertBuf *verts_, uint v_len)
{ {
VertBuf *verts = unwrap(verts_); VertBuf *verts = unwrap(verts_);
@@ -229,7 +223,6 @@ void GPU_vertbuf_attr_fill(GPUVertBuf *verts_, uint a_idx, const void *data)
GPU_vertbuf_attr_fill_stride(verts_, a_idx, stride, data); GPU_vertbuf_attr_fill_stride(verts_, a_idx, stride, data);
} }
/** Fills a whole vertex (all attributes). Data must match packed layout. */
void GPU_vertbuf_vert_set(GPUVertBuf *verts_, uint v_idx, const void *data) void GPU_vertbuf_vert_set(GPUVertBuf *verts_, uint v_idx, const void *data)
{ {
VertBuf *verts = unwrap(verts_); VertBuf *verts = unwrap(verts_);
@@ -284,15 +277,12 @@ void GPU_vertbuf_attr_get_raw_data(GPUVertBuf *verts_, uint a_idx, GPUVertBufRaw
/* -------- Getters -------- */ /* -------- Getters -------- */
/* NOTE: Be careful when using this. The data needs to match the expected format. */
void *GPU_vertbuf_get_data(const GPUVertBuf *verts) void *GPU_vertbuf_get_data(const GPUVertBuf *verts)
{ {
/* TODO: Assert that the format has no padding. */ /* TODO: Assert that the format has no padding. */
return unwrap(verts)->data; return unwrap(verts)->data;
} }
/* Returns the data buffer and set it to null internally to avoid freeing.
* NOTE: Be careful when using this. The data needs to match the expected format. */
void *GPU_vertbuf_steal_data(GPUVertBuf *verts_) void *GPU_vertbuf_steal_data(GPUVertBuf *verts_)
{ {
VertBuf *verts = unwrap(verts_); VertBuf *verts = unwrap(verts_);
@@ -328,7 +318,6 @@ uint GPU_vertbuf_get_memory_usage()
return VertBuf::memory_usage; return VertBuf::memory_usage;
} }
/* Should be rename to GPU_vertbuf_data_upload */
void GPU_vertbuf_use(GPUVertBuf *verts) void GPU_vertbuf_use(GPUVertBuf *verts)
{ {
unwrap(verts)->upload(); unwrap(verts)->upload();
@@ -339,8 +328,6 @@ void GPU_vertbuf_bind_as_ssbo(struct GPUVertBuf *verts, int binding)
unwrap(verts)->bind_as_ssbo(binding); unwrap(verts)->bind_as_ssbo(binding);
} }
/* XXX this is just a wrapper for the use of the Hair refine workaround.
* To be used with GPU_vertbuf_use(). */
void GPU_vertbuf_update_sub(GPUVertBuf *verts, uint start, uint len, void *data) void GPU_vertbuf_update_sub(GPUVertBuf *verts, uint start, uint len, void *data)
{ {
unwrap(verts)->update_sub(start, len, data); unwrap(verts)->update_sub(start, len, data);

View File

@@ -190,17 +190,6 @@ void GPU_vertformat_alias_add(GPUVertFormat *format, const char *alias)
attr->names[attr->name_len++] = copy_attr_name(format, alias); attr->names[attr->name_len++] = copy_attr_name(format, alias);
} }
/**
* Makes vertex attribute from the next vertices to be accessible in the vertex shader.
* For an attribute named "attr" you can access the next nth vertex using "attr{number}".
* Use this function after specifying all the attributes in the format.
*
* NOTE: This does NOT work when using indexed rendering.
* NOTE: Only works for first attribute name. (this limitation can be changed if needed)
*
* WARNING: this function creates a lot of aliases/attributes, make sure to keep the attribute
* name short to avoid overflowing the name-buffer.
*/
void GPU_vertformat_multiload_enable(GPUVertFormat *format, int load_count) void GPU_vertformat_multiload_enable(GPUVertFormat *format, int load_count)
{ {
/* Sanity check. Maximum can be upgraded if needed. */ /* Sanity check. Maximum can be upgraded if needed. */
@@ -271,8 +260,6 @@ static void safe_bytes(char out[11], const char data[8])
} }
} }
/* Warning: Always add a prefix to the result of this function as
* the generated string can start with a number and not be a valid attribute name. */
void GPU_vertformat_safe_attr_name(const char *attr_name, char *r_safe_name, uint UNUSED(max_len)) void GPU_vertformat_safe_attr_name(const char *attr_name, char *r_safe_name, uint UNUSED(max_len))
{ {
char data[8] = {0}; char data[8] = {0};
@@ -306,20 +293,6 @@ void GPU_vertformat_safe_attr_name(const char *attr_name, char *r_safe_name, uin
#endif #endif
} }
/**
* Make attribute layout non-interleaved.
* Warning! This does not change data layout!
* Use direct buffer access to fill the data.
* This is for advanced usage.
*
* De-interleaved data means all attribute data for each attribute
* is stored continuously like this:
* 000011112222
* instead of:
* 012012012012
*
* \note This is per attribute de-interleaving, NOT per component.
*/
void GPU_vertformat_deinterleave(GPUVertFormat *format) void GPU_vertformat_deinterleave(GPUVertFormat *format)
{ {
/* Ideally we should change the stride and offset here. This would allow /* Ideally we should change the stride and offset here. This would allow

View File

@@ -194,7 +194,6 @@ void GPU_viewport_bind(GPUViewport *viewport, int view, const rcti *rect)
viewport->active_view = view; viewport->active_view = view;
} }
/* Should be called from DRW after DRW_opengl_context_enable. */
void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, struct GPUOffScreen *ofs) void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, struct GPUOffScreen *ofs)
{ {
GPUTexture *color, *depth; GPUTexture *color, *depth;
@@ -258,7 +257,6 @@ void GPU_viewport_colorspace_set(GPUViewport *viewport,
viewport->do_color_management = true; viewport->do_color_management = true;
} }
/* Merge the stereo textures. `color` and `overlay` texture will be modified. */
void GPU_viewport_stereo_composite(GPUViewport *viewport, Stereo3dFormat *stereo_format) void GPU_viewport_stereo_composite(GPUViewport *viewport, Stereo3dFormat *stereo_format)
{ {
if (!ELEM(stereo_format->display_mode, S3D_DISPLAY_ANAGLYPH, S3D_DISPLAY_INTERLACE)) { if (!ELEM(stereo_format->display_mode, S3D_DISPLAY_ANAGLYPH, S3D_DISPLAY_INTERLACE)) {
@@ -452,10 +450,6 @@ static void gpu_viewport_draw_colormanaged(GPUViewport *viewport,
} }
} }
/**
* Version of #GPU_viewport_draw_to_screen() that lets caller decide if display colorspace
* transform should be performed.
*/
void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport, void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport,
int view, int view,
const rcti *rect, const rcti *rect,
@@ -508,21 +502,11 @@ void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport,
viewport, view, &pos_rect, &uv_rect, display_colorspace, do_overlay_merge); viewport, view, &pos_rect, &uv_rect, display_colorspace, do_overlay_merge);
} }
/**
* Merge and draw the buffers of \a viewport into the currently active framebuffer, performing
* color transform to display space.
*
* \param rect: Coordinates to draw into. By swapping min and max values, drawing can be done
* with inversed axis coordinates (upside down or sideways).
*/
void GPU_viewport_draw_to_screen(GPUViewport *viewport, int view, const rcti *rect) void GPU_viewport_draw_to_screen(GPUViewport *viewport, int view, const rcti *rect)
{ {
GPU_viewport_draw_to_screen_ex(viewport, view, rect, true, true); GPU_viewport_draw_to_screen_ex(viewport, view, rect, true, true);
} }
/**
* Clear vars assigned from offscreen, so we don't free data owned by `GPUOffScreen`.
*/
void GPU_viewport_unbind_from_offscreen(GPUViewport *viewport, void GPU_viewport_unbind_from_offscreen(GPUViewport *viewport,
struct GPUOffScreen *ofs, struct GPUOffScreen *ofs,
bool display_colorspace, bool display_colorspace,
@@ -587,7 +571,6 @@ GPUTexture *GPU_viewport_depth_texture(GPUViewport *viewport)
return viewport->depth_tx; return viewport->depth_tx;
} }
/* Overlay framebuffer for drawing outside of DRW module. */
GPUFrameBuffer *GPU_viewport_framebuffer_overlay_get(GPUViewport *viewport) GPUFrameBuffer *GPU_viewport_framebuffer_overlay_get(GPUViewport *viewport)
{ {
GPU_framebuffer_ensure_config( GPU_framebuffer_ensure_config(
@@ -599,7 +582,6 @@ GPUFrameBuffer *GPU_viewport_framebuffer_overlay_get(GPUViewport *viewport)
return viewport->overlay_fb; return viewport->overlay_fb;
} }
/* Must be executed inside Draw-manager OpenGL Context. */
void GPU_viewport_free(GPUViewport *viewport) void GPU_viewport_free(GPUViewport *viewport)
{ {
if (viewport->draw_data) { if (viewport->draw_data) {

View File

@@ -421,11 +421,14 @@ static void detect_workarounds()
} // namespace blender::gpu } // namespace blender::gpu
/** Internal capabilities. */ /** Internal capabilities. */
GLint GLContext::max_cubemap_size = 0; GLint GLContext::max_cubemap_size = 0;
GLint GLContext::max_texture_3d_size = 0; GLint GLContext::max_texture_3d_size = 0;
GLint GLContext::max_ubo_binds = 0; GLint GLContext::max_ubo_binds = 0;
GLint GLContext::max_ubo_size = 0; GLint GLContext::max_ubo_size = 0;
/** Extensions. */ /** Extensions. */
bool GLContext::base_instance_support = false; bool GLContext::base_instance_support = false;
bool GLContext::clear_texture_support = false; bool GLContext::clear_texture_support = false;
bool GLContext::copy_image_support = false; bool GLContext::copy_image_support = false;
@@ -439,7 +442,9 @@ bool GLContext::texture_cube_map_array_support = false;
bool GLContext::texture_filter_anisotropic_support = false; bool GLContext::texture_filter_anisotropic_support = false;
bool GLContext::texture_gather_support = false; bool GLContext::texture_gather_support = false;
bool GLContext::vertex_attrib_binding_support = false; bool GLContext::vertex_attrib_binding_support = false;
/** Workarounds. */ /** Workarounds. */
bool GLContext::debug_layer_workaround = false; bool GLContext::debug_layer_workaround = false;
bool GLContext::unused_fb_slot_workaround = false; bool GLContext::unused_fb_slot_workaround = false;
bool GLContext::generate_mipmap_workaround = false; bool GLContext::generate_mipmap_workaround = false;

View File

@@ -74,7 +74,6 @@ void GLVaoCache::init()
vao_id_ = 0; vao_id_ = 0;
} }
/* Create a new VAO object and store it in the cache. */
void GLVaoCache::insert(const GLShaderInterface *interface, GLuint vao) void GLVaoCache::insert(const GLShaderInterface *interface, GLuint vao)
{ {
/* Now insert the cache. */ /* Now insert the cache. */
@@ -191,7 +190,6 @@ void GLVaoCache::clear()
this->init(); this->init();
} }
/* Return 0 on cache miss (invalid VAO) */
GLuint GLVaoCache::lookup(const GLShaderInterface *interface) GLuint GLVaoCache::lookup(const GLShaderInterface *interface)
{ {
const int count = (is_dynamic_vao_count) ? dynamic_vaos.count : GPU_VAO_STATIC_LEN; const int count = (is_dynamic_vao_count) ? dynamic_vaos.count : GPU_VAO_STATIC_LEN;
@@ -205,8 +203,6 @@ GLuint GLVaoCache::lookup(const GLShaderInterface *interface)
return 0; return 0;
} }
/* The GLVaoCache object is only valid for one GLContext.
* Reset the cache if trying to draw in another context; */
void GLVaoCache::context_check() void GLVaoCache::context_check()
{ {
GLContext *ctx = GLContext::get(); GLContext *ctx = GLContext::get();

View File

@@ -43,9 +43,11 @@ class GLShaderInterface;
#define GPU_VAO_STATIC_LEN 3 #define GPU_VAO_STATIC_LEN 3
/* VAO management: remembers all geometry state (vertex attribute bindings & element buffer) /**
* for each shader interface. Start with a static number of vaos and fallback to dynamic count * VAO management: remembers all geometry state (vertex attribute bindings & element buffer)
* if necessary. Once a batch goes dynamic it does not go back. */ * for each shader interface. Start with a static number of VAO's and fallback to dynamic count
* if necessary. Once a batch goes dynamic it does not go back.
*/
class GLVaoCache { class GLVaoCache {
private: private:
/** Context for which the vao_cache_ was generated. */ /** Context for which the vao_cache_ was generated. */
@@ -80,13 +82,23 @@ class GLVaoCache {
GLuint vao_get(GPUBatch *batch); GLuint vao_get(GPUBatch *batch);
GLuint base_instance_vao_get(GPUBatch *batch, int i_first); GLuint base_instance_vao_get(GPUBatch *batch, int i_first);
/**
* Return 0 on cache miss (invalid VAO).
*/
GLuint lookup(const GLShaderInterface *interface); GLuint lookup(const GLShaderInterface *interface);
/**
* Create a new VAO object and store it in the cache.
*/
void insert(const GLShaderInterface *interface, GLuint vao_id); void insert(const GLShaderInterface *interface, GLuint vao_id);
void remove(const GLShaderInterface *interface); void remove(const GLShaderInterface *interface);
void clear(void); void clear(void);
private: private:
void init(void); void init(void);
/**
* The #GLVaoCache object is only valid for one #GLContext.
* Reset the cache if trying to draw in another context;.
*/
void context_check(void); void context_check(void);
}; };
@@ -100,6 +112,7 @@ class GLBatch : public Batch {
void bind(int i_first); void bind(int i_first);
/* Convenience getters. */ /* Convenience getters. */
GLIndexBuf *elem_(void) const GLIndexBuf *elem_(void) const
{ {
return static_cast<GLIndexBuf *>(unwrap(elem)); return static_cast<GLIndexBuf *>(unwrap(elem));

View File

@@ -56,11 +56,14 @@ class GLSharedOrphanLists {
class GLContext : public Context { class GLContext : public Context {
public: public:
/** Capabilities. */ /** Capabilities. */
static GLint max_cubemap_size; static GLint max_cubemap_size;
static GLint max_texture_3d_size; static GLint max_texture_3d_size;
static GLint max_ubo_size; static GLint max_ubo_size;
static GLint max_ubo_binds; static GLint max_ubo_binds;
/** Extensions. */ /** Extensions. */
static bool base_instance_support; static bool base_instance_support;
static bool clear_texture_support; static bool clear_texture_support;
static bool copy_image_support; static bool copy_image_support;
@@ -74,7 +77,9 @@ class GLContext : public Context {
static bool texture_filter_anisotropic_support; static bool texture_filter_anisotropic_support;
static bool texture_gather_support; static bool texture_gather_support;
static bool vertex_attrib_binding_support; static bool vertex_attrib_binding_support;
/** Workarounds. */ /** Workarounds. */
static bool debug_layer_workaround; static bool debug_layer_workaround;
static bool unused_fb_slot_workaround; static bool unused_fb_slot_workaround;
static bool generate_mipmap_workaround; static bool generate_mipmap_workaround;

View File

@@ -142,7 +142,6 @@ static void APIENTRY debug_callback(GLenum UNUSED(source),
#undef APIENTRY #undef APIENTRY
/* This function needs to be called once per context. */
void init_gl_callbacks() void init_gl_callbacks()
{ {
CLOG_ENSURE(&LOG); CLOG_ENSURE(&LOG);

View File

@@ -88,8 +88,16 @@ namespace debug {
void raise_gl_error(const char *info); void raise_gl_error(const char *info);
void check_gl_error(const char *info); void check_gl_error(const char *info);
void check_gl_resources(const char *info); void check_gl_resources(const char *info);
/**
* This function needs to be called once per context.
*/
void init_gl_callbacks(void); void init_gl_callbacks(void);
/**
* Initialize a fallback layer (to KHR_debug) that covers only some functions.
* We override the functions pointers by our own implementation that just checks #glGetError.
* Some additional functions (not overridable) are covered inside the header using wrappers.
*/
void init_debug_layer(void); void init_debug_layer(void);
void object_label(GLenum type, GLuint object, const char *name); void object_label(GLenum type, GLuint object, const char *name);

View File

@@ -105,11 +105,6 @@ DEBUG_FUNC_DECLARE(PFNGLUSEPROGRAMPROC, void, glUseProgram, GLuint, program);
#undef DEBUG_FUNC_DECLARE #undef DEBUG_FUNC_DECLARE
/**
* Initialize a fallback layer (to KHR_debug) that covers only some functions.
* We override the functions pointers by our own implementation that just checks #glGetError.
* Some additional functions (not overridable) are covered inside the header using wrappers.
*/
void init_debug_layer() void init_debug_layer()
{ {
#define DEBUG_WRAP(function) \ #define DEBUG_WRAP(function) \

View File

@@ -110,7 +110,6 @@ void GLFrameBuffer::init()
/** \name Config /** \name Config
* \{ */ * \{ */
/* This is a rather slow operation. Don't check in normal cases. */
bool GLFrameBuffer::check(char err_out[256]) bool GLFrameBuffer::check(char err_out[256])
{ {
this->bind(true); this->bind(true);
@@ -451,9 +450,6 @@ void GLFrameBuffer::read(eGPUFrameBufferBits plane,
glReadPixels(UNPACK4(area), format, type, r_data); glReadPixels(UNPACK4(area), format, type, r_data);
} }
/**
* Copy \a src at the give offset inside \a dst.
*/
void GLFrameBuffer::blit_to( void GLFrameBuffer::blit_to(
eGPUFrameBufferBits planes, int src_slot, FrameBuffer *dst_, int dst_slot, int x, int y) eGPUFrameBufferBits planes, int src_slot, FrameBuffer *dst_, int dst_slot, int x, int y)
{ {

View File

@@ -79,6 +79,9 @@ class GLFrameBuffer : public FrameBuffer {
void bind(bool enabled_srgb) override; void bind(bool enabled_srgb) override;
/**
* This is a rather slow operation. Don't check in normal cases.
*/
bool check(char err_out[256]) override; bool check(char err_out[256]) override;
void clear(eGPUFrameBufferBits buffers, void clear(eGPUFrameBufferBits buffers,
@@ -97,6 +100,9 @@ class GLFrameBuffer : public FrameBuffer {
int slot, int slot,
void *r_data) override; void *r_data) override;
/**
* Copy \a src at the give offset inside \a dst.
*/
void blit_to(eGPUFrameBufferBits planes, void blit_to(eGPUFrameBufferBits planes,
int src_slot, int src_slot,
FrameBuffer *dst, FrameBuffer *dst,

View File

@@ -137,7 +137,6 @@ char *GLShader::glsl_patch_get(GLenum gl_stage)
return glsl_patch_default_get(); return glsl_patch_default_get();
} }
/* Create, compile and attach the shader stage to the shader program. */
GLuint GLShader::create_shader_stage(GLenum gl_stage, MutableSpan<const char *> sources) GLuint GLShader::create_shader_stage(GLenum gl_stage, MutableSpan<const char *> sources)
{ {
GLuint shader = glCreateShader(gl_stage); GLuint shader = glCreateShader(gl_stage);
@@ -258,7 +257,6 @@ void GLShader::unbind()
* TODO(fclem): Should be replaced by compute shaders. * TODO(fclem): Should be replaced by compute shaders.
* \{ */ * \{ */
/* Should be called before linking. */
void GLShader::transform_feedback_names_set(Span<const char *> name_list, void GLShader::transform_feedback_names_set(Span<const char *> name_list,
const eGPUShaderTFBType geom_type) const eGPUShaderTFBType geom_type)
{ {

View File

@@ -53,13 +53,14 @@ class GLShader : public Shader {
GLShader(const char *name); GLShader(const char *name);
~GLShader(); ~GLShader();
/* Return true on success. */ /** Return true on success. */
void vertex_shader_from_glsl(MutableSpan<const char *> sources) override; void vertex_shader_from_glsl(MutableSpan<const char *> sources) override;
void geometry_shader_from_glsl(MutableSpan<const char *> sources) override; void geometry_shader_from_glsl(MutableSpan<const char *> sources) override;
void fragment_shader_from_glsl(MutableSpan<const char *> sources) override; void fragment_shader_from_glsl(MutableSpan<const char *> sources) override;
void compute_shader_from_glsl(MutableSpan<const char *> sources) override; void compute_shader_from_glsl(MutableSpan<const char *> sources) override;
bool finalize(void) override; bool finalize(void) override;
/** Should be called before linking. */
void transform_feedback_names_set(Span<const char *> name_list, void transform_feedback_names_set(Span<const char *> name_list,
const eGPUShaderTFBType geom_type) override; const eGPUShaderTFBType geom_type) override;
bool transform_feedback_enable(GPUVertBuf *buf) override; bool transform_feedback_enable(GPUVertBuf *buf) override;
@@ -73,12 +74,13 @@ class GLShader : public Shader {
void vertformat_from_shader(GPUVertFormat *format) const override; void vertformat_from_shader(GPUVertFormat *format) const override;
/* DEPRECATED: Kept only because of BGL API. */ /** DEPRECATED: Kept only because of BGL API. */
int program_handle_get(void) const override; int program_handle_get(void) const override;
private: private:
char *glsl_patch_get(GLenum gl_stage); char *glsl_patch_get(GLenum gl_stage);
/** Create, compile and attach the shader stage to the shader program. */
GLuint create_shader_stage(GLenum gl_stage, MutableSpan<const char *> sources); GLuint create_shader_stage(GLenum gl_stage, MutableSpan<const char *> sources);
MEM_CXX_CLASS_ALLOC_FUNCS("GLShader"); MEM_CXX_CLASS_ALLOC_FUNCS("GLShader");

View File

@@ -84,7 +84,6 @@ void GLStateManager::apply_state()
active_fb->apply_state(); active_fb->apply_state();
}; };
/* Will set all the states regardless of the current ones. */
void GLStateManager::force_state() void GLStateManager::force_state()
{ {
/* Little exception for clip distances since they need to keep the old count correct. */ /* Little exception for clip distances since they need to keep the old count correct. */
@@ -482,7 +481,6 @@ void GLStateManager::texture_bind(Texture *tex_, eGPUSamplerState sampler_type,
dirty_texture_binds_ |= 1ULL << unit; dirty_texture_binds_ |= 1ULL << unit;
} }
/* Bind the texture to slot 0 for editing purpose. Used by legacy pipeline. */
void GLStateManager::texture_bind_temp(GLTexture *tex) void GLStateManager::texture_bind_temp(GLTexture *tex)
{ {
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);

View File

@@ -72,11 +72,17 @@ class GLStateManager : public StateManager {
GLStateManager(); GLStateManager();
void apply_state(void) override; void apply_state(void) override;
/**
* Will set all the states regardless of the current ones.
*/
void force_state(void) override; void force_state(void) override;
void issue_barrier(eGPUBarrier barrier_bits) override; void issue_barrier(eGPUBarrier barrier_bits) override;
void texture_bind(Texture *tex, eGPUSamplerState sampler, int unit) override; void texture_bind(Texture *tex, eGPUSamplerState sampler, int unit) override;
/**
* Bind the texture to slot 0 for editing purpose. Used by legacy pipeline.
*/
void texture_bind_temp(GLTexture *tex); void texture_bind_temp(GLTexture *tex);
void texture_unbind(Texture *tex) override; void texture_unbind(Texture *tex) override;
void texture_unbind_all(void) override; void texture_unbind_all(void) override;

View File

@@ -62,7 +62,6 @@ GLTexture::~GLTexture()
GLContext::tex_free(tex_id_); GLContext::tex_free(tex_id_);
} }
/* Return true on success. */
bool GLTexture::init_internal() bool GLTexture::init_internal()
{ {
if ((format_ == GPU_DEPTH24_STENCIL8) && GPU_depth_blitting_workaround()) { if ((format_ == GPU_DEPTH24_STENCIL8) && GPU_depth_blitting_workaround()) {
@@ -100,7 +99,6 @@ bool GLTexture::init_internal()
return true; return true;
} }
/* Return true on success. */
bool GLTexture::init_internal(GPUVertBuf *vbo) bool GLTexture::init_internal(GPUVertBuf *vbo)
{ {
GLVertBuf *gl_vbo = static_cast<GLVertBuf *>(unwrap(vbo)); GLVertBuf *gl_vbo = static_cast<GLVertBuf *>(unwrap(vbo));
@@ -123,7 +121,6 @@ bool GLTexture::init_internal(GPUVertBuf *vbo)
return true; return true;
} }
/* Will create enough mipmaps up to get to the given level. */
void GLTexture::ensure_mipmaps(int miplvl) void GLTexture::ensure_mipmaps(int miplvl)
{ {
int effective_h = (type_ == GPU_TEXTURE_1D_ARRAY) ? 0 : h_; int effective_h = (type_ == GPU_TEXTURE_1D_ARRAY) ? 0 : h_;

View File

@@ -63,6 +63,12 @@ class GLTexture : public Texture {
void update_sub( void update_sub(
int mip, int offset[3], int extent[3], eGPUDataFormat type, const void *data) override; int mip, int offset[3], int extent[3], eGPUDataFormat type, const void *data) override;
/**
* This will create the mipmap images and populate them with filtered data from base level.
*
* \warning Depth textures are not populated but they have their mips correctly defined.
* \warning This resets the mipmap range.
*/
void generate_mipmap(void) override; void generate_mipmap(void) override;
void copy_to(Texture *dst) override; void copy_to(Texture *dst) override;
void clear(eGPUDataFormat format, const void *data) override; void clear(eGPUDataFormat format, const void *data) override;
@@ -80,11 +86,14 @@ class GLTexture : public Texture {
static void samplers_update(void); static void samplers_update(void);
protected: protected:
/** Return true on success. */
bool init_internal(void) override; bool init_internal(void) override;
/** Return true on success. */
bool init_internal(GPUVertBuf *vbo) override; bool init_internal(GPUVertBuf *vbo) override;
private: private:
bool proxy_check(int mip); bool proxy_check(int mip);
/** Will create enough mipmaps up to get to the given level. */
void ensure_mipmaps(int mip); void ensure_mipmaps(int mip);
void update_sub_direct_state_access( void update_sub_direct_state_access(
int mip, int offset[3], int extent[3], GLenum gl_format, GLenum gl_type, const void *data); int mip, int offset[3], int extent[3], GLenum gl_format, GLenum gl_type, const void *data);
@@ -294,7 +303,9 @@ inline GLenum to_gl(eGPUDataFormat format)
} }
} }
/* Definitely not complete, edit according to the gl specification. */ /**
* Definitely not complete, edit according to the OpenGL specification.
*/
inline GLenum to_gl_data_format(eGPUTextureFormat format) inline GLenum to_gl_data_format(eGPUTextureFormat format)
{ {
/* You can add any of the available type to this list /* You can add any of the available type to this list
@@ -366,7 +377,9 @@ inline GLenum to_gl_data_format(eGPUTextureFormat format)
} }
} }
/* Assume Unorm / Float target. Used with glReadPixels. */ /**
* Assume Unorm / Float target. Used with #glReadPixels.
*/
inline GLenum channel_len_to_gl(int channel_len) inline GLenum channel_len_to_gl(int channel_len)
{ {
switch (channel_len) { switch (channel_len) {

View File

@@ -108,7 +108,6 @@ static uint16_t vbo_bind(const ShaderInterface *interface,
return enabled_attrib; return enabled_attrib;
} }
/* Update the Attribute Binding of the currently bound VAO. */
void GLVertArray::update_bindings(const GLuint vao, void GLVertArray::update_bindings(const GLuint vao,
const GPUBatch *batch_, /* Should be GLBatch. */ const GPUBatch *batch_, /* Should be GLBatch. */
const ShaderInterface *interface, const ShaderInterface *interface,
@@ -156,7 +155,6 @@ void GLVertArray::update_bindings(const GLuint vao,
} }
} }
/* Another version of update_bindings for Immediate mode. */
void GLVertArray::update_bindings(const GLuint vao, void GLVertArray::update_bindings(const GLuint vao,
const uint v_first, const uint v_first,
const GPUVertFormat *format, const GPUVertFormat *format,

View File

@@ -33,11 +33,17 @@ namespace gpu {
namespace GLVertArray { namespace GLVertArray {
/**
* Update the Attribute Binding of the currently bound VAO.
*/
void update_bindings(const GLuint vao, void update_bindings(const GLuint vao,
const GPUBatch *batch, const GPUBatch *batch,
const ShaderInterface *interface, const ShaderInterface *interface,
const int base_instance); const int base_instance);
/**
* Another version of update_bindings for Immediate mode.
*/
void update_bindings(const GLuint vao, void update_bindings(const GLuint vao,
const uint v_first, const uint v_first,
const GPUVertFormat *format, const GPUVertFormat *format,