aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Weissflog <floooh@gmail.com>2024-01-31 19:47:38 +0100
committerAndre Weissflog <floooh@gmail.com>2024-01-31 19:47:38 +0100
commit0fae329ae9a27d9e76479b285a78afe1e1a228a6 (patch)
treef84bfb206e1bbcff8d1b2209c508dde61a3e04d2
parent3595c35fe34143579616c1ce7c1edbc4c9ea426c (diff)
sokol_gfx.h: remove sg_begin_default_pass and fix metal backend for those changes
-rw-r--r--sokol_gfx.h218
1 files changed, 101 insertions, 117 deletions
diff --git a/sokol_gfx.h b/sokol_gfx.h
index 37f6e57c..4c194720 100644
--- a/sokol_gfx.h
+++ b/sokol_gfx.h
@@ -2351,13 +2351,37 @@ typedef struct sg_pass_action {
FIXME
*/
+typedef struct sg_metal_swapchain {
+ // FIXME: replace with textures and setup RenderPassDescriptor in begin-pass?
+ const void* render_pass_descriptor; // MTLRenderPassDescriptor
+ const void* drawable; // MTLDrawable
+} sg_metal_swapchain;
+
+typedef struct sg_d3d11_swapchain {
+ const void* render_target_view; // ID3D11RenderTargetView
+ const void* depth_stencil_view; // ID3D11DepthStencilView
+} sg_d3d11_swapchain;
+
+typedef struct sg_wgpu_swapchain {
+ const void* render_view; // WGPUTextureView
+ const void* resolve_view; // WGPUTextureView
+ const void* depth_stencil_view; // WGPUTextureView
+} sg_wgpu_swapchain;
+
+typedef struct sg_gl_swapchain {
+ uint32_t framebuffer; // GL framebuffer object
+} sg_gl_swapchain;
+
typedef struct sg_swapchain {
int width;
int height;
int sample_count;
sg_pixel_format color_format;
sg_pixel_format depth_format;
- // FIXME: platform-specific swapchain surfaces
+ sg_metal_swapchain metal;
+ sg_d3d11_swapchain d3d11;
+ sg_wgpu_swapchain wgpu;
+ sg_gl_swapchain gl;
} sg_swapchain;
/*
@@ -3393,7 +3417,8 @@ typedef struct sg_frame_stats {
_SG_LOGITEM_XMACRO(VALIDATE_ATTACHMENTSDESC_DEPTH_IMAGE_NO_RT, "pass depth attachment image must be have render_target=true") \
_SG_LOGITEM_XMACRO(VALIDATE_ATTACHMENTSDESC_DEPTH_IMAGE_SIZES, "pass depth attachment image size must match color attachment image size") \
_SG_LOGITEM_XMACRO(VALIDATE_ATTACHMENTSDESC_DEPTH_IMAGE_SAMPLE_COUNT, "pass depth attachment sample count must match color attachment sample count") \
- _SG_LOGITEM_XMACRO(VALIDATE_BEGINPASS_PASS, "sg_begin_pass: pass must be valid") \
+ _SG_LOGITEM_XMACRO(VALIDATE_BEGINPASS_ATTACHMENTS_EXISTS, "sg_begin_pass: attachments object no longer alive") \
+ _SG_LOGITEM_XMACRO(VALIDATE_BEGINPASS_ATTACHMENTS_VALID, "sg_begin_pass: attachemnts object not in resource state VALID") \
_SG_LOGITEM_XMACRO(VALIDATE_BEGINPASS_COLOR_ATTACHMENT_IMAGE, "sg_begin_pass: one or more color attachment images are not valid") \
_SG_LOGITEM_XMACRO(VALIDATE_BEGINPASS_RESOLVE_ATTACHMENT_IMAGE, "sg_begin_pass: one or more resolve attachment images are not valid") \
_SG_LOGITEM_XMACRO(VALIDATE_BEGINPASS_DEPTHSTENCIL_ATTACHMENT_IMAGE, "sg_begin_pass: one or more depth-stencil attachment images are not valid") \
@@ -3595,40 +3620,17 @@ typedef enum sg_log_item {
*/
typedef struct sg_metal_context_desc {
const void* device;
- const void* (*renderpass_descriptor_cb)(void);
- const void* (*renderpass_descriptor_userdata_cb)(void*);
- const void* (*drawable_cb)(void);
- const void* (*drawable_userdata_cb)(void*);
- void* user_data;
} sg_metal_context_desc;
typedef struct sg_d3d11_context_desc {
const void* device;
const void* device_context;
- const void* (*render_target_view_cb)(void);
- const void* (*render_target_view_userdata_cb)(void*);
- const void* (*depth_stencil_view_cb)(void);
- const void* (*depth_stencil_view_userdata_cb)(void*);
- void* user_data;
} sg_d3d11_context_desc;
typedef struct sg_wgpu_context_desc {
const void* device; // WGPUDevice
- const void* (*render_view_cb)(void); // returns WGPUTextureView
- const void* (*render_view_userdata_cb)(void*);
- const void* (*resolve_view_cb)(void); // returns WGPUTextureView
- const void* (*resolve_view_userdata_cb)(void*);
- const void* (*depth_stencil_view_cb)(void); // returns WGPUTextureView
- const void* (*depth_stencil_view_userdata_cb)(void*);
- void* user_data;
} sg_wgpu_context_desc;
-typedef struct sg_gl_context_desc {
- uint32_t (*default_framebuffer_cb)(void);
- uint32_t (*default_framebuffer_userdata_cb)(void*);
- void* user_data;
-} sg_gl_context_desc;
-
typedef struct sg_context_desc {
sg_pixel_format color_format;
sg_pixel_format depth_format;
@@ -3636,7 +3638,6 @@ typedef struct sg_context_desc {
sg_metal_context_desc metal;
sg_d3d11_context_desc d3d11;
sg_wgpu_context_desc wgpu;
- sg_gl_context_desc gl;
} sg_context_desc;
/*
@@ -3740,8 +3741,6 @@ SOKOL_GFX_API_DECL bool sg_query_buffer_overflow(sg_buffer buf);
SOKOL_GFX_API_DECL bool sg_query_buffer_will_overflow(sg_buffer buf, size_t size);
// rendering functions
-SOKOL_GFX_API_DECL void sg_begin_default_pass(const sg_pass_action* pass_action, int width, int height);
-SOKOL_GFX_API_DECL void sg_begin_default_passf(const sg_pass_action* pass_action, float width, float height);
SOKOL_GFX_API_DECL void sg_begin_pass(const sg_pass* pass);
SOKOL_GFX_API_DECL void sg_apply_viewport(int x, int y, int width, int height, bool origin_top_left);
SOKOL_GFX_API_DECL void sg_apply_viewportf(float x, float y, float width, float height, bool origin_top_left);
@@ -4028,8 +4027,6 @@ inline sg_pipeline sg_make_pipeline(const sg_pipeline_desc& desc) { return sg_ma
inline sg_pass sg_make_attchments(const sg_attachments_desc& desc) { return sg_make_attachments(&desc); }
inline void sg_update_image(sg_image img, const sg_image_data& data) { return sg_update_image(img, &data); }
-inline void sg_begin_default_pass(const sg_pass_action& pass_action, int width, int height) { return sg_begin_default_pass(&pass_action, width, height); }
-inline void sg_begin_default_passf(const sg_pass_action& pass_action, float width, float height) { return sg_begin_default_passf(&pass_action, width, height); }
inline void sg_begin_pass(const sg_pass& pass) { return sg_begin_pass(&pass); }
inline void sg_apply_bindings(const sg_bindings& bindings) { return sg_apply_bindings(&bindings); }
inline void sg_apply_uniforms(sg_shader_stage stage, int ub_index, const sg_range& data) { return sg_apply_uniforms(stage, ub_index, &data); }
@@ -5337,11 +5334,6 @@ typedef struct {
typedef struct {
bool valid;
bool use_shared_storage_mode;
- const void*(*renderpass_descriptor_cb)(void);
- const void*(*renderpass_descriptor_userdata_cb)(void*);
- const void*(*drawable_cb)(void);
- const void*(*drawable_userdata_cb)(void*);
- void* user_data;
uint32_t cur_frame_rotate_index;
int ub_size;
int cur_ub_offset;
@@ -5357,6 +5349,7 @@ typedef struct {
id<MTLCommandQueue> cmd_queue;
id<MTLCommandBuffer> cmd_buffer;
id<MTLRenderCommandEncoder> cmd_encoder;
+ id<MTLDrawable> cur_drawable;
id<MTLBuffer> uniform_buffers[SG_NUM_INFLIGHT_FRAMES];
} _sg_mtl_backend_t;
@@ -11627,17 +11620,10 @@ _SOKOL_PRIVATE void _sg_mtl_setup_backend(const sg_desc* desc) {
// assume already zero-initialized
SOKOL_ASSERT(desc);
SOKOL_ASSERT(desc->context.metal.device);
- SOKOL_ASSERT(desc->context.metal.renderpass_descriptor_cb || desc->context.metal.renderpass_descriptor_userdata_cb);
- SOKOL_ASSERT(desc->context.metal.drawable_cb || desc->context.metal.drawable_userdata_cb);
SOKOL_ASSERT(desc->uniform_buffer_size > 0);
_sg_mtl_init_pool(desc);
_sg_mtl_clear_state_cache();
_sg.mtl.valid = true;
- _sg.mtl.renderpass_descriptor_cb = desc->context.metal.renderpass_descriptor_cb;
- _sg.mtl.renderpass_descriptor_userdata_cb = desc->context.metal.renderpass_descriptor_userdata_cb;
- _sg.mtl.drawable_cb = desc->context.metal.drawable_cb;
- _sg.mtl.drawable_userdata_cb = desc->context.metal.drawable_userdata_cb;
- _sg.mtl.user_data = desc->context.metal.user_data;
_sg.mtl.ub_size = desc->uniform_buffer_size;
_sg.mtl.sem = dispatch_semaphore_create(SG_NUM_INFLIGHT_FRAMES);
_sg.mtl.device = (__bridge id<MTLDevice>) desc->context.metal.device;
@@ -12267,15 +12253,23 @@ _SOKOL_PRIVATE _sg_image_t* _sg_mtl_attachments_ds_image(const _sg_attachments_t
return atts->mtl.depth_stencil.image;
}
-_SOKOL_PRIVATE void _sg_mtl_begin_pass(_sg_attachments_t* atts, const sg_pass_action* action, int w, int h) {
+_SOKOL_PRIVATE void _sg_mtl_begin_pass(const sg_pass_action* action, _sg_attachments_t* atts, const sg_swapchain* swapchain) {
SOKOL_ASSERT(action);
+ SOKOL_ASSERT(swapchain);
SOKOL_ASSERT(!_sg.mtl.in_pass);
SOKOL_ASSERT(_sg.mtl.cmd_queue);
SOKOL_ASSERT(nil == _sg.mtl.cmd_encoder);
- SOKOL_ASSERT(_sg.mtl.renderpass_descriptor_cb || _sg.mtl.renderpass_descriptor_userdata_cb);
+ SOKOL_ASSERT(nil == _sg.mtl.cur_drawable);
_sg.mtl.in_pass = true;
- _sg.mtl.cur_width = w;
- _sg.mtl.cur_height = h;
+ if (atts) {
+ _sg.mtl.cur_width = atts->cmn.width;
+ _sg.mtl.cur_height = atts->cmn.height;
+ } else {
+ SOKOL_ASSERT(swapchain->width > 0);
+ SOKOL_ASSERT(swapchain->height > 0);
+ _sg.mtl.cur_width = swapchain->width;
+ _sg.mtl.cur_height = swapchain->height;
+ }
_sg_mtl_clear_state_cache();
/*
@@ -12312,24 +12306,21 @@ _SOKOL_PRIVATE void _sg_mtl_begin_pass(_sg_attachments_t* atts, const sg_pass_ac
// offscreen render pass
pass_desc = [MTLRenderPassDescriptor renderPassDescriptor];
} else {
- // default render pass, call user-provided callback to provide render pass descriptor
- if (_sg.mtl.renderpass_descriptor_cb) {
- pass_desc = (__bridge MTLRenderPassDescriptor*) _sg.mtl.renderpass_descriptor_cb();
- } else {
- pass_desc = (__bridge MTLRenderPassDescriptor*) _sg.mtl.renderpass_descriptor_userdata_cb(_sg.mtl.user_data);
+ // a swapchain pass descriptor will not be valid if window is minimized, don't do any rendering in this case
+ if (0 == swapchain->metal.render_pass_descriptor) {
+ _sg.mtl.pass_valid = false;
+ return;
}
+ pass_desc = (__bridge MTLRenderPassDescriptor*) swapchain->metal.render_pass_descriptor;
// pin the swapchain resources into memory so that they outlive their command buffer
// (this is necessary because the command buffer doesn't retain references)
int default_pass_desc_ref = _sg_mtl_add_resource(pass_desc);
_sg_mtl_release_resource(_sg.frame_index, default_pass_desc_ref);
+ SOKOL_ASSERT(swapchain->metal.drawable);
+ _sg.mtl.cur_drawable = (__bridge id<MTLDrawable>) swapchain->metal.drawable;
}
- if (pass_desc) {
- _sg.mtl.pass_valid = true;
- } else {
- // default pass descriptor will not be valid if window is minimized, don't do any rendering in this case
- _sg.mtl.pass_valid = false;
- return;
- }
+ SOKOL_ASSERT(pass_desc);
+ _sg.mtl.pass_valid = true;
if (atts) {
// setup pass descriptor for offscreen rendering
SOKOL_ASSERT(atts->slot.state == SG_RESOURCESTATE_VALID);
@@ -12445,25 +12436,20 @@ _SOKOL_PRIVATE void _sg_mtl_end_pass(void) {
// NOTE: MTLRenderCommandEncoder is autoreleased
_sg.mtl.cmd_encoder = nil;
}
+ // if this is a swapchain pass, present the drawable
+ if (nil != _sg.mtl.cur_drawable) {
+ [_sg.mtl.cmd_buffer presentDrawable:_sg.mtl.cur_drawable];
+ _sg.mtl.cur_drawable = nil;
+ }
}
_SOKOL_PRIVATE void _sg_mtl_commit(void) {
SOKOL_ASSERT(!_sg.mtl.in_pass);
SOKOL_ASSERT(!_sg.mtl.pass_valid);
- SOKOL_ASSERT(_sg.mtl.drawable_cb || _sg.mtl.drawable_userdata_cb);
SOKOL_ASSERT(nil == _sg.mtl.cmd_encoder);
SOKOL_ASSERT(nil != _sg.mtl.cmd_buffer);
- // present, commit and signal semaphore when done
- id<MTLDrawable> cur_drawable = nil;
- if (_sg.mtl.drawable_cb) {
- cur_drawable = (__bridge id<MTLDrawable>) _sg.mtl.drawable_cb();
- } else {
- cur_drawable = (__bridge id<MTLDrawable>) _sg.mtl.drawable_userdata_cb(_sg.mtl.user_data);
- }
- if (nil != cur_drawable) {
- [_sg.mtl.cmd_buffer presentDrawable:cur_drawable];
- }
+ // commit the frame's command buffer
[_sg.mtl.cmd_buffer commit];
// garbage-collect resources pending for release
@@ -14910,17 +14896,17 @@ static inline _sg_image_t* _sg_attachments_ds_image(const _sg_attachments_t* att
#endif
}
-static inline void _sg_begin_pass(_sg_attachments_t* atts, const sg_pass_action* action, int w, int h) {
+static inline void _sg_begin_pass(const sg_pass_action* action, _sg_attachments_t* atts, const sg_swapchain* swapchain) {
#if defined(_SOKOL_ANY_GL)
- _sg_gl_begin_pass(atts, action, w, h);
+ _sg_gl_begin_pass(action, atts, swapchain);
#elif defined(SOKOL_METAL)
- _sg_mtl_begin_pass(atts, action, w, h);
+ _sg_mtl_begin_pass(action, atts, swapchain);
#elif defined(SOKOL_D3D11)
- _sg_d3d11_begin_pass(atts, action, w, h);
+ _sg_d3d11_begin_pass(action, atts, swapchain);
#elif defined(SOKOL_WGPU)
- _sg_wgpu_begin_pass(atts, action, w, h);
+ _sg_wgpu_begin_pass(action, atts, swapchain);
#elif defined(SOKOL_DUMMY_BACKEND)
- _sg_dummy_begin_pass(atts, action, w, h);
+ _sg_dummy_begin_pass(action, atts, swapchain);
#else
#error("INVALID BACKEND");
#endif
@@ -15945,7 +15931,7 @@ _SOKOL_PRIVATE bool _sg_validate_attachments_desc(const sg_attachments_desc* des
#endif
}
-_SOKOL_PRIVATE bool _sg_validate_begin_pass(_sg_attachments_t* atts) {
+_SOKOL_PRIVATE bool _sg_validate_begin_pass(const sg_pass* pass) {
#if !defined(SOKOL_DEBUG)
_SOKOL_UNUSED(pass);
return true;
@@ -15954,26 +15940,35 @@ _SOKOL_PRIVATE bool _sg_validate_begin_pass(_sg_attachments_t* atts) {
return true;
}
_sg_validate_begin();
- _SG_VALIDATE(atts->slot.state == SG_RESOURCESTATE_VALID, VALIDATE_BEGINPASS_PASS);
- for (int i = 0; i < SG_MAX_COLOR_ATTACHMENTS; i++) {
- const _sg_attachment_common_t* color_att = &atts->cmn.colors[i];
- const _sg_image_t* color_img = _sg_attachments_color_image(atts, i);
- if (color_img) {
- _SG_VALIDATE(color_img->slot.state == SG_RESOURCESTATE_VALID, VALIDATE_BEGINPASS_COLOR_ATTACHMENT_IMAGE);
- _SG_VALIDATE(color_img->slot.id == color_att->image_id.id, VALIDATE_BEGINPASS_COLOR_ATTACHMENT_IMAGE);
+ if (pass->attachments.id == SG_INVALID_ID) {
+ // this is a swapchain pass
+ // FIXME: validate swapchain params!
+ } else {
+ // this is an 'offscreen pass'
+ const _sg_attachments_t* atts = _sg_lookup_attachments(&_sg.pools, pass->attachments.id);
+ _SG_VALIDATE(atts != 0, VALIDATE_BEGINPASS_ATTACHMENTS_EXISTS);
+ _SG_VALIDATE(atts->slot.state == SG_RESOURCESTATE_VALID, VALIDATE_BEGINPASS_ATTACHMENTS_VALID);
+ for (int i = 0; i < SG_MAX_COLOR_ATTACHMENTS; i++) {
+ const _sg_attachment_common_t* color_att = &atts->cmn.colors[i];
+ const _sg_image_t* color_img = _sg_attachments_color_image(atts, i);
+ if (color_img) {
+ _SG_VALIDATE(color_img->slot.state == SG_RESOURCESTATE_VALID, VALIDATE_BEGINPASS_COLOR_ATTACHMENT_IMAGE);
+ _SG_VALIDATE(color_img->slot.id == color_att->image_id.id, VALIDATE_BEGINPASS_COLOR_ATTACHMENT_IMAGE);
+ }
+ const _sg_attachment_common_t* resolve_att = &atts->cmn.resolves[i];
+ const _sg_image_t* resolve_img = _sg_attachments_resolve_image(atts, i);
+ if (resolve_img) {
+ _SG_VALIDATE(resolve_img->slot.state == SG_RESOURCESTATE_VALID, VALIDATE_BEGINPASS_RESOLVE_ATTACHMENT_IMAGE);
+ _SG_VALIDATE(resolve_img->slot.id == resolve_att->image_id.id, VALIDATE_BEGINPASS_RESOLVE_ATTACHMENT_IMAGE);
+ }
}
- const _sg_attachment_common_t* resolve_att = &atts->cmn.resolves[i];
- const _sg_image_t* resolve_img = _sg_attachments_resolve_image(atts, i);
- if (resolve_img) {
- _SG_VALIDATE(resolve_img->slot.state == SG_RESOURCESTATE_VALID, VALIDATE_BEGINPASS_RESOLVE_ATTACHMENT_IMAGE);
- _SG_VALIDATE(resolve_img->slot.id == resolve_att->image_id.id, VALIDATE_BEGINPASS_RESOLVE_ATTACHMENT_IMAGE);
+ const _sg_image_t* ds_img = _sg_attachments_ds_image(atts);
+ if (ds_img) {
+ const _sg_attachment_common_t* att = &atts->cmn.depth_stencil;
+ _SG_VALIDATE(ds_img->slot.state == SG_RESOURCESTATE_VALID, VALIDATE_BEGINPASS_DEPTHSTENCIL_ATTACHMENT_IMAGE);
+ _SG_VALIDATE(ds_img->slot.id == att->image_id.id, VALIDATE_BEGINPASS_DEPTHSTENCIL_ATTACHMENT_IMAGE);
}
- }
- const _sg_image_t* ds_img = _sg_attachments_ds_image(atts);
- if (ds_img) {
- const _sg_attachment_common_t* att = &atts->cmn.depth_stencil;
- _SG_VALIDATE(ds_img->slot.state == SG_RESOURCESTATE_VALID, VALIDATE_BEGINPASS_DEPTHSTENCIL_ATTACHMENT_IMAGE);
- _SG_VALIDATE(ds_img->slot.id == att->image_id.id, VALIDATE_BEGINPASS_DEPTHSTENCIL_ATTACHMENT_IMAGE);
+ // FIXME: swapchain params must be all zero!
}
return _sg_validate_end();
#endif
@@ -16018,6 +16013,7 @@ _SOKOL_PRIVATE bool _sg_validate_apply_pipeline(sg_pipeline pip_id) {
}
} else {
// default pass
+ // FIXME: match against swapchain attributes
_SG_VALIDATE(pip->cmn.color_count == 1, VALIDATE_APIP_ATT_COUNT);
_SG_VALIDATE(pip->cmn.colors[0].pixel_format == _sg.desc.context.color_format, VALIDATE_APIP_COLOR_FORMAT);
_SG_VALIDATE(pip->cmn.depth.pixel_format == _sg.desc.context.depth_format, VALIDATE_APIP_DEPTH_FORMAT);
@@ -17547,40 +17543,28 @@ SOKOL_API_IMPL void sg_destroy_attachments(sg_attachments atts_id) {
}
}
-SOKOL_API_IMPL void sg_begin_default_pass(const sg_pass_action* pass_action, int width, int height) {
- SOKOL_ASSERT(_sg.valid);
- SOKOL_ASSERT(pass_action);
- sg_pass_action pa;
- _sg_resolve_pass_action(pass_action, &pa);
- _sg.cur_atts.id = SG_INVALID_ID;
- _sg.pass_valid = true;
- _sg_begin_pass(0, &pa, width, height);
- _SG_TRACE_ARGS(begin_default_pass, &pa, width, height);
-}
-
-SOKOL_API_IMPL void sg_begin_default_passf(const sg_pass_action* pass_action, float width, float height) {
- sg_begin_default_pass(pass_action, (int)width, (int)height);
-}
-
SOKOL_API_IMPL void sg_begin_pass(const sg_pass* pass) {
SOKOL_ASSERT(_sg.valid);
SOKOL_ASSERT(pass);
SOKOL_ASSERT((pass->_start_canary == 0) && (pass->_end_canary == 0));
_sg.pass_valid = false;
_sg.cur_atts.id = SG_INVALID_ID;
- _sg_attachments_t* atts = _sg_lookup_attachments(&_sg.pools, pass->attachments.id);
- if (0 == atts) {
- _SG_ERROR(BEGINPASS_ATTACHMENT_INVALID);
+ if (!_sg_validate_begin_pass(pass)) {
return;
}
- if (!_sg_validate_begin_pass(atts)) {
- return;
+ _sg_attachments_t* atts = 0;
+ if (pass->attachments.id != SG_INVALID_ID) {
+ atts = _sg_lookup_attachments(&_sg.pools, pass->attachments.id);
+ if (0 == atts) {
+ _SG_ERROR(BEGINPASS_ATTACHMENT_INVALID);
+ return;
+ }
+ _sg.cur_atts = pass->attachments;
}
- _sg.pass_valid = true;
- _sg.cur_atts = pass->attachments;
sg_pass_action pa;
_sg_resolve_pass_action(&pass->action, &pa);
- _sg_begin_pass(atts, &pa, atts->cmn.width, atts->cmn.height);
+ _sg.pass_valid = true;
+ _sg_begin_pass(&pa, atts, &pass->swapchain);
_SG_TRACE_ARGS(begin_pass, pass);
}