mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 03:55:32 +00:00
vk: Make use of multi-pool memory types
This commit is contained in:
parent
de7ed1cbe9
commit
69bdbe97a8
6 changed files with 65 additions and 38 deletions
|
@ -39,7 +39,7 @@ namespace vk
|
|||
return false;
|
||||
}
|
||||
|
||||
buffer::buffer(const vk::render_device& dev, u64 size, u32 memory_type_index, u32 access_flags, VkBufferUsageFlags usage, VkBufferCreateFlags flags, vmm_allocation_pool allocation_pool)
|
||||
buffer::buffer(const vk::render_device& dev, u64 size, const memory_type_info& memory_type, u32 access_flags, VkBufferUsageFlags usage, VkBufferCreateFlags flags, vmm_allocation_pool allocation_pool)
|
||||
: m_device(dev)
|
||||
{
|
||||
info.size = size;
|
||||
|
@ -54,15 +54,13 @@ namespace vk
|
|||
VkMemoryRequirements memory_reqs;
|
||||
vkGetBufferMemoryRequirements(m_device, value, &memory_reqs);
|
||||
|
||||
if (!(memory_reqs.memoryTypeBits & (1 << memory_type_index)))
|
||||
memory_type_info allocation_type_info = memory_type.get(dev, access_flags, memory_reqs.memoryTypeBits);
|
||||
if (!allocation_type_info)
|
||||
{
|
||||
// Suggested memory type is incompatible with this memory type.
|
||||
// Go through the bitset and test for requested props.
|
||||
if (!dev.get_compatible_memory_type(memory_reqs.memoryTypeBits, access_flags, &memory_type_index))
|
||||
fmt::throw_exception("No compatible memory type was found!");
|
||||
fmt::throw_exception("No compatible memory type was found!");
|
||||
}
|
||||
|
||||
memory = std::make_unique<memory_block>(m_device, memory_reqs.size, memory_reqs.alignment, memory_type_index, allocation_pool);
|
||||
memory = std::make_unique<memory_block>(m_device, memory_reqs.size, memory_reqs.alignment, allocation_type_info, allocation_pool);
|
||||
vkBindBufferMemory(dev, value, memory->get_vk_device_memory(), memory->get_vk_device_memory_offset());
|
||||
}
|
||||
|
||||
|
@ -84,9 +82,6 @@ namespace vk
|
|||
CHECK_RESULT(vkCreateBuffer(m_device, &info, nullptr, &value));
|
||||
|
||||
auto& memory_map = dev.get_memory_mapping();
|
||||
u32 memory_type_index = memory_map.host_visible_coherent;
|
||||
VkFlags access_flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
|
||||
|
||||
ensure(memory_map._vkGetMemoryHostPointerPropertiesEXT);
|
||||
|
||||
VkMemoryHostPointerPropertiesEXT memory_properties{};
|
||||
|
@ -104,12 +99,16 @@ namespace vk
|
|||
required_memory_type_bits = memory_properties.memoryTypeBits;
|
||||
}
|
||||
|
||||
if (!dev.get_compatible_memory_type(required_memory_type_bits, access_flags, &memory_type_index))
|
||||
const auto allocation_type_info = memory_map.host_visible_coherent.get(dev,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
required_memory_type_bits);
|
||||
|
||||
if (!allocation_type_info)
|
||||
{
|
||||
fmt::throw_exception("No compatible memory type was found!");
|
||||
}
|
||||
|
||||
memory = std::make_unique<memory_block_host>(m_device, host_pointer, size, memory_type_index);
|
||||
memory = std::make_unique<memory_block_host>(m_device, host_pointer, size, allocation_type_info);
|
||||
CHECK_RESULT(vkBindBufferMemory(dev, value, memory->get_vk_device_memory(), memory->get_vk_device_memory_offset()));
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace vk
|
|||
VkBufferCreateInfo info = {};
|
||||
std::unique_ptr<vk::memory_block> memory;
|
||||
|
||||
buffer(const vk::render_device& dev, u64 size, u32 memory_type_index, u32 access_flags, VkBufferUsageFlags usage, VkBufferCreateFlags flags, vmm_allocation_pool allocation_pool);
|
||||
buffer(const vk::render_device& dev, u64 size, const memory_type_info& memory_type, u32 access_flags, VkBufferUsageFlags usage, VkBufferCreateFlags flags, vmm_allocation_pool allocation_pool);
|
||||
buffer(const vk::render_device& dev, VkBufferUsageFlags usage, void* host_pointer, u64 size);
|
||||
~buffer();
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace vk
|
|||
}
|
||||
|
||||
image::image(const vk::render_device& dev,
|
||||
u32 memory_type_index,
|
||||
const memory_type_info& memory_type,
|
||||
u32 access_flags,
|
||||
VkImageType image_type,
|
||||
VkFormat format,
|
||||
|
@ -70,7 +70,7 @@ namespace vk
|
|||
info.initialLayout = initial_layout;
|
||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
|
||||
create_impl(dev, access_flags, memory_type_index, allocation_pool);
|
||||
create_impl(dev, access_flags, memory_type, allocation_pool);
|
||||
m_storage_aspect = get_aspect_flags(format);
|
||||
|
||||
if (format_class == RSX_FORMAT_CLASS_UNDEFINED)
|
||||
|
@ -95,7 +95,7 @@ namespace vk
|
|||
vkDestroyImage(m_device, value, nullptr);
|
||||
}
|
||||
|
||||
void image::create_impl(const vk::render_device& dev, u32 access_flags, u32 memory_type_index, vmm_allocation_pool allocation_pool)
|
||||
void image::create_impl(const vk::render_device& dev, u32 access_flags, const memory_type_info& memory_type, vmm_allocation_pool allocation_pool)
|
||||
{
|
||||
ensure(!value && !memory);
|
||||
validate(dev, info);
|
||||
|
@ -105,15 +105,13 @@ namespace vk
|
|||
VkMemoryRequirements memory_req;
|
||||
vkGetImageMemoryRequirements(m_device, value, &memory_req);
|
||||
|
||||
if (!(memory_req.memoryTypeBits & (1 << memory_type_index)))
|
||||
const auto allocation_type_info = memory_type.get(dev, access_flags, memory_req.memoryTypeBits);
|
||||
if (!allocation_type_info)
|
||||
{
|
||||
// Suggested memory type is incompatible with this memory type.
|
||||
// Go through the bitset and test for requested props.
|
||||
if (!dev.get_compatible_memory_type(memory_req.memoryTypeBits, access_flags, &memory_type_index))
|
||||
fmt::throw_exception("No compatible memory type was found!");
|
||||
fmt::throw_exception("No compatible memory type was found!");
|
||||
}
|
||||
|
||||
memory = std::make_shared<vk::memory_block>(m_device, memory_req.size, memory_req.alignment, memory_type_index, allocation_pool);
|
||||
memory = std::make_shared<vk::memory_block>(m_device, memory_req.size, memory_req.alignment, allocation_type_info, allocation_pool);
|
||||
CHECK_RESULT(vkBindImageMemory(m_device, value, memory->get_vk_device_memory(), memory->get_vk_device_memory_offset()));
|
||||
|
||||
current_layout = info.initialLayout;
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace vk
|
|||
|
||||
protected:
|
||||
image() = default;
|
||||
void create_impl(const vk::render_device& dev, u32 access_flags, u32 memory_type_index, vmm_allocation_pool allocation_pool);
|
||||
void create_impl(const vk::render_device& dev, u32 access_flags, const memory_type_info& memory_type, vmm_allocation_pool allocation_pool);
|
||||
|
||||
public:
|
||||
VkImage value = VK_NULL_HANDLE;
|
||||
|
@ -48,7 +48,7 @@ namespace vk
|
|||
std::shared_ptr<vk::memory_block> memory;
|
||||
|
||||
image(const vk::render_device& dev,
|
||||
u32 memory_type_index,
|
||||
const memory_type_info& memory_type,
|
||||
u32 access_flags,
|
||||
VkImageType image_type,
|
||||
VkFormat format,
|
||||
|
|
|
@ -14,29 +14,56 @@ namespace
|
|||
namespace vk
|
||||
{
|
||||
memory_type_info::memory_type_info(u32 index)
|
||||
: num_entries(0)
|
||||
{
|
||||
push(index);
|
||||
}
|
||||
void memory_type_info::push(u32 index)
|
||||
{
|
||||
ensure(num_entries < pools.size());
|
||||
pools[num_entries++] = index;
|
||||
type_ids.push_back(index);
|
||||
}
|
||||
|
||||
memory_type_info::const_iterator memory_type_info::begin() const
|
||||
{
|
||||
return pools.data();
|
||||
return type_ids.data();
|
||||
}
|
||||
|
||||
memory_type_info::const_iterator memory_type_info::end() const
|
||||
{
|
||||
return pools.data() + num_entries;
|
||||
return type_ids.data() + type_ids.size();
|
||||
}
|
||||
|
||||
u32 memory_type_info::first() const
|
||||
{
|
||||
ensure(!type_ids.empty());
|
||||
return type_ids.front();
|
||||
}
|
||||
|
||||
memory_type_info::operator bool() const
|
||||
{
|
||||
return (num_entries > 0);
|
||||
return !type_ids.empty();
|
||||
}
|
||||
|
||||
memory_type_info memory_type_info::get(const render_device& dev, u32 access_flags, u32 type_mask) const
|
||||
{
|
||||
memory_type_info result{};
|
||||
for (const auto& type : type_ids)
|
||||
{
|
||||
if (type_mask & (1 << type))
|
||||
{
|
||||
result.push(type);
|
||||
}
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
u32 type;
|
||||
if (dev.get_compatible_memory_type(type_mask, access_flags, &type))
|
||||
{
|
||||
result = type;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
mem_allocator_vma::mem_allocator_vma(VkDevice dev, VkPhysicalDevice pdev) : mem_allocator_base(dev, pdev)
|
||||
|
@ -268,11 +295,11 @@ namespace vk
|
|||
return g_render_device->get_allocator();
|
||||
}
|
||||
|
||||
memory_block::memory_block(VkDevice dev, u64 block_sz, u64 alignment, u32 memory_type_index, vmm_allocation_pool pool)
|
||||
memory_block::memory_block(VkDevice dev, u64 block_sz, u64 alignment, const memory_type_info& memory_type, vmm_allocation_pool pool)
|
||||
: m_device(dev), m_size(block_sz)
|
||||
{
|
||||
m_mem_allocator = get_current_mem_allocator();
|
||||
m_mem_handle = m_mem_allocator->alloc(block_sz, alignment, memory_type_index, pool);
|
||||
m_mem_handle = m_mem_allocator->alloc(block_sz, alignment, memory_type, pool);
|
||||
}
|
||||
|
||||
memory_block::~memory_block()
|
||||
|
@ -283,14 +310,14 @@ namespace vk
|
|||
}
|
||||
}
|
||||
|
||||
memory_block_host::memory_block_host(VkDevice dev, void* host_pointer, u64 size, u32 memory_type_index) :
|
||||
memory_block_host::memory_block_host(VkDevice dev, void* host_pointer, u64 size, const memory_type_info& memory_type) :
|
||||
m_device(dev), m_mem_handle(VK_NULL_HANDLE), m_host_pointer(host_pointer)
|
||||
{
|
||||
VkMemoryAllocateInfo alloc_info{};
|
||||
VkImportMemoryHostPointerInfoEXT import_info{};
|
||||
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
alloc_info.memoryTypeIndex = memory_type_index;
|
||||
alloc_info.memoryTypeIndex = memory_type.first();
|
||||
alloc_info.allocationSize = size;
|
||||
alloc_info.pNext = &import_info;
|
||||
|
||||
|
|
|
@ -23,10 +23,10 @@ namespace vk
|
|||
|
||||
using namespace vk::vmm_allocation_pool_;
|
||||
|
||||
class render_device;
|
||||
class memory_type_info
|
||||
{
|
||||
std::array<u32, 4> pools;
|
||||
u32 num_entries = 0;
|
||||
std::vector<u32> type_ids;
|
||||
|
||||
public:
|
||||
memory_type_info() = default;
|
||||
|
@ -37,8 +37,11 @@ namespace vk
|
|||
using const_iterator = const u32*;
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
u32 first() const;
|
||||
|
||||
operator bool() const;
|
||||
|
||||
memory_type_info get(const render_device& dev, u32 access_flags, u32 type_mask) const;
|
||||
};
|
||||
|
||||
class mem_allocator_base
|
||||
|
@ -121,7 +124,7 @@ namespace vk
|
|||
|
||||
struct memory_block
|
||||
{
|
||||
memory_block(VkDevice dev, u64 block_sz, u64 alignment, u32 memory_type_index, vmm_allocation_pool pool);
|
||||
memory_block(VkDevice dev, u64 block_sz, u64 alignment, const memory_type_info& memory_type, vmm_allocation_pool pool);
|
||||
virtual ~memory_block();
|
||||
|
||||
virtual VkDeviceMemory get_vk_device_memory();
|
||||
|
@ -147,7 +150,7 @@ namespace vk
|
|||
|
||||
struct memory_block_host : public memory_block
|
||||
{
|
||||
memory_block_host(VkDevice dev, void* host_pointer, u64 size, u32 memory_type_index);
|
||||
memory_block_host(VkDevice dev, void* host_pointer, u64 size, const memory_type_info& memory_type);
|
||||
~memory_block_host();
|
||||
|
||||
VkDeviceMemory get_vk_device_memory() override;
|
||||
|
|
Loading…
Add table
Reference in a new issue