vk: Performance fix for RADV

- RADV does not keep a mapping ptr around for subsequent remap and falls back to heavy amdgpu methods every time
  Explicitly manage pointer in the ring buffer structure to fix this
This commit is contained in:
kd-11 2018-06-14 20:58:28 +03:00 committed by kd-11
parent d77e62c94e
commit 0d61bae1b9
2 changed files with 47 additions and 21 deletions

View File

@ -588,17 +588,11 @@ VKGSRender::VKGSRender() : GSRender()
semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
//VRAM allocation //VRAM allocation
const auto& memory_map = m_device->get_memory_mapping(); m_attrib_ring_info.create(VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VK_ATTRIB_RING_BUFFER_SIZE_M * 0x100000, "attrib buffer", 0x400000);
m_attrib_ring_info.init(VK_ATTRIB_RING_BUFFER_SIZE_M * 0x100000, "attrib buffer", 0x400000); m_uniform_buffer_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "uniform buffer");
m_attrib_ring_info.heap.reset(new vk::buffer(*m_device, VK_ATTRIB_RING_BUFFER_SIZE_M * 0x100000, memory_map.host_visible_coherent, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, 0)); m_transform_constants_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_TRANSFORM_CONSTANTS_BUFFER_SIZE_M * 0x100000, "transform constants buffer");
m_uniform_buffer_ring_info.init(VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "uniform buffer"); m_index_buffer_ring_info.create(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_INDEX_RING_BUFFER_SIZE_M * 0x100000, "index buffer");
m_uniform_buffer_ring_info.heap.reset(new vk::buffer(*m_device, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, memory_map.host_visible_coherent, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 0)); m_texture_upload_buffer_ring_info.create(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_TEXTURE_UPLOAD_RING_BUFFER_SIZE_M * 0x100000, "texture upload buffer", 32 * 0x100000);
m_transform_constants_ring_info.init(VK_TRANSFORM_CONSTANTS_BUFFER_SIZE_M * 0x100000, "transform constants buffer");
m_transform_constants_ring_info.heap.reset(new vk::buffer(*m_device, VK_TRANSFORM_CONSTANTS_BUFFER_SIZE_M * 0x100000, memory_map.host_visible_coherent, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 0));
m_index_buffer_ring_info.init(VK_INDEX_RING_BUFFER_SIZE_M * 0x100000, "index buffer");
m_index_buffer_ring_info.heap.reset(new vk::buffer(*m_device, VK_INDEX_RING_BUFFER_SIZE_M * 0x100000, memory_map.host_visible_coherent, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, 0));
m_texture_upload_buffer_ring_info.init(VK_TEXTURE_UPLOAD_RING_BUFFER_SIZE_M * 0x100000, "texture upload buffer", 32 * 0x100000);
m_texture_upload_buffer_ring_info.heap.reset(new vk::buffer(*m_device, VK_TEXTURE_UPLOAD_RING_BUFFER_SIZE_M * 0x100000, memory_map.host_visible_coherent, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, 0));
for (auto &ctx : frame_context_storage) for (auto &ctx : frame_context_storage)
{ {
@ -606,6 +600,7 @@ VKGSRender::VKGSRender() : GSRender()
ctx.descriptor_pool.create(*m_device, sizes.data(), static_cast<uint32_t>(sizes.size())); ctx.descriptor_pool.create(*m_device, sizes.data(), static_cast<uint32_t>(sizes.size()));
} }
const auto& memory_map = m_device->get_memory_mapping();
null_buffer = std::make_unique<vk::buffer>(*m_device, 32, memory_map.host_visible_coherent, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, 0); null_buffer = std::make_unique<vk::buffer>(*m_device, 32, memory_map.host_visible_coherent, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, 0);
null_buffer_view = std::make_unique<vk::buffer_view>(*m_device, null_buffer->value, VK_FORMAT_R8_UINT, 0, 32); null_buffer_view = std::make_unique<vk::buffer_view>(*m_device, null_buffer->value, VK_FORMAT_R8_UINT, 0, 32);
@ -685,11 +680,11 @@ VKGSRender::~VKGSRender()
vk::destroy_global_resources(); vk::destroy_global_resources();
//Heaps //Heaps
m_index_buffer_ring_info.heap.reset(); m_index_buffer_ring_info.destroy();
m_uniform_buffer_ring_info.heap.reset(); m_uniform_buffer_ring_info.destroy();
m_transform_constants_ring_info.heap.reset(); m_transform_constants_ring_info.destroy();
m_attrib_ring_info.heap.reset(); m_attrib_ring_info.destroy();
m_texture_upload_buffer_ring_info.heap.reset(); m_texture_upload_buffer_ring_info.destroy();
//Fallback bindables //Fallback bindables
null_buffer.reset(); null_buffer.reset();

View File

@ -2566,19 +2566,50 @@ public:
struct vk_data_heap : public data_heap struct vk_data_heap : public data_heap
{ {
std::unique_ptr<vk::buffer> heap; std::unique_ptr<buffer> heap;
bool mapped = false; bool mapped = false;
void *_ptr = nullptr;
// NOTE: Some drivers (RADV) use heavyweight OS map/unmap routines that are insanely slow
// Avoid mapping/unmapping to keep these drivers from stalling
// NOTE2: HOST_CACHED flag does not keep the mapped ptr around in the driver either
void create(VkBufferUsageFlags usage, size_t size, const char *name = "unnamed", size_t guard = 0x10000)
{
const auto device = get_current_renderer();
const auto memory_map = device->get_memory_mapping();
const VkFlags memory_flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
data_heap::init(size, name, guard);
heap.reset(new buffer(*device, size, memory_map.host_visible_coherent, memory_flags, usage, 0));
}
void destroy()
{
if (mapped)
{
heap->unmap();
mapped = false;
}
heap.reset();
}
void* map(size_t offset, size_t size) void* map(size_t offset, size_t size)
{ {
mapped = true; if (!_ptr)
return heap->map(offset, size); {
_ptr = heap->map(0, heap->size());
mapped = true;
}
return (u8*)_ptr + offset;
} }
void unmap() void unmap()
{ {
mapped = false; //mapped = false;
heap->unmap(); //heap->unmap();
} }
}; };
} }