Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
GH Action committed Aug 31, 2024
1 parent 9bae36c commit a8e75b4
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 22 deletions.
108 changes: 86 additions & 22 deletions src/sokol/c/sokol_gfx.h
Original file line number Diff line number Diff line change
Expand Up @@ -1496,6 +1496,7 @@
.wgpu.num_bindgroup_cache_hits
.wgpu.num_bindgroup_cache_misses
.wgpu.num_bindgroup_cache_collisions
.wgpu_num_bindgroup_cache_invalidates
.wgpu.num_bindgroup_cache_vs_hash_key_mismatch

The value to pay attention to is `.wgpu.num_bindgroup_cache_collisions`,
Expand Down Expand Up @@ -3482,6 +3483,7 @@ typedef struct sg_frame_stats_wgpu_bindings {
uint32_t num_bindgroup_cache_hits;
uint32_t num_bindgroup_cache_misses;
uint32_t num_bindgroup_cache_collisions;
uint32_t num_bindgroup_cache_invalidates;
uint32_t num_bindgroup_cache_hash_vs_key_mismatch;
} sg_frame_stats_wgpu_bindings;

Expand Down Expand Up @@ -5783,10 +5785,20 @@ typedef struct {
uint32_t id;
} _sg_wgpu_bindgroup_handle_t;

#define _SG_WGPU_BINDGROUPSCACHE_NUM_ITEMS (1 + _SG_WGPU_MAX_BINDGROUP_ENTRIES)
typedef enum {
_SG_WGPU_BINDGROUPSCACHEITEMTYPE_NONE = 0,
_SG_WGPU_BINDGROUPSCACHEITEMTYPE_IMAGE = 0x1111111111111111,
_SG_WGPU_BINDGROUPSCACHEITEMTYPE_SAMPLER = 0x2222222222222222,
_SG_WGPU_BINDGROUPSCACHEITEMTYPE_STORAGEBUFFER = 0x3333333333333333,
_SG_WGPU_BINDGROUPSCACHEITEMTYPE_PIPELINE = 0x4444444444444444,
} _sg_wgpu_bindgroups_cache_item_type_t;

#define _SG_WGPU_BINDGROUPSCACHEKEY_NUM_ITEMS (1 + _SG_WGPU_MAX_BINDGROUP_ENTRIES)
typedef struct {
uint64_t hash;
uint32_t items[_SG_WGPU_BINDGROUPSCACHE_NUM_ITEMS];
// the format of cache key items is (_sg_wgpu_bindgroups_cache_item_type_t << 32) | handle.id,
// where the item type is a per-resource-type bit pattern
uint64_t items[_SG_WGPU_BINDGROUPSCACHEKEY_NUM_ITEMS];
} _sg_wgpu_bindgroups_cache_key_t;

