Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
292 changes: 289 additions & 3 deletions sokol_gfx.h

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions tests/functional/d3d11/sokol_gfx_d3d11_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,7 @@ UTEST(sokol_gfx_d3d11, draw_indexed_and_instanced) {
ID3D11RenderTargetView* rtv = d3d11_mock_create_rtv(mock_dev);
sg_shader shd = make_test_shader();
sg_pipeline pip = sg_make_pipeline(&(sg_pipeline_desc){
.depth.pixel_format = SG_PIXELFORMAT_NONE,
.shader = shd, .index_type = SG_INDEXTYPE_UINT16,
.layout = { .attrs = { [0] = { .format = SG_VERTEXFORMAT_FLOAT3 }, [1] = { .format = SG_VERTEXFORMAT_UBYTE4N } } },
});
Expand All @@ -796,6 +797,9 @@ UTEST(sokol_gfx_d3d11, draw_indexed_and_instanced) {
sg_buffer vbuf = sg_make_buffer(&(sg_buffer_desc){ .data = SG_RANGE(verts) });
sg_buffer ibuf = sg_make_buffer(&(sg_buffer_desc){ .usage.index_buffer = true, .data = SG_RANGE(indices) });

const uint32_t args[8] = {0, 3, 1, 0, 0, 0, 0, 0};
sg_buffer indirect = sg_make_buffer(&(sg_buffer_desc){ .usage.indirect_buffer = true, .data = SG_RANGE(args) });
T(sg_query_buffer_state(indirect) == SG_RESOURCESTATE_VALID);
sg_begin_pass(&(sg_pass){
.swapchain = { .width = 64, .height = 64, .sample_count = 1,
.color_format = SG_PIXELFORMAT_BGRA8, .depth_format = SG_PIXELFORMAT_NONE,
Expand All @@ -808,6 +812,8 @@ UTEST(sokol_gfx_d3d11, draw_indexed_and_instanced) {
});
sg_draw(0, 6, 1); // exercises DrawIndexed
sg_draw(0, 6, 4); // DrawIndexedInstanced
sg_draw_indirect(indirect, 4);
T(num_log_items == 0);
sg_end_pass();
sg_commit();

Expand All @@ -817,6 +823,7 @@ UTEST(sokol_gfx_d3d11, draw_indexed_and_instanced) {
sg_destroy_shader(shd);
rtv->lpVtbl->Release(rtv);
T(sg_isvalid());
sg_destroy_buffer(indirect);
teardown();
}

Expand All @@ -825,11 +832,15 @@ UTEST(sokol_gfx_d3d11, draw_non_indexed_and_instanced) {
ID3D11RenderTargetView* rtv = d3d11_mock_create_rtv(mock_dev);
sg_shader shd = make_test_shader();
sg_pipeline pip = sg_make_pipeline(&(sg_pipeline_desc){
.depth.pixel_format = SG_PIXELFORMAT_NONE,
.shader = shd,
.layout = { .attrs = { [0] = { .format = SG_VERTEXFORMAT_FLOAT3 }, [1] = { .format = SG_VERTEXFORMAT_UBYTE4N } } },
});
static const float verts[24] = {0};
sg_buffer vbuf = sg_make_buffer(&(sg_buffer_desc){ .data = SG_RANGE(verts) });
const uint32_t args[8] = {0, 3, 1, 0, 0, 0, 0, 0};
sg_buffer indirect = sg_make_buffer(&(sg_buffer_desc){ .usage.indirect_buffer = true, .data = SG_RANGE(args) });
T(sg_query_buffer_state(indirect) == SG_RESOURCESTATE_VALID);
sg_begin_pass(&(sg_pass){
.swapchain = { .width = 64, .height = 64, .sample_count = 1,
.color_format = SG_PIXELFORMAT_BGRA8, .depth_format = SG_PIXELFORMAT_NONE,
Expand All @@ -839,13 +850,16 @@ UTEST(sokol_gfx_d3d11, draw_non_indexed_and_instanced) {
sg_apply_bindings(&(sg_bindings){ .vertex_buffers[0] = vbuf });
sg_draw(0, 3, 1); // Draw
sg_draw(0, 3, 8); // DrawInstanced
sg_draw_indirect(indirect, 4);
T(num_log_items == 0);
sg_end_pass();
sg_commit();
sg_destroy_buffer(vbuf);
sg_destroy_pipeline(pip);
sg_destroy_shader(shd);
rtv->lpVtbl->Release(rtv);
T(sg_isvalid());
sg_destroy_buffer(indirect);
teardown();
}

Expand Down Expand Up @@ -894,14 +908,20 @@ UTEST(sokol_gfx_d3d11, dispatch_compute) {
sg_pipeline pip = sg_make_pipeline(&(sg_pipeline_desc){
.shader = shd, .compute = true,
});
const uint32_t args[8] = {0, 3, 1, 0, 0, 0, 0, 0};
sg_buffer indirect = sg_make_buffer(&(sg_buffer_desc){ .usage.indirect_buffer = true, .data = SG_RANGE(args) });
T(sg_query_buffer_state(indirect) == SG_RESOURCESTATE_VALID);
sg_begin_pass(&(sg_pass){ .compute = true });
sg_apply_pipeline(pip);
sg_dispatch(4, 4, 1);
sg_dispatch_indirect(indirect, 4);
T(num_log_items == 0);
sg_end_pass();
sg_commit();
sg_destroy_pipeline(pip);
sg_destroy_shader(shd);
T(sg_isvalid());
sg_destroy_buffer(indirect);
teardown();
}

Expand Down
45 changes: 45 additions & 0 deletions tests/functional/gl/sokol_gfx_gl_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1066,9 +1066,22 @@ UTEST(sokol_gfx_gl, compute_pass_no_framebuffer_bind) {
});
sg_pipeline pip = sg_make_pipeline(&(sg_pipeline_desc){ .shader = shd, .compute = true });
gl_mock_clear_calls();
sg_buffer indirect = {0};
if (sg_query_features().compute) {
const uint32_t args[8] = {0, 3, 1, 0, 0, 0, 0, 0};
indirect = sg_make_buffer(&(sg_buffer_desc){ .usage.indirect_buffer = true, .data = SG_RANGE(args) });
T(sg_query_buffer_state(indirect) == SG_RESOURCESTATE_VALID);
}
sg_begin_pass(&(sg_pass){ .compute = true });
sg_apply_pipeline(pip);
sg_dispatch(4, 4, 1);
if (sg_query_features().compute) {
sg_dispatch_indirect(indirect, 4);
const gl_mock_call_t* call = gl_mock_last_call(GL_MOCK_FUNC_glDispatchComputeIndirect);
TA(call != 0);
T(call->args[0].i == 4);
T(gl_mock_bindings()->dispatch_indirect_buffer == 0);
}
sg_end_pass();
sg_commit();
// compute pass does not touch framebuffer state
Expand All @@ -1077,6 +1090,7 @@ UTEST(sokol_gfx_gl, compute_pass_no_framebuffer_bind) {
sg_destroy_pipeline(pip);
sg_destroy_shader(shd);
T(sg_isvalid());
sg_destroy_buffer(indirect);
teardown();
}
#endif
Expand All @@ -1093,6 +1107,12 @@ UTEST(sokol_gfx_gl, draw_arrays_non_indexed_and_instanced) {
});
static const float verts[9] = {0};
sg_buffer vbuf = sg_make_buffer(&(sg_buffer_desc){ .data = SG_RANGE(verts) });
sg_buffer indirect = {0};
if (sg_query_features().compute) {
const uint32_t args[8] = {0, 3, 1, 0, 0, 0, 0, 0};
indirect = sg_make_buffer(&(sg_buffer_desc){ .usage.indirect_buffer = true, .data = SG_RANGE(args) });
T(sg_query_buffer_state(indirect) == SG_RESOURCESTATE_VALID);
}
sg_begin_pass(&(sg_pass){
.swapchain = { .width = 64, .height = 64, .sample_count = 1,
.color_format = SG_PIXELFORMAT_RGBA8, .depth_format = SG_PIXELFORMAT_DEPTH_STENCIL },
Expand All @@ -1102,6 +1122,14 @@ UTEST(sokol_gfx_gl, draw_arrays_non_indexed_and_instanced) {
gl_mock_clear_calls();
sg_draw(0, 3, 1); // glDrawArrays
sg_draw(0, 3, 4); // glDrawArraysInstanced
if (sg_query_features().compute) {
sg_draw_indirect(indirect, 4);
const gl_mock_call_t* call = gl_mock_last_call(GL_MOCK_FUNC_glDrawArraysIndirect);
TA(call != 0);
T(call->args[0].i == GL_TRIANGLES);
T(call->args[1].p == (const void*)(uintptr_t)4);
T(gl_mock_bindings()->draw_indirect_buffer == 0);
}
sg_end_pass();
sg_commit();
T(gl_mock_count_calls(GL_MOCK_FUNC_glDrawArrays) == 1);
Expand All @@ -1110,6 +1138,7 @@ UTEST(sokol_gfx_gl, draw_arrays_non_indexed_and_instanced) {
sg_destroy_pipeline(pip);
sg_destroy_shader(shd);
T(sg_isvalid());
sg_destroy_buffer(indirect);
teardown();
}

Expand All @@ -1126,6 +1155,12 @@ UTEST(sokol_gfx_gl, draw_indexed_and_instanced) {
sg_buffer ibuf = sg_make_buffer(&(sg_buffer_desc){
.usage.index_buffer = true, .data = SG_RANGE(indices),
});
sg_buffer indirect = {0};
if (sg_query_features().compute) {
const uint32_t args[8] = {0, 3, 1, 0, 0, 0, 0, 0};
indirect = sg_make_buffer(&(sg_buffer_desc){ .usage.indirect_buffer = true, .data = SG_RANGE(args) });
T(sg_query_buffer_state(indirect) == SG_RESOURCESTATE_VALID);
}
sg_begin_pass(&(sg_pass){
.swapchain = { .width = 64, .height = 64, .sample_count = 1,
.color_format = SG_PIXELFORMAT_RGBA8, .depth_format = SG_PIXELFORMAT_DEPTH_STENCIL },
Expand All @@ -1135,6 +1170,15 @@ UTEST(sokol_gfx_gl, draw_indexed_and_instanced) {
gl_mock_clear_calls();
sg_draw(0, 6, 1);
sg_draw(0, 6, 4);
if (sg_query_features().compute) {
sg_draw_indirect(indirect, 4);
const gl_mock_call_t* call = gl_mock_last_call(GL_MOCK_FUNC_glDrawElementsIndirect);
TA(call != 0);
T(call->args[0].i == GL_TRIANGLES);
T(call->args[1].i == GL_UNSIGNED_SHORT);
T(call->args[2].p == (const void*)(uintptr_t)4);
T(gl_mock_bindings()->draw_indirect_buffer == 0);
}
sg_end_pass();
sg_commit();
// no base_vertex/base_instance in the bindings, so sokol_gfx picks the
Expand All @@ -1146,6 +1190,7 @@ UTEST(sokol_gfx_gl, draw_indexed_and_instanced) {
sg_destroy_pipeline(pip);
sg_destroy_shader(shd);
T(sg_isvalid());
sg_destroy_buffer(indirect);
teardown();
}

Expand Down
33 changes: 33 additions & 0 deletions tests/functional/metal/sokol_gfx_metal_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1942,6 +1942,9 @@ UTEST(sokol_gfx_metal, draw_variants) {
.depth.pixel_format = SG_PIXELFORMAT_DEPTH_STENCIL,
.colors[0].pixel_format = SG_PIXELFORMAT_BGRA8,
});
const uint32_t args[8] = {0, 3, 1, 0, 0, 0, 0, 0};
sg_buffer indirect = sg_make_buffer(&(sg_buffer_desc){ .usage.indirect_buffer = true, .data = SG_RANGE(args) });
T(sg_query_buffer_state(indirect) == SG_RESOURCESTATE_VALID);
sg_begin_pass(&(sg_pass){ .swapchain = swapchain(&sc) });
sg_apply_pipeline(pip);
sg_apply_bindings(&(sg_bindings){ .vertex_buffers[0] = make_vbuf() });
Expand All @@ -1964,6 +1967,12 @@ UTEST(sokol_gfx_metal, draw_variants) {
const int num_draws = metal_mock_count_calls(METAL_MOCK_FUNC_drawPrimitives);
sg_draw(0, 0, 1);
T(metal_mock_count_calls(METAL_MOCK_FUNC_drawPrimitives) == num_draws);
sg_draw_indirect(indirect, 4);
call = metal_mock_last_call(METAL_MOCK_FUNC_drawPrimitivesIndirect);
ASSERT_TRUE(call != 0);
T(call->args[0].u == MTLPrimitiveTypeTriangleStrip);
T(call->args[1].p == sg_mtl_query_buffer_info(indirect).buf[0]);
T(call->args[2].u == 4);
sg_end_pass();
sg_commit();
teardown();
Expand All @@ -1985,6 +1994,9 @@ UTEST(sokol_gfx_metal, draw_indexed) {
.usage = { .index_buffer = true, .immutable = true },
.data = { .ptr = scratch, .size = 64 },
});
const uint32_t args[8] = {0, 3, 1, 0, 0, 0, 0, 0};
sg_buffer indirect = sg_make_buffer(&(sg_buffer_desc){ .usage.indirect_buffer = true, .data = SG_RANGE(args) });
T(sg_query_buffer_state(indirect) == SG_RESOURCESTATE_VALID);
sg_begin_pass(&(sg_pass){ .swapchain = swapchain(&sc) });
sg_apply_pipeline(pip);
sg_apply_bindings(&(sg_bindings){
Expand All @@ -2007,6 +2019,15 @@ UTEST(sokol_gfx_metal, draw_indexed) {
T(call != 0);
T(call->args[6].i == 4);
T(call->args[7].u == 5);
sg_draw_indirect(indirect, 4);
call = metal_mock_last_call(METAL_MOCK_FUNC_drawIndexedPrimitivesIndirect);
ASSERT_TRUE(call != 0);
T(call->args[0].u == MTLPrimitiveTypeTriangle);
T(call->args[1].u == MTLIndexTypeUInt16);
T(call->args[2].p == sg_mtl_query_buffer_info(ibuf).buf[0]);
T(call->args[3].u == 8);
T(call->args[4].p == sg_mtl_query_buffer_info(indirect).buf[0]);
T(call->args[5].u == 4);
sg_end_pass();
sg_commit();
teardown();
Expand All @@ -2033,6 +2054,9 @@ UTEST(sokol_gfx_metal, dispatch) {
.usage = { .storage_image = true, .immutable = true },
});
sg_view view = sg_make_view(&(sg_view_desc){ .storage_image.image = img });
const uint32_t args[8] = {0, 3, 1, 0, 0, 0, 0, 0};
sg_buffer indirect = sg_make_buffer(&(sg_buffer_desc){ .usage.indirect_buffer = true, .data = SG_RANGE(args) });
T(sg_query_buffer_state(indirect) == SG_RESOURCESTATE_VALID);
sg_begin_pass(&(sg_pass){ .compute = true });
sg_apply_pipeline(pip);
sg_apply_bindings(&(sg_bindings){ .views[0] = view });
Expand All @@ -2045,6 +2069,15 @@ UTEST(sokol_gfx_metal, dispatch) {
T(state->last_threadgroups_per_grid.height == 3);
T(state->last_threads_per_threadgroup.width == 8);
T(state->last_threads_per_threadgroup.height == 4);
sg_dispatch_indirect(indirect, 4);
const metal_mock_call_t* call = metal_mock_last_call(METAL_MOCK_FUNC_dispatchThreadgroupsIndirect);
ASSERT_TRUE(call != 0);
T(call->args[0].p == sg_mtl_query_buffer_info(indirect).buf[0]);
T(call->args[1].u == 4);
T(call->args[2].u == 8);
T(call->args[3].u == 4);
T(call->args[4].u == 1);
T(state->num_dispatches == 2);
sg_end_pass();
sg_commit();
teardown();
Expand Down
32 changes: 32 additions & 0 deletions tests/functional/sokol_gfx_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,10 @@ UTEST(sokol_gfx, query_buffer_defaults) {
desc = sg_query_buffer_defaults(&(sg_buffer_desc){ .usage.write_transient = true });
T(desc.usage.vertex_buffer);
T(desc.usage.write_transient);
desc = sg_query_buffer_defaults(&(sg_buffer_desc){ .usage.indirect_buffer = true });
T(desc.usage.indirect_buffer);
T(!desc.usage.vertex_buffer);
T(desc.usage.immutable);
sg_shutdown();
}

Expand Down Expand Up @@ -1965,6 +1969,34 @@ UTEST(sokol_gfx, make_buffer_storagebuffer_not_supported_and_size) {
sg_shutdown();
}

UTEST(sokol_gfx, indirect_buffer) {
setup(&(sg_desc){0});
const uint32_t args[5] = { 3, 1, 0, 0, 0 };
sg_buffer buf = sg_make_buffer(&(sg_buffer_desc){ .usage.indirect_buffer = true, .data = SG_RANGE(args) });
T(sg_query_buffer_state(buf) == SG_RESOURCESTATE_FAILED);
T(log_items[0] == SG_LOGITEM_VALIDATE_BUFFERDESC_INDIRECTBUFFER_SUPPORTED);
reset_log_items();
_sg.features.compute = true;
buf = sg_make_buffer(&(sg_buffer_desc){ .usage.indirect_buffer = true, .data = SG_RANGE(args) });
T(sg_query_buffer_state(buf) == SG_RESOURCESTATE_VALID);
_sg.cur_pass.valid = true;
_sg.cur_pass.in_pass = true;
_sg.next_draw_valid = true;
sg_draw_indirect(buf, 0);
T(sg_query_stats().cur_frame.num_draw_indirect == 1);
reset_log_items();
sg_draw_indirect(buf, 2);
T(log_items[0] == SG_LOGITEM_VALIDATE_INDIRECT_BUFFER_OFFSET);
reset_log_items();
sg_draw_indirect(buf, 8);
T(log_items[0] == SG_LOGITEM_VALIDATE_INDIRECT_BUFFER_RANGE);
_sg.cur_pass.is_compute = true;
sg_dispatch_indirect(buf, 0);
T(sg_query_stats().cur_frame.num_dispatch_indirect == 1);
_sg.cur_pass.in_pass = false;
sg_shutdown();
}

UTEST(sokol_gfx, make_image_validate_start_canary) {
setup(&(sg_desc){0});
const uint32_t pixels[8][8] = {0};
Expand Down
4 changes: 4 additions & 0 deletions tests/mocks/d3d11/d3d11.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ typedef enum D3D11_USAGE {

/* D3D11_RESOURCE_MISC_FLAG */
#define D3D11_RESOURCE_MISC_TEXTURECUBE 0x0004u
#define D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS 0x0010u
#define D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS 0x0020u

typedef enum D3D11_FILTER {
Expand Down Expand Up @@ -837,6 +838,9 @@ typedef struct ID3D11DeviceContextVtbl {
void (STDMETHODCALLTYPE *Draw)(ID3D11DeviceContext* self, UINT VertexCount, UINT StartVertexLocation);
void (STDMETHODCALLTYPE *DrawInstanced)(ID3D11DeviceContext* self, UINT VertexCountPerInstance, UINT InstanceCount, UINT StartVertexLocation, UINT StartInstanceLocation);
void (STDMETHODCALLTYPE *Dispatch)(ID3D11DeviceContext* self, UINT X, UINT Y, UINT Z);
void (STDMETHODCALLTYPE *DrawIndexedInstancedIndirect)(ID3D11DeviceContext* self, ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs);
void (STDMETHODCALLTYPE *DrawInstancedIndirect)(ID3D11DeviceContext* self, ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs);
void (STDMETHODCALLTYPE *DispatchIndirect)(ID3D11DeviceContext* self, ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs);
HRESULT (STDMETHODCALLTYPE *Map)(ID3D11DeviceContext* self, ID3D11Resource* pResource, UINT Subresource, D3D11_MAP MapType, UINT MapFlags, D3D11_MAPPED_SUBRESOURCE* pMapped);
void (STDMETHODCALLTYPE *Unmap)(ID3D11DeviceContext* self, ID3D11Resource* pResource, UINT Subresource);
ULONG (STDMETHODCALLTYPE *AddRef)(ID3D11DeviceContext* self);
Expand Down
7 changes: 7 additions & 0 deletions tests/mocks/d3d11/d3d11_mock.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,10 @@ static void ctx_Draw(ID3D11DeviceContext* self, UINT n, UINT s)
static void ctx_DrawInstanced(ID3D11DeviceContext* self, UINT n, UINT i, UINT s, UINT bi) { (void)self; (void)n; (void)i; (void)s; (void)bi; }
static void ctx_Dispatch(ID3D11DeviceContext* self, UINT x, UINT y, UINT z) { (void)self; (void)x; (void)y; (void)z; }

static void ctx_DrawIndexedInstancedIndirect(ID3D11DeviceContext* self, ID3D11Buffer* args, UINT offset) { (void)self; (void)args; (void)offset; }
static void ctx_DrawInstancedIndirect(ID3D11DeviceContext* self, ID3D11Buffer* args, UINT offset) { (void)self; (void)args; (void)offset; }
static void ctx_DispatchIndirect(ID3D11DeviceContext* self, ID3D11Buffer* args, UINT offset) { (void)self; (void)args; (void)offset; }

static HRESULT ctx_Map(ID3D11DeviceContext* self, ID3D11Resource* pRes, UINT sub, D3D11_MAP mt, UINT flags, D3D11_MAPPED_SUBRESOURCE* pMapped) {
(void)self; (void)sub; (void)mt; (void)flags;
mock_obj_t* res = (mock_obj_t*)pRes;
Expand Down Expand Up @@ -445,6 +449,9 @@ static const struct ID3D11DeviceContextVtbl context_vtbl = {
ctx_Draw,
ctx_DrawInstanced,
ctx_Dispatch,
ctx_DrawIndexedInstancedIndirect,
ctx_DrawInstancedIndirect,
ctx_DispatchIndirect,
ctx_Map,
ctx_Unmap,
(ULONG (STDMETHODCALLTYPE*)(ID3D11DeviceContext*))mock_addref,
Expand Down
6 changes: 6 additions & 0 deletions tests/mocks/gl/gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@ typedef uint64_t GLuint64;
#define GL_SCISSOR_TEST 0x0C11
#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
#define GL_SHADER_STORAGE_BARRIER_BIT 0x2000
#define GL_DRAW_INDIRECT_BUFFER 0x8F3F
#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE
#define GL_COMMAND_BARRIER_BIT 0x00000040
#define GL_SHADER_STORAGE_BUFFER 0x90D2
#define GL_SHORT 0x1402
#define GL_SRC1_ALPHA 0x8589
Expand Down Expand Up @@ -530,6 +533,9 @@ typedef uint64_t GLuint64;
_GLM_XMACRO(glTexImage2DMultisample, void, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)) \
_GLM_XMACRO(glTexImage3DMultisample, void, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations)) \
_GLM_XMACRO(glDispatchCompute, void, (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z)) \
_GLM_XMACRO(glDrawArraysIndirect, void, (GLenum mode, const void* indirect)) \
_GLM_XMACRO(glDrawElementsIndirect, void, (GLenum mode, GLenum type, const void* indirect)) \
_GLM_XMACRO(glDispatchComputeIndirect, void, (GLintptr indirect)) \
_GLM_XMACRO(glMemoryBarrier, void, (GLbitfield barriers)) \
_GLM_XMACRO(glBindImageTexture, void, (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format)) \
_GLM_XMACRO(glTexStorage2DMultisample, void, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)) \
Expand Down
Loading
Loading