diff --git a/src/d3d8/d3d8_device.cpp b/src/d3d8/d3d8_device.cpp index 8ceefd82a..457902fa2 100644 --- a/src/d3d8/d3d8_device.cpp +++ b/src/d3d8/d3d8_device.cpp @@ -1400,6 +1400,9 @@ namespace dxvk { if (unlikely(StreamNumber >= d8caps::MAX_STREAMS)) return D3DERR_INVALIDCALL; + if (unlikely(ShouldRecord())) + return m_recorder->SetStreamSource(StreamNumber, pStreamData, Stride); + D3D8VertexBuffer* buffer = static_cast(pStreamData); HRESULT res = GetD3D9()->SetStreamSource(StreamNumber, D3D8VertexBuffer::GetD3D9Nullable(buffer), 0, Stride); diff --git a/src/d3d8/d3d8_state_block.cpp b/src/d3d8/d3d8_state_block.cpp index b4cb468e3..63ad739b6 100644 --- a/src/d3d8/d3d8_state_block.cpp +++ b/src/d3d8/d3d8_state_block.cpp @@ -13,6 +13,13 @@ HRESULT dxvk::D3D8StateBlock::Capture() { m_textures[stage] = m_device->m_textures[stage].ptr(); } + for (DWORD stream = 0; stream < m_streams.size(); stream++) { + if (m_capture.streams.get(stream)) { + m_streams[stream].buffer = m_device->m_streams[stream].buffer.ptr(); + m_streams[stream].stride = m_device->m_streams[stream].stride; + } + } + if (m_capture.indices) { m_baseVertexIndex = m_device->m_baseVertexIndex; m_indices = m_device->m_indices.ptr(); @@ -38,6 +45,11 @@ HRESULT dxvk::D3D8StateBlock::Apply() { m_device->SetTexture(stage, m_textures[stage]); } + for (DWORD stream = 0; stream < m_streams.size(); stream++) { + if (m_capture.streams.get(stream)) + m_device->SetStreamSource(stream, m_streams[stream].buffer, m_streams[stream].stride); + } + if (m_capture.indices) m_device->SetIndices(m_indices, m_baseVertexIndex); diff --git a/src/d3d8/d3d8_state_block.h b/src/d3d8/d3d8_state_block.h index 18ab4cb91..8b5ede1bd 100644 --- a/src/d3d8/d3d8_state_block.h +++ b/src/d3d8/d3d8_state_block.h @@ -16,6 +16,7 @@ namespace dxvk { bool swvp : 1; bit::bitset textures; + bit::bitset streams; D3D8StateCapture() : vs(false) @@ -24,6 +25,7 @@ namespace dxvk { , swvp(false) { // Ensure all bits are initialized to false textures.clearAll(); + streams.clearAll(); } }; @@ -54,9 +56,11 @@ namespace dxvk { m_capture.indices = true; m_capture.swvp = true; m_capture.textures.setAll(); + m_capture.streams.setAll(); } m_textures.fill(nullptr); + m_streams.fill(D3D8VBOP()); } ~D3D8StateBlock() {} @@ -97,6 +101,13 @@ namespace dxvk { return D3D_OK; } + inline HRESULT SetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer8* pStreamData, UINT Stride) { + m_streams[StreamNumber].buffer = pStreamData; + m_streams[StreamNumber].stride = Stride; + m_capture.streams.set(StreamNumber, true); + return D3D_OK; + } + inline HRESULT SetIndices(IDirect3DIndexBuffer8* pIndexData, UINT BaseVertexIndex) { m_indices = pIndexData; m_baseVertexIndex = BaseVertexIndex; @@ -115,6 +126,11 @@ namespace dxvk { Com m_stateBlock; D3DSTATEBLOCKTYPE m_type; + struct D3D8VBOP { + IDirect3DVertexBuffer8* buffer = nullptr; + UINT stride = 0; + }; + private: // State Data // D3D8StateCapture m_capture; @@ -123,6 +139,7 @@ namespace dxvk { DWORD m_pixelShader; // ps std::array m_textures; // textures + std::array m_streams; // stream data IDirect3DIndexBuffer8* m_indices = nullptr; // indices UINT m_baseVertexIndex; // indices