typedef struct {
Expand Down Expand Up @@ -14034,6 +14046,26 @@ _SOKOL_PRIVATE uint64_t _sg_wgpu_hash(const void* key, int len, uint64_t seed) {
return h;
}

_SOKOL_PRIVATE uint64_t _sg_wgpu_bindgroups_cache_item(_sg_wgpu_bindgroups_cache_item_type_t type, uint32_t id) {
return (((uint64_t)type) << 32) | id;
}

_SOKOL_PRIVATE uint64_t _sg_wgpu_bindgroups_cache_pip_item(uint32_t id) {
return _sg_wgpu_bindgroups_cache_item(_SG_WGPU_BINDGROUPSCACHEITEMTYPE_PIPELINE, id);
}

_SOKOL_PRIVATE uint64_t _sg_wgpu_bindgroups_cache_image_item(uint32_t id) {
return _sg_wgpu_bindgroups_cache_item(_SG_WGPU_BINDGROUPSCACHEITEMTYPE_IMAGE, id);
}

_SOKOL_PRIVATE uint64_t _sg_wgpu_bindgroups_cache_sampler_item(uint32_t id) {
return _sg_wgpu_bindgroups_cache_item(_SG_WGPU_BINDGROUPSCACHEITEMTYPE_SAMPLER, id);
}

_SOKOL_PRIVATE uint64_t _sg_wgpu_bindgroups_cache_sbuf_item(uint32_t id) {
return _sg_wgpu_bindgroups_cache_item(_SG_WGPU_BINDGROUPSCACHEITEMTYPE_STORAGEBUFFER, id);
}

_SOKOL_PRIVATE void _sg_wgpu_init_bindgroups_cache_key(_sg_wgpu_bindgroups_cache_key_t* key, const _sg_bindings_t* bnd) {
SOKOL_ASSERT(bnd);
SOKOL_ASSERT(bnd->pip);
Expand All @@ -14045,38 +14077,39 @@ _SOKOL_PRIVATE void _sg_wgpu_init_bindgroups_cache_key(_sg_wgpu_bindgroups_cache
SOKOL_ASSERT(bnd->num_fs_sbufs <= SG_MAX_SHADERSTAGE_STORAGEBUFFERS);

_sg_clear(key->items, sizeof(key->items));
key->items[0] = bnd->pip->slot.id;
const int vs_imgs_offset = 1;
const int vs_smps_offset = vs_imgs_offset + SG_MAX_SHADERSTAGE_IMAGES;
const int vs_sbufs_offset = vs_smps_offset + SG_MAX_SHADERSTAGE_SAMPLERS;
const int fs_imgs_offset = vs_sbufs_offset + SG_MAX_SHADERSTAGE_STORAGEBUFFERS;
const int fs_smps_offset = fs_imgs_offset + SG_MAX_SHADERSTAGE_IMAGES;
const int fs_sbufs_offset = fs_smps_offset + SG_MAX_SHADERSTAGE_SAMPLERS;
SOKOL_ASSERT((fs_sbufs_offset + SG_MAX_SHADERSTAGE_STORAGEBUFFERS) == _SG_WGPU_BINDGROUPSCACHE_NUM_ITEMS);
int item_idx = 0;
key->items[item_idx++] = _sg_wgpu_bindgroups_cache_pip_item(bnd->pip->slot.id);
for (int i = 0; i < bnd->num_vs_imgs; i++) {
SOKOL_ASSERT(bnd->vs_imgs[i]);
key->items[vs_imgs_offset + i] = bnd->vs_imgs[i]->slot.id;
SOKOL_ASSERT(item_idx < _SG_WGPU_BINDGROUPSCACHEKEY_NUM_ITEMS);
key->items[item_idx++] = _sg_wgpu_bindgroups_cache_image_item(bnd->vs_imgs[i]->slot.id);
}
for (int i = 0; i < bnd->num_vs_smps; i++) {
SOKOL_ASSERT(bnd->vs_smps[i]);
key->items[vs_smps_offset + i] = bnd->vs_smps[i]->slot.id;
SOKOL_ASSERT(item_idx < _SG_WGPU_BINDGROUPSCACHEKEY_NUM_ITEMS);
key->items[item_idx++] = _sg_wgpu_bindgroups_cache_sampler_item(bnd->vs_smps[i]->slot.id);
}
for (int i = 0; i < bnd->num_vs_sbufs; i++) {
SOKOL_ASSERT(bnd->vs_sbufs[i]);
key->items[vs_sbufs_offset + i] = bnd->vs_sbufs[i]->slot.id;
SOKOL_ASSERT(item_idx < _SG_WGPU_BINDGROUPSCACHEKEY_NUM_ITEMS);
key->items[item_idx++] = _sg_wgpu_bindgroups_cache_sbuf_item(bnd->vs_sbufs[i]->slot.id);
}
for (int i = 0; i < bnd->num_fs_imgs; i++) {
SOKOL_ASSERT(bnd->fs_imgs[i]);
key->items[fs_imgs_offset + i] = bnd->fs_imgs[i]->slot.id;
SOKOL_ASSERT(item_idx < _SG_WGPU_BINDGROUPSCACHEKEY_NUM_ITEMS);
key->items[item_idx++] = _sg_wgpu_bindgroups_cache_image_item(bnd->fs_imgs[i]->slot.id);
}
for (int i = 0; i < bnd->num_fs_smps; i++) {
SOKOL_ASSERT(bnd->fs_smps[i]);
key->items[fs_smps_offset + i] = bnd->fs_smps[i]->slot.id;
SOKOL_ASSERT(item_idx < _SG_WGPU_BINDGROUPSCACHEKEY_NUM_ITEMS);
key->items[item_idx++] = _sg_wgpu_bindgroups_cache_sampler_item(bnd->fs_smps[i]->slot.id);
}
for (int i = 0; i < bnd->num_fs_sbufs; i++) {
SOKOL_ASSERT(bnd->fs_sbufs[i]);
key->items[fs_sbufs_offset + i] = bnd->fs_sbufs[i]->slot.id;
SOKOL_ASSERT(item_idx < _SG_WGPU_BINDGROUPSCACHEKEY_NUM_ITEMS);
key->items[item_idx++] = _sg_wgpu_bindgroups_cache_sbuf_item(bnd->fs_sbufs[i]->slot.id);
}
SOKOL_ASSERT(item_idx == (1 + bnd->num_vs_imgs + bnd->num_vs_smps + bnd->num_vs_sbufs + bnd->num_fs_imgs + bnd->num_fs_smps + bnd->num_fs_sbufs));
key->hash = _sg_wgpu_hash(&key->items, (int)sizeof(key->items), 0x1234567887654321);
}

Expand Down Expand Up @@ -14228,6 +14261,33 @@ _SOKOL_PRIVATE uint32_t _sg_wgpu_bindgroups_cache_get(uint64_t hash) {
return _sg.wgpu.bindgroups_cache.items[index].id;
}

// called from wgpu resource destroy functions to also invalidate any
// bindgroups cache slot and bindgroup referencing that resource
_SOKOL_PRIVATE void _sg_wgpu_bindgroups_cache_invalidate(_sg_wgpu_bindgroups_cache_item_type_t type, uint32_t id) {
const uint64_t key_item = _sg_wgpu_bindgroups_cache_item(type, id);
SOKOL_ASSERT(_sg.wgpu.bindgroups_cache.items);
for (uint32_t cache_item_idx = 0; cache_item_idx < _sg.wgpu.bindgroups_cache.num; cache_item_idx++) {
const uint32_t bg_id = _sg.wgpu.bindgroups_cache.items[cache_item_idx].id;
if (bg_id != SG_INVALID_ID) {
_sg_wgpu_bindgroup_t* bg = _sg_wgpu_lookup_bindgroup(bg_id);
SOKOL_ASSERT(bg && (bg->slot.state == SG_RESOURCESTATE_VALID));
// check if resource is in bindgroup, if yes discard bindgroup and invalidate cache slot
bool invalidate_cache_item = false;
for (int key_item_idx = 0; key_item_idx < _SG_WGPU_BINDGROUPSCACHEKEY_NUM_ITEMS; key_item_idx++) {
if (bg->key.items[key_item_idx] == key_item) {
invalidate_cache_item = true;
break;
}
}
if (invalidate_cache_item) {
_sg_wgpu_discard_bindgroup(bg); bg = 0;
_sg_wgpu_bindgroups_cache_set(cache_item_idx, SG_INVALID_ID);
_sg_stats_add(wgpu.bindings.num_bindgroup_cache_invalidates, 1);
}
}
}
}

_SOKOL_PRIVATE void _sg_wgpu_bindings_cache_clear(void) {
memset(&_sg.wgpu.bindings_cache, 0, sizeof(_sg.wgpu.bindings_cache));
}
Expand Down Expand Up @@ -14288,7 +14348,7 @@ _SOKOL_PRIVATE void _sg_wgpu_bindings_cache_bg_update(const _sg_wgpu_bindgroup_t
}
}

_SOKOL_PRIVATE void _sg_wgpu_set_bindings_bindgroup(_sg_wgpu_bindgroup_t* bg) {
_SOKOL_PRIVATE void _sg_wgpu_set_bindgroup(_sg_wgpu_bindgroup_t* bg) {
if (_sg_wgpu_bindings_cache_bg_dirty(bg)) {
_sg_wgpu_bindings_cache_bg_update(bg);
_sg_stats_add(wgpu.bindings.num_set_bindgroup, 1);
Expand Down Expand Up @@ -14334,7 +14394,7 @@ _SOKOL_PRIVATE bool _sg_wgpu_apply_bindgroup(_sg_bindings_t* bnd) {
_sg_wgpu_bindgroups_cache_set(key.hash, bg->slot.id);
}
if (bg && bg->slot.state == SG_RESOURCESTATE_VALID) {
_sg_wgpu_set_bindings_bindgroup(bg);
_sg_wgpu_set_bindgroup(bg);
} else {
return false;
}
Expand All @@ -14343,15 +14403,15 @@ _SOKOL_PRIVATE bool _sg_wgpu_apply_bindgroup(_sg_bindings_t* bnd) {
_sg_wgpu_bindgroup_t* bg = _sg_wgpu_create_bindgroup(bnd);
if (bg) {
if (bg->slot.state == SG_RESOURCESTATE_VALID) {
_sg_wgpu_set_bindings_bindgroup(bg);
_sg_wgpu_set_bindgroup(bg);
}
_sg_wgpu_discard_bindgroup(bg);
} else {
return false;
}
}
} else {
_sg_wgpu_set_bindings_bindgroup(0);
_sg_wgpu_set_bindgroup(0);
}
return true;
}
Expand Down Expand Up @@ -14484,8 +14544,10 @@ _SOKOL_PRIVATE sg_resource_state _sg_wgpu_create_buffer(_sg_buffer_t* buf, const

_SOKOL_PRIVATE void _sg_wgpu_discard_buffer(_sg_buffer_t* buf) {
SOKOL_ASSERT(buf);
if (buf->cmn.type == SG_BUFFERTYPE_STORAGEBUFFER) {
_sg_wgpu_bindgroups_cache_invalidate(_SG_WGPU_BINDGROUPSCACHEITEMTYPE_STORAGEBUFFER, buf->slot.id);
}
if (buf->wgpu.buf) {
wgpuBufferDestroy(buf->wgpu.buf);
wgpuBufferRelease(buf->wgpu.buf);
}
}
Expand Down Expand Up @@ -14621,12 +14683,12 @@ _SOKOL_PRIVATE sg_resource_state _sg_wgpu_create_image(_sg_image_t* img, const s

_SOKOL_PRIVATE void _sg_wgpu_discard_image(_sg_image_t* img) {
SOKOL_ASSERT(img);
_sg_wgpu_bindgroups_cache_invalidate(_SG_WGPU_BINDGROUPSCACHEITEMTYPE_IMAGE, img->slot.id);
if (img->wgpu.view) {
wgpuTextureViewRelease(img->wgpu.view);
img->wgpu.view = 0;
}
if (img->wgpu.tex) {
wgpuTextureDestroy(img->wgpu.tex);
wgpuTextureRelease(img->wgpu.tex);
img->wgpu.tex = 0;
}
Expand Down Expand Up @@ -14667,6 +14729,7 @@ _SOKOL_PRIVATE sg_resource_state _sg_wgpu_create_sampler(_sg_sampler_t* smp, con

_SOKOL_PRIVATE void _sg_wgpu_discard_sampler(_sg_sampler_t* smp) {
SOKOL_ASSERT(smp);
_sg_wgpu_bindgroups_cache_invalidate(_SG_WGPU_BINDGROUPSCACHEITEMTYPE_SAMPLER, smp->slot.id);
if (smp->wgpu.smp) {
wgpuSamplerRelease(smp->wgpu.smp);
smp->wgpu.smp = 0;
Expand Down Expand Up @@ -14904,6 +14967,7 @@ _SOKOL_PRIVATE sg_resource_state _sg_wgpu_create_pipeline(_sg_pipeline_t* pip, _

_SOKOL_PRIVATE void _sg_wgpu_discard_pipeline(_sg_pipeline_t* pip) {
SOKOL_ASSERT(pip);
_sg_wgpu_bindgroups_cache_invalidate(_SG_WGPU_BINDGROUPSCACHEITEMTYPE_PIPELINE, pip->slot.id);
if (pip == _sg.wgpu.cur_pipeline) {
_sg.wgpu.cur_pipeline = 0;
_sg.wgpu.cur_pipeline_id.id = SG_INVALID_ID;
Expand Down
1 change: 1 addition & 0 deletions src/sokol/gfx.zig
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,7 @@ pub const FrameStatsWgpuBindings = extern struct {
num_bindgroup_cache_hits: u32 = 0,
num_bindgroup_cache_misses: u32 = 0,
num_bindgroup_cache_collisions: u32 = 0,
num_bindgroup_cache_invalidates: u32 = 0,
num_bindgroup_cache_hash_vs_key_mismatch: u32 = 0,
};
pub const FrameStatsWgpu = extern struct {
Expand Down

0 comments on commit a8e75b4

Please sign in to comment.