mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-27 13:54:16 +01:00
[d3d11] Lazy-bind shader resources
This commit is contained in:
parent
4fdbfffdcc
commit
f2ab76c8db
@ -3206,6 +3206,28 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename ContextType>
|
||||||
|
void D3D11CommonContext<ContextType>::ApplyDirtyShaderResources(
|
||||||
|
DxbcProgramType Stage,
|
||||||
|
const DxbcBindingMask& BoundMask,
|
||||||
|
DxbcBindingMask& DirtyMask) {
|
||||||
|
const auto& state = m_state.srv[Stage];
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < state.maxCount; i += 64u) {
|
||||||
|
uint32_t maskIndex = i / 64u;
|
||||||
|
uint64_t bindMask = BoundMask.srvMask[maskIndex] & DirtyMask.srvMask[maskIndex];
|
||||||
|
|
||||||
|
if (!bindMask)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DirtyMask.srvMask[maskIndex] -= bindMask;
|
||||||
|
|
||||||
|
for (uint32_t slot : bit::BitMask(bindMask))
|
||||||
|
BindShaderResource(Stage, slot + i, state.views[slot + i].ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename ContextType>
|
template<typename ContextType>
|
||||||
void D3D11CommonContext<ContextType>::ApplyDirtyGraphicsBindings() {
|
void D3D11CommonContext<ContextType>::ApplyDirtyGraphicsBindings() {
|
||||||
auto dirtyMask = m_state.lazy.shadersDirty & m_state.lazy.shadersUsed;
|
auto dirtyMask = m_state.lazy.shadersDirty & m_state.lazy.shadersUsed;
|
||||||
@ -3218,6 +3240,7 @@ namespace dxvk {
|
|||||||
auto& dirtyMask = m_state.lazy.bindingsDirty[stage];
|
auto& dirtyMask = m_state.lazy.bindingsDirty[stage];
|
||||||
|
|
||||||
ApplyDirtyConstantBuffers(stage, boundMask, dirtyMask);
|
ApplyDirtyConstantBuffers(stage, boundMask, dirtyMask);
|
||||||
|
ApplyDirtyShaderResources(stage, boundMask, dirtyMask);
|
||||||
|
|
||||||
m_state.lazy.shadersDirty.clr(stage);
|
m_state.lazy.shadersDirty.clr(stage);
|
||||||
}
|
}
|
||||||
@ -3232,6 +3255,7 @@ namespace dxvk {
|
|||||||
auto& dirtyMask = m_state.lazy.bindingsDirty[stage];
|
auto& dirtyMask = m_state.lazy.bindingsDirty[stage];
|
||||||
|
|
||||||
ApplyDirtyConstantBuffers(stage, boundMask, dirtyMask);
|
ApplyDirtyConstantBuffers(stage, boundMask, dirtyMask);
|
||||||
|
ApplyDirtyShaderResources(stage, boundMask, dirtyMask);
|
||||||
|
|
||||||
m_state.lazy.shadersDirty.clr(stage);
|
m_state.lazy.shadersDirty.clr(stage);
|
||||||
}
|
}
|
||||||
@ -3839,36 +3863,38 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
template<typename ContextType>
|
template<typename ContextType>
|
||||||
template<DxbcProgramType ShaderStage>
|
|
||||||
void D3D11CommonContext<ContextType>::BindShaderResource(
|
void D3D11CommonContext<ContextType>::BindShaderResource(
|
||||||
|
DxbcProgramType ShaderStage,
|
||||||
UINT Slot,
|
UINT Slot,
|
||||||
D3D11ShaderResourceView* pResource) {
|
D3D11ShaderResourceView* pResource) {
|
||||||
|
uint32_t slotId = computeSrvBinding(ShaderStage, Slot);
|
||||||
|
|
||||||
if (pResource) {
|
if (pResource) {
|
||||||
if (pResource->GetViewInfo().Dimension != D3D11_RESOURCE_DIMENSION_BUFFER) {
|
if (pResource->GetViewInfo().Dimension != D3D11_RESOURCE_DIMENSION_BUFFER) {
|
||||||
EmitCs([
|
EmitCs([
|
||||||
cSlotId = Slot,
|
cSlotId = slotId,
|
||||||
|
cStage = GetShaderStage(ShaderStage),
|
||||||
cView = pResource->GetImageView()
|
cView = pResource->GetImageView()
|
||||||
] (DxvkContext* ctx) mutable {
|
] (DxvkContext* ctx) mutable {
|
||||||
VkShaderStageFlagBits stage = GetShaderStage(ShaderStage);
|
ctx->bindResourceImageView(cStage, cSlotId,
|
||||||
ctx->bindResourceImageView(stage, cSlotId,
|
|
||||||
Forwarder::move(cView));
|
Forwarder::move(cView));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
EmitCs([
|
EmitCs([
|
||||||
cSlotId = Slot,
|
cSlotId = slotId,
|
||||||
|
cStage = GetShaderStage(ShaderStage),
|
||||||
cView = pResource->GetBufferView()
|
cView = pResource->GetBufferView()
|
||||||
] (DxvkContext* ctx) mutable {
|
] (DxvkContext* ctx) mutable {
|
||||||
VkShaderStageFlagBits stage = GetShaderStage(ShaderStage);
|
ctx->bindResourceBufferView(cStage, cSlotId,
|
||||||
ctx->bindResourceBufferView(stage, cSlotId,
|
|
||||||
Forwarder::move(cView));
|
Forwarder::move(cView));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
EmitCs([
|
EmitCs([
|
||||||
cSlotId = Slot
|
cSlotId = slotId,
|
||||||
|
cStage = GetShaderStage(ShaderStage)
|
||||||
] (DxvkContext* ctx) {
|
] (DxvkContext* ctx) {
|
||||||
VkShaderStageFlagBits stage = GetShaderStage(ShaderStage);
|
ctx->bindResourceImageView(cStage, cSlotId, nullptr);
|
||||||
ctx->bindResourceImageView(stage, cSlotId, nullptr);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4362,6 +4388,20 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename ContextType>
|
||||||
|
bool D3D11CommonContext<ContextType>::DirtyShaderResource(
|
||||||
|
DxbcProgramType ShaderStage,
|
||||||
|
uint32_t Slot,
|
||||||
|
bool IsNull) {
|
||||||
|
uint32_t idx = Slot / 64u;
|
||||||
|
|
||||||
|
return DirtyBindingGeneric(ShaderStage,
|
||||||
|
m_state.lazy.bindingsUsed[ShaderStage].srvMask[idx],
|
||||||
|
m_state.lazy.bindingsDirty[ShaderStage].srvMask[idx],
|
||||||
|
uint64_t(1u) << Slot, IsNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename ContextType>
|
template<typename ContextType>
|
||||||
void D3D11CommonContext<ContextType>::DiscardBuffer(
|
void D3D11CommonContext<ContextType>::DiscardBuffer(
|
||||||
ID3D11Resource* pResource) {
|
ID3D11Resource* pResource) {
|
||||||
@ -4694,8 +4734,6 @@ namespace dxvk {
|
|||||||
void D3D11CommonContext<ContextType>::ResolveSrvHazards(
|
void D3D11CommonContext<ContextType>::ResolveSrvHazards(
|
||||||
T* pView) {
|
T* pView) {
|
||||||
auto& bindings = m_state.srv[ShaderStage];
|
auto& bindings = m_state.srv[ShaderStage];
|
||||||
|
|
||||||
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) {
|
||||||
@ -4708,7 +4746,8 @@ namespace dxvk {
|
|||||||
bindings.views[srvId] = nullptr;
|
bindings.views[srvId] = nullptr;
|
||||||
bindings.hazardous.clr(srvId);
|
bindings.hazardous.clr(srvId);
|
||||||
|
|
||||||
BindShaderResource<ShaderStage>(slotId + srvId, nullptr);
|
if (!DirtyShaderResource(ShaderStage, srvId, true))
|
||||||
|
BindShaderResource(ShaderStage, srvId, nullptr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Avoid further redundant iterations
|
// Avoid further redundant iterations
|
||||||
@ -4880,10 +4919,8 @@ namespace dxvk {
|
|||||||
template<DxbcProgramType Stage>
|
template<DxbcProgramType Stage>
|
||||||
void D3D11CommonContext<ContextType>::RestoreShaderResources() {
|
void D3D11CommonContext<ContextType>::RestoreShaderResources() {
|
||||||
const auto& bindings = m_state.srv[Stage];
|
const auto& bindings = m_state.srv[Stage];
|
||||||
uint32_t slotId = computeSrvBinding(Stage, 0);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < bindings.maxCount; i++)
|
for (uint32_t i = 0; i < bindings.maxCount; i++)
|
||||||
BindShaderResource<Stage>(slotId + i, bindings.views[i].ptr());
|
BindShaderResource(Stage, i, bindings.views[i].ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5015,7 +5052,6 @@ namespace dxvk {
|
|||||||
UINT NumResources,
|
UINT NumResources,
|
||||||
ID3D11ShaderResourceView* const* ppResources) {
|
ID3D11ShaderResourceView* const* ppResources) {
|
||||||
auto& bindings = m_state.srv[ShaderStage];
|
auto& bindings = m_state.srv[ShaderStage];
|
||||||
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]);
|
||||||
@ -5034,7 +5070,9 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bindings.views[StartSlot + i] = resView;
|
bindings.views[StartSlot + i] = resView;
|
||||||
BindShaderResource<ShaderStage>(slotId + i, resView);
|
|
||||||
|
if (!DirtyShaderResource(ShaderStage, StartSlot + i, !resView))
|
||||||
|
BindShaderResource(ShaderStage, StartSlot + i, resView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -804,6 +804,11 @@ namespace dxvk {
|
|||||||
const DxbcBindingMask& BoundMask,
|
const DxbcBindingMask& BoundMask,
|
||||||
DxbcBindingMask& DirtyMask);
|
DxbcBindingMask& DirtyMask);
|
||||||
|
|
||||||
|
void ApplyDirtyShaderResources(
|
||||||
|
DxbcProgramType Stage,
|
||||||
|
const DxbcBindingMask& BoundMask,
|
||||||
|
DxbcBindingMask& DirtyMask);
|
||||||
|
|
||||||
void ApplyDirtyGraphicsBindings();
|
void ApplyDirtyGraphicsBindings();
|
||||||
|
|
||||||
void ApplyDirtyComputeBindings();
|
void ApplyDirtyComputeBindings();
|
||||||
@ -881,8 +886,8 @@ namespace dxvk {
|
|||||||
UINT Slot,
|
UINT Slot,
|
||||||
D3D11SamplerState* pSampler);
|
D3D11SamplerState* pSampler);
|
||||||
|
|
||||||
template<DxbcProgramType ShaderStage>
|
|
||||||
void BindShaderResource(
|
void BindShaderResource(
|
||||||
|
DxbcProgramType ShaderStage,
|
||||||
UINT Slot,
|
UINT Slot,
|
||||||
D3D11ShaderResourceView* pResource);
|
D3D11ShaderResourceView* pResource);
|
||||||
|
|
||||||
@ -933,6 +938,11 @@ namespace dxvk {
|
|||||||
uint32_t Slot,
|
uint32_t Slot,
|
||||||
bool IsNull);
|
bool IsNull);
|
||||||
|
|
||||||
|
bool DirtyShaderResource(
|
||||||
|
DxbcProgramType ShaderStage,
|
||||||
|
uint32_t Slot,
|
||||||
|
bool IsNull);
|
||||||
|
|
||||||
void DiscardBuffer(
|
void DiscardBuffer(
|
||||||
ID3D11Resource* pResource);
|
ID3D11Resource* pResource);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user