update parallel rdp

This commit is contained in:
Logan McNaughton committed 2022-05-29 18:33:47 -06:00
1 parent 37f61aef57
commit b96f789d1a
108 files changed
+58317 -109283

No files matched your search

@@ -1,4 +1,4 @@
/* Copyright (c) 2017-2020 Hans-Kristian Arntzen
/* Copyright (c) 2017-2022 Hans-Kristian Arntzen
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -22,49 +22,71 @@
#include "device.hpp"
#include "timer.hpp"
#include "thread_group.hpp"
using namespace std;
namespace Vulkan
{
#if 0
void Device::register_sampler(VkSampler sampler, Fossilize::Hash hash, const VkSamplerCreateInfo &info)
{
state_recorder.record_sampler(sampler, info, hash);
if (!state_recorder.record_sampler(sampler, info, hash))
LOGW("Failed to register sampler.\n");
}
#endif
void Device::register_descriptor_set_layout(VkDescriptorSetLayout layout, Fossilize::Hash hash, const VkDescriptorSetLayoutCreateInfo &info)
{
state_recorder.record_descriptor_set_layout(layout, info, hash);
if (!state_recorder.record_descriptor_set_layout(layout, info, hash))
LOGW("Failed to register descriptor set layout.\n");
}
void Device::register_pipeline_layout(VkPipelineLayout layout, Fossilize::Hash hash, const VkPipelineLayoutCreateInfo &info)
{
state_recorder.record_pipeline_layout(layout, info, hash);
if (!state_recorder.record_pipeline_layout(layout, info, hash))
LOGW("Failed to register pipeline layout.\n");
}
void Device::register_shader_module(VkShaderModule module, Fossilize::Hash hash, const VkShaderModuleCreateInfo &info)
{
state_recorder.record_shader_module(module, info, hash);
if (!state_recorder.record_shader_module(module, info, hash))
LOGW("Failed to register shader module.\n");
}
void Device::register_compute_pipeline(Fossilize::Hash hash, const VkComputePipelineCreateInfo &info)
{
state_recorder.record_compute_pipeline(VK_NULL_HANDLE, info, nullptr, 0, hash);
if (!state_recorder.record_compute_pipeline(VK_NULL_HANDLE, info, nullptr, 0, hash))
LOGW("Failed to register compute pipeline.\n");
}
void Device::register_graphics_pipeline(Fossilize::Hash hash, const VkGraphicsPipelineCreateInfo &info)
{
state_recorder.record_graphics_pipeline(VK_NULL_HANDLE, info, nullptr, 0, hash);
if (!state_recorder.record_graphics_pipeline(VK_NULL_HANDLE, info, nullptr, 0, hash))
LOGW("Failed to register graphics pipeline.\n");
}
void Device::register_render_pass(VkRenderPass render_pass, Fossilize::Hash hash, const VkRenderPassCreateInfo &info)
{
state_recorder.record_render_pass(render_pass, info, hash);
if (!state_recorder.record_render_pass(render_pass, info, hash))
LOGW("Failed to register render pass.\n");
}
bool Device::enqueue_create_shader_module(Fossilize::Hash hash, const VkShaderModuleCreateInfo *create_info, VkShaderModule *module)
{
auto *ret = shaders.emplace_yield(hash, hash, this, create_info->pCode, create_info->codeSize);
if (!replayer_state.feature_filter->shader_module_is_supported(create_info))
return false;
ResourceLayout layout;
Shader *ret;
// If we know the resource layout already, just reuse that. Avoids spinning up SPIRV-Cross reflection
// and allows us to not even build it for release builds.
if (shader_manager.get_resource_layout_by_shader_hash(hash, layout))
ret = shaders.emplace_yield(hash, hash, this, create_info->pCode, create_info->codeSize, &layout);
else
ret = shaders.emplace_yield(hash, hash, this, create_info->pCode, create_info->codeSize);
*module = ret->get_module();
replayer_state.shader_map[*module] = ret;
return true;
@@ -76,7 +98,8 @@ void Device::notify_replayed_resources_for_type()
if (replayer_state.pipeline_group)
{
replayer_state.pipeline_group->wait();
replayer_state.pipeline_group.reset();
replayer_state.pipeline_group->release_reference();
replayer_state.pipeline_group = nullptr;
}
#endif
}
@@ -107,7 +130,10 @@ VkPipeline Device::fossilize_create_graphics_pipeline(Fossilize::Hash hash, VkGr
register_graphics_pipeline(hash, info);
LOGI("Creating graphics pipeline.\n");
#ifdef VULKAN_DEBUG
LOGI("Replaying graphics pipeline.\n");
#endif
VkPipeline pipeline = VK_NULL_HANDLE;
VkResult res = table->vkCreateGraphicsPipelines(device, pipeline_cache, 1, &info, nullptr, &pipeline);
if (res != VK_SUCCESS)
@@ -129,7 +155,9 @@ VkPipeline Device::fossilize_create_compute_pipeline(Fossilize::Hash hash, VkCom
register_compute_pipeline(hash, info);
LOGI("Creating compute pipeline.\n");
#ifdef VULKAN_DEBUG
LOGI("Replaying compute pipeline.\n");
#endif
VkPipeline pipeline = VK_NULL_HANDLE;
VkResult res = table->vkCreateComputePipelines(device, pipeline_cache, 1, &info, nullptr, &pipeline);
if (res != VK_SUCCESS)
@@ -141,15 +169,26 @@ bool Device::enqueue_create_graphics_pipeline(Fossilize::Hash hash,
const VkGraphicsPipelineCreateInfo *create_info,
VkPipeline *pipeline)
{
if (!replayer_state.feature_filter->graphics_pipeline_is_supported(create_info))
return false;
#ifdef GRANITE_VULKAN_MT
if (!replayer_state.pipeline_group)
replayer_state.pipeline_group = Granite::Global::thread_group()->create_task();
if (!replayer_state.pipeline_group && get_system_handles().thread_group)
replayer_state.pipeline_group = get_system_handles().thread_group->create_task().release();
replayer_state.pipeline_group->enqueue_task([this, info = *create_info, hash, pipeline]() mutable {
if (replayer_state.pipeline_group)
{
replayer_state.pipeline_group->enqueue_task([this, info = *create_info, hash, pipeline]() mutable {
*pipeline = fossilize_create_graphics_pipeline(hash, info);
});
return true;
}
else
{
auto info = *create_info;
*pipeline = fossilize_create_graphics_pipeline(hash, info);
});
return true;
return *pipeline != VK_NULL_HANDLE;
}
#else
auto info = *create_info;
*pipeline = fossilize_create_graphics_pipeline(hash, info);
@@ -161,15 +200,26 @@ bool Device::enqueue_create_compute_pipeline(Fossilize::Hash hash,
const VkComputePipelineCreateInfo *create_info,
VkPipeline *pipeline)
{
if (!replayer_state.feature_filter->compute_pipeline_is_supported(create_info))
return false;
#ifdef GRANITE_VULKAN_MT
if (!replayer_state.pipeline_group)
replayer_state.pipeline_group = Granite::Global::thread_group()->create_task();
if (!replayer_state.pipeline_group && get_system_handles().thread_group)
replayer_state.pipeline_group = get_system_handles().thread_group->create_task().release();
replayer_state.pipeline_group->enqueue_task([this, info = *create_info, hash, pipeline]() mutable {
if (replayer_state.pipeline_group)
{
replayer_state.pipeline_group->enqueue_task([this, info = *create_info, hash, pipeline]() mutable {
*pipeline = fossilize_create_compute_pipeline(hash, info);
});
return true;
}
else
{
auto info = *create_info;
*pipeline = fossilize_create_compute_pipeline(hash, info);
});
return true;
return *pipeline != VK_NULL_HANDLE;
}
#else
auto info = *create_info;
*pipeline = fossilize_create_compute_pipeline(hash, info);
@@ -181,16 +231,31 @@ bool Device::enqueue_create_render_pass(Fossilize::Hash hash,
const VkRenderPassCreateInfo *create_info,
VkRenderPass *render_pass)
{
if (!replayer_state.feature_filter->render_pass_is_supported(create_info))
return false;
auto *ret = render_passes.emplace_yield(hash, hash, this, *create_info);
*render_pass = ret->get_render_pass();
replayer_state.render_pass_map[*render_pass] = ret;
return true;
}
bool Device::enqueue_create_sampler(Fossilize::Hash hash, const VkSamplerCreateInfo *, VkSampler *sampler)
bool Device::enqueue_create_render_pass2(Fossilize::Hash, const VkRenderPassCreateInfo2 *, VkRenderPass *)
{
*sampler = get_stock_sampler(static_cast<StockSampler>(hash & 0xffffu)).get_sampler();
return true;
return false;
}
bool Device::enqueue_create_raytracing_pipeline(
Fossilize::Hash, const VkRayTracingPipelineCreateInfoKHR *, VkPipeline *)
{
return false;
}
bool Device::enqueue_create_sampler(Fossilize::Hash, const VkSamplerCreateInfo *, VkSampler *)
{
//*sampler = get_stock_sampler(static_cast<StockSampler>(hash & 0xffffu)).get_sampler();
//return true;
return false;
}
bool Device::enqueue_create_descriptor_set_layout(Fossilize::Hash, const VkDescriptorSetLayoutCreateInfo *, VkDescriptorSetLayout *layout)
@@ -207,13 +272,16 @@ bool Device::enqueue_create_pipeline_layout(Fossilize::Hash, const VkPipelineLay
return true;
}
void Device::init_pipeline_state()
void Device::init_pipeline_state(const Fossilize::FeatureFilter &filter)
{
replayer_state.feature_filter = &filter;
state_recorder.init_recording_thread(nullptr);
if (!get_system_handles().filesystem)
return;
auto file = Granite::Global::filesystem()->open("assets://pipelines.json", Granite::FileMode::ReadOnly);
auto file = get_system_handles().filesystem->open("assets://pipelines.json", Granite::FileMode::ReadOnly);
if (!file)
file = Granite::Global::filesystem()->open("cache://pipelines.json", Granite::FileMode::ReadOnly);
file = get_system_handles().filesystem->open("cache://pipelines.json", Granite::FileMode::ReadOnly);
if (!file)
return;
@@ -228,14 +296,25 @@ void Device::init_pipeline_state()
LOGI("Replaying cached state.\n");
Fossilize::StateReplayer replayer;
auto start = Util::get_current_time_nsecs();
replayer.parse(*this, nullptr, static_cast<const char *>(mapped), file->get_size());
if (!replayer.parse(*this, nullptr, static_cast<const char *>(mapped), file->get_size()))
LOGE("Failed to parse Fossilize archive.\n");
auto end = Util::get_current_time_nsecs();
LOGI("Completed replaying cached state in %.3f ms.\n", (end - start) * 1e-6);
if (replayer_state.pipeline_group)
{
replayer_state.pipeline_group->wait();
replayer_state.pipeline_group->release_reference();
}
replayer_state = {};
promote_read_write_caches_to_read_only();
}
void Device::flush_pipeline_state()
{
if (!get_system_handles().filesystem)
return;
uint8_t *serialized = nullptr;
size_t serialized_size = 0;
if (!state_recorder.serialize(&serialized, &serialized_size))
@@ -244,7 +323,8 @@ void Device::flush_pipeline_state()
return;
}
auto file = Granite::Global::filesystem()->open("cache://pipelines.json", Granite::FileMode::WriteOnly);
auto file = get_system_handles().filesystem->open("cache://pipelines.json",
Granite::FileMode::WriteOnlyTransactional);
if (file)
{
auto *data = static_cast<uint8_t *>(file->map_write(serialized_size));
@@ -257,6 +337,6 @@ void Device::flush_pipeline_state()
LOGE("Failed to serialize pipeline data.\n");
}
state_recorder.free_serialized(serialized);
Fossilize::StateRecorder::free_serialized(serialized);
}
}