1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

sokol: upgrade to latest version, add program icon support (#11559)

* updated sokol_gfx.h to the last version: 16d7b2e

* merged sokol_app and update enums.v

* added missing icons structs

* try to fixing Mac keyboard problems

* added v patch marker to sokol_app.h

* upgrade for sokol_gl.h, sokol_fontstash.h

* manage sgl_load_default_pipeline

* added load_default_pipeline() for sokol coherence

* vfmt sapp_structs.c.v

Co-authored-by: Delyan Angelov <delian66@gmail.com>
This commit is contained in:
penguindark 2021-09-21 08:55:06 +02:00 committed by GitHub
parent 49886b8c40
commit e4bd2306da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 2487 additions and 1020 deletions

File diff suppressed because it is too large Load Diff

View File

@ -871,7 +871,8 @@ typedef struct sg_limits {
int max_image_size_3d; // max width/height/depth of SG_IMAGETYPE_3D images
int max_image_size_array; // max width/height of SG_IMAGETYPE_ARRAY images
int max_image_array_layers; // max number of layers in SG_IMAGETYPE_ARRAY images
int max_vertex_attrs; // <= SG_MAX_VERTEX_ATTRIBUTES (only on some GLES2 impls)
int max_vertex_attrs; // <= SG_MAX_VERTEX_ATTRIBUTES or less (on some GLES2 impls)
int gl_max_vertex_uniform_vectors; // <= GL_MAX_VERTEX_UNIFORM_VECTORS (only on GL backends)
} sg_limits;
/*
@ -2529,7 +2530,6 @@ inline int sg_append_buffer(sg_buffer buf_id, const sg_range& data) { return sg_
#pragma comment (lib, "user32")
#pragma comment (lib, "dxgi")
#pragma comment (lib, "d3d11")
#pragma comment (lib, "dxguid")
#endif
#endif
#elif defined(SOKOL_METAL)
@ -2831,6 +2831,7 @@ inline int sg_append_buffer(sg_buffer buf_id, const sg_range& data) { return sg_
#define GL_CLAMP_TO_BORDER 0x812D
#define GL_TEXTURE_BORDER_COLOR 0x1004
#define GL_CURRENT_PROGRAM 0x8B8D
#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
#endif
#ifndef GL_UNSIGNED_INT_2_10_10_10_REV
@ -3109,7 +3110,7 @@ typedef struct {
} _sg_pipeline_common_t;
_SOKOL_PRIVATE void _sg_pipeline_common_init(_sg_pipeline_common_t* cmn, const sg_pipeline_desc* desc) {
SOKOL_ASSERT(desc->color_count < SG_MAX_COLOR_ATTACHMENTS);
SOKOL_ASSERT((desc->color_count >= 1) && (desc->color_count <= SG_MAX_COLOR_ATTACHMENTS));
cmn->shader_id = desc->shader;
cmn->index_type = desc->index_type;
for (int i = 0; i < SG_MAX_SHADERSTAGE_BUFFERS; i++) {
@ -3336,7 +3337,7 @@ typedef _sg_gl_image_t _sg_image_t;
typedef struct {
GLint gl_loc;
sg_uniform_type type;
uint8_t count;
uint16_t count;
uint16_t offset;
} _sg_gl_uniform_t;
@ -3596,14 +3597,6 @@ typedef struct {
HINSTANCE d3dcompiler_dll;
bool d3dcompiler_dll_load_failed;
pD3DCompile D3DCompile_func;
/* the following arrays are used for unbinding resources, they will always contain zeroes */
ID3D11RenderTargetView* zero_rtvs[SG_MAX_COLOR_ATTACHMENTS];
ID3D11Buffer* zero_vbs[SG_MAX_SHADERSTAGE_BUFFERS];
UINT zero_vb_offsets[SG_MAX_SHADERSTAGE_BUFFERS];
UINT zero_vb_strides[SG_MAX_SHADERSTAGE_BUFFERS];
ID3D11Buffer* zero_cbs[SG_MAX_SHADERSTAGE_UBS];
ID3D11ShaderResourceView* zero_srvs[SG_MAX_SHADERSTAGE_IMAGES];
ID3D11SamplerState* zero_smps[SG_MAX_SHADERSTAGE_IMAGES];
/* global subresourcedata array for texture updates */
D3D11_SUBRESOURCE_DATA subres_data[SG_MAX_MIPMAPS * SG_MAX_TEXTUREARRAY_LAYERS];
} _sg_d3d11_backend_t;
@ -5517,6 +5510,9 @@ _SOKOL_PRIVATE void _sg_gl_init_limits(void) {
gl_int = SG_MAX_VERTEX_ATTRIBUTES;
}
_sg.limits.max_vertex_attrs = gl_int;
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &gl_int);
_SG_GL_CHECK_ERROR();
_sg.limits.gl_max_vertex_uniform_vectors = gl_int;
#if !defined(SOKOL_GLES2)
if (!_sg.gl.gles2) {
glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &gl_int);
@ -5976,6 +5972,14 @@ _SOKOL_PRIVATE void _sg_gl_cache_invalidate_program(GLuint prog) {
}
}
/* called from _sg_gl_destroy_pipeline() */
_SOKOL_PRIVATE void _sg_gl_cache_invalidate_pipeline(_sg_pipeline_t* pip) {
if (pip == _sg.gl.cache.cur_pipeline) {
_sg.gl.cache.cur_pipeline = 0;
_sg.gl.cache.cur_pipeline_id.id = SG_INVALID_ID;
}
}
_SOKOL_PRIVATE void _sg_gl_reset_state_cache(void) {
if (_sg.gl.cur_context) {
_SG_GL_CHECK_ERROR();
@ -6151,6 +6155,7 @@ _SOKOL_PRIVATE sg_resource_state _sg_gl_create_buffer(_sg_buffer_t* buf, const s
}
else {
glGenBuffers(1, &gl_buf);
SOKOL_ASSERT(gl_buf);
_sg_gl_cache_store_buffer_binding(gl_target);
_sg_gl_cache_bind_buffer(gl_target, gl_buf);
glBufferData(gl_target, buf->cmn.size, 0, gl_usage);
@ -6475,7 +6480,7 @@ _SOKOL_PRIVATE sg_resource_state _sg_gl_create_shader(_sg_shader_t* shd, const s
}
_sg_gl_uniform_t* u = &ub->uniforms[u_index];
u->type = u_desc->type;
u->count = (uint8_t) u_desc->array_count;
u->count = (uint16_t) u_desc->array_count;
u->offset = (uint16_t) cur_uniform_offset;
cur_uniform_offset += _sg_uniform_size(u->type, u->count);
if (u_desc->name) {
@ -6598,8 +6603,7 @@ _SOKOL_PRIVATE sg_resource_state _sg_gl_create_pipeline(_sg_pipeline_t* pip, _sg
_SOKOL_PRIVATE void _sg_gl_destroy_pipeline(_sg_pipeline_t* pip) {
SOKOL_ASSERT(pip);
_SOKOL_UNUSED(pip);
/* empty */
_sg_gl_cache_invalidate_pipeline(pip);
}
/*
@ -6765,6 +6769,7 @@ _SOKOL_PRIVATE sg_resource_state _sg_gl_create_pass(_sg_pass_t* pass, _sg_image_
_SOKOL_PRIVATE void _sg_gl_destroy_pass(_sg_pass_t* pass) {
SOKOL_ASSERT(pass);
SOKOL_ASSERT(pass != _sg.gl.cur_pass);
_SG_GL_CHECK_ERROR();
if (0 != pass->gl.fb) {
glDeleteFramebuffers(1, &pass->gl.fb);
@ -7840,6 +7845,14 @@ static inline void _sg_d3d11_Unmap(ID3D11DeviceContext* self, ID3D11Resource* pR
#endif
}
static inline void _sg_d3d11_ClearState(ID3D11DeviceContext* self) {
#if defined(__cplusplus)
self->ClearState();
#else
self->lpVtbl->ClearState(self);
#endif
}
/*-- enum translation functions ----------------------------------------------*/
_SOKOL_PRIVATE D3D11_USAGE _sg_d3d11_usage(sg_usage usg) {
switch (usg) {
@ -8178,21 +8191,7 @@ _SOKOL_PRIVATE void _sg_d3d11_discard_backend(void) {
_SOKOL_PRIVATE void _sg_d3d11_clear_state(void) {
/* clear all the device context state, so that resource refs don't keep stuck in the d3d device context */
_sg_d3d11_OMSetRenderTargets(_sg.d3d11.ctx, SG_MAX_COLOR_ATTACHMENTS, _sg.d3d11.zero_rtvs, NULL);
_sg_d3d11_RSSetState(_sg.d3d11.ctx, NULL);
_sg_d3d11_OMSetDepthStencilState(_sg.d3d11.ctx, NULL, 0);
_sg_d3d11_OMSetBlendState(_sg.d3d11.ctx, NULL, NULL, 0xFFFFFFFF);
_sg_d3d11_IASetVertexBuffers(_sg.d3d11.ctx, 0, SG_MAX_SHADERSTAGE_BUFFERS, _sg.d3d11.zero_vbs, _sg.d3d11.zero_vb_strides, _sg.d3d11.zero_vb_offsets);
_sg_d3d11_IASetIndexBuffer(_sg.d3d11.ctx, NULL, DXGI_FORMAT_UNKNOWN, 0);
_sg_d3d11_IASetInputLayout(_sg.d3d11.ctx, NULL);
_sg_d3d11_VSSetShader(_sg.d3d11.ctx, NULL, NULL, 0);
_sg_d3d11_PSSetShader(_sg.d3d11.ctx, NULL, NULL, 0);
_sg_d3d11_VSSetConstantBuffers(_sg.d3d11.ctx, 0, SG_MAX_SHADERSTAGE_UBS, _sg.d3d11.zero_cbs);
_sg_d3d11_PSSetConstantBuffers(_sg.d3d11.ctx, 0, SG_MAX_SHADERSTAGE_UBS, _sg.d3d11.zero_cbs);
_sg_d3d11_VSSetShaderResources(_sg.d3d11.ctx, 0, SG_MAX_SHADERSTAGE_IMAGES, _sg.d3d11.zero_srvs);
_sg_d3d11_PSSetShaderResources(_sg.d3d11.ctx, 0, SG_MAX_SHADERSTAGE_IMAGES, _sg.d3d11.zero_srvs);
_sg_d3d11_VSSetSamplers(_sg.d3d11.ctx, 0, SG_MAX_SHADERSTAGE_IMAGES, _sg.d3d11.zero_smps);
_sg_d3d11_PSSetSamplers(_sg.d3d11.ctx, 0, SG_MAX_SHADERSTAGE_IMAGES, _sg.d3d11.zero_smps);
_sg_d3d11_ClearState(_sg.d3d11.ctx);
}
_SOKOL_PRIVATE void _sg_d3d11_reset_state_cache(void) {
@ -8839,6 +8838,10 @@ _SOKOL_PRIVATE sg_resource_state _sg_d3d11_create_pipeline(_sg_pipeline_t* pip,
_SOKOL_PRIVATE void _sg_d3d11_destroy_pipeline(_sg_pipeline_t* pip) {
SOKOL_ASSERT(pip);
if (pip == _sg.d3d11.cur_pipeline) {
_sg.d3d11.cur_pipeline = 0;
_sg.d3d11.cur_pipeline_id.id = SG_INVALID_ID;
}
if (pip->d3d11.il) {
_sg_d3d11_Release(pip->d3d11.il);
}
@ -8945,6 +8948,7 @@ _SOKOL_PRIVATE sg_resource_state _sg_d3d11_create_pass(_sg_pass_t* pass, _sg_ima
_SOKOL_PRIVATE void _sg_d3d11_destroy_pass(_sg_pass_t* pass) {
SOKOL_ASSERT(pass);
SOKOL_ASSERT(pass != _sg.d3d11.cur_pass);
for (int i = 0; i < SG_MAX_COLOR_ATTACHMENTS; i++) {
if (pass->d3d11.color_atts[i].rtv) {
_sg_d3d11_Release(pass->d3d11.color_atts[i].rtv);
@ -9329,13 +9333,17 @@ _SOKOL_PRIVATE MTLLoadAction _sg_mtl_load_action(sg_action a) {
_SOKOL_PRIVATE MTLResourceOptions _sg_mtl_buffer_resource_options(sg_usage usg) {
switch (usg) {
case SG_USAGE_IMMUTABLE:
#if defined(_SG_TARGET_MACOS)
return MTLResourceStorageModeManaged;
#else
return MTLResourceStorageModeShared;
#endif
case SG_USAGE_DYNAMIC:
case SG_USAGE_STREAM:
#if defined(_SG_TARGET_MACOS)
return MTLCPUCacheModeWriteCombined|MTLResourceStorageModeManaged;
return MTLResourceCPUCacheModeWriteCombined|MTLResourceStorageModeManaged;
#else
return MTLCPUCacheModeWriteCombined;
return MTLResourceCPUCacheModeWriteCombined|MTLResourceStorageModeShared;
#endif
default:
SOKOL_UNREACHABLE;
@ -9981,14 +9989,10 @@ _SOKOL_PRIVATE void _sg_mtl_setup_backend(const sg_desc* desc) {
_sg.mtl.sem = dispatch_semaphore_create(SG_NUM_INFLIGHT_FRAMES);
_sg.mtl.device = (__bridge id<MTLDevice>) desc->context.metal.device;
_sg.mtl.cmd_queue = [_sg.mtl.device newCommandQueue];
MTLResourceOptions res_opts = MTLResourceCPUCacheModeWriteCombined;
#if defined(_SG_TARGET_MACOS)
res_opts |= MTLResourceStorageModeManaged;
#endif
for (int i = 0; i < SG_NUM_INFLIGHT_FRAMES; i++) {
_sg.mtl.uniform_buffers[i] = [_sg.mtl.device
newBufferWithLength:(NSUInteger)_sg.mtl.ub_size
options:res_opts
options:MTLResourceCPUCacheModeWriteCombined|MTLResourceStorageModeShared
];
}
_sg_mtl_init_caps();
@ -10175,18 +10179,18 @@ _SOKOL_PRIVATE bool _sg_mtl_init_texdesc_common(MTLTextureDescriptor* mtl_desc,
mtl_desc.arrayLength = 1;
}
mtl_desc.usage = MTLTextureUsageShaderRead;
MTLResourceOptions res_options = 0;
if (img->cmn.usage != SG_USAGE_IMMUTABLE) {
mtl_desc.cpuCacheMode = MTLCPUCacheModeWriteCombined;
res_options |= MTLResourceCPUCacheModeWriteCombined;
}
#if defined(_SG_TARGET_MACOS)
/* macOS: use managed textures */
mtl_desc.resourceOptions = MTLResourceStorageModeManaged;
mtl_desc.storageMode = MTLStorageModeManaged;
res_options |= MTLResourceStorageModeManaged;
#else
/* iOS: use CPU/GPU shared memory */
mtl_desc.resourceOptions = MTLResourceStorageModeShared;
mtl_desc.storageMode = MTLStorageModeShared;
res_options |= MTLResourceStorageModeShared;
#endif
mtl_desc.resourceOptions = res_options;
return true;
}
@ -10194,11 +10198,8 @@ _SOKOL_PRIVATE bool _sg_mtl_init_texdesc_common(MTLTextureDescriptor* mtl_desc,
_SOKOL_PRIVATE void _sg_mtl_init_texdesc_rt(MTLTextureDescriptor* mtl_desc, _sg_image_t* img) {
SOKOL_ASSERT(img->cmn.render_target);
_SOKOL_UNUSED(img);
/* reset the cpuCacheMode to 'default' */
mtl_desc.cpuCacheMode = MTLCPUCacheModeDefaultCache;
/* render targets are only visible to the GPU */
mtl_desc.resourceOptions = MTLResourceStorageModePrivate;
mtl_desc.storageMode = MTLStorageModePrivate;
/* non-MSAA render targets are shader-readable */
mtl_desc.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget;
}
@ -10206,11 +10207,8 @@ _SOKOL_PRIVATE void _sg_mtl_init_texdesc_rt(MTLTextureDescriptor* mtl_desc, _sg_
/* initialize MTLTextureDescritor with MSAA attributes */
_SOKOL_PRIVATE void _sg_mtl_init_texdesc_rt_msaa(MTLTextureDescriptor* mtl_desc, _sg_image_t* img) {
SOKOL_ASSERT(img->cmn.sample_count > 1);
/* reset the cpuCacheMode to 'default' */
mtl_desc.cpuCacheMode = MTLCPUCacheModeDefaultCache;
/* render targets are only visible to the GPU */
mtl_desc.resourceOptions = MTLResourceStorageModePrivate;
mtl_desc.storageMode = MTLStorageModePrivate;
/* MSAA render targets are not shader-readable (instead they are resolved) */
mtl_desc.usage = MTLTextureUsageRenderTarget;
mtl_desc.textureType = MTLTextureType2DMultisample;
@ -10578,6 +10576,11 @@ _SOKOL_PRIVATE void _sg_mtl_begin_pass(_sg_pass_t* pass, const sg_pass_action* a
/* block until the oldest frame in flight has finished */
dispatch_semaphore_wait(_sg.mtl.sem, DISPATCH_TIME_FOREVER);
_sg.mtl.cmd_buffer = [_sg.mtl.cmd_queue commandBufferWithUnretainedReferences];
[_sg.mtl.cmd_buffer addCompletedHandler:^(id<MTLCommandBuffer> cmd_buffer) {
// NOTE: this code is called on a different thread!
_SOKOL_UNUSED(cmd_buffer);
dispatch_semaphore_signal(_sg.mtl.sem);
}];
}
/* if this is first pass in frame, get uniform buffer base pointer */
@ -10712,10 +10715,6 @@ _SOKOL_PRIVATE void _sg_mtl_commit(void) {
SOKOL_ASSERT(nil == _sg.mtl.cmd_encoder);
SOKOL_ASSERT(nil != _sg.mtl.cmd_buffer);
#if defined(_SG_TARGET_MACOS)
[_sg.mtl.uniform_buffers[_sg.mtl.cur_frame_rotate_index] didModifyRange:NSMakeRange(0, (NSUInteger)_sg.mtl.cur_ub_offset)];
#endif
/* present, commit and signal semaphore when done */
id<MTLDrawable> cur_drawable = nil;
if (_sg.mtl.drawable_cb) {
@ -10724,11 +10723,9 @@ _SOKOL_PRIVATE void _sg_mtl_commit(void) {
else {
cur_drawable = (__bridge id<MTLDrawable>) _sg.mtl.drawable_userdata_cb(_sg.mtl.user_data);
}
[_sg.mtl.cmd_buffer presentDrawable:cur_drawable];
[_sg.mtl.cmd_buffer addCompletedHandler:^(id<MTLCommandBuffer> cmd_buffer) {
_SOKOL_UNUSED(cmd_buffer);
dispatch_semaphore_signal(_sg.mtl.sem);
}];
if (nil != cur_drawable) {
[_sg.mtl.cmd_buffer presentDrawable:cur_drawable];
}
[_sg.mtl.cmd_buffer commit];
/* garbage-collect resources pending for release */
@ -12288,6 +12285,10 @@ _SOKOL_PRIVATE sg_resource_state _sg_wgpu_create_pipeline(_sg_pipeline_t* pip, _
_SOKOL_PRIVATE void _sg_wgpu_destroy_pipeline(_sg_pipeline_t* pip) {
SOKOL_ASSERT(pip);
if (pip == _sg.wgpu.cur_pipeline) {
_sg.wgpu.cur_pipeline = 0;
_Sg.wgpu.cur_pipeline_id.id = SG_INVALID_ID;
}
if (pip->wgpu.pip) {
wgpuRenderPipelineRelease(pip->wgpu.pip);
pip->wgpu.pip = 0;
@ -15371,6 +15372,7 @@ SOKOL_API_IMPL void sg_apply_uniforms(sg_shader_stage stage, int ub_index, const
}
if (!_sg.next_draw_valid) {
_SG_TRACE_NOARGS(err_draw_invalid);
return;
}
_sg_apply_uniforms(stage, ub_index, data);
_SG_TRACE_ARGS(apply_uniforms, stage, ub_index, data);
@ -15554,6 +15556,7 @@ SOKOL_API_IMPL sg_image_info sg_query_image_info(sg_image img_id) {
info.slot.state = img->slot.state;
info.slot.res_id = img->slot.id;
info.slot.ctx_id = img->slot.ctx_id;
info.upd_frame_index = img->cmn.upd_frame_index;
#if defined(SOKOL_D3D11)
info.num_slots = 1;
info.active_slot = 0;

View File

@ -112,7 +112,7 @@
sgl_load_pipeline(...);
sgl_begin_triangles();
for each vertex:
sg_v2f_t2f_c1i(...);
sgl_v2f_t2f_c1i(...);
sgl_end();
sgl_pop_pipeline();
sgl_disable_texture();
@ -1645,8 +1645,8 @@ static int _sfons_render_create(void* user_ptr, int width, int height) {
shd_desc.fs.byte_code = _sfons_fs_bytecode_wgpu;
shd_desc.fs.byte_code_size = sizeof(_sfons_fs_bytecode_wgpu);
#else
shd_desc.vs.source = _sfons_vs_src_dummy;
shd_desc.fs.source = _sfons_fs_src_dummy;
shd_desc.vs.source = _sfons_vs_source_dummy;
shd_desc.fs.source = _sfons_fs_source_dummy;
#endif
shd_desc.label = "sfons-shader";
sfons->shd = sg_make_shader(&shd_desc);
@ -1782,4 +1782,4 @@ SOKOL_API_IMPL uint32_t sfons_rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
return ((uint32_t)r) | ((uint32_t)g<<8) | ((uint32_t)b<<16) | ((uint32_t)a<<24);
}
#endif /* SOKOL_FONTSTASH_IMPL */
#endif /* SOKOL_FONTSTASH_IMPL */

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,8 @@ pub enum EventType {
resized
iconified
restored
focused
unfocused
suspended
resumed
update_cursor
@ -39,6 +41,9 @@ pub enum Modifier {
ctrl = 2 //(1<<1)
alt = 4 //(1<<2)
super = 8 //(1<<3)
lmb = 0x100
rmb = 0x200
mmb = 0x400
}
pub enum KeyCode {

View File

@ -1,5 +1,30 @@
module sapp
const (
sapp_max_touchpoints = 8
sapp_max_mousebuttons = 3
sapp_max_keycodes = 512
sapp_max_iconimages = 8
)
pub struct C.sapp_range {
pub:
ptr voidptr
size usize
}
pub struct C.sapp_image_desc {
pub:
width int
height int
pixels C.spp_range
}
pub struct C.sapp_icon_desc {
sokol_default bool
images [sapp_max_iconimages]C.sapp_image_desc
}
pub struct C.sapp_desc {
pub:
init_cb fn () // these are the user-provided callbacks without user data
@ -29,6 +54,7 @@ pub:
enable_dragndrop bool // enable file dropping (drag'n'drop), default is false
max_dropped_files int // max number of dropped files to process (default: 1)
max_dropped_file_path_length int // max length in bytes of a dropped UTF-8 file path (default: 2048)
icon C.sapp_icon_desc
// backend-specific options
gl_force_gles2 bool // if true, setup GLES2/WebGL even if GLES3/WebGL2 is available
win32_console_utf8 bool // if true, set the output console codepage to UTF-8
@ -60,7 +86,7 @@ pub:
scroll_x f32
scroll_y f32
num_touches int
touches [8]C.sapp_touchpoint
touches [sapp_max_touchpoints]C.sapp_touchpoint
window_width int
window_height int
framebuffer_width int
@ -83,7 +109,7 @@ pub:
scroll_x f32
scroll_y f32
num_touches int
touches [8]C.sapp_touchpoint
touches [sapp_max_touchpoints]C.sapp_touchpoint
window_width int
window_height int
framebuffer_width int

View File

@ -75,9 +75,14 @@ pub fn texture(img C.sg_image) {
}
// pipeline stack functions
[inline]
pub fn load_default_pipeline() {
C.sgl_load_default_pipeline()
}
[inline]
pub fn default_pipeline() {
C.sgl_default_pipeline()
C.sgl_load_default_pipeline()
}
[inline]

View File

@ -22,7 +22,7 @@ fn C.sgl_disable_texture()
fn C.sgl_texture(img C.sg_image)
// pipeline stack functions
fn C.sgl_default_pipeline()
fn C.sgl_load_default_pipeline()
fn C.sgl_load_pipeline(pip C.sgl_pipeline)
fn C.sgl_push_pipeline()
fn C.sgl_pop_pipeline()