diff --git a/src/d3d9/d3d9_buffer.h b/src/d3d9/d3d9_buffer.h index 0a1582e3..92f6b69c 100644 --- a/src/d3d9/d3d9_buffer.h +++ b/src/d3d9/d3d9_buffer.h @@ -33,6 +33,10 @@ namespace dxvk { return m_buffer.Unlock(); } + void STDMETHODCALLTYPE PreLoad() final { + m_buffer.PreLoad(); + } + D3D9CommonBuffer* GetCommonBuffer() { return &m_buffer; } diff --git a/src/d3d9/d3d9_common_buffer.cpp b/src/d3d9/d3d9_common_buffer.cpp index 2ab6bb07..913425eb 100644 --- a/src/d3d9/d3d9_common_buffer.cpp +++ b/src/d3d9/d3d9_common_buffer.cpp @@ -50,6 +50,16 @@ namespace dxvk { } + void D3D9CommonBuffer::PreLoad() { + if (IsPoolManaged(m_desc.Pool)) { + auto lock = m_parent->LockDevice(); + + if (NeedsUpload()) + m_parent->FlushBuffer(this); + } + } + + Rc D3D9CommonBuffer::CreateBuffer() const { DxvkBufferCreateInfo info; info.size = m_desc.Size; diff --git a/src/d3d9/d3d9_common_buffer.h b/src/d3d9/d3d9_common_buffer.h index 2e343435..ba4149d5 100644 --- a/src/d3d9/d3d9_common_buffer.h +++ b/src/d3d9/d3d9_common_buffer.h @@ -163,6 +163,8 @@ namespace dxvk { return locked; } + void PreLoad(); + private: Rc CreateBuffer() const; diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index 61cf6fa9..b8eff840 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -465,6 +465,27 @@ namespace dxvk { } + void D3D9CommonTexture::PreLoadAll() { + if (IsManaged()) { + auto lock = m_device->LockDevice(); + + m_device->UploadManagedTexture(this); + } + } + + + void D3D9CommonTexture::PreLoadSubresource(UINT Subresource) { + if (IsManaged()) { + auto lock = m_device->LockDevice(); + + if (GetNeedsUpload(Subresource)) { + m_device->FlushImage(this, Subresource); + SetNeedsUpload(Subresource, false); + } + } + } + + void D3D9CommonTexture::CreateSampleView(UINT Lod) { // This will be a no-op for SYSTEMMEM types given we // don't expose the cap to allow texturing with them. diff --git a/src/d3d9/d3d9_common_texture.h b/src/d3d9/d3d9_common_texture.h index fcca8924..789ca66a 100644 --- a/src/d3d9/d3d9_common_texture.h +++ b/src/d3d9/d3d9_common_texture.h @@ -355,6 +355,7 @@ namespace dxvk { bool GetUploading(UINT Subresource) const { return m_uploading.get(Subresource); } void SetNeedsUpload(UINT Subresource, bool upload) { m_needsUpload.set(Subresource, upload); } + bool GetNeedsUpload(UINT Subresource) const { return m_needsUpload.get(Subresource); } bool NeedsAnyUpload() { return m_needsUpload.any(); } void ClearNeedsUpload() { return m_needsUpload.clearAll(); } @@ -366,6 +367,9 @@ namespace dxvk { void SetMipFilter(D3DTEXTUREFILTERTYPE filter) { m_mipFilter = filter; } D3DTEXTUREFILTERTYPE GetMipFilter() const { return m_mipFilter; } + void PreLoadAll(); + void PreLoadSubresource(UINT Subresource); + private: D3D9DeviceEx* m_device; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 641ba2eb..ed7ff1b1 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -4120,6 +4120,7 @@ namespace dxvk { (!atiHack) ? formatInfo : nullptr, pBox); + uint8_t* data = reinterpret_cast(physSlice.mapPtr); data += offset; pLockedBox->pBits = data; @@ -4886,22 +4887,24 @@ namespace dxvk { } - void D3D9DeviceEx::UploadManagedTextures(uint32_t mask) { - for (uint32_t tex = mask; tex; tex &= tex - 1) { - // Guaranteed to not be nullptr... - auto texInfo = GetCommonTexture(m_state.textures[bit::tzcnt(tex)]); + void D3D9DeviceEx::UploadManagedTexture(D3D9CommonTexture* pResource) { + for (uint32_t i = 0; i < pResource->GetUploadBitmask().dwordCount(); i++) { + for (uint32_t subresources = pResource->GetUploadBitmask().dword(i); subresources; subresources &= subresources - 1) { + uint32_t subresource = i * 32 + bit::tzcnt(subresources); - for (uint32_t i = 0; i < texInfo->GetUploadBitmask().dwordCount(); i++) { - for (uint32_t subresources = texInfo->GetUploadBitmask().dword(i); subresources; subresources &= subresources - 1) { - uint32_t subresource = i * 32 + bit::tzcnt(subresources); - - this->FlushImage(texInfo, subresource); - } + this->FlushImage(pResource, subresource); } - - texInfo->ClearNeedsUpload(); } + pResource->ClearNeedsUpload(); + } + + + void D3D9DeviceEx::UploadManagedTextures(uint32_t mask) { + // Guaranteed to not be nullptr... + for (uint32_t tex = mask; tex; tex &= tex - 1) + UploadManagedTexture(GetCommonTexture(m_state.textures[bit::tzcnt(tex)])); + m_activeTexturesToUpload &= ~mask; } diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 462c94a4..6f00b503 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -748,6 +748,8 @@ namespace dxvk { void MarkRenderHazards(); + void UploadManagedTexture(D3D9CommonTexture* pResource); + void UploadManagedTextures(uint32_t mask); void GenerateTextureMips(uint32_t mask); diff --git a/src/d3d9/d3d9_resource.h b/src/d3d9/d3d9_resource.h index caa9f504..5d343e20 100644 --- a/src/d3d9/d3d9_resource.h +++ b/src/d3d9/d3d9_resource.h @@ -70,9 +70,6 @@ namespace dxvk { return m_priority; } - void STDMETHODCALLTYPE PreLoad() { - } - protected: diff --git a/src/d3d9/d3d9_subresource.h b/src/d3d9/d3d9_subresource.h index b058499c..db55427c 100644 --- a/src/d3d9/d3d9_subresource.h +++ b/src/d3d9/d3d9_subresource.h @@ -52,6 +52,10 @@ namespace dxvk { return this->GetDevice()->QueryInterface(riid, ppContainer); } + void STDMETHODCALLTYPE PreLoad() { + m_texture->PreLoadSubresource(GetSubresource()); + } + D3D9CommonTexture* GetCommonTexture() { return m_texture; } diff --git a/src/d3d9/d3d9_texture.h b/src/d3d9/d3d9_texture.h index 43f4d2c8..47f09a84 100644 --- a/src/d3d9/d3d9_texture.h +++ b/src/d3d9/d3d9_texture.h @@ -93,6 +93,10 @@ namespace dxvk { this->m_parent->EmitGenerateMips(&m_texture); } + void STDMETHODCALLTYPE PreLoad() final { + m_texture.PreLoadAll(); + } + D3D9CommonTexture* GetCommonTexture() { return &m_texture; }