update parallel rdp

This commit is contained in:
Logan McNaughton
2022-12-07 18:11:41 -07:00
parent 1f7414444d
commit dc27483cc9
35 changed files with 4001 additions and 1071 deletions
+82 -60
View File
@@ -46,6 +46,7 @@ static unsigned get_thread_index()
return Util::get_current_thread_index();
}
#define LOCK() std::lock_guard<std::mutex> holder__{lock.lock}
#define LOCK_MEMORY() std::lock_guard<std::mutex> holder__{lock.memory_lock}
#define DRAIN_FRAME_LOCK() \
std::unique_lock<std::mutex> holder__{lock.lock}; \
lock.cond.wait(holder__, [&]() { \
@@ -53,6 +54,7 @@ static unsigned get_thread_index()
})
#else
#define LOCK() ((void)0)
#define LOCK_MEMORY() ((void)0)
#define DRAIN_FRAME_LOCK() VK_ASSERT(lock.counter == 0)
static unsigned get_thread_index()
{
@@ -678,11 +680,11 @@ void Device::init_pipeline_cache()
#ifdef GRANITE_VULKAN_FILESYSTEM
if (!system_handles.filesystem)
return;
auto file = system_handles.filesystem->open("cache://pipeline_cache.bin", Granite::FileMode::ReadOnly);
auto file = system_handles.filesystem->open_readonly_mapping("cache://pipeline_cache.bin");
if (file)
{
auto size = file->get_size();
auto *mapped = static_cast<uint8_t *>(file->map());
auto *mapped = file->data<uint8_t>();
if (mapped && !init_pipeline_cache(mapped, size))
LOGE("Failed to initialize pipeline cache.\n");
}
@@ -751,9 +753,8 @@ void Device::flush_pipeline_cache()
return;
}
auto file = system_handles.filesystem->open(
"cache://pipeline_cache.bin",
Granite::FileMode::WriteOnlyTransactional);
auto file = system_handles.filesystem->open_transactional_mapping(
"cache://pipeline_cache.bin", size);
if (!file)
{
@@ -761,14 +762,7 @@ void Device::flush_pipeline_cache()
return;
}
uint8_t *data = static_cast<uint8_t *>(file->map_write(size));
if (!data)
{
LOGE("Failed to get pipeline cache data.\n");
return;
}
if (!get_pipeline_cache_data(data, size))
if (!get_pipeline_cache_data(file->mutable_data<uint8_t>(), size))
{
LOGE("Failed to get pipeline cache data.\n");
return;
@@ -858,11 +852,7 @@ void Device::set_context(const Context &context)
init_timeline_semaphores();
init_bindless();
#ifdef ANDROID
init_frame_contexts(3); // Android needs a bit more ... ;)
#else
init_frame_contexts(2); // By default, regular double buffer between CPU and GPU.
#endif
managers.memory.init(this);
managers.semaphore.init(this);
@@ -2443,7 +2433,10 @@ void Device::wait_idle_nolock()
frame->trim_command_pools();
}
managers.memory.garbage_collect();
{
LOCK_MEMORY();
managers.memory.garbage_collect();
}
}
void Device::promote_read_write_caches_to_read_only()
@@ -2583,6 +2576,8 @@ void Device::init_calibrated_timestamps()
{
#ifdef _WIN32
const auto supported_domain = VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT;
#elif defined(ANDROID)
const auto supported_domain = VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT;
#else
const auto supported_domain = VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT;
#endif
@@ -2799,8 +2794,15 @@ void Device::PerFrame::begin()
managers.semaphore.recycle(semaphore);
for (auto &event : recycled_events)
managers.event.recycle(event);
for (auto &alloc : allocations)
alloc.free_immediate(managers.memory);
if (!allocations.empty())
{
#ifdef GRANITE_VULKAN_MT
std::lock_guard<std::mutex> holder{device.lock.memory_lock};
#endif
for (auto &alloc : allocations)
alloc.free_immediate(managers.memory);
}
destroyed_framebuffers.clear();
destroyed_samplers.clear();
@@ -3520,16 +3522,20 @@ DeviceAllocationOwnerHandle Device::allocate_memory(const MemoryAllocateInfo &in
return {};
DeviceAllocation alloc = {};
if (!managers.memory.allocate_generic_memory(info.requirements.size, info.requirements.alignment,
info.mode, index, &alloc))
{
return {};
LOCK_MEMORY();
if (!managers.memory.allocate_generic_memory(info.requirements.size, info.requirements.alignment, info.mode,
index, &alloc))
{
return {};
}
}
return DeviceAllocationOwnerHandle(handle_pool.allocations.allocate(this, alloc));
}
void Device::get_memory_budget(HeapBudget *budget)
{
LOCK_MEMORY();
managers.memory.get_memory_budget(budget);
}
@@ -3670,12 +3676,16 @@ bool Device::allocate_image_memory(DeviceAllocation *allocation, const ImageCrea
else
mode = tiling == VK_IMAGE_TILING_OPTIMAL ? AllocationMode::OptimalResource : AllocationMode::LinearHostMappable;
if (!managers.memory.allocate_image_memory(reqs.size, reqs.alignment, mode, memory_type,
image, (info.misc & IMAGE_MISC_FORCE_NO_DEDICATED_BIT) != 0,
allocation, use_external ? &external : nullptr))
{
LOGE("Failed to allocate image memory (type %u, size: %u).\n", unsigned(memory_type), unsigned(reqs.size));
return false;
LOCK_MEMORY();
if (!managers.memory.allocate_image_memory(reqs.size, reqs.alignment, mode, memory_type, image,
(info.misc & IMAGE_MISC_FORCE_NO_DEDICATED_BIT) != 0, allocation,
use_external ? &external : nullptr))
{
LOGE("Failed to allocate image memory (type %u, size: %u).\n",
unsigned(memory_type), unsigned(reqs.size));
return false;
}
}
if (table->vkBindImageMemory(device, image, allocation->get_memory(),
@@ -4341,14 +4351,20 @@ BufferHandle Device::create_imported_host_buffer(const BufferCreateInfo &create_
auto allocation = DeviceAllocation::make_imported_allocation(memory, info.size, memory_type);
if (table->vkMapMemory(device, memory, 0, VK_WHOLE_SIZE, 0, reinterpret_cast<void **>(&allocation.host_base)) != VK_SUCCESS)
{
allocation.free_immediate(managers.memory);
{
LOCK_MEMORY();
allocation.free_immediate(managers.memory);
}
table->vkDestroyBuffer(device, buffer, nullptr);
return BufferHandle{};
}
if (table->vkBindBufferMemory(device, buffer, memory, 0) != VK_SUCCESS)
{
allocation.free_immediate(managers.memory);
{
LOCK_MEMORY();
allocation.free_immediate(managers.memory);
}
table->vkDestroyBuffer(device, buffer, nullptr);
return BufferHandle{};
}
@@ -4454,47 +4470,53 @@ BufferHandle Device::create_buffer(const BufferCreateInfo &create_info, const vo
auto external = create_info.external;
if (!managers.memory.allocate_buffer_memory(reqs.memoryRequirements.size, reqs.memoryRequirements.alignment,
mode, memory_type, buffer, &allocation,
use_external ? &external : nullptr))
{
if (use_external)
LOCK_MEMORY();
if (!managers.memory.allocate_buffer_memory(reqs.memoryRequirements.size, reqs.memoryRequirements.alignment,
mode, memory_type, buffer, &allocation,
use_external ? &external : nullptr))
{
LOGE("Failed to export / import buffer memory.\n");
table->vkDestroyBuffer(device, buffer, nullptr);
return BufferHandle(nullptr);
}
if (use_external)
{
LOGE("Failed to export / import buffer memory.\n");
table->vkDestroyBuffer(device, buffer, nullptr);
return BufferHandle(nullptr);
}
auto fallback_domain = create_info.domain;
auto fallback_domain = create_info.domain;
// This memory type is rather scarce, so fallback to Host type if we've exhausted this memory.
if (create_info.domain == BufferDomain::LinkedDeviceHost)
{
LOGW("Exhausted LinkedDeviceHost memory, falling back to host.\n");
fallback_domain = BufferDomain::Host;
// This memory type is rather scarce, so fallback to Host type if we've exhausted this memory.
if (create_info.domain == BufferDomain::LinkedDeviceHost)
{
LOGW("Exhausted LinkedDeviceHost memory, falling back to host.\n");
fallback_domain = BufferDomain::Host;
}
else if (create_info.domain == BufferDomain::LinkedDeviceHostPreferDevice)
{
LOGW("Exhausted LinkedDeviceHostPreferDevice memory, falling back to device.\n");
fallback_domain = BufferDomain::Device;
}
}
else if (create_info.domain == BufferDomain::LinkedDeviceHostPreferDevice)
{
LOGW("Exhausted LinkedDeviceHostPreferDevice memory, falling back to device.\n");
fallback_domain = BufferDomain::Device;
}
memory_type = find_memory_type(fallback_domain, reqs.memoryRequirements.memoryTypeBits);
memory_type = find_memory_type(fallback_domain, reqs.memoryRequirements.memoryTypeBits);
if (memory_type == UINT32_MAX || fallback_domain == create_info.domain ||
!managers.memory.allocate_buffer_memory(reqs.memoryRequirements.size, reqs.memoryRequirements.alignment,
mode, memory_type, buffer, &allocation, nullptr))
{
LOGE("Failed to allocate fallback memory.\n");
table->vkDestroyBuffer(device, buffer, nullptr);
return BufferHandle(nullptr);
if (memory_type == UINT32_MAX || fallback_domain == create_info.domain ||
!managers.memory.allocate_buffer_memory(reqs.memoryRequirements.size, reqs.memoryRequirements.alignment,
mode, memory_type, buffer, &allocation, nullptr))
{
LOGE("Failed to allocate fallback memory.\n");
table->vkDestroyBuffer(device, buffer, nullptr);
return BufferHandle(nullptr);
}
}
}
if (table->vkBindBufferMemory(device, buffer, allocation.get_memory(), allocation.get_offset()) != VK_SUCCESS)
{
allocation.free_immediate(managers.memory);
{
LOCK_MEMORY();
allocation.free_immediate(managers.memory);
}
table->vkDestroyBuffer(device, buffer, nullptr);
return BufferHandle(nullptr);
}