aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Weissflog <floooh@gmail.com>2025-01-24 18:59:51 +0100
committerAndre Weissflog <floooh@gmail.com>2025-01-24 18:59:51 +0100
commitd47a9435bc47c3db96a0bbacd2279f7dea84ef75 (patch)
tree77006d14b5c3aa99f2a62a55e16d3358c084b4a7
parentd5e3696609d15405c1e5cbe7fac9b2e19baab954 (diff)
sokol_gfx d3d11: check bindslot ranges in release, don't crash when shader creation fails
-rw-r--r--sokol_gfx.h48
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));