diff options
| author | Andre Weissflog <floooh@gmail.com> | 2023-02-19 16:33:25 +0100 |
|---|---|---|
| committer | Andre Weissflog <floooh@gmail.com> | 2023-02-19 16:33:25 +0100 |
| commit | 494fb11e9af560d9df0d65c754b24f3ce3e5b7b9 (patch) | |
| tree | c1d089fd0293a81d0aff1fe7313dfd1db7bc3393 | |
| parent | a0a7c38f5bfb1ed14d5d6b824ab919df023acb1d (diff) | |
sokol_gfx.h: implement sg_query_shader_desc()
| -rw-r--r-- | sokol_gfx.h | 43 | ||||
| -rw-r--r-- | tests/functional/sokol_gfx_test.c | 57 |
2 files changed, 94 insertions, 6 deletions
diff --git a/sokol_gfx.h b/sokol_gfx.h index c7dc9ddb..9d1dc071 100644 --- a/sokol_gfx.h +++ b/sokol_gfx.h @@ -311,9 +311,15 @@ sg_pass_desc sg_query_pass_desc(sg_pass pass) ...but NOTE that the returned desc structs may be incomplete, - for instance any references to external data, or generally - information that is no longer available after creation will - be zeroed. + only attributes that is kept around internally after resource creation + will be filled in, and in some cases (like shaders) that's very little. + The returned desc structs might still be useful as partial blueprint + for creating similar resources if filled up with the missing + properties. Missing properties will be set to zero. + + Also calling the functions on an invalid resource will return + completely zeroed structs (it makes sense to check with sg_query_*_state() + first) --- you can inspect various internal resource attributes via: @@ -3808,7 +3814,7 @@ _SOKOL_PRIVATE void _sg_image_common_init(_sg_image_common_t* cmn, const sg_imag typedef struct { size_t size; -} _sg_uniform_block_t; +} _sg_shader_uniform_block_t; typedef struct { sg_image_type image_type; @@ -3818,7 +3824,7 @@ typedef struct { typedef struct { int num_uniform_blocks; int num_images; - _sg_uniform_block_t uniform_blocks[SG_MAX_SHADERSTAGE_UBS]; + _sg_shader_uniform_block_t uniform_blocks[SG_MAX_SHADERSTAGE_UBS]; _sg_shader_image_t images[SG_MAX_SHADERSTAGE_IMAGES]; } _sg_shader_stage_t; @@ -9554,7 +9560,7 @@ _SOKOL_PRIVATE sg_resource_state _sg_d3d11_create_shader(_sg_shader_t* shd, cons _sg_shader_stage_t* cmn_stage = &shd->cmn.stage[stage_index]; _sg_d3d11_shader_stage_t* d3d11_stage = &shd->d3d11.stage[stage_index]; for (int ub_index = 0; ub_index < cmn_stage->num_uniform_blocks; ub_index++) { - const _sg_uniform_block_t* ub = &cmn_stage->uniform_blocks[ub_index]; + const _sg_shader_uniform_block_t* ub = &cmn_stage->uniform_blocks[ub_index]; /* create a D3D constant buffer for each uniform block */ SOKOL_ASSERT(0 == d3d11_stage->cbufs[ub_index]); @@ -16911,6 +16917,31 @@ SOKOL_API_IMPL sg_image_desc sg_query_image_desc(sg_image img_id) { return desc; } +SOKOL_API_IMPL sg_shader_desc sg_query_shader_desc(sg_shader shd_id) { + SOKOL_ASSERT(_sg.valid); + sg_shader_desc desc; + _sg_clear(&desc, sizeof(desc)); + const _sg_shader_t* shd = _sg_lookup_shader(&_sg.pools, shd_id.id); + if (shd) { + for (int stage_idx = 0; stage_idx < SG_NUM_SHADER_STAGES; stage_idx++) { + sg_shader_stage_desc* stage_desc = (stage_idx == 0) ? &desc.vs : &desc.fs; + const _sg_shader_stage_t* stage = &shd->cmn.stage[stage_idx]; + for (int ub_idx = 0; ub_idx < stage->num_uniform_blocks; ub_idx++) { + sg_shader_uniform_block_desc* ub_desc = &stage_desc->uniform_blocks[ub_idx]; + const _sg_shader_uniform_block_t* ub = &stage->uniform_blocks[ub_idx]; + ub_desc->size = ub->size; + } + for (int img_idx = 0; img_idx < stage->num_images; img_idx++) { + sg_shader_image_desc* img_desc = &stage_desc->images[img_idx]; + const _sg_shader_image_t* img = &stage->images[img_idx]; + img_desc->image_type = img->image_type; + img_desc->sampler_type = img->sampler_type; + } + } + } + return desc; +} + SOKOL_API_IMPL sg_buffer_desc sg_query_buffer_defaults(const sg_buffer_desc* desc) { SOKOL_ASSERT(_sg.valid && desc); return _sg_buffer_desc_defaults(desc); diff --git a/tests/functional/sokol_gfx_test.c b/tests/functional/sokol_gfx_test.c index a9e0d0e5..8a8612c6 100644 --- a/tests/functional/sokol_gfx_test.c +++ b/tests/functional/sokol_gfx_test.c @@ -929,6 +929,63 @@ UTEST(sokol_gfx, query_image_desc) { sg_shutdown(); } +UTEST(sokol_gfx, query_shader_desc) { + setup(&(sg_desc){0}); + + sg_shader s0 = sg_make_shader(&(sg_shader_desc){ + .attrs = { + [0] = { .name = "pos", .sem_name = "POS", .sem_index = 1 }, + }, + .vs = { + .source = "vs_source", + .uniform_blocks = { + [0] = { + .size = 128, + .layout = SG_UNIFORMLAYOUT_STD140, + .uniforms = { + [0] = { .name = "blub", .type = SG_UNIFORMTYPE_FLOAT4, .array_count = 1 }, + [1] = { .name = "blob", .type = SG_UNIFORMTYPE_FLOAT2, .array_count = 1 }, + } + } + }, + .images = { + [0] = { .name = "img0", .image_type = SG_IMAGETYPE_2D, .sampler_type = SG_SAMPLERTYPE_FLOAT }, + } + }, + .fs = { + .source = "fs_source", + .images = { + [0] = { .name = "img1", .image_type = SG_IMAGETYPE_ARRAY, .sampler_type = SG_SAMPLERTYPE_UINT }, + } + }, + .label = "label", + }); + const sg_shader_desc s0_desc = sg_query_shader_desc(s0); + T(s0_desc.attrs[0].name == 0); + T(s0_desc.attrs[0].sem_name == 0); + T(s0_desc.attrs[0].sem_index == 0); + T(s0_desc.vs.source == 0); + T(s0_desc.vs.uniform_blocks[0].size == 128); + T(s0_desc.vs.uniform_blocks[0].layout == 0); + T(s0_desc.vs.uniform_blocks[0].uniforms[0].name == 0); + T(s0_desc.vs.uniform_blocks[0].uniforms[0].type == 0); + T(s0_desc.vs.uniform_blocks[0].uniforms[0].array_count == 0); + T(s0_desc.vs.images[0].name == 0); + T(s0_desc.vs.images[0].image_type == SG_IMAGETYPE_2D); + T(s0_desc.vs.images[0].sampler_type == SG_SAMPLERTYPE_FLOAT); + T(s0_desc.fs.source == 0); + T(s0_desc.fs.uniform_blocks[0].size == 0); + T(s0_desc.fs.uniform_blocks[0].layout == 0); + T(s0_desc.fs.uniform_blocks[0].uniforms[0].name == 0); + T(s0_desc.fs.uniform_blocks[0].uniforms[0].type == 0); + T(s0_desc.fs.uniform_blocks[0].uniforms[0].array_count == 0); + T(s0_desc.fs.images[0].name == 0); + T(s0_desc.fs.images[0].image_type == SG_IMAGETYPE_ARRAY); + T(s0_desc.fs.images[0].sampler_type == SG_SAMPLERTYPE_UINT); + + sg_shutdown(); +} + UTEST(sokol_gfx, buffer_resource_states) { setup(&(sg_desc){0}); sg_buffer buf = sg_alloc_buffer(); |