|
@@ -9744,11 +9744,9 @@ _SOKOL_PRIVATE void _sg_d3d11_update_image(_sg_image_t* img, const sg_image_data
|
|
|
#if __has_feature(objc_arc)
|
|
|
#define _SG_OBJC_RETAIN(obj) { }
|
|
|
#define _SG_OBJC_RELEASE(obj) { obj = nil; }
|
|
|
-#define _SG_OBJC_RELEASE_WITH_NULL(obj) { obj = [NSNull null]; }
|
|
|
#else
|
|
|
#define _SG_OBJC_RETAIN(obj) { [obj retain]; }
|
|
|
#define _SG_OBJC_RELEASE(obj) { [obj release]; obj = nil; }
|
|
|
-#define _SG_OBJC_RELEASE_WITH_NULL(obj) { [obj release]; obj = [NSNull null]; }
|
|
|
#endif
|
|
|
|
|
|
/*-- enum translation functions ----------------------------------------------*/
|
|
@@ -10144,6 +10142,7 @@ _SOKOL_PRIVATE int _sg_mtl_add_resource(id res) {
|
|
|
return _SG_MTL_INVALID_SLOT_INDEX;
|
|
|
}
|
|
|
const int slot_index = _sg_mtl_alloc_pool_slot();
|
|
|
+ // NOTE: the NSMutableArray will take ownership of its items
|
|
|
SOKOL_ASSERT([NSNull null] == _sg.mtl.idpool.pool[(NSUInteger)slot_index]);
|
|
|
_sg.mtl.idpool.pool[(NSUInteger)slot_index] = res;
|
|
|
return slot_index;
|
|
@@ -10183,8 +10182,11 @@ _SOKOL_PRIVATE void _sg_mtl_garbage_collect(uint32_t frame_index) {
|
|
|
/* safe to release this resource */
|
|
|
const int slot_index = _sg.mtl.idpool.release_queue[_sg.mtl.idpool.release_queue_back].slot_index;
|
|
|
SOKOL_ASSERT((slot_index > 0) && (slot_index < _sg.mtl.idpool.num_slots));
|
|
|
+ /* note: the NSMutableArray takes ownership of its items, assigning an NSNull object will
|
|
|
+ release the object, no matter if using ARC or not
|
|
|
+ */
|
|
|
SOKOL_ASSERT(_sg.mtl.idpool.pool[(NSUInteger)slot_index] != [NSNull null]);
|
|
|
- _SG_OBJC_RELEASE_WITH_NULL(_sg.mtl.idpool.pool[(NSUInteger)slot_index]);
|
|
|
+ _sg.mtl.idpool.pool[(NSUInteger)slot_index] = [NSNull null];
|
|
|
/* put the now free pool index back on the free queue */
|
|
|
_sg_mtl_free_pool_slot(slot_index);
|
|
|
/* reset the release queue slot and advance the back index */
|
|
@@ -10249,6 +10251,7 @@ _SOKOL_PRIVATE int _sg_mtl_create_sampler(id<MTLDevice> mtl_device, const sg_ima
|
|
|
id<MTLSamplerState> mtl_sampler = [mtl_device newSamplerStateWithDescriptor:mtl_desc];
|
|
|
_SG_OBJC_RELEASE(mtl_desc);
|
|
|
int sampler_handle = _sg_mtl_add_resource(mtl_sampler);
|
|
|
+ _SG_OBJC_RELEASE(mtl_sampler);
|
|
|
_sg_smpcache_add_item(&_sg.mtl.sampler_cache, img_desc, (uintptr_t)sampler_handle);
|
|
|
return sampler_handle;
|
|
|
}
|
|
@@ -10518,6 +10521,7 @@ _SOKOL_PRIVATE sg_resource_state _sg_mtl_create_buffer(_sg_buffer_t* buf, const
|
|
|
}
|
|
|
}
|
|
|
buf->mtl.buf[slot] = _sg_mtl_add_resource(mtl_buf);
|
|
|
+ _SG_OBJC_RELEASE(mtl_buf);
|
|
|
}
|
|
|
return SG_RESOURCESTATE_VALID;
|
|
|
}
|
|
@@ -10695,6 +10699,7 @@ _SOKOL_PRIVATE sg_resource_state _sg_mtl_create_image(_sg_image_t* img, const sg
|
|
|
id<MTLTexture> tex = [_sg.mtl.device newTextureWithDescriptor:mtl_desc];
|
|
|
SOKOL_ASSERT(nil != tex);
|
|
|
img->mtl.depth_tex = _sg_mtl_add_resource(tex);
|
|
|
+ _SG_OBJC_RELEASE(tex);
|
|
|
}
|
|
|
else {
|
|
|
/* create the color texture
|
|
@@ -10721,6 +10726,7 @@ _SOKOL_PRIVATE sg_resource_state _sg_mtl_create_image(_sg_image_t* img, const sg
|
|
|
}
|
|
|
}
|
|
|
img->mtl.tex[slot] = _sg_mtl_add_resource(tex);
|
|
|
+ _SG_OBJC_RELEASE(tex);
|
|
|
}
|
|
|
|
|
|
/* if MSAA color render target, create an additional MSAA render-surface texture */
|
|
@@ -10728,6 +10734,7 @@ _SOKOL_PRIVATE sg_resource_state _sg_mtl_create_image(_sg_image_t* img, const sg
|
|
|
_sg_mtl_init_texdesc_rt_msaa(mtl_desc, img);
|
|
|
id<MTLTexture> tex = [_sg.mtl.device newTextureWithDescriptor:mtl_desc];
|
|
|
img->mtl.msaa_tex = _sg_mtl_add_resource(tex);
|
|
|
+ _SG_OBJC_RELEASE(tex);
|
|
|
}
|
|
|
|
|
|
/* create (possibly shared) sampler state */
|
|
@@ -10778,18 +10785,18 @@ _SOKOL_PRIVATE sg_resource_state _sg_mtl_create_shader(_sg_shader_t* shd, const
|
|
|
_sg_shader_common_init(&shd->cmn, desc);
|
|
|
|
|
|
/* create metal libray objects and lookup entry functions */
|
|
|
- id<MTLLibrary> vs_lib;
|
|
|
- id<MTLLibrary> fs_lib;
|
|
|
- id<MTLFunction> vs_func;
|
|
|
- id<MTLFunction> fs_func;
|
|
|
+ id<MTLLibrary> vs_lib = nil;
|
|
|
+ id<MTLLibrary> fs_lib = nil;
|
|
|
+ id<MTLFunction> vs_func = nil;
|
|
|
+ id<MTLFunction> fs_func = nil;
|
|
|
const char* vs_entry = desc->vs.entry;
|
|
|
const char* fs_entry = desc->fs.entry;
|
|
|
if (desc->vs.bytecode.ptr && desc->fs.bytecode.ptr) {
|
|
|
/* separate byte code provided */
|
|
|
vs_lib = _sg_mtl_library_from_bytecode(desc->vs.bytecode.ptr, desc->vs.bytecode.size);
|
|
|
fs_lib = _sg_mtl_library_from_bytecode(desc->fs.bytecode.ptr, desc->fs.bytecode.size);
|
|
|
- if (nil == vs_lib || nil == fs_lib) {
|
|
|
- return SG_RESOURCESTATE_FAILED;
|
|
|
+ if ((nil == vs_lib) || (nil == fs_lib)) {
|
|
|
+ goto failed;
|
|
|
}
|
|
|
vs_func = [vs_lib newFunctionWithName:[NSString stringWithUTF8String:vs_entry]];
|
|
|
fs_func = [fs_lib newFunctionWithName:[NSString stringWithUTF8String:fs_entry]];
|
|
@@ -10798,29 +10805,47 @@ _SOKOL_PRIVATE sg_resource_state _sg_mtl_create_shader(_sg_shader_t* shd, const
|
|
|
/* separate sources provided */
|
|
|
vs_lib = _sg_mtl_compile_library(desc->vs.source);
|
|
|
fs_lib = _sg_mtl_compile_library(desc->fs.source);
|
|
|
- if (nil == vs_lib || nil == fs_lib) {
|
|
|
- return SG_RESOURCESTATE_FAILED;
|
|
|
+ if ((nil == vs_lib) || (nil == fs_lib)) {
|
|
|
+ goto failed;
|
|
|
}
|
|
|
vs_func = [vs_lib newFunctionWithName:[NSString stringWithUTF8String:vs_entry]];
|
|
|
fs_func = [fs_lib newFunctionWithName:[NSString stringWithUTF8String:fs_entry]];
|
|
|
}
|
|
|
else {
|
|
|
- return SG_RESOURCESTATE_FAILED;
|
|
|
+ goto failed;
|
|
|
}
|
|
|
if (nil == vs_func) {
|
|
|
SOKOL_LOG("vertex shader entry function not found\n");
|
|
|
- return SG_RESOURCESTATE_FAILED;
|
|
|
+ goto failed;
|
|
|
}
|
|
|
if (nil == fs_func) {
|
|
|
SOKOL_LOG("fragment shader entry function not found\n");
|
|
|
- return SG_RESOURCESTATE_FAILED;
|
|
|
+ goto failed;
|
|
|
}
|
|
|
/* it is legal to call _sg_mtl_add_resource with a nil value, this will return a special 0xFFFFFFFF index */
|
|
|
shd->mtl.stage[SG_SHADERSTAGE_VS].mtl_lib = _sg_mtl_add_resource(vs_lib);
|
|
|
+ _SG_OBJC_RELEASE(vs_lib);
|
|
|
shd->mtl.stage[SG_SHADERSTAGE_FS].mtl_lib = _sg_mtl_add_resource(fs_lib);
|
|
|
+ _SG_OBJC_RELEASE(fs_lib);
|
|
|
shd->mtl.stage[SG_SHADERSTAGE_VS].mtl_func = _sg_mtl_add_resource(vs_func);
|
|
|
+ _SG_OBJC_RELEASE(vs_func);
|
|
|
shd->mtl.stage[SG_SHADERSTAGE_FS].mtl_func = _sg_mtl_add_resource(fs_func);
|
|
|
+ _SG_OBJC_RELEASE(fs_func);
|
|
|
return SG_RESOURCESTATE_VALID;
|
|
|
+failed:
|
|
|
+ if (vs_lib != nil) {
|
|
|
+ _SG_OBJC_RELEASE(vs_lib);
|
|
|
+ }
|
|
|
+ if (fs_lib != nil) {
|
|
|
+ _SG_OBJC_RELEASE(fs_lib);
|
|
|
+ }
|
|
|
+ if (vs_func != nil) {
|
|
|
+ _SG_OBJC_RELEASE(vs_func);
|
|
|
+ }
|
|
|
+ if (fs_func != nil) {
|
|
|
+ _SG_OBJC_RELEASE(fs_func);
|
|
|
+ }
|
|
|
+ return SG_RESOURCESTATE_FAILED;
|
|
|
}
|
|
|
|
|
|
_SOKOL_PRIVATE void _sg_mtl_destroy_shader(_sg_shader_t* shd) {
|
|
@@ -10947,7 +10972,9 @@ _SOKOL_PRIVATE sg_resource_state _sg_mtl_create_pipeline(_sg_pipeline_t* pip, _s
|
|
|
id<MTLDepthStencilState> mtl_dss = [_sg.mtl.device newDepthStencilStateWithDescriptor:ds_desc];
|
|
|
_SG_OBJC_RELEASE(ds_desc);
|
|
|
pip->mtl.rps = _sg_mtl_add_resource(mtl_rps);
|
|
|
+ _SG_OBJC_RELEASE(mtl_rps);
|
|
|
pip->mtl.dss = _sg_mtl_add_resource(mtl_dss);
|
|
|
+ _SG_OBJC_RELEASE(mtl_dss);
|
|
|
return SG_RESOURCESTATE_VALID;
|
|
|
}
|
|
|
|