[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)) if (m_captures.flags.test(D3D9CapturedStateFlag::VertexDecl))
SetVertexDeclaration(m_deviceState->vertexDecl.ptr()); SetVertexDeclaration(m_deviceState->vertexDecl.ptr());
ApplyOrCapture<D3D9StateFunction::Capture>(); ApplyOrCapture<D3D9StateFunction::Capture, true>();
return D3D_OK; return D3D_OK;
} }
@ -61,7 +61,7 @@ namespace dxvk {
if (m_captures.flags.test(D3D9CapturedStateFlag::VertexDecl) && m_state.vertexDecl != nullptr) if (m_captures.flags.test(D3D9CapturedStateFlag::VertexDecl) && m_state.vertexDecl != nullptr)
m_parent->SetVertexDeclaration(m_state.vertexDecl.ptr()); m_parent->SetVertexDeclaration(m_state.vertexDecl.ptr());
ApplyOrCapture<D3D9StateFunction::Apply>(); ApplyOrCapture<D3D9StateFunction::Apply, false>();
m_applying = false; m_applying = false;
return D3D_OK; 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) { HRESULT D3D9StateBlock::SetStreamSourceFreq(UINT StreamNumber, UINT Setting) {
m_state.streamFreq[StreamNumber] = Setting; m_state.streamFreq[StreamNumber] = Setting;
@ -572,8 +586,12 @@ namespace dxvk {
m_captures.flags.set(D3D9CapturedStateFlag::Material); m_captures.flags.set(D3D9CapturedStateFlag::Material);
} }
if (Type != D3D9StateBlockType::None) if (Type != D3D9StateBlockType::None) {
this->Capture(); 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 OffsetInBytes,
UINT Stride); UINT Stride);
HRESULT SetStreamSourceWithoutOffset(
UINT StreamNumber,
D3D9VertexBuffer* pStreamData,
UINT Stride);
HRESULT SetStreamSourceFreq(UINT StreamNumber, UINT Setting); HRESULT SetStreamSourceFreq(UINT StreamNumber, UINT Setting);
HRESULT SetStateTexture(DWORD StateSampler, IDirect3DBaseTexture9* pTexture); HRESULT SetStateTexture(DWORD StateSampler, IDirect3DBaseTexture9* pTexture);
@ -181,7 +186,7 @@ namespace dxvk {
Capture Capture
}; };
template <typename Dst, typename Src> template <typename Dst, typename Src, bool IgnoreStreamOffset>
void ApplyOrCapture(Dst* dst, const Src* src) { void ApplyOrCapture(Dst* dst, const Src* src) {
if (m_captures.flags.test(D3D9CapturedStateFlag::StreamFreq)) { if (m_captures.flags.test(D3D9CapturedStateFlag::StreamFreq)) {
for (uint32_t idx : bit::BitMask(m_captures.streamFreq.dword(0))) for (uint32_t idx : bit::BitMask(m_captures.streamFreq.dword(0)))
@ -211,11 +216,19 @@ namespace dxvk {
if (m_captures.flags.test(D3D9CapturedStateFlag::VertexBuffers)) { if (m_captures.flags.test(D3D9CapturedStateFlag::VertexBuffers)) {
for (uint32_t idx : bit::BitMask(m_captures.vertexBuffers.dword(0))) { for (uint32_t idx : bit::BitMask(m_captures.vertexBuffers.dword(0))) {
const auto& vbo = src->vertexBuffers[idx]; const auto& vbo = src->vertexBuffers[idx];
dst->SetStreamSource( if constexpr (!IgnoreStreamOffset) {
idx, dst->SetStreamSource(
vbo.vertexBuffer.ptr(), idx,
vbo.offset, vbo.vertexBuffer.ptr(),
vbo.stride); 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() { void ApplyOrCapture() {
if constexpr (Func == D3D9StateFunction::Apply) if constexpr (Func == D3D9StateFunction::Apply)
ApplyOrCapture(m_parent, &m_state); ApplyOrCapture<D3D9DeviceEx, D3D9CapturableState, IgnoreStreamOffset>(m_parent, &m_state);
else if constexpr (Func == D3D9StateFunction::Capture) else if constexpr (Func == D3D9StateFunction::Capture)
ApplyOrCapture(this, m_deviceState); ApplyOrCapture<D3D9StateBlock, D3D9DeviceState, IgnoreStreamOffset>(this, m_deviceState);
} }
template < template <