diff --git a/src/d3d9/d3d9_stateblock.cpp b/src/d3d9/d3d9_stateblock.cpp index 0d5bacd9..fb2033cd 100644 --- a/src/d3d9/d3d9_stateblock.cpp +++ b/src/d3d9/d3d9_stateblock.cpp @@ -49,7 +49,7 @@ namespace dxvk { if (m_captures.flags.test(D3D9CapturedStateFlag::VertexDecl)) SetVertexDeclaration(m_deviceState->vertexDecl.ptr()); - ApplyOrCapture(); + ApplyOrCapture(); 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(); + ApplyOrCapture(); 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(); + } } } diff --git a/src/d3d9/d3d9_stateblock.h b/src/d3d9/d3d9_stateblock.h index 50826617..64bea6f2 100644 --- a/src/d3d9/d3d9_stateblock.h +++ b/src/d3d9/d3d9_stateblock.h @@ -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 + template 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 + template void ApplyOrCapture() { if constexpr (Func == D3D9StateFunction::Apply) - ApplyOrCapture(m_parent, &m_state); + ApplyOrCapture(m_parent, &m_state); else if constexpr (Func == D3D9StateFunction::Capture) - ApplyOrCapture(this, m_deviceState); + ApplyOrCapture(this, m_deviceState); } template <