1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-12 22:08:59 +01:00

[d3d11] Refactor shader resource state

This commit is contained in:
Philip Rebohle 2022-08-04 15:56:49 +02:00
parent 33e169e85f
commit 1b4cb66dc3
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 71 additions and 90 deletions

View File

@ -1361,9 +1361,7 @@ namespace dxvk {
D3D10DeviceLock lock = LockContext(); D3D10DeviceLock lock = LockContext();
SetShaderResources<DxbcProgramType::VertexShader>( SetShaderResources<DxbcProgramType::VertexShader>(
m_state.vs.shaderResources, StartSlot, NumViews, ppShaderResourceViews);
StartSlot, NumViews,
ppShaderResourceViews);
} }
@ -1431,7 +1429,7 @@ namespace dxvk {
ID3D11ShaderResourceView** ppShaderResourceViews) { ID3D11ShaderResourceView** ppShaderResourceViews) {
D3D10DeviceLock lock = LockContext(); D3D10DeviceLock lock = LockContext();
GetShaderResources(m_state.vs.shaderResources, GetShaderResources<DxbcProgramType::VertexShader>(
StartSlot, NumViews, ppShaderResourceViews); StartSlot, NumViews, ppShaderResourceViews);
} }
@ -1503,9 +1501,7 @@ namespace dxvk {
D3D10DeviceLock lock = LockContext(); D3D10DeviceLock lock = LockContext();
SetShaderResources<DxbcProgramType::HullShader>( SetShaderResources<DxbcProgramType::HullShader>(
m_state.hs.shaderResources, StartSlot, NumViews, ppShaderResourceViews);
StartSlot, NumViews,
ppShaderResourceViews);
} }
@ -1573,7 +1569,7 @@ namespace dxvk {
ID3D11ShaderResourceView** ppShaderResourceViews) { ID3D11ShaderResourceView** ppShaderResourceViews) {
D3D10DeviceLock lock = LockContext(); D3D10DeviceLock lock = LockContext();
GetShaderResources(m_state.hs.shaderResources, GetShaderResources<DxbcProgramType::HullShader>(
StartSlot, NumViews, ppShaderResourceViews); StartSlot, NumViews, ppShaderResourceViews);
} }
@ -1645,9 +1641,7 @@ namespace dxvk {
D3D10DeviceLock lock = LockContext(); D3D10DeviceLock lock = LockContext();
SetShaderResources<DxbcProgramType::DomainShader>( SetShaderResources<DxbcProgramType::DomainShader>(
m_state.ds.shaderResources, StartSlot, NumViews, ppShaderResourceViews);
StartSlot, NumViews,
ppShaderResourceViews);
} }
@ -1715,7 +1709,7 @@ namespace dxvk {
ID3D11ShaderResourceView** ppShaderResourceViews) { ID3D11ShaderResourceView** ppShaderResourceViews) {
D3D10DeviceLock lock = LockContext(); D3D10DeviceLock lock = LockContext();
GetShaderResources(m_state.ds.shaderResources, GetShaderResources<DxbcProgramType::DomainShader>(
StartSlot, NumViews, ppShaderResourceViews); StartSlot, NumViews, ppShaderResourceViews);
} }
@ -1787,9 +1781,7 @@ namespace dxvk {
D3D10DeviceLock lock = LockContext(); D3D10DeviceLock lock = LockContext();
SetShaderResources<DxbcProgramType::GeometryShader>( SetShaderResources<DxbcProgramType::GeometryShader>(
m_state.gs.shaderResources, StartSlot, NumViews, ppShaderResourceViews);
StartSlot, NumViews,
ppShaderResourceViews);
} }
@ -1857,7 +1849,7 @@ namespace dxvk {
ID3D11ShaderResourceView** ppShaderResourceViews) { ID3D11ShaderResourceView** ppShaderResourceViews) {
D3D10DeviceLock lock = LockContext(); D3D10DeviceLock lock = LockContext();
GetShaderResources(m_state.gs.shaderResources, GetShaderResources<DxbcProgramType::GeometryShader>(
StartSlot, NumViews, ppShaderResourceViews); StartSlot, NumViews, ppShaderResourceViews);
} }
@ -1929,9 +1921,7 @@ namespace dxvk {
D3D10DeviceLock lock = LockContext(); D3D10DeviceLock lock = LockContext();
SetShaderResources<DxbcProgramType::PixelShader>( SetShaderResources<DxbcProgramType::PixelShader>(
m_state.ps.shaderResources, StartSlot, NumViews, ppShaderResourceViews);
StartSlot, NumViews,
ppShaderResourceViews);
} }
@ -1999,7 +1989,7 @@ namespace dxvk {
ID3D11ShaderResourceView** ppShaderResourceViews) { ID3D11ShaderResourceView** ppShaderResourceViews) {
D3D10DeviceLock lock = LockContext(); D3D10DeviceLock lock = LockContext();
GetShaderResources(m_state.ps.shaderResources, GetShaderResources<DxbcProgramType::PixelShader>(
StartSlot, NumViews, ppShaderResourceViews); StartSlot, NumViews, ppShaderResourceViews);
} }
@ -2071,9 +2061,7 @@ namespace dxvk {
D3D10DeviceLock lock = LockContext(); D3D10DeviceLock lock = LockContext();
SetShaderResources<DxbcProgramType::ComputeShader>( SetShaderResources<DxbcProgramType::ComputeShader>(
m_state.cs.shaderResources, StartSlot, NumViews, ppShaderResourceViews);
StartSlot, NumViews,
ppShaderResourceViews);
} }
@ -2198,7 +2186,7 @@ namespace dxvk {
ID3D11ShaderResourceView** ppShaderResourceViews) { ID3D11ShaderResourceView** ppShaderResourceViews) {
D3D10DeviceLock lock = LockContext(); D3D10DeviceLock lock = LockContext();
GetShaderResources(m_state.cs.shaderResources, GetShaderResources<DxbcProgramType::ComputeShader>(
StartSlot, NumViews, ppShaderResourceViews); StartSlot, NumViews, ppShaderResourceViews);
} }
@ -3769,14 +3757,16 @@ namespace dxvk {
template<typename ContextType> template<typename ContextType>
template<DxbcProgramType ShaderStage>
void D3D11CommonContext<ContextType>::GetShaderResources( void D3D11CommonContext<ContextType>::GetShaderResources(
const D3D11ShaderResourceBindings& Bindings,
UINT StartSlot, UINT StartSlot,
UINT NumViews, UINT NumViews,
ID3D11ShaderResourceView** ppShaderResourceViews) { ID3D11ShaderResourceView** ppShaderResourceViews) {
const auto& bindings = m_state.srv[ShaderStage];
for (uint32_t i = 0; i < NumViews; i++) { for (uint32_t i = 0; i < NumViews; i++) {
ppShaderResourceViews[i] = StartSlot + i < Bindings.views.size() ppShaderResourceViews[i] = StartSlot + i < bindings.views.size()
? Bindings.views[StartSlot + i].ref() ? bindings.views[StartSlot + i].ref()
: nullptr; : nullptr;
} }
} }
@ -3914,6 +3904,7 @@ namespace dxvk {
// Reset resource bindings // Reset resource bindings
m_state.cbv.reset(); m_state.cbv.reset();
m_state.srv.reset();
// Default samplers // Default samplers
for (uint32_t i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) { for (uint32_t i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) {
@ -3925,23 +3916,6 @@ namespace dxvk {
m_state.cs.samplers[i] = nullptr; m_state.cs.samplers[i] = nullptr;
} }
// Default shader resources
for (uint32_t i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) {
m_state.vs.shaderResources.views[i] = nullptr;
m_state.hs.shaderResources.views[i] = nullptr;
m_state.ds.shaderResources.views[i] = nullptr;
m_state.gs.shaderResources.views[i] = nullptr;
m_state.ps.shaderResources.views[i] = nullptr;
m_state.cs.shaderResources.views[i] = nullptr;
}
m_state.vs.shaderResources.hazardous.clear();
m_state.hs.shaderResources.hazardous.clear();
m_state.ds.shaderResources.hazardous.clear();
m_state.gs.shaderResources.hazardous.clear();
m_state.ps.shaderResources.hazardous.clear();
m_state.cs.shaderResources.hazardous.clear();
// Default UAVs // Default UAVs
for (uint32_t i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) { for (uint32_t i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) {
m_state.ps.unorderedAccessViews[i] = nullptr; m_state.ps.unorderedAccessViews[i] = nullptr;
@ -4016,29 +3990,30 @@ namespace dxvk {
template<typename ContextType> template<typename ContextType>
template<DxbcProgramType ShaderStage, typename T> template<DxbcProgramType ShaderStage, typename T>
void D3D11CommonContext<ContextType>::ResolveSrvHazards( void D3D11CommonContext<ContextType>::ResolveSrvHazards(
T* pView, T* pView) {
D3D11ShaderResourceBindings& Bindings) { auto& bindings = m_state.srv[ShaderStage];
uint32_t slotId = computeSrvBinding(ShaderStage, 0); uint32_t slotId = computeSrvBinding(ShaderStage, 0);
int32_t srvId = Bindings.hazardous.findNext(0); int32_t srvId = bindings.hazardous.findNext(0);
while (srvId >= 0) { while (srvId >= 0) {
auto srv = Bindings.views[srvId].ptr(); auto srv = bindings.views[srvId].ptr();
if (likely(srv && srv->TestHazards())) { if (likely(srv && srv->TestHazards())) {
bool hazard = CheckViewOverlap(pView, srv); bool hazard = CheckViewOverlap(pView, srv);
if (unlikely(hazard)) { if (unlikely(hazard)) {
Bindings.views[srvId] = nullptr; bindings.views[srvId] = nullptr;
Bindings.hazardous.clr(srvId); bindings.hazardous.clr(srvId);
BindShaderResource<ShaderStage>(slotId + srvId, nullptr); BindShaderResource<ShaderStage>(slotId + srvId, nullptr);
} }
} else { } else {
// Avoid further redundant iterations // Avoid further redundant iterations
Bindings.hazardous.clr(srvId); bindings.hazardous.clr(srvId);
} }
srvId = Bindings.hazardous.findNext(srvId + 1); srvId = bindings.hazardous.findNext(srvId + 1);
} }
} }
@ -4048,7 +4023,7 @@ namespace dxvk {
void D3D11CommonContext<ContextType>::ResolveCsSrvHazards( void D3D11CommonContext<ContextType>::ResolveCsSrvHazards(
T* pView) { T* pView) {
if (!pView) return; if (!pView) return;
ResolveSrvHazards<DxbcProgramType::ComputeShader> (pView, m_state.cs.shaderResources); ResolveSrvHazards<DxbcProgramType::ComputeShader>(pView);
} }
@ -4057,11 +4032,11 @@ namespace dxvk {
void D3D11CommonContext<ContextType>::ResolveOmSrvHazards( void D3D11CommonContext<ContextType>::ResolveOmSrvHazards(
T* pView) { T* pView) {
if (!pView) return; if (!pView) return;
ResolveSrvHazards<DxbcProgramType::VertexShader> (pView, m_state.vs.shaderResources); ResolveSrvHazards<DxbcProgramType::VertexShader>(pView);
ResolveSrvHazards<DxbcProgramType::HullShader> (pView, m_state.hs.shaderResources); ResolveSrvHazards<DxbcProgramType::HullShader>(pView);
ResolveSrvHazards<DxbcProgramType::DomainShader> (pView, m_state.ds.shaderResources); ResolveSrvHazards<DxbcProgramType::DomainShader>(pView);
ResolveSrvHazards<DxbcProgramType::GeometryShader> (pView, m_state.gs.shaderResources); ResolveSrvHazards<DxbcProgramType::GeometryShader>(pView);
ResolveSrvHazards<DxbcProgramType::PixelShader> (pView, m_state.ps.shaderResources); ResolveSrvHazards<DxbcProgramType::PixelShader>(pView);
} }
@ -4164,12 +4139,12 @@ namespace dxvk {
RestoreSamplers<DxbcProgramType::PixelShader> (m_state.ps.samplers); RestoreSamplers<DxbcProgramType::PixelShader> (m_state.ps.samplers);
RestoreSamplers<DxbcProgramType::ComputeShader> (m_state.cs.samplers); RestoreSamplers<DxbcProgramType::ComputeShader> (m_state.cs.samplers);
RestoreShaderResources<DxbcProgramType::VertexShader> (m_state.vs.shaderResources); RestoreShaderResources<DxbcProgramType::VertexShader>();
RestoreShaderResources<DxbcProgramType::HullShader> (m_state.hs.shaderResources); RestoreShaderResources<DxbcProgramType::HullShader>();
RestoreShaderResources<DxbcProgramType::DomainShader> (m_state.ds.shaderResources); RestoreShaderResources<DxbcProgramType::DomainShader>();
RestoreShaderResources<DxbcProgramType::GeometryShader> (m_state.gs.shaderResources); RestoreShaderResources<DxbcProgramType::GeometryShader>();
RestoreShaderResources<DxbcProgramType::PixelShader> (m_state.ps.shaderResources); RestoreShaderResources<DxbcProgramType::PixelShader>();
RestoreShaderResources<DxbcProgramType::ComputeShader> (m_state.cs.shaderResources); RestoreShaderResources<DxbcProgramType::ComputeShader>();
RestoreUnorderedAccessViews<DxbcProgramType::PixelShader> (m_state.ps.unorderedAccessViews); RestoreUnorderedAccessViews<DxbcProgramType::PixelShader> (m_state.ps.unorderedAccessViews);
RestoreUnorderedAccessViews<DxbcProgramType::ComputeShader> (m_state.cs.unorderedAccessViews); RestoreUnorderedAccessViews<DxbcProgramType::ComputeShader> (m_state.cs.unorderedAccessViews);
@ -4202,12 +4177,12 @@ namespace dxvk {
template<typename ContextType> template<typename ContextType>
template<DxbcProgramType Stage> template<DxbcProgramType Stage>
void D3D11CommonContext<ContextType>::RestoreShaderResources( void D3D11CommonContext<ContextType>::RestoreShaderResources() {
D3D11ShaderResourceBindings& Bindings) { const auto& bindings = m_state.srv[Stage];
uint32_t slotId = computeSrvBinding(Stage, 0); uint32_t slotId = computeSrvBinding(Stage, 0);
for (uint32_t i = 0; i < Bindings.views.size(); i++) for (uint32_t i = 0; i < bindings.views.size(); i++)
BindShaderResource<Stage>(slotId + i, Bindings.views[i].ptr()); BindShaderResource<Stage>(slotId + i, bindings.views[i].ptr());
} }
@ -4332,16 +4307,16 @@ namespace dxvk {
template<typename ContextType> template<typename ContextType>
template<DxbcProgramType ShaderStage> template<DxbcProgramType ShaderStage>
void D3D11CommonContext<ContextType>::SetShaderResources( void D3D11CommonContext<ContextType>::SetShaderResources(
D3D11ShaderResourceBindings& Bindings,
UINT StartSlot, UINT StartSlot,
UINT NumResources, UINT NumResources,
ID3D11ShaderResourceView* const* ppResources) { ID3D11ShaderResourceView* const* ppResources) {
auto& bindings = m_state.srv[ShaderStage];
uint32_t slotId = computeSrvBinding(ShaderStage, StartSlot); uint32_t slotId = computeSrvBinding(ShaderStage, StartSlot);
for (uint32_t i = 0; i < NumResources; i++) { for (uint32_t i = 0; i < NumResources; i++) {
auto resView = static_cast<D3D11ShaderResourceView*>(ppResources[i]); auto resView = static_cast<D3D11ShaderResourceView*>(ppResources[i]);
if (Bindings.views[StartSlot + i] != resView) { if (bindings.views[StartSlot + i] != resView) {
if (unlikely(resView && resView->TestHazards())) { if (unlikely(resView && resView->TestHazards())) {
if (TestSrvHazards<ShaderStage>(resView)) if (TestSrvHazards<ShaderStage>(resView))
resView = nullptr; resView = nullptr;
@ -4349,10 +4324,10 @@ namespace dxvk {
// Only set if necessary, but don't reset it on every // Only set if necessary, but don't reset it on every
// bind as this would be more expensive than a few // bind as this would be more expensive than a few
// redundant checks in OMSetRenderTargets and friends. // redundant checks in OMSetRenderTargets and friends.
Bindings.hazardous.set(StartSlot + i, resView); bindings.hazardous.set(StartSlot + i, resView);
} }
Bindings.views[StartSlot + i] = resView; bindings.views[StartSlot + i] = resView;
BindShaderResource<ShaderStage>(slotId + i, resView); BindShaderResource<ShaderStage>(slotId + i, resView);
} }
} }

View File

@ -894,8 +894,8 @@ namespace dxvk {
UINT* pFirstConstant, UINT* pFirstConstant,
UINT* pNumConstants); UINT* pNumConstants);
template<DxbcProgramType ShaderStage>
void GetShaderResources( void GetShaderResources(
const D3D11ShaderResourceBindings& Bindings,
UINT StartSlot, UINT StartSlot,
UINT NumViews, UINT NumViews,
ID3D11ShaderResourceView** ppShaderResourceViews); ID3D11ShaderResourceView** ppShaderResourceViews);
@ -914,8 +914,7 @@ namespace dxvk {
template<DxbcProgramType ShaderStage, typename T> template<DxbcProgramType ShaderStage, typename T>
void ResolveSrvHazards( void ResolveSrvHazards(
T* pView, T* pView);
D3D11ShaderResourceBindings& Bindings);
template<typename T> template<typename T>
void ResolveCsSrvHazards( void ResolveCsSrvHazards(
@ -941,8 +940,7 @@ namespace dxvk {
D3D11SamplerBindings& Bindings); D3D11SamplerBindings& Bindings);
template<DxbcProgramType Stage> template<DxbcProgramType Stage>
void RestoreShaderResources( void RestoreShaderResources();
D3D11ShaderResourceBindings& Bindings);
template<DxbcProgramType Stage> template<DxbcProgramType Stage>
void RestoreUnorderedAccessViews( void RestoreUnorderedAccessViews(
@ -964,7 +962,6 @@ namespace dxvk {
template<DxbcProgramType ShaderStage> template<DxbcProgramType ShaderStage>
void SetShaderResources( void SetShaderResources(
D3D11ShaderResourceBindings& Bindings,
UINT StartSlot, UINT StartSlot,
UINT NumResources, UINT NumResources,
ID3D11ShaderResourceView* const* ppResources); ID3D11ShaderResourceView* const* ppResources);

View File

@ -68,15 +68,29 @@ namespace dxvk {
using D3D11CbvBindings = D3D11ShaderStageState<D3D11ShaderStageCbvBinding>; using D3D11CbvBindings = D3D11ShaderStageState<D3D11ShaderStageCbvBinding>;
using D3D11SamplerBindings = std::array< /**
D3D11SamplerState*, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT>; * \brief Shader resource bindings
*
* Stores bound shader resource views, as well as a bit
struct D3D11ShaderResourceBindings { * set of views that are potentially hazardous.
*/
struct D3D11ShaderStageSrvBinding {
std::array<Com<D3D11ShaderResourceView>, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> views = { }; std::array<Com<D3D11ShaderResourceView>, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> views = { };
DxvkBindingSet<D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> hazardous = { }; DxvkBindingSet<D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> hazardous = { };
void reset() {
for (uint32_t i = 0; i < views.size(); i++)
views[i] = nullptr;
hazardous.clear();
}
}; };
using D3D11SrvBindings = D3D11ShaderStageState<D3D11ShaderStageSrvBinding>;
using D3D11SamplerBindings = std::array<
D3D11SamplerState*, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT>;
using D3D11UnorderedAccessBindings = std::array< using D3D11UnorderedAccessBindings = std::array<
Com<D3D11UnorderedAccessView>, D3D11_1_UAV_SLOT_COUNT>; Com<D3D11UnorderedAccessView>, D3D11_1_UAV_SLOT_COUNT>;
@ -85,35 +99,30 @@ namespace dxvk {
struct D3D11ContextStateVS { struct D3D11ContextStateVS {
Com<D3D11VertexShader> shader = nullptr; Com<D3D11VertexShader> shader = nullptr;
D3D11SamplerBindings samplers = { }; D3D11SamplerBindings samplers = { };
D3D11ShaderResourceBindings shaderResources = { };
}; };
struct D3D11ContextStateHS { struct D3D11ContextStateHS {
Com<D3D11HullShader> shader = nullptr; Com<D3D11HullShader> shader = nullptr;
D3D11SamplerBindings samplers = { }; D3D11SamplerBindings samplers = { };
D3D11ShaderResourceBindings shaderResources = { };
}; };
struct D3D11ContextStateDS { struct D3D11ContextStateDS {
Com<D3D11DomainShader> shader = nullptr; Com<D3D11DomainShader> shader = nullptr;
D3D11SamplerBindings samplers = { }; D3D11SamplerBindings samplers = { };
D3D11ShaderResourceBindings shaderResources = { };
}; };
struct D3D11ContextStateGS { struct D3D11ContextStateGS {
Com<D3D11GeometryShader> shader = nullptr; Com<D3D11GeometryShader> shader = nullptr;
D3D11SamplerBindings samplers = { }; D3D11SamplerBindings samplers = { };
D3D11ShaderResourceBindings shaderResources = { };
}; };
struct D3D11ContextStatePS { struct D3D11ContextStatePS {
Com<D3D11PixelShader> shader = nullptr; Com<D3D11PixelShader> shader = nullptr;
D3D11SamplerBindings samplers = { }; D3D11SamplerBindings samplers = { };
D3D11ShaderResourceBindings shaderResources = { };
D3D11UnorderedAccessBindings unorderedAccessViews = { }; D3D11UnorderedAccessBindings unorderedAccessViews = { };
}; };
@ -121,7 +130,6 @@ namespace dxvk {
struct D3D11ContextStateCS { struct D3D11ContextStateCS {
Com<D3D11ComputeShader> shader = nullptr; Com<D3D11ComputeShader> shader = nullptr;
D3D11SamplerBindings samplers = { }; D3D11SamplerBindings samplers = { };
D3D11ShaderResourceBindings shaderResources = { };
D3D11UnorderedAccessBindings unorderedAccessViews = { }; D3D11UnorderedAccessBindings unorderedAccessViews = { };
DxvkBindingSet<D3D11_1_UAV_SLOT_COUNT> uavMask = { }; DxvkBindingSet<D3D11_1_UAV_SLOT_COUNT> uavMask = { };
@ -222,6 +230,7 @@ namespace dxvk {
D3D11ContextStatePR pr; D3D11ContextStatePR pr;
D3D11CbvBindings cbv; D3D11CbvBindings cbv;
D3D11SrvBindings srv;
}; };
} }