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

View File

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

View File

@ -103,11 +103,28 @@ namespace dxvk {
};
using D3D11SamplerBindings = D3D11ShaderStageState<D3D11ShaderStageSamplerBinding>;
/**
* \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>;
using D3D11UnorderedAccessBindings = 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 {
Com<D3D11VertexShader> shader = nullptr;
};
@ -130,15 +147,11 @@ namespace dxvk {
struct D3D11ContextStatePS {
Com<D3D11PixelShader> shader = nullptr;
D3D11UnorderedAccessBindings unorderedAccessViews = { };
};
struct D3D11ContextStateCS {
Com<D3D11ComputeShader> shader = nullptr;
D3D11UnorderedAccessBindings unorderedAccessViews = { };
DxvkBindingSet<D3D11_1_UAV_SLOT_COUNT> uavMask = { };
};
@ -170,10 +183,17 @@ namespace dxvk {
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 {
std::array<Com<D3D11RenderTargetView, false>, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> renderTargetViews = { };
Com<D3D11DepthStencilView, false> depthStencilView = { };
D3D11ShaderStageUavBinding uavs = { };
D3D11RenderTargetViewBinding rtvs = { };
Com<D3D11DepthStencilView, false> dsv = { };
D3D11BlendState* cbState = nullptr;
D3D11DepthStencilState* dsState = nullptr;
@ -181,11 +201,34 @@ namespace dxvk {
FLOAT blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
UINT sampleCount = 0u;
UINT sampleMask = 0xFFFFFFFFu;
UINT stencilRef = 0u;
UINT sampleMask = D3D11_DEFAULT_SAMPLE_MASK;
UINT stencilRef = D3D11_DEFAULT_STENCIL_REFERENCE;
UINT maxRtv = 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;
D3D11SrvBindings srv;
D3D11UavBindings uav;
D3D11SamplerBindings samplers;
};