mirror of
https://github.com/simple64/simple64.git
synced 2026-11-14 21:58:42 +01:00
update parallel rdp
This commit is contained in:
1 parent
d3a26d3959
commit
14e7485541
24 files changed
+1295
-391
No files matched your search
@@ -100,66 +100,147 @@ Device::Device()
|
||||
#endif
|
||||
}
|
||||
|
||||
Semaphore Device::request_legacy_semaphore()
|
||||
Semaphore Device::request_semaphore(VkSemaphoreTypeKHR type, VkSemaphore vk_semaphore, bool transfer_ownership)
|
||||
{
|
||||
LOCK();
|
||||
auto semaphore = managers.semaphore.request_cleared_semaphore();
|
||||
Semaphore ptr(handle_pool.semaphores.allocate(this, semaphore, false));
|
||||
if (type == VK_SEMAPHORE_TYPE_TIMELINE_KHR && !ext.timeline_semaphore_features.timelineSemaphore)
|
||||
{
|
||||
LOGE("Timeline semaphores not supported.\n");
|
||||
return Semaphore{};
|
||||
}
|
||||
|
||||
if (vk_semaphore == VK_NULL_HANDLE)
|
||||
{
|
||||
if (type == VK_SEMAPHORE_TYPE_BINARY_KHR)
|
||||
{
|
||||
LOCK();
|
||||
vk_semaphore = managers.semaphore.request_cleared_semaphore();
|
||||
}
|
||||
else
|
||||
{
|
||||
VkSemaphoreTypeCreateInfoKHR type_info = { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR };
|
||||
VkSemaphoreCreateInfo info = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
|
||||
info.pNext = &type_info;
|
||||
type_info.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE_KHR;
|
||||
type_info.initialValue = 0;
|
||||
if (table->vkCreateSemaphore(device, &info, nullptr, &vk_semaphore) != VK_SUCCESS)
|
||||
{
|
||||
LOGE("Failed to create semaphore.\n");
|
||||
return Semaphore{};
|
||||
}
|
||||
}
|
||||
transfer_ownership = true;
|
||||
}
|
||||
|
||||
if (type == VK_SEMAPHORE_TYPE_BINARY_KHR)
|
||||
{
|
||||
Semaphore ptr(handle_pool.semaphores.allocate(this, vk_semaphore, false, transfer_ownership));
|
||||
return ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
Semaphore ptr(handle_pool.semaphores.allocate(this, 0, vk_semaphore, transfer_ownership));
|
||||
ptr->set_proxy_timeline();
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
Semaphore Device::request_timeline_semaphore_as_binary(const SemaphoreHolder &holder, uint64_t value)
|
||||
{
|
||||
VK_ASSERT(holder.get_semaphore_type() == VK_SEMAPHORE_TYPE_TIMELINE_KHR);
|
||||
VK_ASSERT(holder.is_proxy_timeline());
|
||||
Semaphore ptr(handle_pool.semaphores.allocate(this, value, holder.get_semaphore(), false));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
Semaphore Device::request_semaphore_external(VkSemaphoreTypeKHR type,
|
||||
VkExternalSemaphoreHandleTypeFlagBits handle_type)
|
||||
{
|
||||
if (type == VK_SEMAPHORE_TYPE_TIMELINE_KHR && !ext.timeline_semaphore_features.timelineSemaphore)
|
||||
{
|
||||
LOGE("Timeline semaphores not supported.\n");
|
||||
return Semaphore{};
|
||||
}
|
||||
|
||||
if (!ext.supports_external)
|
||||
{
|
||||
LOGE("External semaphores not supported.\n");
|
||||
return Semaphore{};
|
||||
}
|
||||
|
||||
VkSemaphoreTypeCreateInfoKHR type_info = { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR };
|
||||
type_info.semaphoreType = type;
|
||||
VkExternalSemaphoreFeatureFlags features;
|
||||
|
||||
{
|
||||
VkExternalSemaphoreProperties props = { VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES };
|
||||
VkPhysicalDeviceExternalSemaphoreInfo info = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO };
|
||||
info.handleType = handle_type;
|
||||
|
||||
// Workaround AMD Windows bug where it reports TIMELINE as not supported.
|
||||
// D3D12_FENCE used to be BINARY type before timelines were introduced to Vulkan.
|
||||
if (type != VK_SEMAPHORE_TYPE_BINARY_KHR && handle_type != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT)
|
||||
info.pNext = &type_info;
|
||||
vkGetPhysicalDeviceExternalSemaphoreProperties(gpu, &info, &props);
|
||||
|
||||
features = props.externalSemaphoreFeatures;
|
||||
|
||||
if (!features)
|
||||
{
|
||||
LOGE("External semaphore handle type #%x is not supported.\n", handle_type);
|
||||
return Semaphore{};
|
||||
}
|
||||
}
|
||||
|
||||
VkSemaphoreCreateInfo info = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
|
||||
VkExportSemaphoreCreateInfo export_info = { VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO };
|
||||
|
||||
if ((features & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT) != 0)
|
||||
{
|
||||
export_info.handleTypes = handle_type;
|
||||
export_info.pNext = info.pNext;
|
||||
info.pNext = &export_info;
|
||||
}
|
||||
|
||||
if (type != VK_SEMAPHORE_TYPE_BINARY_KHR)
|
||||
{
|
||||
type_info.pNext = info.pNext;
|
||||
info.pNext = &type_info;
|
||||
}
|
||||
|
||||
VkSemaphore semaphore;
|
||||
if (table->vkCreateSemaphore(device, &info, nullptr, &semaphore) != VK_SUCCESS)
|
||||
{
|
||||
LOGE("Failed to create external semaphore.\n");
|
||||
return Semaphore{};
|
||||
}
|
||||
|
||||
if (type == VK_SEMAPHORE_TYPE_TIMELINE_KHR)
|
||||
{
|
||||
Semaphore ptr(handle_pool.semaphores.allocate(this, 0, semaphore, true));
|
||||
ptr->set_external_object_compatible(handle_type, features);
|
||||
ptr->set_proxy_timeline();
|
||||
return ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
Semaphore ptr(handle_pool.semaphores.allocate(this, semaphore, false, true));
|
||||
ptr->set_external_object_compatible(handle_type, features);
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
Semaphore Device::request_proxy_semaphore()
|
||||
{
|
||||
LOCK();
|
||||
Semaphore ptr(handle_pool.semaphores.allocate(this));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
Semaphore Device::request_external_semaphore(VkSemaphore semaphore, bool signalled)
|
||||
{
|
||||
LOCK();
|
||||
VK_ASSERT(semaphore);
|
||||
Semaphore ptr(handle_pool.semaphores.allocate(this, semaphore, signalled));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
Semaphore Device::request_imported_semaphore(int fd, VkExternalSemaphoreHandleTypeFlagBits handle_type)
|
||||
{
|
||||
LOCK();
|
||||
if (!ext.supports_external)
|
||||
return {};
|
||||
|
||||
VkExternalSemaphoreProperties props = { VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES };
|
||||
VkPhysicalDeviceExternalSemaphoreInfo info = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO };
|
||||
info.handleType = handle_type;
|
||||
|
||||
vkGetPhysicalDeviceExternalSemaphoreProperties(gpu, &info, &props);
|
||||
if ((props.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT) == 0)
|
||||
return Semaphore(nullptr);
|
||||
|
||||
auto semaphore = managers.semaphore.request_cleared_semaphore();
|
||||
|
||||
VkImportSemaphoreFdInfoKHR import = { VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR };
|
||||
import.fd = fd;
|
||||
import.semaphore = semaphore;
|
||||
import.handleType = handle_type;
|
||||
import.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT;
|
||||
Semaphore ptr(handle_pool.semaphores.allocate(this, semaphore, false));
|
||||
|
||||
if (table->vkImportSemaphoreFdKHR(device, &import) != VK_SUCCESS)
|
||||
return Semaphore(nullptr);
|
||||
|
||||
ptr->signal_external();
|
||||
ptr->destroy_on_consume();
|
||||
return ptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Device::add_wait_semaphore(CommandBuffer::Type type, Semaphore semaphore, VkPipelineStageFlags stages, bool flush)
|
||||
{
|
||||
VK_ASSERT(!semaphore->is_proxy_timeline());
|
||||
|
||||
LOCK();
|
||||
add_wait_semaphore_nolock(get_physical_queue_type(type), semaphore, stages, flush);
|
||||
add_wait_semaphore_nolock(get_physical_queue_type(type), std::move(semaphore), stages, flush);
|
||||
}
|
||||
|
||||
void Device::add_wait_semaphore_nolock(QueueIndices physical_type, Semaphore semaphore, VkPipelineStageFlags stages,
|
||||
@@ -175,7 +256,7 @@ void Device::add_wait_semaphore_nolock(QueueIndices physical_type, Semaphore sem
|
||||
VK_ASSERT(sem.get() != semaphore.get());
|
||||
#endif
|
||||
|
||||
semaphore->signal_pending_wait();
|
||||
semaphore->set_pending_wait();
|
||||
data.wait_semaphores.push_back(semaphore);
|
||||
data.wait_stages.push_back(stages);
|
||||
data.need_fence = true;
|
||||
@@ -721,6 +802,11 @@ void Device::init_workarounds()
|
||||
workarounds.split_binary_timeline_semaphores = true;
|
||||
}
|
||||
}
|
||||
else if (ext.driver_properties.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY)
|
||||
{
|
||||
LOGW("Disabling pipeline cache control.\n");
|
||||
workarounds.broken_pipeline_cache_control = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1089,7 +1175,7 @@ void Device::submit_nolock(CommandBufferHandle cmd, Fence *fence, unsigned semap
|
||||
{
|
||||
LOGI("Submitting profiled command buffer, draining GPU.\n");
|
||||
Fence drain_fence;
|
||||
submit_empty_nolock(physical_type, &drain_fence, 0, nullptr, -1);
|
||||
submit_empty_nolock(physical_type, &drain_fence, nullptr, -1);
|
||||
drain_fence->wait();
|
||||
drain_fence->set_internal_sync_object();
|
||||
}
|
||||
@@ -1102,6 +1188,7 @@ void Device::submit_nolock(CommandBufferHandle cmd, Fence *fence, unsigned semap
|
||||
if (fence || semaphore_count)
|
||||
{
|
||||
submit_queue(physical_type, fence ? &signalled_fence : nullptr,
|
||||
nullptr,
|
||||
semaphore_count, semaphores,
|
||||
profiled_submit ? 0 : -1);
|
||||
}
|
||||
@@ -1121,7 +1208,7 @@ void Device::submit_nolock(CommandBufferHandle cmd, Fence *fence, unsigned semap
|
||||
LOGI("Submitted profiled command buffer, draining GPU and report ...\n");
|
||||
auto &query_pool = get_performance_query_pool(physical_type);
|
||||
Fence drain_fence;
|
||||
submit_empty_nolock(physical_type, &drain_fence, 0, nullptr, fence || semaphore_count ? -1 : 0);
|
||||
submit_empty_nolock(physical_type, &drain_fence, nullptr, fence || semaphore_count ? -1 : 0);
|
||||
drain_fence->wait();
|
||||
drain_fence->set_internal_sync_object();
|
||||
query_pool.report();
|
||||
@@ -1130,21 +1217,24 @@ void Device::submit_nolock(CommandBufferHandle cmd, Fence *fence, unsigned semap
|
||||
decrement_frame_counter_nolock();
|
||||
}
|
||||
|
||||
void Device::submit_empty(CommandBuffer::Type type, Fence *fence,
|
||||
unsigned semaphore_count, Semaphore *semaphores)
|
||||
void Device::submit_empty(CommandBuffer::Type type, Fence *fence, SemaphoreHolder *semaphore)
|
||||
{
|
||||
VK_ASSERT(!semaphore || !semaphore->is_proxy_timeline());
|
||||
LOCK();
|
||||
submit_empty_nolock(get_physical_queue_type(type), fence, semaphore_count, semaphores, -1);
|
||||
submit_empty_nolock(get_physical_queue_type(type), fence, semaphore, -1);
|
||||
}
|
||||
|
||||
void Device::submit_empty_nolock(QueueIndices physical_type, Fence *fence,
|
||||
unsigned semaphore_count, Semaphore *semaphores, int profiling_iteration)
|
||||
SemaphoreHolder *semaphore, int profiling_iteration)
|
||||
{
|
||||
if (physical_type != QUEUE_INDEX_TRANSFER)
|
||||
flush_frame(QUEUE_INDEX_TRANSFER);
|
||||
|
||||
InternalFence signalled_fence;
|
||||
submit_queue(physical_type, fence ? &signalled_fence : nullptr, semaphore_count, semaphores, profiling_iteration);
|
||||
|
||||
submit_queue(physical_type, fence ? &signalled_fence : nullptr, semaphore,
|
||||
0, nullptr, profiling_iteration);
|
||||
|
||||
if (fence)
|
||||
{
|
||||
if (signalled_fence.value)
|
||||
@@ -1155,6 +1245,7 @@ void Device::submit_empty_nolock(QueueIndices physical_type, Fence *fence,
|
||||
}
|
||||
|
||||
void Device::submit_empty_inner(QueueIndices physical_type, InternalFence *fence,
|
||||
SemaphoreHolder *external_semaphore,
|
||||
unsigned semaphore_count, Semaphore *semaphores)
|
||||
{
|
||||
auto &data = queue_data[physical_type];
|
||||
@@ -1168,7 +1259,9 @@ void Device::submit_empty_inner(QueueIndices physical_type, InternalFence *fence
|
||||
Helper::BatchComposer composer(get_workarounds().split_binary_timeline_semaphores);
|
||||
collect_wait_semaphores(data, wait_semaphores);
|
||||
composer.add_wait_submissions(wait_semaphores);
|
||||
emit_queue_signals(composer, timeline_semaphore, timeline_value,
|
||||
|
||||
emit_queue_signals(composer, external_semaphore,
|
||||
timeline_semaphore, timeline_value,
|
||||
fence, semaphore_count, semaphores);
|
||||
|
||||
VkFence cleared_fence = fence && !ext.timeline_semaphore_features.timelineSemaphore ?
|
||||
@@ -1287,7 +1380,7 @@ void Device::collect_wait_semaphores(QueueData &data, Helper::WaitSemaphores &se
|
||||
{
|
||||
auto &semaphore = data.wait_semaphores[i];
|
||||
auto vk_semaphore = semaphore->consume();
|
||||
if (semaphore->get_timeline_value())
|
||||
if (semaphore->get_semaphore_type() == VK_SEMAPHORE_TYPE_TIMELINE_KHR)
|
||||
{
|
||||
sem.timeline_waits.push_back(vk_semaphore);
|
||||
sem.timeline_wait_stages.push_back(data.wait_stages[i]);
|
||||
@@ -1295,10 +1388,10 @@ void Device::collect_wait_semaphores(QueueData &data, Helper::WaitSemaphores &se
|
||||
}
|
||||
else
|
||||
{
|
||||
if (semaphore->can_recycle())
|
||||
frame().recycled_semaphores.push_back(vk_semaphore);
|
||||
else
|
||||
if (semaphore->is_external_object_compatible())
|
||||
frame().destroyed_semaphores.push_back(vk_semaphore);
|
||||
else
|
||||
frame().recycled_semaphores.push_back(vk_semaphore);
|
||||
|
||||
sem.binary_waits.push_back(vk_semaphore);
|
||||
sem.binary_wait_stages.push_back(data.wait_stages[i]);
|
||||
@@ -1415,10 +1508,9 @@ Helper::BatchComposer::bake(int profiling_iteration)
|
||||
{
|
||||
profiling_infos[i] = { VK_STRUCTURE_TYPE_PERFORMANCE_QUERY_SUBMIT_INFO_KHR };
|
||||
profiling_infos[i].counterPassIndex = uint32_t(profiling_iteration);
|
||||
if (submit.pNext)
|
||||
timeline_submit.pNext = &profiling_infos[i];
|
||||
else
|
||||
submit.pNext = &profiling_infos[i];
|
||||
|
||||
profiling_infos[i].pNext = submit.pNext;
|
||||
submit.pNext = &profiling_infos[i];
|
||||
}
|
||||
|
||||
submit.commandBufferCount = cmds[i].size();
|
||||
@@ -1473,23 +1565,39 @@ void Helper::BatchComposer::add_wait_semaphore(SemaphoreHolder &sem, VkPipelineS
|
||||
if (!cmds[submit_index].empty() || !signals[submit_index].empty())
|
||||
begin_batch();
|
||||
|
||||
uint64_t timeline = sem.get_timeline_value();
|
||||
bool is_timeline = sem.get_semaphore_type() == VK_SEMAPHORE_TYPE_TIMELINE_KHR;
|
||||
|
||||
if (split_binary_timeline_semaphores)
|
||||
{
|
||||
if ((timeline == 0 && has_timeline_semaphore_in_batch(submit_index)) ||
|
||||
(timeline != 0 && has_binary_semaphore_in_batch(submit_index)))
|
||||
if ((!is_timeline && has_timeline_semaphore_in_batch(submit_index)) ||
|
||||
(is_timeline && has_binary_semaphore_in_batch(submit_index)))
|
||||
begin_batch();
|
||||
}
|
||||
|
||||
waits[submit_index].push_back(sem.get_semaphore());
|
||||
wait_stages[submit_index].push_back(stage);
|
||||
wait_counts[submit_index].push_back(timeline);
|
||||
wait_counts[submit_index].push_back(is_timeline ? sem.get_timeline_value() : 0);
|
||||
}
|
||||
|
||||
void Device::emit_queue_signals(Helper::BatchComposer &composer,
|
||||
SemaphoreHolder *external_semaphore,
|
||||
VkSemaphore sem, uint64_t timeline, InternalFence *fence,
|
||||
unsigned semaphore_count, Semaphore *semaphores)
|
||||
{
|
||||
if (external_semaphore)
|
||||
{
|
||||
VK_ASSERT(!external_semaphore->is_signalled());
|
||||
VK_ASSERT(!external_semaphore->is_proxy_timeline());
|
||||
VK_ASSERT(external_semaphore->get_semaphore());
|
||||
external_semaphore->signal_external();
|
||||
composer.add_signal_semaphore(external_semaphore->get_semaphore(),
|
||||
external_semaphore->get_semaphore_type() == VK_SEMAPHORE_TYPE_TIMELINE_KHR ?
|
||||
external_semaphore->get_timeline_value() : 0);
|
||||
|
||||
// Make sure we observe that the external semaphore is signalled before fences are signalled.
|
||||
composer.begin_batch();
|
||||
}
|
||||
|
||||
// Add external signal semaphores.
|
||||
if (ext.timeline_semaphore_features.timelineSemaphore)
|
||||
{
|
||||
@@ -1506,7 +1614,8 @@ void Device::emit_queue_signals(Helper::BatchComposer &composer,
|
||||
for (unsigned i = 0; i < semaphore_count; i++)
|
||||
{
|
||||
VK_ASSERT(!semaphores[i]);
|
||||
semaphores[i] = Semaphore(handle_pool.semaphores.allocate(this, timeline, sem));
|
||||
semaphores[i] = Semaphore(handle_pool.semaphores.allocate(this, timeline, sem, false));
|
||||
semaphores[i]->signal_external();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1522,7 +1631,7 @@ void Device::emit_queue_signals(Helper::BatchComposer &composer,
|
||||
VkSemaphore cleared_semaphore = managers.semaphore.request_cleared_semaphore();
|
||||
composer.add_signal_semaphore(cleared_semaphore, 0);
|
||||
VK_ASSERT(!semaphores[i]);
|
||||
semaphores[i] = Semaphore(handle_pool.semaphores.allocate(this, cleared_semaphore, true));
|
||||
semaphores[i] = Semaphore(handle_pool.semaphores.allocate(this, cleared_semaphore, true, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1556,6 +1665,7 @@ VkResult Device::submit_batches(Helper::BatchComposer &composer, VkQueue queue,
|
||||
}
|
||||
|
||||
void Device::submit_queue(QueueIndices physical_type, InternalFence *fence,
|
||||
SemaphoreHolder *external_semaphore,
|
||||
unsigned semaphore_count, Semaphore *semaphores, int profiling_iteration)
|
||||
{
|
||||
// Always check if we need to flush pending transfers.
|
||||
@@ -1568,7 +1678,7 @@ void Device::submit_queue(QueueIndices physical_type, InternalFence *fence,
|
||||
if (submissions.empty())
|
||||
{
|
||||
if (fence || semaphore_count)
|
||||
submit_empty_inner(physical_type, fence, semaphore_count, semaphores);
|
||||
submit_empty_inner(physical_type, fence, external_semaphore, semaphore_count, semaphores);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1601,12 +1711,12 @@ void Device::submit_queue(QueueIndices physical_type, InternalFence *fence,
|
||||
{
|
||||
VK_ASSERT(wsi.acquire->is_signalled());
|
||||
composer.add_wait_semaphore(*wsi.acquire, wsi_stages);
|
||||
if (!wsi.acquire->get_timeline_value())
|
||||
if (wsi.acquire->get_semaphore_type() == VK_SEMAPHORE_TYPE_BINARY_KHR)
|
||||
{
|
||||
if (wsi.acquire->can_recycle())
|
||||
frame().recycled_semaphores.push_back(wsi.acquire->get_semaphore());
|
||||
else
|
||||
if (wsi.acquire->is_external_object_compatible())
|
||||
frame().destroyed_semaphores.push_back(wsi.acquire->get_semaphore());
|
||||
else
|
||||
frame().recycled_semaphores.push_back(wsi.acquire->get_semaphore());
|
||||
}
|
||||
wsi.acquire->consume();
|
||||
wsi.acquire.reset();
|
||||
@@ -1615,7 +1725,7 @@ void Device::submit_queue(QueueIndices physical_type, InternalFence *fence,
|
||||
composer.add_command_buffer(cmd->get_command_buffer());
|
||||
|
||||
VkSemaphore release = managers.semaphore.request_cleared_semaphore();
|
||||
wsi.release = Semaphore(handle_pool.semaphores.allocate(this, release, true));
|
||||
wsi.release = Semaphore(handle_pool.semaphores.allocate(this, release, true, true));
|
||||
wsi.release->set_internal_sync_object();
|
||||
composer.add_signal_semaphore(release, 0);
|
||||
wsi.present_queue = queue;
|
||||
@@ -1637,7 +1747,7 @@ void Device::submit_queue(QueueIndices physical_type, InternalFence *fence,
|
||||
if (fence)
|
||||
fence->fence = cleared_fence;
|
||||
|
||||
emit_queue_signals(composer, timeline_semaphore, timeline_value,
|
||||
emit_queue_signals(composer, external_semaphore, timeline_semaphore, timeline_value,
|
||||
fence, semaphore_count, semaphores);
|
||||
|
||||
auto start_ts = write_calibrated_timestamp_nolock();
|
||||
@@ -1662,7 +1772,7 @@ void Device::flush_frame(QueueIndices physical_type)
|
||||
|
||||
if (physical_type == QUEUE_INDEX_TRANSFER)
|
||||
sync_buffer_blocks();
|
||||
submit_queue(physical_type, nullptr, 0, nullptr);
|
||||
submit_queue(physical_type, nullptr);
|
||||
}
|
||||
|
||||
void Device::sync_buffer_blocks()
|
||||
@@ -1731,7 +1841,7 @@ void Device::end_frame_nolock()
|
||||
{
|
||||
if (queue_data[i].need_fence || !frame().submissions[i].empty())
|
||||
{
|
||||
submit_queue(i, &fence, 0, nullptr);
|
||||
submit_queue(i, &fence);
|
||||
if (fence.fence != VK_NULL_HANDLE)
|
||||
{
|
||||
frame().wait_fences.push_back(fence.fence);
|
||||
@@ -2017,10 +2127,10 @@ void Device::init_swapchain(const vector<VkImage> &swapchain_images, unsigned wi
|
||||
VkImageViewCreateInfo view_info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
|
||||
view_info.image = image;
|
||||
view_info.format = format;
|
||||
view_info.components.r = VK_COMPONENT_SWIZZLE_R;
|
||||
view_info.components.g = VK_COMPONENT_SWIZZLE_G;
|
||||
view_info.components.b = VK_COMPONENT_SWIZZLE_B;
|
||||
view_info.components.a = VK_COMPONENT_SWIZZLE_A;
|
||||
view_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
view_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
view_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
view_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
view_info.subresourceRange.aspectMask = format_to_aspect_mask(format);
|
||||
view_info.subresourceRange.baseMipLevel = 0;
|
||||
view_info.subresourceRange.baseArrayLayer = 0;
|
||||
@@ -3255,99 +3365,6 @@ ImageViewHandle Device::create_image_view(const ImageViewCreateInfo &create_info
|
||||
return ImageViewHandle(nullptr);
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
ImageHandle Device::create_imported_image(int fd, VkDeviceSize size, uint32_t memory_type,
|
||||
VkExternalMemoryHandleTypeFlagBits handle_type,
|
||||
const ImageCreateInfo &create_info)
|
||||
{
|
||||
if (!ext.supports_external)
|
||||
return {};
|
||||
|
||||
ImageResourceHolder holder(this);
|
||||
|
||||
VkImageCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
|
||||
info.format = create_info.format;
|
||||
info.extent.width = create_info.width;
|
||||
info.extent.height = create_info.height;
|
||||
info.extent.depth = create_info.depth;
|
||||
info.imageType = create_info.type;
|
||||
info.mipLevels = create_info.levels;
|
||||
info.arrayLayers = create_info.layers;
|
||||
info.samples = create_info.samples;
|
||||
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
info.usage = create_info.usage;
|
||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
info.flags = create_info.flags;
|
||||
info.pNext = create_info.pnext;
|
||||
VK_ASSERT(create_info.domain != ImageDomain::Transient);
|
||||
|
||||
VkExternalMemoryImageCreateInfo externalInfo = { VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO };
|
||||
externalInfo.handleTypes = handle_type;
|
||||
externalInfo.pNext = info.pNext;
|
||||
info.pNext = &externalInfo;
|
||||
|
||||
VK_ASSERT(image_format_is_supported(create_info.format, image_usage_to_features(info.usage), info.tiling));
|
||||
|
||||
if (table->vkCreateImage(device, &info, nullptr, &holder.image) != VK_SUCCESS)
|
||||
return ImageHandle(nullptr);
|
||||
|
||||
VkMemoryAllocateInfo alloc_info = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
|
||||
alloc_info.allocationSize = size;
|
||||
alloc_info.memoryTypeIndex = memory_type;
|
||||
|
||||
VkMemoryDedicatedAllocateInfo dedicated_info = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO };
|
||||
dedicated_info.image = holder.image;
|
||||
alloc_info.pNext = &dedicated_info;
|
||||
|
||||
VkImportMemoryFdInfoKHR fd_info = { VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR };
|
||||
fd_info.handleType = handle_type;
|
||||
fd_info.fd = fd;
|
||||
dedicated_info.pNext = &fd_info;
|
||||
|
||||
VkMemoryRequirements reqs;
|
||||
table->vkGetImageMemoryRequirements(device, holder.image, &reqs);
|
||||
if (reqs.size > size)
|
||||
return ImageHandle(nullptr);
|
||||
|
||||
if (((1u << memory_type) & reqs.memoryTypeBits) == 0)
|
||||
return ImageHandle(nullptr);
|
||||
|
||||
if (table->vkAllocateMemory(device, &alloc_info, nullptr, &holder.memory) != VK_SUCCESS)
|
||||
return ImageHandle(nullptr);
|
||||
|
||||
if (table->vkBindImageMemory(device, holder.image, holder.memory, 0) != VK_SUCCESS)
|
||||
return ImageHandle(nullptr);
|
||||
|
||||
// Create default image views.
|
||||
// App could of course to this on its own, but it's very handy to have these being created automatically for you.
|
||||
VkImageViewType view_type = VK_IMAGE_VIEW_TYPE_MAX_ENUM;
|
||||
if (info.usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
|
||||
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
|
||||
{
|
||||
if (!holder.create_default_views(create_info, nullptr))
|
||||
return ImageHandle(nullptr);
|
||||
view_type = holder.get_default_view_type();
|
||||
}
|
||||
|
||||
auto allocation = DeviceAllocation::make_imported_allocation(holder.memory, size, memory_type);
|
||||
ImageHandle handle(handle_pool.images.allocate(this, holder.image, holder.image_view, allocation, create_info, view_type));
|
||||
if (handle)
|
||||
{
|
||||
holder.owned = false;
|
||||
handle->get_view().set_alt_views(holder.depth_view, holder.stencil_view);
|
||||
handle->get_view().set_render_target_views(move(holder.rt_views));
|
||||
|
||||
// Set possible dstStage and dstAccess.
|
||||
handle->set_stage_flags(image_usage_to_possible_stages(info.usage));
|
||||
handle->set_access_flags(image_usage_to_possible_access(info.usage));
|
||||
return handle;
|
||||
}
|
||||
else
|
||||
return ImageHandle(nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
InitialImageBuffer Device::create_image_staging_buffer(const TextureFormatLayout &layout)
|
||||
{
|
||||
InitialImageBuffer result;
|
||||
@@ -3461,8 +3478,11 @@ DeviceAllocationOwnerHandle Device::allocate_memory(const MemoryAllocateInfo &in
|
||||
return {};
|
||||
|
||||
DeviceAllocation alloc = {};
|
||||
if (!managers.memory.allocate(info.requirements.size, info.requirements.alignment, info.mode, index, &alloc))
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -3491,6 +3511,19 @@ bool Device::allocate_image_memory(DeviceAllocation *allocation, const ImageCrea
|
||||
return false;
|
||||
}
|
||||
|
||||
bool use_external = (info.misc & IMAGE_MISC_EXTERNAL_MEMORY_BIT) != 0;
|
||||
if (use_external && info.num_memory_aliases != 0)
|
||||
{
|
||||
LOGE("Cannot use external and memory aliases at the same time.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (use_external && tiling == VK_IMAGE_TILING_LINEAR)
|
||||
{
|
||||
LOGE("Cannot use linear tiling with external memory.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (info.num_memory_aliases != 0)
|
||||
{
|
||||
*allocation = {};
|
||||
@@ -3584,16 +3617,20 @@ bool Device::allocate_image_memory(DeviceAllocation *allocation, const ImageCrea
|
||||
return false;
|
||||
}
|
||||
|
||||
ExternalHandle external = info.external;
|
||||
|
||||
AllocationMode mode;
|
||||
if (tiling == VK_IMAGE_TILING_OPTIMAL &&
|
||||
(info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT)) != 0)
|
||||
if (use_external)
|
||||
mode = AllocationMode::External;
|
||||
else if (tiling == VK_IMAGE_TILING_OPTIMAL &&
|
||||
(info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT)) != 0)
|
||||
mode = AllocationMode::OptimalRenderTarget;
|
||||
else
|
||||
mode = tiling == VK_IMAGE_TILING_OPTIMAL ? AllocationMode::OptimalResource : AllocationMode::LinearHostMappable;
|
||||
|
||||
if (!managers.memory.allocate_image_memory(reqs.size, reqs.alignment, mode, memory_type,
|
||||
allocation, image,
|
||||
(info.misc & IMAGE_MISC_FORCE_NO_DEDICATED_BIT) != 0))
|
||||
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;
|
||||
@@ -3752,7 +3789,7 @@ ImageHandle Device::create_image_from_staging_buffer(const ImageCreateInfo &crea
|
||||
return ImageHandle(nullptr);
|
||||
|
||||
VkImageFormatProperties2 props = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2 };
|
||||
if (!get_image_format_properties(info.format, info.imageType, info.tiling, info.usage, info.flags, &props))
|
||||
if (!get_image_format_properties(info.format, info.imageType, info.tiling, info.usage, info.flags, nullptr, &props))
|
||||
return ImageHandle(nullptr);
|
||||
|
||||
if (!props.imageFormatProperties.maxArrayLayers ||
|
||||
@@ -3772,6 +3809,63 @@ ImageHandle Device::create_image_from_staging_buffer(const ImageCreateInfo &crea
|
||||
return ImageHandle(nullptr);
|
||||
}
|
||||
|
||||
bool use_external = (create_info.misc & IMAGE_MISC_EXTERNAL_MEMORY_BIT) != 0;
|
||||
if (use_external && create_info.domain != ImageDomain::Physical)
|
||||
{
|
||||
LOGE("Must use physical image domain for external memory images.\n");
|
||||
return ImageHandle(nullptr);
|
||||
}
|
||||
|
||||
if (use_external && !ext.supports_external)
|
||||
{
|
||||
LOGE("External memory not supported.\n");
|
||||
return ImageHandle(nullptr);
|
||||
}
|
||||
|
||||
VkExternalMemoryImageCreateInfo external_info = { VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO };
|
||||
if (ext.supports_external && use_external)
|
||||
{
|
||||
// Ensure that the handle type is supported.
|
||||
VkImageFormatProperties2 props2 = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2 };
|
||||
VkExternalImageFormatProperties external_props =
|
||||
{ VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES };
|
||||
VkPhysicalDeviceExternalImageFormatInfo external_format_info =
|
||||
{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO };
|
||||
external_format_info.handleType = create_info.external.memory_handle_type;
|
||||
|
||||
props2.pNext = &external_props;
|
||||
if (!get_image_format_properties(info.format, info.imageType, info.tiling,
|
||||
info.usage, info.flags,
|
||||
&external_format_info, &props2))
|
||||
{
|
||||
LOGE("Image format is not supported for external memory type #%x.\n",
|
||||
external_format_info.handleType);
|
||||
return ImageHandle(nullptr);
|
||||
}
|
||||
|
||||
bool supports_import = (external_props.externalMemoryProperties.externalMemoryFeatures &
|
||||
VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) != 0;
|
||||
bool supports_export = (external_props.externalMemoryProperties.externalMemoryFeatures &
|
||||
VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) != 0;
|
||||
|
||||
if (!supports_import && create_info.external)
|
||||
{
|
||||
LOGE("Attempting to import with handle type #%x, but it is not supported.\n",
|
||||
create_info.external.memory_handle_type);
|
||||
return ImageHandle(nullptr);
|
||||
}
|
||||
else if (!supports_export && !create_info.external)
|
||||
{
|
||||
LOGE("Attempting to export with handle type #%x, but it is not supported.\n",
|
||||
create_info.external.memory_handle_type);
|
||||
return ImageHandle(nullptr);
|
||||
}
|
||||
|
||||
external_info.handleTypes = create_info.external.memory_handle_type;
|
||||
external_info.pNext = info.pNext;
|
||||
info.pNext = &external_info;
|
||||
}
|
||||
|
||||
if (table->vkCreateImage(device, &info, nullptr, &holder.image) != VK_SUCCESS)
|
||||
{
|
||||
LOGE("Failed to create image in vkCreateImage.\n");
|
||||
@@ -4223,17 +4317,23 @@ BufferHandle Device::create_imported_host_buffer(const BufferCreateInfo &create_
|
||||
|
||||
BufferHandle Device::create_buffer(const BufferCreateInfo &create_info, const void *initial)
|
||||
{
|
||||
VkBuffer buffer;
|
||||
VkMemoryRequirements reqs;
|
||||
DeviceAllocation allocation;
|
||||
VkBuffer buffer;
|
||||
|
||||
bool zero_initialize = (create_info.misc & BUFFER_MISC_ZERO_INITIALIZE_BIT) != 0;
|
||||
bool use_external = (create_info.misc & BUFFER_MISC_EXTERNAL_MEMORY_BIT) != 0;
|
||||
if (initial && zero_initialize)
|
||||
{
|
||||
LOGE("Cannot initialize buffer with data and clear.\n");
|
||||
return BufferHandle{};
|
||||
}
|
||||
|
||||
if (use_external && create_info.domain != BufferDomain::Device)
|
||||
{
|
||||
LOGE("When using external memory, must be Device domain.\n");
|
||||
return BufferHandle{};
|
||||
}
|
||||
|
||||
VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
|
||||
info.size = create_info.size;
|
||||
info.usage = create_info.usage | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
@@ -4242,12 +4342,55 @@ BufferHandle Device::create_buffer(const BufferCreateInfo &create_info, const vo
|
||||
uint32_t sharing_indices[QUEUE_INDEX_COUNT];
|
||||
fill_buffer_sharing_indices(info, sharing_indices);
|
||||
|
||||
if (use_external && !ext.supports_external)
|
||||
{
|
||||
LOGE("External memory not supported.\n");
|
||||
return BufferHandle{};
|
||||
}
|
||||
|
||||
VkExternalMemoryBufferCreateInfo external_info = { VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO };
|
||||
if (ext.supports_external && use_external)
|
||||
{
|
||||
// Ensure that the handle type is supported.
|
||||
VkPhysicalDeviceExternalBufferInfo external_buffer_props_info =
|
||||
{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO };
|
||||
VkExternalBufferProperties external_buffer_props = { VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES };
|
||||
external_buffer_props_info.handleType = create_info.external.memory_handle_type;
|
||||
external_buffer_props_info.usage = info.usage;
|
||||
external_buffer_props_info.flags = info.flags;
|
||||
vkGetPhysicalDeviceExternalBufferProperties(gpu, &external_buffer_props_info, &external_buffer_props);
|
||||
|
||||
bool supports_import = (external_buffer_props.externalMemoryProperties.externalMemoryFeatures &
|
||||
VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) != 0;
|
||||
bool supports_export = (external_buffer_props.externalMemoryProperties.externalMemoryFeatures &
|
||||
VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) != 0;
|
||||
|
||||
if (!supports_import && !create_info.external)
|
||||
{
|
||||
LOGE("Attempting to import with handle type #%x, but it is not supported.\n",
|
||||
create_info.external.memory_handle_type);
|
||||
return BufferHandle{};
|
||||
}
|
||||
else if (!supports_export && create_info.external)
|
||||
{
|
||||
LOGE("Attempting to export with handle type #%x, but it is not supported.\n",
|
||||
create_info.external.memory_handle_type);
|
||||
return BufferHandle{};
|
||||
}
|
||||
|
||||
external_info.handleTypes = create_info.external.memory_handle_type;
|
||||
info.pNext = &external_info;
|
||||
}
|
||||
|
||||
if (table->vkCreateBuffer(device, &info, nullptr, &buffer) != VK_SUCCESS)
|
||||
return BufferHandle(nullptr);
|
||||
|
||||
table->vkGetBufferMemoryRequirements(device, buffer, &reqs);
|
||||
VkMemoryRequirements2 reqs = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 };
|
||||
VkBufferMemoryRequirementsInfo2 req_info = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2 };
|
||||
req_info.buffer = buffer;
|
||||
table->vkGetBufferMemoryRequirements2(device, &req_info, &reqs);
|
||||
|
||||
uint32_t memory_type = find_memory_type(create_info.domain, reqs.memoryTypeBits);
|
||||
uint32_t memory_type = find_memory_type(create_info.domain, reqs.memoryRequirements.memoryTypeBits);
|
||||
if (memory_type == UINT32_MAX)
|
||||
{
|
||||
LOGE("Failed to find memory type.\n");
|
||||
@@ -4256,7 +4399,9 @@ BufferHandle Device::create_buffer(const BufferCreateInfo &create_info, const vo
|
||||
}
|
||||
|
||||
AllocationMode mode;
|
||||
if (create_info.domain == BufferDomain::Device &&
|
||||
if ((create_info.misc & BUFFER_MISC_EXTERNAL_MEMORY_BIT) != 0)
|
||||
mode = AllocationMode::External;
|
||||
else if (create_info.domain == BufferDomain::Device &&
|
||||
(create_info.usage & (VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) != 0)
|
||||
mode = AllocationMode::LinearDeviceHighPriority;
|
||||
else if (create_info.domain == BufferDomain::Device ||
|
||||
@@ -4265,8 +4410,19 @@ BufferHandle Device::create_buffer(const BufferCreateInfo &create_info, const vo
|
||||
else
|
||||
mode = AllocationMode::LinearHostMappable;
|
||||
|
||||
if (!managers.memory.allocate(reqs.size, reqs.alignment, mode, memory_type, &allocation))
|
||||
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)
|
||||
{
|
||||
LOGE("Failed to export / import buffer memory.\n");
|
||||
table->vkDestroyBuffer(device, buffer, nullptr);
|
||||
return BufferHandle(nullptr);
|
||||
}
|
||||
|
||||
auto fallback_domain = create_info.domain;
|
||||
|
||||
// This memory type is rather scarce, so fallback to Host type if we've exhausted this memory.
|
||||
@@ -4282,11 +4438,11 @@ BufferHandle Device::create_buffer(const BufferCreateInfo &create_info, const vo
|
||||
fallback_domain = BufferDomain::Device;
|
||||
}
|
||||
|
||||
memory_type = find_memory_type(fallback_domain, reqs.memoryTypeBits);
|
||||
memory_type = find_memory_type(fallback_domain, reqs.memoryRequirements.memoryTypeBits);
|
||||
|
||||
if (memory_type == UINT32_MAX ||
|
||||
fallback_domain == create_info.domain ||
|
||||
!managers.memory.allocate(reqs.size, reqs.alignment, mode, memory_type, &allocation))
|
||||
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);
|
||||
@@ -4401,10 +4557,12 @@ void Device::get_format_properties(VkFormat format, VkFormatProperties3KHR *prop
|
||||
|
||||
bool Device::get_image_format_properties(VkFormat format, VkImageType type, VkImageTiling tiling,
|
||||
VkImageUsageFlags usage, VkImageCreateFlags flags,
|
||||
const void *pNext,
|
||||
VkImageFormatProperties2 *properties2) const
|
||||
{
|
||||
VK_ASSERT(properties2->sType == VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2);
|
||||
VkPhysicalDeviceImageFormatInfo2 info = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 };
|
||||
info.pNext = pNext;
|
||||
info.format = format;
|
||||
info.type = type;
|
||||
info.tiling = tiling;
|
||||
@@ -4698,18 +4856,9 @@ void Device::query_available_performance_counters(CommandBuffer::Type type, uint
|
||||
*desc = query_pool.get_available_counter_descs();
|
||||
}
|
||||
|
||||
bool Device::init_performance_counters(const std::vector<std::string> &names)
|
||||
bool Device::init_performance_counters(CommandBuffer::Type type, const std::vector<std::string> &names)
|
||||
{
|
||||
for (int i = 0; i < QUEUE_INDEX_COUNT; i++)
|
||||
{
|
||||
if (&get_performance_query_pool(QueueIndices(i)) == &queue_data[i].performance_query_pool)
|
||||
{
|
||||
if (!queue_data[i].performance_query_pool.init_counters(names))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return queue_data[get_physical_queue_type(type)].performance_query_pool.init_counters(names);
|
||||
}
|
||||
|
||||
void Device::release_profiling()
|
||||
|
||||
Reference in new issue
Block a user