[d3d9] Ignore the vertex stream offset in StateBlock::Capture

Fixes a Wine test and matches further testing on Windows.
This commit is contained in:
Robin Kertels 2024-03-13 01:25:16 +01:00
parent 0e466b0413
commit 99039459f8
No known key found for this signature in database
GPG Key ID: 3824904F14D40757
2 changed files with 44 additions and 13 deletions

View File

@ -49,7 +49,7 @@ namespace dxvk {
if (m_captures.flags.test(D3D9CapturedStateFlag::VertexDecl))
SetVertexDeclaration(m_deviceState->vertexDecl.ptr());
ApplyOrCapture<D3D9StateFunction::Capture>();
ApplyOrCapture<D3D9StateFunction::Capture, true>();
return D3D_OK;
}
@ -61,7 +61,7 @@ namespace dxvk {
if (m_captures.flags.test(D3D9CapturedStateFlag::VertexDecl) && m_state.vertexDecl != nullptr)
m_parent->SetVertexDeclaration(m_state.vertexDecl.ptr());
ApplyOrCapture<D3D9StateFunction::Apply>();
ApplyOrCapture<D3D9StateFunction::Apply, false>();
m_applying = false;
return D3D_OK;
@ -122,6 +122,20 @@ namespace dxvk {
}
HRESULT D3D9StateBlock::SetStreamSourceWithoutOffset(
UINT StreamNumber,
D3D9VertexBuffer* pStreamData,
UINT Stride) {
m_state.vertexBuffers[StreamNumber].vertexBuffer = pStreamData;
m_state.vertexBuffers[StreamNumber].stride = Stride;
m_captures.flags.set(D3D9CapturedStateFlag::VertexBuffers);
m_captures.vertexBuffers.set(StreamNumber, true);
return D3D_OK;
}
HRESULT D3D9StateBlock::SetStreamSourceFreq(UINT StreamNumber, UINT Setting) {
m_state.streamFreq[StreamNumber] = Setting;
@ -572,8 +586,12 @@ namespace dxvk {
m_captures.flags.set(D3D9CapturedStateFlag::Material);
}
if (Type != D3D9StateBlockType::None)
this->Capture();
if (Type != D3D9StateBlockType::None) {
if (m_captures.flags.test(D3D9CapturedStateFlag::VertexDecl))
SetVertexDeclaration(m_deviceState->vertexDecl.ptr());
ApplyOrCapture<D3D9StateFunction::Capture, false>();
}
}
}

View File

@ -115,6 +115,11 @@ namespace dxvk {
UINT OffsetInBytes,
UINT Stride);
HRESULT SetStreamSourceWithoutOffset(
UINT StreamNumber,
D3D9VertexBuffer* pStreamData,
UINT Stride);
HRESULT SetStreamSourceFreq(UINT StreamNumber, UINT Setting);
HRESULT SetStateTexture(DWORD StateSampler, IDirect3DBaseTexture9* pTexture);
@ -181,7 +186,7 @@ namespace dxvk {
Capture
};
template <typename Dst, typename Src>
template <typename Dst, typename Src, bool IgnoreStreamOffset>
void ApplyOrCapture(Dst* dst, const Src* src) {
if (m_captures.flags.test(D3D9CapturedStateFlag::StreamFreq)) {
for (uint32_t idx : bit::BitMask(m_captures.streamFreq.dword(0)))
@ -211,11 +216,19 @@ namespace dxvk {
if (m_captures.flags.test(D3D9CapturedStateFlag::VertexBuffers)) {
for (uint32_t idx : bit::BitMask(m_captures.vertexBuffers.dword(0))) {
const auto& vbo = src->vertexBuffers[idx];
dst->SetStreamSource(
idx,
vbo.vertexBuffer.ptr(),
vbo.offset,
vbo.stride);
if constexpr (!IgnoreStreamOffset) {
dst->SetStreamSource(
idx,
vbo.vertexBuffer.ptr(),
vbo.offset,
vbo.stride);
} else {
// For whatever reason, D3D9 doesn't capture the stream offset
dst->SetStreamSourceWithoutOffset(
idx,
vbo.vertexBuffer.ptr(),
vbo.stride);
}
}
}
@ -324,12 +337,12 @@ namespace dxvk {
}
}
template <D3D9StateFunction Func>
template <D3D9StateFunction Func, bool IgnoreStreamOffset>
void ApplyOrCapture() {
if constexpr (Func == D3D9StateFunction::Apply)
ApplyOrCapture(m_parent, &m_state);
ApplyOrCapture<D3D9DeviceEx, D3D9CapturableState, IgnoreStreamOffset>(m_parent, &m_state);
else if constexpr (Func == D3D9StateFunction::Capture)
ApplyOrCapture(this, m_deviceState);
ApplyOrCapture<D3D9StateBlock, D3D9DeviceState, IgnoreStreamOffset>(this, m_deviceState);
}
template <