diff options
| author | Andre Weissflog <floooh@gmail.com> | 2025-01-24 18:59:51 +0100 |
|---|---|---|
| committer | Andre Weissflog <floooh@gmail.com> | 2025-01-24 18:59:51 +0100 |
| commit | d47a9435bc47c3db96a0bbacd2279f7dea84ef75 (patch) | |
| tree | 77006d14b5c3aa99f2a62a55e16d3358c084b4a7 | |
| parent | d5e3696609d15405c1e5cbe7fac9b2e19baab954 (diff) | |
sokol_gfx d3d11: check bindslot ranges in release, don't crash when shader creation fails
| -rw-r--r-- | sokol_gfx.h | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/sokol_gfx.h b/sokol_gfx.h index 4425da4a..d7016868 100644 --- a/sokol_gfx.h +++ b/sokol_gfx.h @@ -3707,6 +3707,10 @@ typedef struct sg_frame_stats { _SG_LOGITEM_XMACRO(D3D11_CREATE_3D_SRV_FAILED, "CreateShaderResourceView() failed for 3d texture (d3d11)") \ _SG_LOGITEM_XMACRO(D3D11_CREATE_MSAA_TEXTURE_FAILED, "CreateTexture2D() failed for MSAA render target texture (d3d11)") \ _SG_LOGITEM_XMACRO(D3D11_CREATE_SAMPLER_STATE_FAILED, "CreateSamplerState() failed (d3d11)") \ + _SG_LOGITEM_XMACRO(D3D11_UNIFORMBLOCK_HLSL_REGISTER_B_OUT_OF_RANGE, "uniform block 'hlsl_register_b_n' is out of range (must be 0..7)") \ + _SG_LOGITEM_XMACRO(D3D11_STORAGEBUFFER_HLSL_REGISTER_T_OUT_OF_RANGE, "storage buffer 'hlsl_register_t_n' is out of range (must be 0..23)") \ + _SG_LOGITEM_XMACRO(D3D11_IMAGE_HLSL_REGISTER_T_OUT_OF_RANGE, "image 'hlsl_register_t_n' is out of range (must be 0..23)") \ + _SG_LOGITEM_XMACRO(D3D11_SAMPLER_HLSL_REGISTER_S_OUT_OF_RANGE, "sampler 'hlsl_register_s_n' is out of rang (must be 0..15)") \ _SG_LOGITEM_XMACRO(D3D11_LOAD_D3DCOMPILER_47_DLL_FAILED, "loading d3dcompiler_47.dll failed (d3d11)") \ _SG_LOGITEM_XMACRO(D3D11_SHADER_COMPILATION_FAILED, "shader compilation failed (d3d11)") \ _SG_LOGITEM_XMACRO(D3D11_SHADER_COMPILATION_OUTPUT, "") \ @@ -10997,11 +11001,47 @@ _SOKOL_PRIVATE ID3DBlob* _sg_d3d11_compile_shader(const sg_shader_function* shd_ return output; } +// NOTE: this is an out-of-range check for HLSL bindslots that's also active in release mode +_SOKOL_PRIVATE bool _sg_d3d11_ensure_hlsl_bindslot_ranges(const sg_shader_desc* desc) { + SOKOL_ASSERT(desc); + for (size_t i = 0; i < SG_MAX_UNIFORMBLOCK_BINDSLOTS; i++) { + if (desc->uniform_blocks[i].hlsl_register_b_n >= _SG_D3D11_MAX_STAGE_UB_BINDINGS) { + _SG_ERROR(D3D11_UNIFORMBLOCK_HLSL_REGISTER_B_OUT_OF_RANGE); + return false; + } + } + for (size_t i = 0; i < SG_MAX_STORAGEBUFFER_BINDSLOTS; i++) { + if (desc->storage_buffers[i].hlsl_register_t_n >= _SG_D3D11_MAX_STAGE_TEX_SBUF_BINDINGS) { + _SG_ERROR(D3D11_STORAGEBUFFER_HLSL_REGISTER_T_OUT_OF_RANGE); + return false; + } + } + for (size_t i = 0; i < SG_MAX_IMAGE_BINDSLOTS; i++) { + if (desc->images[i].hlsl_register_t_n >= _SG_D3D11_MAX_STAGE_TEX_SBUF_BINDINGS) { + _SG_ERROR(D3D11_IMAGE_HLSL_REGISTER_T_OUT_OF_RANGE); + return false; + } + } + for (size_t i = 0; i < SG_MAX_SAMPLER_BINDSLOTS; i++) { + if (desc->samplers[i].hlsl_register_s_n >= _SG_D3D11_MAX_STAGE_SMP_BINDINGS) { + _SG_ERROR(D3D11_SAMPLER_HLSL_REGISTER_S_OUT_OF_RANGE); + return false; + } + } + return true; +} + _SOKOL_PRIVATE sg_resource_state _sg_d3d11_create_shader(_sg_shader_t* shd, const sg_shader_desc* desc) { SOKOL_ASSERT(shd && desc); SOKOL_ASSERT(!shd->d3d11.vs && !shd->d3d11.fs && !shd->d3d11.vs_blob); HRESULT hr; + // perform a range-check on HLSL bindslots that's also active in release + // mode to avoid potential out-of-bounds array accesses + if (!_sg_d3d11_ensure_hlsl_bindslot_ranges(desc)) { + return SG_RESOURCESTATE_FAILED; + } + // copy vertex attribute semantic names and indices for (size_t i = 0; i < SG_MAX_VERTEX_ATTRIBUTES; i++) { _sg_strcpy(&shd->d3d11.attrs[i].sem_name, desc->attrs[i].hlsl_sem_name); @@ -18834,7 +18874,12 @@ SOKOL_API_IMPL void sg_apply_pipeline(sg_pipeline pip_id) { _sg.cur_pipeline = pip_id; _sg_pipeline_t* pip = _sg_lookup_pipeline(&_sg.pools, pip_id.id); SOKOL_ASSERT(pip); + _sg.next_draw_valid = (SG_RESOURCESTATE_VALID == pip->slot.state); + if (!_sg.next_draw_valid) { + return; + } + SOKOL_ASSERT(pip->shader && (pip->shader->slot.id == pip->cmn.shader_id.id)); _sg_apply_pipeline(pip); @@ -18859,6 +18904,9 @@ SOKOL_API_IMPL void sg_apply_bindings(const sg_bindings* bindings) { if (!_sg.cur_pass.valid) { return; } + if (!_sg.next_draw_valid) { + return; + } _sg_bindings_t bnd; _sg_clear(&bnd, sizeof(bnd)); |