mirror of
https://github.com/simple64/simple64.git
synced 2026-09-08 13:22:44 +02:00
update parallel rdp
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user