aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Weissflog <floooh@gmail.com>2025-09-22 15:49:42 +0200
committerAndre Weissflog <floooh@gmail.com>2025-09-22 15:49:42 +0200
commitda402deacc1db13ed55eb1a0c4d5cabbbb265ca7 (patch)
treea8b6b907d5bdf3692cc42ec63e3910a5a06b18bc
parent74bd1cc77022586de08e72b597dfccff4a6465f4 (diff)
sokol_gfx.h d3d11: fix a srv-vs-uav bindings chicken-egg-situation
-rw-r--r--sokol_gfx.h86
1 files changed, 54 insertions, 32 deletions
diff --git a/sokol_gfx.h b/sokol_gfx.h
index 4da8f302..4593a656 100644
--- a/sokol_gfx.h
+++ b/sokol_gfx.h
@@ -6312,6 +6312,18 @@ typedef struct {
HINSTANCE d3dcompiler_dll;
bool d3dcompiler_dll_load_failed;
pD3DCompile D3DCompile_func;
+ // static bindings arrays
+ struct {
+ ID3D11Buffer* vbs[SG_MAX_VERTEXBUFFER_BINDSLOTS];
+ UINT vb_offsets[SG_MAX_VERTEXBUFFER_BINDSLOTS];
+ ID3D11ShaderResourceView* vs_srvs[_SG_D3D11_MAX_STAGE_SRV_BINDINGS];
+ ID3D11ShaderResourceView* fs_srvs[_SG_D3D11_MAX_STAGE_SRV_BINDINGS];
+ ID3D11ShaderResourceView* cs_srvs[_SG_D3D11_MAX_STAGE_SRV_BINDINGS];
+ ID3D11UnorderedAccessView* cs_uavs[_SG_D3D11_MAX_STAGE_UAV_BINDINGS];
+ ID3D11SamplerState* vs_smps[_SG_D3D11_MAX_STAGE_SMP_BINDINGS];
+ ID3D11SamplerState* fs_smps[_SG_D3D11_MAX_STAGE_SMP_BINDINGS];
+ ID3D11SamplerState* cs_smps[_SG_D3D11_MAX_STAGE_SMP_BINDINGS];
+ } bnd;
// global subresourcedata array for texture updates
D3D11_SUBRESOURCE_DATA subres_data[_SG_D3D11_MAX_TEXTURE_SUBRESOURCES];
} _sg_d3d11_backend_t;
@@ -13477,27 +13489,36 @@ _SOKOL_PRIVATE bool _sg_d3d11_apply_bindings(_sg_bindings_ptrs_t* bnd) {
const _sg_shader_t* shd = _sg_shader_ref_ptr(&bnd->pip->cmn.shader);
const bool is_compute = bnd->pip->cmn.is_compute;
+ if (is_compute) {
+ _sg_clear(&_sg.d3d11.bnd.cs_srvs, sizeof(_sg.d3d11.bnd.cs_srvs));
+ _sg_clear(&_sg.d3d11.bnd.cs_uavs, sizeof(_sg.d3d11.bnd.cs_uavs));
+ _sg_clear(&_sg.d3d11.bnd.cs_smps, sizeof(_sg.d3d11.bnd.cs_smps));
+ } else {
+ _sg_clear(&_sg.d3d11.bnd.vbs, sizeof(_sg.d3d11.bnd.vbs));
+ _sg_clear(&_sg.d3d11.bnd.vb_offsets, sizeof(_sg.d3d11.bnd.vb_offsets));
+ _sg_clear(&_sg.d3d11.bnd.vs_srvs, sizeof(_sg.d3d11.bnd.vs_srvs));
+ _sg_clear(&_sg.d3d11.bnd.fs_srvs, sizeof(_sg.d3d11.bnd.fs_srvs));
+ _sg_clear(&_sg.d3d11.bnd.vs_smps, sizeof(_sg.d3d11.bnd.vs_smps));
+ _sg_clear(&_sg.d3d11.bnd.fs_smps, sizeof(_sg.d3d11.bnd.fs_smps));
+ }
+
// gather all the D3D11 resources into arrays
ID3D11Buffer* d3d11_ib = bnd->ib ? bnd->ib->d3d11.buf : 0;
- ID3D11Buffer* d3d11_vbs[SG_MAX_VERTEXBUFFER_BINDSLOTS] = {0};
- UINT d3d11_vb_offsets[SG_MAX_VERTEXBUFFER_BINDSLOTS] = {0};
- ID3D11ShaderResourceView* d3d11_vs_srvs[_SG_D3D11_MAX_STAGE_SRV_BINDINGS] = {0};
- ID3D11ShaderResourceView* d3d11_fs_srvs[_SG_D3D11_MAX_STAGE_SRV_BINDINGS] = {0};
- ID3D11ShaderResourceView* d3d11_cs_srvs[_SG_D3D11_MAX_STAGE_SRV_BINDINGS] = {0};
- ID3D11UnorderedAccessView* d3d11_cs_uavs[_SG_D3D11_MAX_STAGE_UAV_BINDINGS] = {0};
- ID3D11SamplerState* d3d11_vs_smps[_SG_D3D11_MAX_STAGE_SMP_BINDINGS] = {0};
- ID3D11SamplerState* d3d11_fs_smps[_SG_D3D11_MAX_STAGE_SMP_BINDINGS] = {0};
- ID3D11SamplerState* d3d11_cs_smps[_SG_D3D11_MAX_STAGE_SMP_BINDINGS] = {0};
-
- if (!is_compute) {
+
+ if (is_compute) {
+ // on D3D11 we need to break a chicken-egg-situation where a resource
+ // may still be set as shader resource view, but is going to be set
+ // as unordered-access-view, so first clear all shader resource view bindings
+ _sg_d3d11_CSSetShaderResources(_sg.d3d11.ctx, 0, _SG_D3D11_MAX_STAGE_SRV_BINDINGS, _sg.d3d11.bnd.cs_srvs);
+ } else {
for (size_t i = 0; i < SG_MAX_VERTEXBUFFER_BINDSLOTS; i++) {
const _sg_buffer_t* vb = bnd->vbs[i];
if (vb == 0) {
continue;
}
SOKOL_ASSERT(vb->d3d11.buf);
- d3d11_vbs[i] = vb->d3d11.buf;
- d3d11_vb_offsets[i] = (UINT)bnd->vb_offsets[i];
+ _sg.d3d11.bnd.vbs[i] = vb->d3d11.buf;
+ _sg.d3d11.bnd.vb_offsets[i] = (UINT)bnd->vb_offsets[i];
}
}
for (size_t i = 0; i < SG_MAX_VIEW_BINDSLOTS; i++) {
@@ -13519,9 +13540,9 @@ _SOKOL_PRIVATE bool _sg_d3d11_apply_bindings(_sg_bindings_ptrs_t* bnd) {
ID3D11ShaderResourceView* d3d11_srv = view->d3d11.srv;
SOKOL_ASSERT(d3d11_srv);
switch (stage) {
- case SG_SHADERSTAGE_VERTEX: d3d11_vs_srvs[d3d11_slot] = d3d11_srv; break;
- case SG_SHADERSTAGE_FRAGMENT: d3d11_fs_srvs[d3d11_slot] = d3d11_srv; break;
- case SG_SHADERSTAGE_COMPUTE: d3d11_cs_srvs[d3d11_slot] = d3d11_srv; break;
+ case SG_SHADERSTAGE_VERTEX: _sg.d3d11.bnd.vs_srvs[d3d11_slot] = d3d11_srv; break;
+ case SG_SHADERSTAGE_FRAGMENT: _sg.d3d11.bnd.fs_srvs[d3d11_slot] = d3d11_srv; break;
+ case SG_SHADERSTAGE_COMPUTE: _sg.d3d11.bnd.cs_srvs[d3d11_slot] = d3d11_srv; break;
default: SOKOL_UNREACHABLE;
}
} else if (shd_view->view_type == SG_VIEWTYPE_STORAGEBUFFER) {
@@ -13531,9 +13552,9 @@ _SOKOL_PRIVATE bool _sg_d3d11_apply_bindings(_sg_bindings_ptrs_t* bnd) {
ID3D11ShaderResourceView* d3d11_srv = view->d3d11.srv;
SOKOL_ASSERT(d3d11_srv);
switch (stage) {
- case SG_SHADERSTAGE_VERTEX: d3d11_vs_srvs[d3d11_slot] = d3d11_srv; break;
- case SG_SHADERSTAGE_FRAGMENT: d3d11_fs_srvs[d3d11_slot] = d3d11_srv; break;
- case SG_SHADERSTAGE_COMPUTE: d3d11_cs_srvs[d3d11_slot] = d3d11_srv; break;
+ case SG_SHADERSTAGE_VERTEX: _sg.d3d11.bnd.vs_srvs[d3d11_slot] = d3d11_srv; break;
+ case SG_SHADERSTAGE_FRAGMENT: _sg.d3d11.bnd.fs_srvs[d3d11_slot] = d3d11_srv; break;
+ case SG_SHADERSTAGE_COMPUTE: _sg.d3d11.bnd.cs_srvs[d3d11_slot] = d3d11_srv; break;
default: SOKOL_UNREACHABLE;
}
} else {
@@ -13542,7 +13563,7 @@ _SOKOL_PRIVATE bool _sg_d3d11_apply_bindings(_sg_bindings_ptrs_t* bnd) {
SOKOL_ASSERT(d3d11_slot < _SG_D3D11_MAX_STAGE_UAV_BINDINGS);
ID3D11UnorderedAccessView* d3d11_uav = view->d3d11.uav;
SOKOL_ASSERT(d3d11_uav);
- d3d11_cs_uavs[d3d11_slot] = d3d11_uav;
+ _sg.d3d11.bnd.cs_uavs[d3d11_slot] = d3d11_uav;
}
} else if (shd_view->view_type == SG_VIEWTYPE_STORAGEIMAGE) {
SOKOL_ASSERT(stage == SG_SHADERSTAGE_COMPUTE);
@@ -13550,7 +13571,7 @@ _SOKOL_PRIVATE bool _sg_d3d11_apply_bindings(_sg_bindings_ptrs_t* bnd) {
SOKOL_ASSERT(d3d11_slot < _SG_D3D11_MAX_STAGE_UAV_BINDINGS);
ID3D11UnorderedAccessView* d3d11_uav = view->d3d11.uav;
SOKOL_ASSERT(d3d11_uav);
- d3d11_cs_uavs[d3d11_slot] = d3d11_uav;
+ _sg.d3d11.bnd.cs_uavs[d3d11_slot] = d3d11_uav;
} else SOKOL_UNREACHABLE;
}
for (size_t i = 0; i < SG_MAX_SAMPLER_BINDSLOTS; i++) {
@@ -13565,26 +13586,27 @@ _SOKOL_PRIVATE bool _sg_d3d11_apply_bindings(_sg_bindings_ptrs_t* bnd) {
SOKOL_ASSERT(smp->d3d11.smp);
ID3D11SamplerState* d3d11_smp = smp->d3d11.smp;
switch (stage) {
- case SG_SHADERSTAGE_VERTEX: d3d11_vs_smps[d3d11_slot] = d3d11_smp; break;
- case SG_SHADERSTAGE_FRAGMENT: d3d11_fs_smps[d3d11_slot] = d3d11_smp; break;
- case SG_SHADERSTAGE_COMPUTE: d3d11_cs_smps[d3d11_slot] = d3d11_smp; break;
+ case SG_SHADERSTAGE_VERTEX: _sg.d3d11.bnd.vs_smps[d3d11_slot] = d3d11_smp; break;
+ case SG_SHADERSTAGE_FRAGMENT: _sg.d3d11.bnd.fs_smps[d3d11_slot] = d3d11_smp; break;
+ case SG_SHADERSTAGE_COMPUTE: _sg.d3d11.bnd.cs_smps[d3d11_slot] = d3d11_smp; break;
default: SOKOL_UNREACHABLE;
}
}
if (is_compute) {
- _sg_d3d11_CSSetShaderResources(_sg.d3d11.ctx, 0, _SG_D3D11_MAX_STAGE_SRV_BINDINGS, d3d11_cs_srvs);
- _sg_d3d11_CSSetSamplers(_sg.d3d11.ctx, 0, _SG_D3D11_MAX_STAGE_SMP_BINDINGS, d3d11_cs_smps);
- _sg_d3d11_CSSetUnorderedAccessViews(_sg.d3d11.ctx, 0, _SG_D3D11_MAX_STAGE_UAV_BINDINGS, d3d11_cs_uavs, NULL);
+ // NOTE: keep UAVs on front of SRVs
+ _sg_d3d11_CSSetUnorderedAccessViews(_sg.d3d11.ctx, 0, _SG_D3D11_MAX_STAGE_UAV_BINDINGS, _sg.d3d11.bnd.cs_uavs, NULL);
+ _sg_d3d11_CSSetShaderResources(_sg.d3d11.ctx, 0, _SG_D3D11_MAX_STAGE_SRV_BINDINGS, _sg.d3d11.bnd.cs_srvs);
+ _sg_d3d11_CSSetSamplers(_sg.d3d11.ctx, 0, _SG_D3D11_MAX_STAGE_SMP_BINDINGS, _sg.d3d11.bnd.cs_smps);
_sg_stats_add(d3d11.bindings.num_cs_set_shader_resources, 1);
_sg_stats_add(d3d11.bindings.num_cs_set_samplers, 1);
_sg_stats_add(d3d11.bindings.num_cs_set_unordered_access_views, 1);
} else {
- _sg_d3d11_IASetVertexBuffers(_sg.d3d11.ctx, 0, SG_MAX_VERTEXBUFFER_BINDSLOTS, d3d11_vbs, bnd->pip->d3d11.vb_strides, d3d11_vb_offsets);
+ _sg_d3d11_IASetVertexBuffers(_sg.d3d11.ctx, 0, SG_MAX_VERTEXBUFFER_BINDSLOTS, _sg.d3d11.bnd.vbs, bnd->pip->d3d11.vb_strides, _sg.d3d11.bnd.vb_offsets);
_sg_d3d11_IASetIndexBuffer(_sg.d3d11.ctx, d3d11_ib, bnd->pip->d3d11.index_format, (UINT)bnd->ib_offset);
- _sg_d3d11_VSSetShaderResources(_sg.d3d11.ctx, 0, _SG_D3D11_MAX_STAGE_SRV_BINDINGS, d3d11_vs_srvs);
- _sg_d3d11_PSSetShaderResources(_sg.d3d11.ctx, 0, _SG_D3D11_MAX_STAGE_SRV_BINDINGS, d3d11_fs_srvs);
- _sg_d3d11_VSSetSamplers(_sg.d3d11.ctx, 0, _SG_D3D11_MAX_STAGE_SMP_BINDINGS, d3d11_vs_smps);
- _sg_d3d11_PSSetSamplers(_sg.d3d11.ctx, 0, _SG_D3D11_MAX_STAGE_SMP_BINDINGS, d3d11_fs_smps);
+ _sg_d3d11_VSSetShaderResources(_sg.d3d11.ctx, 0, _SG_D3D11_MAX_STAGE_SRV_BINDINGS, _sg.d3d11.bnd.vs_srvs);
+ _sg_d3d11_PSSetShaderResources(_sg.d3d11.ctx, 0, _SG_D3D11_MAX_STAGE_SRV_BINDINGS, _sg.d3d11.bnd.fs_srvs);
+ _sg_d3d11_VSSetSamplers(_sg.d3d11.ctx, 0, _SG_D3D11_MAX_STAGE_SMP_BINDINGS, _sg.d3d11.bnd.vs_smps);
+ _sg_d3d11_PSSetSamplers(_sg.d3d11.ctx, 0, _SG_D3D11_MAX_STAGE_SMP_BINDINGS, _sg.d3d11.bnd.fs_smps);
_sg_stats_add(d3d11.bindings.num_ia_set_vertex_buffers, 1);
_sg_stats_add(d3d11.bindings.num_ia_set_index_buffer, 1);
_sg_stats_add(d3d11.bindings.num_vs_set_shader_resources, 1);