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

[d3d11] Refactor unordered access view and output merger state

This commit is contained in:
Philip Rebohle 2022-08-04 16:23:47 +02:00
parent 8383423fbe
commit 4e1f6e5efd
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 112 additions and 91 deletions

View File

@ -2082,16 +2082,16 @@ namespace dxvk {
uint32_t uavSlotId = computeUavBinding (DxbcProgramType::ComputeShader, 0); uint32_t uavSlotId = computeUavBinding (DxbcProgramType::ComputeShader, 0);
uint32_t ctrSlotId = computeUavCounterBinding(DxbcProgramType::ComputeShader, 0); uint32_t ctrSlotId = computeUavCounterBinding(DxbcProgramType::ComputeShader, 0);
int32_t uavId = m_state.cs.uavMask.findNext(0); int32_t uavId = m_state.uav.mask.findNext(0);
while (uavId >= 0) { while (uavId >= 0) {
if (uint32_t(uavId) < StartSlot || uint32_t(uavId) >= StartSlot + NumUAVs) { if (uint32_t(uavId) < StartSlot || uint32_t(uavId) >= StartSlot + NumUAVs) {
for (uint32_t i = 0; i < NumUAVs; i++) { for (uint32_t i = 0; i < NumUAVs; i++) {
auto uav = static_cast<D3D11UnorderedAccessView*>(ppUnorderedAccessViews[i]); auto uav = static_cast<D3D11UnorderedAccessView*>(ppUnorderedAccessViews[i]);
if (CheckViewOverlap(uav, m_state.cs.unorderedAccessViews[uavId].ptr())) { if (CheckViewOverlap(uav, m_state.uav.views[uavId].ptr())) {
m_state.cs.unorderedAccessViews[uavId] = nullptr; m_state.uav.views[uavId] = nullptr;
m_state.cs.uavMask.clr(uavId); m_state.uav.mask.clr(uavId);
BindUnorderedAccessView<DxbcProgramType::ComputeShader>( BindUnorderedAccessView<DxbcProgramType::ComputeShader>(
uavSlotId + uavId, nullptr, uavSlotId + uavId, nullptr,
@ -2099,9 +2099,9 @@ namespace dxvk {
} }
} }
uavId = m_state.cs.uavMask.findNext(uavId + 1); uavId = m_state.uav.mask.findNext(uavId + 1);
} else { } else {
uavId = m_state.cs.uavMask.findNext(StartSlot + NumUAVs); uavId = m_state.uav.mask.findNext(StartSlot + NumUAVs);
} }
} }
@ -2110,9 +2110,9 @@ namespace dxvk {
auto uav = static_cast<D3D11UnorderedAccessView*>(ppUnorderedAccessViews[i]); auto uav = static_cast<D3D11UnorderedAccessView*>(ppUnorderedAccessViews[i]);
auto ctr = pUAVInitialCounts ? pUAVInitialCounts[i] : ~0u; auto ctr = pUAVInitialCounts ? pUAVInitialCounts[i] : ~0u;
if (m_state.cs.unorderedAccessViews[StartSlot + i] != uav || ctr != ~0u) { if (m_state.uav.views[StartSlot + i] != uav || ctr != ~0u) {
m_state.cs.unorderedAccessViews[StartSlot + i] = uav; m_state.uav.views[StartSlot + i] = uav;
m_state.cs.uavMask.set(StartSlot + i, uav != nullptr); m_state.uav.mask.set(StartSlot + i, uav != nullptr);
BindUnorderedAccessView<DxbcProgramType::ComputeShader>( BindUnorderedAccessView<DxbcProgramType::ComputeShader>(
uavSlotId + StartSlot + i, uav, uavSlotId + StartSlot + i, uav,
@ -2199,8 +2199,8 @@ namespace dxvk {
D3D10DeviceLock lock = LockContext(); D3D10DeviceLock lock = LockContext();
for (uint32_t i = 0; i < NumUAVs; i++) { for (uint32_t i = 0; i < NumUAVs; i++) {
ppUnorderedAccessViews[i] = StartSlot + i < m_state.cs.unorderedAccessViews.size() ppUnorderedAccessViews[i] = StartSlot + i < m_state.uav.views.size()
? m_state.cs.unorderedAccessViews[StartSlot + i].ref() ? m_state.uav.views[StartSlot + i].ref()
: nullptr; : nullptr;
} }
} }
@ -2311,19 +2311,19 @@ namespace dxvk {
if (ppRenderTargetViews) { if (ppRenderTargetViews) {
for (UINT i = 0; i < NumRTVs; i++) { for (UINT i = 0; i < NumRTVs; i++) {
ppRenderTargetViews[i] = i < m_state.om.renderTargetViews.size() ppRenderTargetViews[i] = i < m_state.om.rtvs.size()
? m_state.om.renderTargetViews[i].ref() ? m_state.om.rtvs[i].ref()
: nullptr; : nullptr;
} }
} }
if (ppDepthStencilView) if (ppDepthStencilView)
*ppDepthStencilView = m_state.om.depthStencilView.ref(); *ppDepthStencilView = m_state.om.dsv.ref();
if (ppUnorderedAccessViews) { if (ppUnorderedAccessViews) {
for (UINT i = 0; i < NumUAVs; i++) { for (UINT i = 0; i < NumUAVs; i++) {
ppUnorderedAccessViews[i] = UAVStartSlot + i < m_state.ps.unorderedAccessViews.size() ppUnorderedAccessViews[i] = UAVStartSlot + i < m_state.om.uavs.size()
? m_state.ps.unorderedAccessViews[UAVStartSlot + i].ref() ? m_state.om.uavs[UAVStartSlot + i].ref()
: nullptr; : nullptr;
} }
} }
@ -3133,20 +3133,20 @@ namespace dxvk {
// D3D11 doesn't have the concept of a framebuffer object, // D3D11 doesn't have the concept of a framebuffer object,
// so we'll just create a new one every time the render // so we'll just create a new one every time the render
// target bindings are updated. Set up the attachments. // target bindings are updated. Set up the attachments.
for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) { for (UINT i = 0; i < m_state.om.rtvs.size(); i++) {
if (m_state.om.renderTargetViews[i] != nullptr) { if (m_state.om.rtvs[i] != nullptr) {
attachments.color[i] = { attachments.color[i] = {
m_state.om.renderTargetViews[i]->GetImageView(), m_state.om.rtvs[i]->GetImageView(),
m_state.om.renderTargetViews[i]->GetRenderLayout() }; m_state.om.rtvs[i]->GetRenderLayout() };
sampleCount = m_state.om.renderTargetViews[i]->GetSampleCount(); sampleCount = m_state.om.rtvs[i]->GetSampleCount();
} }
} }
if (m_state.om.depthStencilView != nullptr) { if (m_state.om.dsv != nullptr) {
attachments.depth = { attachments.depth = {
m_state.om.depthStencilView->GetImageView(), m_state.om.dsv->GetImageView(),
m_state.om.depthStencilView->GetRenderLayout() }; m_state.om.dsv->GetRenderLayout() };
sampleCount = m_state.om.depthStencilView->GetSampleCount(); sampleCount = m_state.om.dsv->GetSampleCount();
} }
// Create and bind the framebuffer object to the context // Create and bind the framebuffer object to the context
@ -3895,15 +3895,9 @@ namespace dxvk {
// Reset resource bindings // Reset resource bindings
m_state.cbv.reset(); m_state.cbv.reset();
m_state.srv.reset(); m_state.srv.reset();
m_state.uav.reset();
m_state.samplers.reset(); m_state.samplers.reset();
m_state.om.reset();
// Default UAVs
for (uint32_t i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) {
m_state.ps.unorderedAccessViews[i] = nullptr;
m_state.cs.unorderedAccessViews[i] = nullptr;
}
m_state.cs.uavMask.clear();
// Default ID state // Default ID state
m_state.id.argBuffer = nullptr; m_state.id.argBuffer = nullptr;
@ -3922,24 +3916,6 @@ namespace dxvk {
m_state.ia.indexBuffer.offset = 0; m_state.ia.indexBuffer.offset = 0;
m_state.ia.indexBuffer.format = DXGI_FORMAT_UNKNOWN; m_state.ia.indexBuffer.format = DXGI_FORMAT_UNKNOWN;
// Default OM State
for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
m_state.om.renderTargetViews[i] = nullptr;
m_state.om.depthStencilView = nullptr;
m_state.om.cbState = nullptr;
m_state.om.dsState = nullptr;
for (uint32_t i = 0; i < 4; i++)
m_state.om.blendFactor[i] = 1.0f;
m_state.om.sampleCount = 0;
m_state.om.sampleMask = D3D11_DEFAULT_SAMPLE_MASK;
m_state.om.stencilRef = D3D11_DEFAULT_STENCIL_REFERENCE;
m_state.om.maxRtv = 0;
m_state.om.maxUav = 0;
// Default RS state // Default RS state
m_state.rs.state = nullptr; m_state.rs.state = nullptr;
m_state.rs.numViewports = 0; m_state.rs.numViewports = 0;
@ -4029,14 +4005,14 @@ namespace dxvk {
bool hazard = false; bool hazard = false;
if (CheckViewOverlap(pView, m_state.om.depthStencilView.ptr())) { if (CheckViewOverlap(pView, m_state.om.dsv.ptr())) {
m_state.om.depthStencilView = nullptr; m_state.om.dsv = nullptr;
hazard = true; hazard = true;
} }
for (uint32_t i = 0; i < m_state.om.maxRtv; i++) { for (uint32_t i = 0; i < m_state.om.maxRtv; i++) {
if (CheckViewOverlap(pView, m_state.om.renderTargetViews[i].ptr())) { if (CheckViewOverlap(pView, m_state.om.rtvs[i].ptr())) {
m_state.om.renderTargetViews[i] = nullptr; m_state.om.rtvs[i] = nullptr;
hazard = true; hazard = true;
} }
} }
@ -4055,8 +4031,8 @@ namespace dxvk {
uint32_t ctrSlotId = computeUavCounterBinding(DxbcProgramType::PixelShader, 0); uint32_t ctrSlotId = computeUavCounterBinding(DxbcProgramType::PixelShader, 0);
for (uint32_t i = 0; i < m_state.om.maxUav; i++) { for (uint32_t i = 0; i < m_state.om.maxUav; i++) {
if (CheckViewOverlap(pView, m_state.ps.unorderedAccessViews[i].ptr())) { if (CheckViewOverlap(pView, m_state.om.uavs[i].ptr())) {
m_state.ps.unorderedAccessViews[i] = nullptr; m_state.om.uavs[i] = nullptr;
BindUnorderedAccessView<DxbcProgramType::PixelShader>( BindUnorderedAccessView<DxbcProgramType::PixelShader>(
uavSlotId + i, nullptr, uavSlotId + i, nullptr,
@ -4120,8 +4096,8 @@ namespace dxvk {
RestoreShaderResources<DxbcProgramType::PixelShader>(); RestoreShaderResources<DxbcProgramType::PixelShader>();
RestoreShaderResources<DxbcProgramType::ComputeShader>(); RestoreShaderResources<DxbcProgramType::ComputeShader>();
RestoreUnorderedAccessViews<DxbcProgramType::PixelShader> (m_state.ps.unorderedAccessViews); RestoreUnorderedAccessViews<DxbcProgramType::PixelShader>();
RestoreUnorderedAccessViews<DxbcProgramType::ComputeShader> (m_state.cs.unorderedAccessViews); RestoreUnorderedAccessViews<DxbcProgramType::ComputeShader>();
RestoreSamplers<DxbcProgramType::VertexShader>(); RestoreSamplers<DxbcProgramType::VertexShader>();
RestoreSamplers<DxbcProgramType::HullShader>(); RestoreSamplers<DxbcProgramType::HullShader>();
@ -4169,15 +4145,17 @@ namespace dxvk {
template<typename ContextType> template<typename ContextType>
template<DxbcProgramType Stage> template<DxbcProgramType Stage>
void D3D11CommonContext<ContextType>::RestoreUnorderedAccessViews( void D3D11CommonContext<ContextType>::RestoreUnorderedAccessViews() {
D3D11UnorderedAccessBindings& Bindings) { const auto& views = Stage == DxbcProgramType::ComputeShader
? m_state.uav.views
: m_state.om.uavs;
uint32_t uavSlotId = computeUavBinding (Stage, 0); uint32_t uavSlotId = computeUavBinding (Stage, 0);
uint32_t ctrSlotId = computeUavCounterBinding(Stage, 0); uint32_t ctrSlotId = computeUavCounterBinding(Stage, 0);
for (uint32_t i = 0; i < Bindings.size(); i++) { for (uint32_t i = 0; i < views.size(); i++) {
BindUnorderedAccessView<Stage>( BindUnorderedAccessView<Stage>(
uavSlotId + i, uavSlotId + i, views[i].ptr(),
Bindings[i].ptr(),
ctrSlotId + i, ~0u); ctrSlotId + i, ~0u);
} }
} }
@ -4355,13 +4333,13 @@ namespace dxvk {
if (!ValidateRenderTargets(NumRTVs, ppRenderTargetViews, pDepthStencilView)) if (!ValidateRenderTargets(NumRTVs, ppRenderTargetViews, pDepthStencilView))
return; return;
for (uint32_t i = 0; i < m_state.om.renderTargetViews.size(); i++) { for (uint32_t i = 0; i < m_state.om.rtvs.size(); i++) {
auto rtv = i < NumRTVs auto rtv = i < NumRTVs
? static_cast<D3D11RenderTargetView*>(ppRenderTargetViews[i]) ? static_cast<D3D11RenderTargetView*>(ppRenderTargetViews[i])
: nullptr; : nullptr;
if (m_state.om.renderTargetViews[i] != rtv) { if (m_state.om.rtvs[i] != rtv) {
m_state.om.renderTargetViews[i] = rtv; m_state.om.rtvs[i] = rtv;
needsUpdate = true; needsUpdate = true;
ResolveOmSrvHazards(rtv); ResolveOmSrvHazards(rtv);
@ -4372,8 +4350,8 @@ namespace dxvk {
auto dsv = static_cast<D3D11DepthStencilView*>(pDepthStencilView); auto dsv = static_cast<D3D11DepthStencilView*>(pDepthStencilView);
if (m_state.om.depthStencilView != dsv) { if (m_state.om.dsv != dsv) {
m_state.om.depthStencilView = dsv; m_state.om.dsv = dsv;
needsUpdate = true; needsUpdate = true;
ResolveOmSrvHazards(dsv); ResolveOmSrvHazards(dsv);
} }
@ -4398,8 +4376,8 @@ namespace dxvk {
ctr = pUAVInitialCounts ? pUAVInitialCounts[i - UAVStartSlot] : ~0u; ctr = pUAVInitialCounts ? pUAVInitialCounts[i - UAVStartSlot] : ~0u;
} }
if (m_state.ps.unorderedAccessViews[i] != uav || ctr != ~0u) { if (m_state.om.uavs[i] != uav || ctr != ~0u) {
m_state.ps.unorderedAccessViews[i] = uav; m_state.om.uavs[i] = uav;
BindUnorderedAccessView<DxbcProgramType::PixelShader>( BindUnorderedAccessView<DxbcProgramType::PixelShader>(
uavSlotId + i, uav, uavSlotId + i, uav,
@ -4487,20 +4465,20 @@ namespace dxvk {
bool hazard = false; bool hazard = false;
if (ShaderStage == DxbcProgramType::ComputeShader) { if (ShaderStage == DxbcProgramType::ComputeShader) {
int32_t uav = m_state.cs.uavMask.findNext(0); int32_t uav = m_state.uav.mask.findNext(0);
while (uav >= 0 && !hazard) { while (uav >= 0 && !hazard) {
hazard = CheckViewOverlap(pView, m_state.cs.unorderedAccessViews[uav].ptr()); hazard = CheckViewOverlap(pView, m_state.uav.views[uav].ptr());
uav = m_state.cs.uavMask.findNext(uav + 1); uav = m_state.uav.mask.findNext(uav + 1);
} }
} else { } else {
hazard = CheckViewOverlap(pView, m_state.om.depthStencilView.ptr()); hazard = CheckViewOverlap(pView, m_state.om.dsv.ptr());
for (uint32_t i = 0; !hazard && i < m_state.om.maxRtv; i++) for (uint32_t i = 0; !hazard && i < m_state.om.maxRtv; i++)
hazard = CheckViewOverlap(pView, m_state.om.renderTargetViews[i].ptr()); hazard = CheckViewOverlap(pView, m_state.om.rtvs[i].ptr());
for (uint32_t i = 0; !hazard && i < m_state.om.maxUav; i++) for (uint32_t i = 0; !hazard && i < m_state.om.maxUav; i++)
hazard = CheckViewOverlap(pView, m_state.ps.unorderedAccessViews[i].ptr()); hazard = CheckViewOverlap(pView, m_state.om.uavs[i].ptr());
} }
return hazard; return hazard;

View File

@ -942,8 +942,7 @@ namespace dxvk {
void RestoreShaderResources(); void RestoreShaderResources();
template<DxbcProgramType Stage> template<DxbcProgramType Stage>
void RestoreUnorderedAccessViews( void RestoreUnorderedAccessViews();
D3D11UnorderedAccessBindings& Bindings);
template<DxbcProgramType ShaderStage> template<DxbcProgramType ShaderStage>
void SetConstantBuffers( void SetConstantBuffers(

View File

@ -104,8 +104,25 @@ namespace dxvk {
using D3D11SamplerBindings = D3D11ShaderStageState<D3D11ShaderStageSamplerBinding>; using D3D11SamplerBindings = D3D11ShaderStageState<D3D11ShaderStageSamplerBinding>;
using D3D11UnorderedAccessBindings = std::array< /**
Com<D3D11UnorderedAccessView>, D3D11_1_UAV_SLOT_COUNT>; * \brief UAV bindings
*
* Stores bound UAVs. For compute shader UAVs,
* we also store a bit mask of bound UAVs.
*/
using D3D11ShaderStageUavBinding = std::array<Com<D3D11UnorderedAccessView>, D3D11_1_UAV_SLOT_COUNT>;
struct D3D11UavBindings {
D3D11ShaderStageUavBinding views = { };
DxvkBindingSet<D3D11_1_UAV_SLOT_COUNT> mask = { };
void reset() {
for (uint32_t i = 0; i < views.size(); i++)
views[i] = nullptr;
mask.clear();
}
};
struct D3D11ContextStateVS { struct D3D11ContextStateVS {
@ -130,15 +147,11 @@ namespace dxvk {
struct D3D11ContextStatePS { struct D3D11ContextStatePS {
Com<D3D11PixelShader> shader = nullptr; Com<D3D11PixelShader> shader = nullptr;
D3D11UnorderedAccessBindings unorderedAccessViews = { };
}; };
struct D3D11ContextStateCS { struct D3D11ContextStateCS {
Com<D3D11ComputeShader> shader = nullptr; Com<D3D11ComputeShader> shader = nullptr;
D3D11UnorderedAccessBindings unorderedAccessViews = { };
DxvkBindingSet<D3D11_1_UAV_SLOT_COUNT> uavMask = { };
}; };
@ -170,10 +183,17 @@ namespace dxvk {
D3D11IndexBufferBinding indexBuffer = { }; D3D11IndexBufferBinding indexBuffer = { };
}; };
/**
* \brief Output merger state
*
* Stores RTV, DSV, and graphics UAV bindings, as well as related state.
*/
using D3D11RenderTargetViewBinding = std::array<Com<D3D11RenderTargetView, false>, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT>;
struct D3D11ContextStateOM { struct D3D11ContextStateOM {
std::array<Com<D3D11RenderTargetView, false>, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> renderTargetViews = { }; D3D11ShaderStageUavBinding uavs = { };
Com<D3D11DepthStencilView, false> depthStencilView = { }; D3D11RenderTargetViewBinding rtvs = { };
Com<D3D11DepthStencilView, false> dsv = { };
D3D11BlendState* cbState = nullptr; D3D11BlendState* cbState = nullptr;
D3D11DepthStencilState* dsState = nullptr; D3D11DepthStencilState* dsState = nullptr;
@ -181,11 +201,34 @@ namespace dxvk {
FLOAT blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; FLOAT blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
UINT sampleCount = 0u; UINT sampleCount = 0u;
UINT sampleMask = 0xFFFFFFFFu; UINT sampleMask = D3D11_DEFAULT_SAMPLE_MASK;
UINT stencilRef = 0u; UINT stencilRef = D3D11_DEFAULT_STENCIL_REFERENCE;
UINT maxRtv = 0u; UINT maxRtv = 0u;
UINT maxUav = 0u; UINT maxUav = 0u;
void reset() {
for (uint32_t i = 0; i < maxUav; i++)
uavs[i] = nullptr;
for (uint32_t i = 0; i < maxRtv; i++)
rtvs[i] = nullptr;
dsv = nullptr;
cbState = nullptr;
dsState = nullptr;
for (uint32_t i = 0; i < 4; i++)
blendFactor[i] = 1.0f;
sampleCount = 0u;
sampleMask = D3D11_DEFAULT_SAMPLE_MASK;
stencilRef = D3D11_DEFAULT_STENCIL_REFERENCE;
maxRtv = 0;
maxUav = 0;
}
}; };
@ -237,6 +280,7 @@ namespace dxvk {
D3D11CbvBindings cbv; D3D11CbvBindings cbv;
D3D11SrvBindings srv; D3D11SrvBindings srv;
D3D11UavBindings uav;
D3D11SamplerBindings samplers; D3D11SamplerBindings samplers;
}; };