diff options
| author | Andre Weissflog <floooh@gmail.com> | 2025-04-07 15:24:46 +0200 |
|---|---|---|
| committer | Andre Weissflog <floooh@gmail.com> | 2025-04-07 15:24:46 +0200 |
| commit | 0c6ac02e7e76c79e7fcd2c16ed7daa7ea937594a (patch) | |
| tree | 0db9e14e705c15f85bbb02e1ce61bec9b7189a3d | |
| parent | da9de496f938b7575eff7f01ab774d77469bd390 (diff) | |
sokol_gfx.h: sg_buffer_usage and sg_image_usage, plus Metal fixes
| -rw-r--r-- | sokol_gfx.h | 251 |
1 files changed, 108 insertions, 143 deletions
diff --git a/sokol_gfx.h b/sokol_gfx.h index 1e63aa31..0f51a49b 100644 --- a/sokol_gfx.h +++ b/sokol_gfx.h @@ -2069,68 +2069,6 @@ typedef enum sg_resource_state { } sg_resource_state; /* - sg_usage - - A resource usage hint describing the update strategy of - buffers and images. This is used in the sg_buffer_desc.usage - and sg_image_desc.usage members when creating buffers - and images: - - SG_USAGE_IMMUTABLE: the resource will never be updated with - new (CPU-side) data, instead the content of the - resource must be provided on creation - SG_USAGE_DYNAMIC: the resource will be updated infrequently - with new data (this could range from "once - after creation", to "quite often but not - every frame") - SG_USAGE_STREAM: the resource will be updated each frame - with new content - - The rendering backends use this hint to prevent that the - CPU needs to wait for the GPU when attempting to update - a resource that might be currently accessed by the GPU. - - Resource content is updated with the functions sg_update_buffer() or - sg_append_buffer() for buffer objects, and sg_update_image() for image - objects. For the sg_update_*() functions, only one update is allowed per - frame and resource object, while sg_append_buffer() can be called - multiple times per frame on the same buffer. The application must update - all data required for rendering (this means that the update data can be - smaller than the resource size, if only a part of the overall resource - size is used for rendering, you only need to make sure that the data that - *is* used is valid). - - The default usage is SG_USAGE_IMMUTABLE. -*/ -typedef enum sg_usage { - _SG_USAGE_DEFAULT, // value 0 reserved for default-init - SG_USAGE_IMMUTABLE, - SG_USAGE_DYNAMIC, - SG_USAGE_STREAM, - _SG_USAGE_NUM, - _SG_USAGE_FORCE_U32 = 0x7FFFFFFF -} sg_usage; - -/* - sg_buffer_type - - Indicates whether a buffer will be bound as vertex-, - index- or storage-buffer. - - Used in the sg_buffer_desc.type member when creating a buffer. - - The default value is SG_BUFFERTYPE_VERTEXBUFFER. -*/ -typedef enum sg_buffer_type { - _SG_BUFFERTYPE_DEFAULT, // value 0 reserved for default-init - SG_BUFFERTYPE_VERTEXBUFFER, - SG_BUFFERTYPE_INDEXBUFFER, - SG_BUFFERTYPE_STORAGEBUFFER, - _SG_BUFFERTYPE_NUM, - _SG_BUFFERTYPE_FORCE_U32 = 0x7FFFFFFF -} sg_buffer_type; - -/* sg_index_type Indicates whether indexed rendering (fetching vertex-indices from an @@ -2978,6 +2916,20 @@ typedef struct sg_bindings { } sg_bindings; /* + sg_buffer_usage + + TODO +*/ +typedef struct sg_buffer_usage { + bool vertex_buffer; + bool index_buffer; + bool storage_buffer; + bool immutable; + bool dynamic_update; + bool stream_update; +} sg_buffer_usage; + +/* sg_buffer_desc Creation parameters for sg_buffer objects, used in the @@ -2986,8 +2938,7 @@ typedef struct sg_bindings { The default configuration is: .size: 0 (*must* be >0 for buffers without data) - .type: SG_BUFFERTYPE_VERTEXBUFFER - .usage: SG_USAGE_IMMUTABLE + .usage .vertex = true, .immutable = true .data.ptr 0 (*must* be valid for immutable buffers) .data.size 0 (*must* be > 0 for immutable buffers) .label 0 (optional string label) @@ -3033,8 +2984,7 @@ typedef struct sg_bindings { typedef struct sg_buffer_desc { uint32_t _start_canary; size_t size; - sg_buffer_type type; - sg_usage usage; + sg_buffer_usage usage; sg_range data; const char* label; // optionally inject backend-specific resources @@ -3046,6 +2996,19 @@ typedef struct sg_buffer_desc { } sg_buffer_desc; /* + sg_image_usage + + TODO +*/ +typedef struct sg_image_usage { + bool render_attachment; + bool storage_attachment; + bool immutable; + bool dynamic_update; + bool stream_update; +} sg_image_usage; + +/* sg_image_data Defines the content of an image through a 2D array of sg_range structs. @@ -3063,15 +3026,15 @@ typedef struct sg_image_data { The default configuration is: - .type: SG_IMAGETYPE_2D - .render_target: false + .type SG_IMAGETYPE_2D + .usage .immutable = true .width 0 (must be set to >0) .height 0 (must be set to >0) .num_slices 1 (3D textures: depth; array textures: number of layers) - .num_mipmaps: 1 - .usage: SG_USAGE_IMMUTABLE - .pixel_format: SG_PIXELFORMAT_RGBA8 for textures, or sg_desc.environment.defaults.color_format for render targets - .sample_count: 1 for textures, or sg_desc.environment.defaults.sample_count for render targets + .num_mipmaps 1 + .usage SG_USAGE_IMMUTABLE + .pixel_format SG_PIXELFORMAT_RGBA8 for textures, or sg_desc.environment.defaults.color_format for render targets + .sample_count 1 for textures, or sg_desc.environment.defaults.sample_count for render targets .data an sg_image_data struct to define the initial content .label 0 (optional string label for trace hooks) @@ -3115,12 +3078,11 @@ typedef struct sg_image_data { typedef struct sg_image_desc { uint32_t _start_canary; sg_image_type type; - bool render_target; + sg_image_usage usage; int width; int height; int num_slices; int num_mipmaps; - sg_usage usage; sg_pixel_format pixel_format; int sample_count; sg_image_data data; @@ -4057,10 +4019,10 @@ typedef struct sg_frame_stats { _SG_LOGITEM_XMACRO(VALIDATE_IMAGEDESC_MSAA_3D_IMAGE, "3D images cannot have a sample_count > 1") \ _SG_LOGITEM_XMACRO(VALIDATE_IMAGEDESC_MSAA_CUBE_IMAGE, "cube images cannot have sample_count > 1") \ _SG_LOGITEM_XMACRO(VALIDATE_IMAGEDESC_DEPTH_3D_IMAGE, "3D images cannot have a depth/stencil image format") \ - _SG_LOGITEM_XMACRO(VALIDATE_IMAGEDESC_RT_IMMUTABLE, "render target images must be SG_USAGE_IMMUTABLE") \ + _SG_LOGITEM_XMACRO(VALIDATE_IMAGEDESC_RT_IMMUTABLE, "render target images must be sg_image_usage.immutable") \ _SG_LOGITEM_XMACRO(VALIDATE_IMAGEDESC_RT_NO_DATA, "render target images cannot be initialized with data") \ _SG_LOGITEM_XMACRO(VALIDATE_IMAGEDESC_INJECTED_NO_DATA, "images with injected textures cannot be initialized with data") \ - _SG_LOGITEM_XMACRO(VALIDATE_IMAGEDESC_DYNAMIC_NO_DATA, "dynamic/stream images cannot be initialized with data") \ + _SG_LOGITEM_XMACRO(VALIDATE_IMAGEDESC_DYNAMIC_NO_DATA, "dynamic/stream-update images cannot be initialized with data") \ _SG_LOGITEM_XMACRO(VALIDATE_IMAGEDESC_COMPRESSED_IMMUTABLE, "compressed images must be immutable") \ _SG_LOGITEM_XMACRO(VALIDATE_SAMPLERDESC_CANARY, "sg_sampler_desc not initialized") \ _SG_LOGITEM_XMACRO(VALIDATE_SAMPLERDESC_ANISTROPIC_REQUIRES_LINEAR_FILTERING, "sg_sampler_desc.max_anisotropy > 1 requires min/mag/mipmap_filter to be SG_FILTER_LINEAR") \ @@ -4546,15 +4508,14 @@ SOKOL_GFX_API_DECL sg_pipeline_desc sg_query_pipeline_defaults(const sg_pipeline SOKOL_GFX_API_DECL sg_attachments_desc sg_query_attachments_defaults(const sg_attachments_desc* desc); // assorted query functions SOKOL_GFX_API_DECL size_t sg_query_buffer_size(sg_buffer buf); -SOKOL_GFX_API_DECL sg_buffer_type sg_query_buffer_type(sg_buffer buf); -SOKOL_GFX_API_DECL sg_usage sg_query_buffer_usage(sg_buffer buf); +SOKOL_GFX_API_DECL sg_buffer_usage sg_query_buffer_usage(sg_buffer buf); SOKOL_GFX_API_DECL sg_image_type sg_query_image_type(sg_image img); SOKOL_GFX_API_DECL int sg_query_image_width(sg_image img); SOKOL_GFX_API_DECL int sg_query_image_height(sg_image img); SOKOL_GFX_API_DECL int sg_query_image_num_slices(sg_image img); SOKOL_GFX_API_DECL int sg_query_image_num_mipmaps(sg_image img); SOKOL_GFX_API_DECL sg_pixel_format sg_query_image_pixelformat(sg_image img); -SOKOL_GFX_API_DECL sg_usage sg_query_image_usage(sg_image img); +SOKOL_GFX_API_DECL sg_image_usage sg_query_image_usage(sg_image img); SOKOL_GFX_API_DECL int sg_query_image_sample_count(sg_image img); // separate resource allocation and initialization (for async setup) @@ -5461,8 +5422,7 @@ typedef struct { uint32_t append_frame_index; int num_slots; int active_slot; - sg_buffer_type type; - sg_usage usage; + sg_buffer_usage usage; } _sg_buffer_common_t; _SOKOL_PRIVATE void _sg_buffer_common_init(_sg_buffer_common_t* cmn, const sg_buffer_desc* desc) { @@ -5471,9 +5431,8 @@ _SOKOL_PRIVATE void _sg_buffer_common_init(_sg_buffer_common_t* cmn, const sg_bu cmn->append_overflow = false; cmn->update_frame_index = 0; cmn->append_frame_index = 0; - cmn->num_slots = (desc->usage == SG_USAGE_IMMUTABLE) ? 1 : SG_NUM_INFLIGHT_FRAMES; + cmn->num_slots = desc->usage.immutable ? 1 : SG_NUM_INFLIGHT_FRAMES; cmn->active_slot = 0; - cmn->type = desc->type; cmn->usage = desc->usage; } @@ -5482,22 +5441,20 @@ typedef struct { int num_slots; int active_slot; sg_image_type type; - bool render_target; int width; int height; int num_slices; int num_mipmaps; - sg_usage usage; + sg_image_usage usage; sg_pixel_format pixel_format; int sample_count; } _sg_image_common_t; _SOKOL_PRIVATE void _sg_image_common_init(_sg_image_common_t* cmn, const sg_image_desc* desc) { cmn->upd_frame_index = 0; - cmn->num_slots = (desc->usage == SG_USAGE_IMMUTABLE) ? 1 : SG_NUM_INFLIGHT_FRAMES; + cmn->num_slots = desc->usage.immutable ? 1 : SG_NUM_INFLIGHT_FRAMES; cmn->active_slot = 0; cmn->type = desc->type; - cmn->render_target = desc->render_target; cmn->width = desc->width; cmn->height = desc->height; cmn->num_slices = desc->num_slices; @@ -12689,16 +12646,11 @@ _SOKOL_PRIVATE MTLResourceOptions _sg_mtl_resource_options_storage_mode_managed_ #endif } -_SOKOL_PRIVATE MTLResourceOptions _sg_mtl_buffer_resource_options(sg_usage usg) { - switch (usg) { - case SG_USAGE_IMMUTABLE: - return _sg_mtl_resource_options_storage_mode_managed_or_shared(); - case SG_USAGE_DYNAMIC: - case SG_USAGE_STREAM: - return MTLResourceCPUCacheModeWriteCombined | _sg_mtl_resource_options_storage_mode_managed_or_shared(); - default: - SOKOL_UNREACHABLE; - return 0; +_SOKOL_PRIVATE MTLResourceOptions _sg_mtl_buffer_resource_options(const sg_buffer_usage* usage) { + if (usage->immutable) { + return _sg_mtl_resource_options_storage_mode_managed_or_shared(); + } else { + return MTLResourceCPUCacheModeWriteCombined | _sg_mtl_resource_options_storage_mode_managed_or_shared(); } } @@ -13373,7 +13325,7 @@ _SOKOL_PRIVATE sg_resource_state _sg_mtl_create_buffer(_sg_buffer_t* buf, const SOKOL_ASSERT(buf && desc); SOKOL_ASSERT(buf->cmn.size > 0); const bool injected = (0 != desc->mtl_buffers[0]); - MTLResourceOptions mtl_options = _sg_mtl_buffer_resource_options(buf->cmn.usage); + MTLResourceOptions mtl_options = _sg_mtl_buffer_resource_options(&buf->cmn.usage); for (int slot = 0; slot < buf->cmn.num_slots; slot++) { id<MTLBuffer> mtl_buf; if (injected) { @@ -13477,7 +13429,7 @@ _SOKOL_PRIVATE bool _sg_mtl_init_texdesc_common(MTLTextureDescriptor* mtl_desc, } mtl_desc.usage = MTLTextureUsageShaderRead; MTLResourceOptions res_options = 0; - if (img->cmn.usage != SG_USAGE_IMMUTABLE) { + if (!img->cmn.usage.immutable) { res_options |= MTLResourceCPUCacheModeWriteCombined; } res_options |= _sg_mtl_resource_options_storage_mode_managed_or_shared(); @@ -13487,7 +13439,7 @@ _SOKOL_PRIVATE bool _sg_mtl_init_texdesc_common(MTLTextureDescriptor* mtl_desc, // initialize MTLTextureDescriptor with rendertarget attributes _SOKOL_PRIVATE void _sg_mtl_init_texdesc_rt(MTLTextureDescriptor* mtl_desc, _sg_image_t* img) { - SOKOL_ASSERT(img->cmn.render_target); + SOKOL_ASSERT(img->cmn.usage.render_attachment); _SOKOL_UNUSED(img); mtl_desc.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget; mtl_desc.resourceOptions = MTLResourceStorageModePrivate; @@ -13517,7 +13469,7 @@ _SOKOL_PRIVATE sg_resource_state _sg_mtl_create_image(_sg_image_t* img, const sg _SG_OBJC_RELEASE(mtl_desc); return SG_RESOURCESTATE_FAILED; } - if (img->cmn.render_target) { + if (img->cmn.usage.render_attachment) { if (img->cmn.sample_count > 1) { _sg_mtl_init_texdesc_rt_msaa(mtl_desc, img); } else { @@ -13536,7 +13488,9 @@ _SOKOL_PRIVATE sg_resource_state _sg_mtl_create_image(_sg_image_t* img, const sg _SG_ERROR(METAL_CREATE_TEXTURE_FAILED); return SG_RESOURCESTATE_FAILED; } - if ((img->cmn.usage == SG_USAGE_IMMUTABLE) && !img->cmn.render_target) { + // FIXME: make initial image data optional for immutable textures + // and render usage shouldn't matter for this + if (img->cmn.usage.immutable && !img->cmn.usage.render_attachment) { _sg_mtl_copy_image_data(img, mtl_tex, &desc->data); } } @@ -17781,7 +17735,7 @@ _SOKOL_PRIVATE bool _sg_validate_buffer_desc(const sg_buffer_desc* desc) { (0 != desc->mtl_buffers[0]) || (0 != desc->d3d11_buffer) || (0 != desc->wgpu_buffer); - if (!injected && (desc->usage == SG_USAGE_IMMUTABLE)) { + if (!injected && desc->usage.immutable) { if (desc->data.ptr) { _SG_VALIDATE(desc->size == desc->data.size, VALIDATE_BUFFERDESC_EXPECT_MATCHING_DATA_SIZE); } else { @@ -17791,7 +17745,7 @@ _SOKOL_PRIVATE bool _sg_validate_buffer_desc(const sg_buffer_desc* desc) { _SG_VALIDATE(0 == desc->data.ptr, VALIDATE_BUFFERDESC_EXPECT_NO_DATA); _SG_VALIDATE(desc->data.size == 0, VALIDATE_BUFFERDESC_EXPECT_ZERO_DATA_SIZE); } - if (desc->type == SG_BUFFERTYPE_STORAGEBUFFER) { + if (desc->usage.storage_buffer) { _SG_VALIDATE(_sg.features.compute, VALIDATE_BUFFERDESC_STORAGEBUFFER_SUPPORTED); _SG_VALIDATE(_sg_multiple_u64(desc->size, 4), VALIDATE_BUFFERDESC_STORAGEBUFFER_SIZE_MULTIPLE_4); } @@ -17839,7 +17793,7 @@ _SOKOL_PRIVATE bool _sg_validate_image_desc(const sg_image_desc* desc) { _SG_VALIDATE(desc->width > 0, VALIDATE_IMAGEDESC_WIDTH); _SG_VALIDATE(desc->height > 0, VALIDATE_IMAGEDESC_HEIGHT); const sg_pixel_format fmt = desc->pixel_format; - const sg_usage usage = desc->usage; + const sg_image_usage* usage = &desc->usage; const bool injected = (0 != desc->gl_textures[0]) || (0 != desc->mtl_textures[0]) || (0 != desc->d3d11_texture) || @@ -17847,10 +17801,10 @@ _SOKOL_PRIVATE bool _sg_validate_image_desc(const sg_image_desc* desc) { if (_sg_is_depth_or_depth_stencil_format(fmt)) { _SG_VALIDATE(desc->type != SG_IMAGETYPE_3D, VALIDATE_IMAGEDESC_DEPTH_3D_IMAGE); } - if (desc->render_target) { + if (usage->render_attachment) { SOKOL_ASSERT(((int)fmt >= 0) && ((int)fmt < _SG_PIXELFORMAT_NUM)); _SG_VALIDATE(_sg.formats[fmt].render, VALIDATE_IMAGEDESC_RT_PIXELFORMAT); - _SG_VALIDATE(usage == SG_USAGE_IMMUTABLE, VALIDATE_IMAGEDESC_RT_IMMUTABLE); + _SG_VALIDATE(usage->immutable, VALIDATE_IMAGEDESC_RT_IMMUTABLE); _SG_VALIDATE(desc->data.subimage[0][0].ptr==0, VALIDATE_IMAGEDESC_RT_NO_DATA); if (desc->sample_count > 1) { _SG_VALIDATE(_sg.formats[fmt].msaa, VALIDATE_IMAGEDESC_NO_MSAA_RT_SUPPORT); @@ -17863,11 +17817,10 @@ _SOKOL_PRIVATE bool _sg_validate_image_desc(const sg_image_desc* desc) { const bool valid_nonrt_fmt = !_sg_is_valid_rendertarget_depth_format(fmt); _SG_VALIDATE(valid_nonrt_fmt, VALIDATE_IMAGEDESC_NONRT_PIXELFORMAT); const bool is_compressed = _sg_is_compressed_pixel_format(desc->pixel_format); - const bool is_immutable = (usage == SG_USAGE_IMMUTABLE); if (is_compressed) { - _SG_VALIDATE(is_immutable, VALIDATE_IMAGEDESC_COMPRESSED_IMMUTABLE); + _SG_VALIDATE(usage->immutable, VALIDATE_IMAGEDESC_COMPRESSED_IMMUTABLE); } - if (!injected && is_immutable) { + if (!injected && usage->immutable) { // image desc must have valid data _sg_validate_image_data(&desc->data, desc->pixel_format, @@ -17885,7 +17838,7 @@ _SOKOL_PRIVATE bool _sg_validate_image_desc(const sg_image_desc* desc) { if (injected) { _SG_VALIDATE(no_data && no_size, VALIDATE_IMAGEDESC_INJECTED_NO_DATA); } - if (!is_immutable) { + if (!usage->immutable) { _SG_VALIDATE(no_data && no_size, VALIDATE_IMAGEDESC_DYNAMIC_NO_DATA); } } @@ -18335,7 +18288,7 @@ _SOKOL_PRIVATE bool _sg_validate_attachments_desc(const sg_attachments_desc* des _SG_VALIDATE(img, VALIDATE_ATTACHMENTSDESC_IMAGE); if (0 != img) { _SG_VALIDATE(img->slot.state == SG_RESOURCESTATE_VALID, VALIDATE_ATTACHMENTSDESC_IMAGE); - _SG_VALIDATE(img->cmn.render_target, VALIDATE_ATTACHMENTSDESC_IMAGE_NO_RT); + _SG_VALIDATE(img->cmn.usage.render_attachment, VALIDATE_ATTACHMENTSDESC_IMAGE_NO_RT); _SG_VALIDATE(att->mip_level < img->cmn.num_mipmaps, VALIDATE_ATTACHMENTSDESC_MIPLEVEL); if (img->cmn.type == SG_IMAGETYPE_CUBE) { _SG_VALIDATE(att->slice < 6, VALIDATE_ATTACHMENTSDESC_FACE); @@ -18364,11 +18317,11 @@ _SOKOL_PRIVATE bool _sg_validate_attachments_desc(const sg_attachments_desc* des _SG_VALIDATE(res_img, VALIDATE_ATTACHMENTSDESC_RESOLVE_IMAGE); if (res_img != 0) { _SG_VALIDATE(res_img->slot.state == SG_RESOURCESTATE_VALID, VALIDATE_ATTACHMENTSDESC_RESOLVE_IMAGE); - _SG_VALIDATE(res_img->cmn.render_target, VALIDATE_ATTACHMENTSDESC_RESOLVE_IMAGE_NO_RT); + _SG_VALIDATE(res_img->cmn.usage.render_attachment, VALIDATE_ATTACHMENTSDESC_RESOLVE_IMAGE_NO_RT); _SG_VALIDATE(res_img->cmn.sample_count == 1, VALIDATE_ATTACHMENTSDESC_RESOLVE_SAMPLE_COUNT); _SG_VALIDATE(res_att->mip_level < res_img->cmn.num_mipmaps, VALIDATE_ATTACHMENTSDESC_RESOLVE_MIPLEVEL); if (res_img->cmn.type == SG_IMAGETYPE_CUBE) { - _SG_VALIDATE(res_att->slice < 6, VALIDATE_ATTACHMENTSDESC_RESOLVE_FACE); + _SG_VALIDATE(res_att->slice < SG_CUBEFACE_NUM, VALIDATE_ATTACHMENTSDESC_RESOLVE_FACE); } else if (res_img->cmn.type == SG_IMAGETYPE_ARRAY) { _SG_VALIDATE(res_att->slice < res_img->cmn.num_slices, VALIDATE_ATTACHMENTSDESC_RESOLVE_LAYER); } else if (res_img->cmn.type == SG_IMAGETYPE_3D) { @@ -18398,7 +18351,7 @@ _SOKOL_PRIVATE bool _sg_validate_attachments_desc(const sg_attachments_desc* des // NOTE: this can't actually happen because of VALIDATE_IMAGEDESC_DEPTH_3D_IMAGE _SG_VALIDATE(att->slice < img->cmn.num_slices, VALIDATE_ATTACHMENTSDESC_DEPTH_SLICE); } - _SG_VALIDATE(img->cmn.render_target, VALIDATE_ATTACHMENTSDESC_DEPTH_IMAGE_NO_RT); + _SG_VALIDATE(img->cmn.usage.render_attachment, VALIDATE_ATTACHMENTSDESC_DEPTH_IMAGE_NO_RT); _SG_VALIDATE((color_width == -1) || (color_width == _sg_miplevel_dim(img->cmn.width, att->mip_level)), VALIDATE_ATTACHMENTSDESC_DEPTH_IMAGE_SIZES); _SG_VALIDATE((color_height == -1) || (color_height == _sg_miplevel_dim(img->cmn.height, att->mip_level)), VALIDATE_ATTACHMENTSDESC_DEPTH_IMAGE_SIZES); _SG_VALIDATE((color_sample_count == -1) || (color_sample_count == img->cmn.sample_count), VALIDATE_ATTACHMENTSDESC_DEPTH_IMAGE_SAMPLE_COUNT); @@ -18675,7 +18628,7 @@ _SOKOL_PRIVATE bool _sg_validate_apply_bindings(const sg_bindings* bindings) { const _sg_buffer_t* buf = _sg_lookup_buffer(&_sg.pools, bindings->vertex_buffers[i].id); _SG_VALIDATE(buf != 0, VALIDATE_ABND_VB_EXISTS); if (buf && buf->slot.state == SG_RESOURCESTATE_VALID) { - _SG_VALIDATE(SG_BUFFERTYPE_VERTEXBUFFER == buf->cmn.type, VALIDATE_ABND_VB_TYPE); + _SG_VALIDATE(buf->cmn.usage.vertex_buffer, VALIDATE_ABND_VB_TYPE); _SG_VALIDATE(!buf->cmn.append_overflow, VALIDATE_ABND_VB_OVERFLOW); } } @@ -18699,7 +18652,7 @@ _SOKOL_PRIVATE bool _sg_validate_apply_bindings(const sg_bindings* bindings) { const _sg_buffer_t* buf = _sg_lookup_buffer(&_sg.pools, bindings->index_buffer.id); _SG_VALIDATE(buf != 0, VALIDATE_ABND_IB_EXISTS); if (buf && buf->slot.state == SG_RESOURCESTATE_VALID) { - _SG_VALIDATE(SG_BUFFERTYPE_INDEXBUFFER == buf->cmn.type, VALIDATE_ABND_IB_TYPE); + _SG_VALIDATE(buf->cmn.usage.index_buffer, VALIDATE_ABND_IB_TYPE); _SG_VALIDATE(!buf->cmn.append_overflow, VALIDATE_ABND_IB_OVERFLOW); } } @@ -18768,10 +18721,10 @@ _SOKOL_PRIVATE bool _sg_validate_apply_bindings(const sg_bindings* bindings) { const _sg_buffer_t* sbuf = _sg_lookup_buffer(&_sg.pools, bindings->storage_buffers[i].id); _SG_VALIDATE(sbuf != 0, VALIDATE_ABND_STORAGEBUFFER_EXISTS); if (sbuf) { - _SG_VALIDATE(sbuf->cmn.type == SG_BUFFERTYPE_STORAGEBUFFER, VALIDATE_ABND_STORAGEBUFFER_BINDING_BUFFERTYPE); + _SG_VALIDATE(sbuf->cmn.usage.storage_buffer, VALIDATE_ABND_STORAGEBUFFER_BINDING_BUFFERTYPE); // read/write bindings are only allowed for immutable buffers if (!shd->cmn.storage_buffers[i].readonly) { - _SG_VALIDATE(sbuf->cmn.usage == SG_USAGE_IMMUTABLE, VALIDATE_ABND_STORAGEBUFFER_READWRITE_IMMUTABLE); + _SG_VALIDATE(sbuf->cmn.usage.immutable, VALIDATE_ABND_STORAGEBUFFER_READWRITE_IMMUTABLE); } } } @@ -18857,7 +18810,7 @@ _SOKOL_PRIVATE bool _sg_validate_update_buffer(const _sg_buffer_t* buf, const sg } SOKOL_ASSERT(buf && data && data->ptr); _sg_validate_begin(); - _SG_VALIDATE(buf->cmn.usage != SG_USAGE_IMMUTABLE, VALIDATE_UPDATEBUF_USAGE); + _SG_VALIDATE(!buf->cmn.usage.immutable, VALIDATE_UPDATEBUF_USAGE); _SG_VALIDATE(buf->cmn.size >= (int)data->size, VALIDATE_UPDATEBUF_SIZE); _SG_VALIDATE(buf->cmn.update_frame_index != _sg.frame_index, VALIDATE_UPDATEBUF_ONCE); _SG_VALIDATE(buf->cmn.append_frame_index != _sg.frame_index, VALIDATE_UPDATEBUF_APPEND); @@ -18876,7 +18829,7 @@ _SOKOL_PRIVATE bool _sg_validate_append_buffer(const _sg_buffer_t* buf, const sg } SOKOL_ASSERT(buf && data && data->ptr); _sg_validate_begin(); - _SG_VALIDATE(buf->cmn.usage != SG_USAGE_IMMUTABLE, VALIDATE_APPENDBUF_USAGE); + _SG_VALIDATE(!buf->cmn.usage.immutable, VALIDATE_APPENDBUF_USAGE); _SG_VALIDATE(buf->cmn.size >= (buf->cmn.append_pos + (int)data->size), VALIDATE_APPENDBUF_SIZE); _SG_VALIDATE(buf->cmn.update_frame_index != _sg.frame_index, VALIDATE_APPENDBUF_UPDATE); return _sg_validate_end(); @@ -18894,7 +18847,7 @@ _SOKOL_PRIVATE bool _sg_validate_update_image(const _sg_image_t* img, const sg_i } SOKOL_ASSERT(img && data); _sg_validate_begin(); - _SG_VALIDATE(img->cmn.usage != SG_USAGE_IMMUTABLE, VALIDATE_UPDIMG_USAGE); + _SG_VALIDATE(!img->cmn.usage.immutable, VALIDATE_UPDIMG_USAGE); _SG_VALIDATE(img->cmn.upd_frame_index != _sg.frame_index, VALIDATE_UPDIMG_ONCE); _sg_validate_image_data(data, img->cmn.pixel_format, @@ -18914,23 +18867,42 @@ _SOKOL_PRIVATE bool _sg_validate_update_image(const _sg_image_t* img, const sg_i // ██ ██ ███████ ███████ ██████ ██████ ██ ██ ██████ ███████ ███████ // // >>resources +_SOKOL_PRIVATE sg_buffer_usage _sg_buffer_usage_defaults(const sg_buffer_usage* usg) { + sg_buffer_usage def = *usg; + if (!(def.vertex_buffer || def.index_buffer || def.storage_buffer)) { + def.vertex_buffer = true; + } + if (!(def.immutable || def.stream_update || def.dynamic_update)) { + def.immutable = true; + } + return def; +} + + _SOKOL_PRIVATE sg_buffer_desc _sg_buffer_desc_defaults(const sg_buffer_desc* desc) { sg_buffer_desc def = *desc; - def.type = _sg_def(def.type, SG_BUFFERTYPE_VERTEXBUFFER); - def.usage = _sg_def(def.usage, SG_USAGE_IMMUTABLE); + def.usage = _sg_buffer_usage_defaults(&def.usage); if (def.size == 0) { def.size = def.data.size; } return def; } +_SOKOL_PRIVATE sg_image_usage _sg_image_usage_defaults(const sg_image_usage *usg) { + sg_image_usage def = *usg; + if (!(def.immutable || def.stream_update || def.dynamic_update)) { + def.immutable = true; + } + return def; +} + _SOKOL_PRIVATE sg_image_desc _sg_image_desc_defaults(const sg_image_desc* desc) { sg_image_desc def = *desc; def.type = _sg_def(def.type, SG_IMAGETYPE_2D); + def.usage = _sg_image_usage_defaults(&def.usage); def.num_slices = _sg_def(def.num_slices, 1); def.num_mipmaps = _sg_def(def.num_mipmaps, 1); - def.usage = _sg_def(def.usage, SG_USAGE_IMMUTABLE); - if (desc->render_target) { + if (def.usage.render_attachment) { def.pixel_format = _sg_def(def.pixel_format, _sg.desc.environment.defaults.color_format); def.sample_count = _sg_def(def.sample_count, _sg.desc.environment.defaults.sample_count); } else { @@ -20761,7 +20733,6 @@ SOKOL_API_IMPL sg_buffer_desc sg_query_buffer_desc(sg_buffer buf_id) { const _sg_buffer_t* buf = _sg_lookup_buffer(&_sg.pools, buf_id.id); if (buf) { desc.size = (size_t)buf->cmn.size; - desc.type = buf->cmn.type; desc.usage = buf->cmn.usage; } return desc; @@ -20776,22 +20747,15 @@ SOKOL_API_IMPL size_t sg_query_buffer_size(sg_buffer buf_id) { return 0; } -SOKOL_API_IMPL sg_buffer_type sg_query_buffer_type(sg_buffer buf_id) { - SOKOL_ASSERT(_sg.valid); - const _sg_buffer_t* buf = _sg_lookup_buffer(&_sg.pools, buf_id.id); - if (buf) { - return buf->cmn.type; - } - return _SG_BUFFERTYPE_DEFAULT; -} - -SOKOL_API_IMPL sg_usage sg_query_buffer_usage(sg_buffer buf_id) { +SOKOL_API_IMPL sg_buffer_usage sg_query_buffer_usage(sg_buffer buf_id) { SOKOL_ASSERT(_sg.valid); + sg_buffer_usage usg; + _sg_clear(&usg, sizeof(usg)); const _sg_buffer_t* buf = _sg_lookup_buffer(&_sg.pools, buf_id.id); if (buf) { - return buf->cmn.usage; + usg = buf->cmn.usage; } - return _SG_USAGE_DEFAULT; + return usg; } SOKOL_API_IMPL sg_image_desc sg_query_image_desc(sg_image img_id) { @@ -20801,7 +20765,6 @@ SOKOL_API_IMPL sg_image_desc sg_query_image_desc(sg_image img_id) { const _sg_image_t* img = _sg_lookup_image(&_sg.pools, img_id.id); if (img) { desc.type = img->cmn.type; - desc.render_target = img->cmn.render_target; desc.width = img->cmn.width; desc.height = img->cmn.height; desc.num_slices = img->cmn.num_slices; @@ -20867,13 +20830,15 @@ SOKOL_API_IMPL sg_pixel_format sg_query_image_pixelformat(sg_image img_id) { return _SG_PIXELFORMAT_DEFAULT; } -SOKOL_API_IMPL sg_usage sg_query_image_usage(sg_image img_id) { +SOKOL_API_IMPL sg_image_usage sg_query_image_usage(sg_image img_id) { SOKOL_ASSERT(_sg.valid); + sg_image_usage usg; + _sg_clear(&usg, sizeof(usg)); const _sg_image_t* img = _sg_lookup_image(&_sg.pools, img_id.id); if (img) { - return img->cmn.usage; + usg = img->cmn.usage; } - return _SG_USAGE_DEFAULT; + return usg; } SOKOL_API_IMPL int sg_query_image_sample_count(sg_image img_id) { |