[d3d9] Track if any color writes are enabled for an RT

Use this for determining whether to rebind FB and in checks, otherwise we can miss stuff for pure surface RTs
This commit is contained in:
Joshua Ashton 2023-05-24 14:05:13 +01:00
parent 075c0bf203
commit 269bab2c34
2 changed files with 33 additions and 19 deletions

View File

@ -1972,31 +1972,23 @@ namespace dxvk {
break;
case D3DRS_COLORWRITEENABLE:
if (likely(!old != !Value)) {
m_flags.set(D3D9DeviceFlag::DirtyFramebuffer);
UpdateActiveRTs(0);
}
if (likely(!old != !Value))
UpdateAnyColorWrites(0, !!Value);
m_flags.set(D3D9DeviceFlag::DirtyBlendState);
break;
case D3DRS_COLORWRITEENABLE1:
if (likely(!old != !Value && (m_boundRTs & (1 << 1)))) {
m_flags.set(D3D9DeviceFlag::DirtyFramebuffer);
UpdateActiveRTs(1);
}
if (likely(!old != !Value))
UpdateAnyColorWrites(1, !!Value);
m_flags.set(D3D9DeviceFlag::DirtyBlendState);
break;
case D3DRS_COLORWRITEENABLE2:
if (likely(!old != !Value && (m_boundRTs & (1 << 2)))) {
m_flags.set(D3D9DeviceFlag::DirtyFramebuffer);
UpdateActiveRTs(2);
}
if (likely(!old != !Value))
UpdateAnyColorWrites(2, !!Value);
m_flags.set(D3D9DeviceFlag::DirtyBlendState);
break;
case D3DRS_COLORWRITEENABLE3:
if (likely(!old != !Value && (m_boundRTs & (1 << 3)))) {
m_flags.set(D3D9DeviceFlag::DirtyFramebuffer);
UpdateActiveRTs(3);
}
if (likely(!old != !Value))
UpdateAnyColorWrites(3, !!Value);
m_flags.set(D3D9DeviceFlag::DirtyBlendState);
break;
@ -3297,7 +3289,7 @@ namespace dxvk {
// If we have any RTs we would have bound to the the FB
// not in the new shader mask, mark the framebuffer as dirty
// so we unbind them.
if (m_activeRTs & m_psShaderMasks.rtMask & (~newShaderMasks.rtMask))
if (m_boundRTs & m_anyColorWrites & m_psShaderMasks.rtMask & (~newShaderMasks.rtMask))
m_flags.set(D3D9DeviceFlag::DirtyFramebuffer);
if (m_psShaderMasks.samplerMask != newShaderMasks.samplerMask ||
@ -5355,13 +5347,28 @@ namespace dxvk {
if ((m_boundRTs & bit) != 0 &&
m_state.renderTargets[index]->GetBaseTexture() != nullptr &&
m_state.renderStates[ColorWriteIndex(index)])
m_anyColorWrites & bit)
m_activeRTs |= bit;
UpdateActiveHazardsRT(bit);
}
inline void D3D9DeviceEx::UpdateAnyColorWrites(uint32_t index, bool has) {
const uint32_t bit = 1 << index;
m_anyColorWrites &= ~bit;
if (has)
m_anyColorWrites |= bit;
if (m_boundRTs & bit) {
m_flags.set(D3D9DeviceFlag::DirtyFramebuffer);
UpdateActiveRTs(index);
}
}
inline void D3D9DeviceEx::UpdateActiveTextures(uint32_t index, DWORD combinedUsage) {
const uint32_t bit = 1 << index;
@ -5675,7 +5682,7 @@ namespace dxvk {
else if (unlikely(sampleCount != rtImageInfo.sampleCount))
continue;
if (!m_state.renderStates[ColorWriteIndex(i)])
if (!(m_anyColorWrites & (1 << i)))
continue;
if (!(m_psShaderMasks.rtMask & (1 << i)))
@ -7369,6 +7376,9 @@ namespace dxvk {
UpdateVertexBoolSpec(0u);
UpdatePixelBoolSpec(0u);
UpdateCommonSamplerSpec(0u, 0u, 0u);
for (uint32_t i = 0; i < caps::MaxSimultaneousRenderTargets; i++)
UpdateAnyColorWrites(i, true);
}

View File

@ -29,6 +29,7 @@
#include "d3d9_spec_constants.h"
#include "d3d9_interop.h"
#include <cstdint>
#include <unordered_set>
#include <vector>
#include <type_traits>
@ -773,6 +774,8 @@ namespace dxvk {
void UpdateActiveRTs(uint32_t index);
void UpdateAnyColorWrites(uint32_t index, bool has);
void UpdateActiveTextures(uint32_t index, DWORD combinedUsage);
void UpdateActiveHazardsRT(uint32_t rtMask);
@ -1289,6 +1292,7 @@ namespace dxvk {
uint32_t m_dirtyTextures = 0;
uint32_t m_boundRTs = 0;
uint32_t m_anyColorWrites = 0;
uint32_t m_activeRTs = 0;
uint32_t m_activeRTTextures = 0;