diff --git a/src/d3d9/d3d9_mem.cpp b/src/d3d9/d3d9_mem.cpp index c288fd3ac..ec2562469 100644 --- a/src/d3d9/d3d9_mem.cpp +++ b/src/d3d9/d3d9_mem.cpp @@ -7,6 +7,8 @@ #ifdef D3D9_ALLOW_UNMAPPING #include +#else +#include #endif namespace dxvk { @@ -287,6 +289,59 @@ namespace dxvk { return m_ptr; } +#else + + D3D9Memory D3D9MemoryAllocator::Alloc(uint32_t Size) { + D3D9Memory memory(this, Size); + m_allocatedMemory += Size; + return memory; + } + + uint32_t D3D9MemoryAllocator::MappedMemory() { + return m_allocatedMemory.load(); + } + + uint32_t D3D9MemoryAllocator::UsedMemory() { + return m_allocatedMemory.load(); + } + + uint32_t D3D9MemoryAllocator::AllocatedMemory() { + return m_allocatedMemory.load(); + } + + D3D9Memory::D3D9Memory(D3D9MemoryAllocator* pAllocator, size_t Size) + : m_allocator (pAllocator), + m_ptr (malloc(Size)), + m_size (Size) {} + + D3D9Memory::D3D9Memory(D3D9Memory&& other) + : m_allocator(std::exchange(other.m_allocator, nullptr)), + m_ptr(std::exchange(other.m_ptr, nullptr)), + m_size(std::exchange(other.m_size, 0)) {} + + D3D9Memory::~D3D9Memory() { + this->Free(); + } + + D3D9Memory& D3D9Memory::operator = (D3D9Memory&& other) { + this->Free(); + + m_allocator = std::exchange(other.m_allocator, nullptr); + m_ptr = std::exchange(other.m_ptr, nullptr); + m_size = std::exchange(other.m_size, 0); + return *this; + } + + void D3D9Memory::Free() { + if (m_ptr == nullptr) + return; + + free(m_ptr); + m_ptr = nullptr; + m_allocator->NotifyFreed(m_size); + } + + #endif } diff --git a/src/d3d9/d3d9_mem.h b/src/d3d9/d3d9_mem.h index b0d61f053..1da862653 100644 --- a/src/d3d9/d3d9_mem.h +++ b/src/d3d9/d3d9_mem.h @@ -126,25 +126,49 @@ namespace dxvk { }; #else - class D3D9Memory { + class D3D9Memory { + friend D3D9MemoryAllocator; + public: - operator bool() const { return false; } + D3D9Memory() {} + ~D3D9Memory(); + + D3D9Memory (const D3D9Memory&) = delete; + D3D9Memory& operator = (const D3D9Memory&) = delete; + + D3D9Memory (D3D9Memory&& other); + D3D9Memory& operator = (D3D9Memory&& other); + + operator bool() const { return m_ptr != nullptr; } void Map() {} void Unmap() {} - void* Ptr() { return nullptr; } + void* Ptr() { return m_ptr; } + size_t GetSize() const { return m_size; } private: + D3D9Memory(D3D9MemoryAllocator* pAllocator, size_t Size); void Free(); + + D3D9MemoryAllocator* m_allocator = nullptr; + void* m_ptr = nullptr; + size_t m_size = 0; }; class D3D9MemoryAllocator { public: - D3D9Memory Alloc(uint32_t Size) { return { }; } - uint32_t MappedMemory() { return 0; } - uint32_t UsedMemory() { return 0; } - uint32_t AllocatedMemory() { return 0; } + D3D9Memory Alloc(uint32_t Size); + uint32_t MappedMemory(); + uint32_t UsedMemory(); + uint32_t AllocatedMemory(); + void NotifyFreed(uint32_t Size) { + m_allocatedMemory -= Size; + } + + private: + std::atomic m_allocatedMemory = 0; + }; #endif