Skip to content

Commit

Permalink
Add back shader reloading for the render graph
Browse files Browse the repository at this point in the history
  • Loading branch information
yuphin committed Nov 20, 2022
1 parent 3342ad8 commit d3385d0
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 24 deletions.
2 changes: 1 addition & 1 deletion Lumen.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_CXX20_CISO646_REMOVED_WARNING;TINYEXR_USE_MINIZ;TINYEXR_USE_MINIZ</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)libs\glm;$(SolutionDir)libs\glfw\include;$(VULKAN_SDK)\Include;$(SolutionDir)libs\spdlog\include;$(SolutionDir)src;$(SolutionDir)libs\stb_image;$(SolutionDir)libs\gli;$(SolutionDir)libs\tinygltf;$(SolutionDir)libs\imgui;$(SolutionDir)libs\nvvk;$(SolutionDir)libs;C:\VulkanSDK\1.3.216.0\Include</AdditionalIncludeDirectories>
<LanguageStandard>stdcpplatest</LanguageStandard>
<LanguageStandard>stdcpp20</LanguageStandard>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>LumenPCH.h</PrecompiledHeaderFile>
Expand Down
4 changes: 2 additions & 2 deletions src/Framework/Pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#include "Pipeline.h"
#include "VkUtils.h"

Pipeline::Pipeline(VulkanContext* ctx, size_t pass_idx, const std::string& name)
: ctx(ctx), pass_idx(pass_idx), name(name) {}
Pipeline::Pipeline(VulkanContext* ctx, const std::string& name)
: ctx(ctx),name(name) {}

void Pipeline::reload() {}

Expand Down
3 changes: 1 addition & 2 deletions src/Framework/Pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ struct PipelineTrace {
struct Pipeline {
public:
enum class PipelineType { GFX = 0, RT = 1, COMPUTE = 2 };
Pipeline(VulkanContext* ctx, size_t pass_idx, const std::string& name);
Pipeline(VulkanContext* ctx, const std::string& name);
void reload();
void cleanup();
void create_gfx_pipeline(const GraphicsPassSettings& settings, const std::vector<uint32_t>& descriptor_counts,
Expand Down Expand Up @@ -55,7 +55,6 @@ struct Pipeline {
VkWriteDescriptorSetAccelerationStructureKHR tlas_info = {};
SBTWrapper sbt_wrapper;
PipelineType type;
size_t pass_idx;
bool running = true;
VkDescriptorUpdateTemplate update_template = nullptr;
VkShaderStageFlags pc_stages = 0;
Expand Down
43 changes: 33 additions & 10 deletions src/Framework/RenderGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// Possible solution: Make compilation with debugPrintf shaders synchronous?

#define DIRTY_CHECK(x) \
if (!x) { \
if (!(x)) { \
return *this; \
}
static VkPipelineStageFlags get_pipeline_stage(PassType pass_type, VkAccessFlags access_flags) {
Expand Down Expand Up @@ -292,14 +292,22 @@ RenderPass& RenderGraph::add_rt(const std::string& name, const RTPassSettings& s
auto& storage = pipeline_cache[name];
if (!recording && storage.pass_idxs.size()) {
auto idx = storage.pass_idxs[storage.offset_idx];
++storage.offset_idx;
passes[idx].active = true;
if (reload_shaders) {
if (storage.offset_idx == 0) {
pipeline_cache[name].pipeline->cleanup();
pipeline_cache[name].pipeline = std::make_unique<Pipeline>(ctx, name);
}
passes[idx].pipeline = pipeline_cache[name].pipeline.get();
}
++storage.offset_idx;
return passes[idx];
}

pipeline = pipeline_cache[name].pipeline.get();
cached = true;
} else {
pipeline_cache[name] = {std::make_unique<Pipeline>(ctx, pass_idx, name)};
pipeline_cache[name] = {std::make_unique<Pipeline>(ctx, name)};
pipeline = pipeline_cache[name].pipeline.get();
}
passes.emplace_back(PassType::RT, pipeline, name, this, pass_idx, settings, cached);
Expand All @@ -315,17 +323,24 @@ RenderPass& RenderGraph::add_gfx(const std::string& name, const GraphicsPassSett
auto& storage = pipeline_cache[name];
if (!recording && storage.pass_idxs.size()) {
auto idx = storage.pass_idxs[storage.offset_idx];
++storage.offset_idx;
auto& curr_pass = passes[idx];
curr_pass.gfx_settings->color_outputs = settings.color_outputs;
curr_pass.gfx_settings->depth_output = settings.depth_output;
curr_pass.active = true;
if (reload_shaders) {
if (storage.offset_idx == 0) {
pipeline_cache[name].pipeline->cleanup();
pipeline_cache[name].pipeline = std::make_unique<Pipeline>(ctx, name);
}
passes[idx].pipeline = pipeline_cache[name].pipeline.get();
}
++storage.offset_idx;
return curr_pass;
}
pipeline = pipeline_cache[name].pipeline.get();
cached = true;
} else {
pipeline_cache[name] = {std::make_unique<Pipeline>(ctx, pass_idx, name)};
pipeline_cache[name] = {std::make_unique<Pipeline>(ctx, name)};
pipeline = pipeline_cache[name].pipeline.get();
}
passes.emplace_back(PassType::Graphics, pipeline, name, this, pass_idx, settings, cached);
Expand All @@ -342,13 +357,20 @@ RenderPass& RenderGraph::add_compute(const std::string& name, const ComputePassS
if (!recording && storage.pass_idxs.size()) {
auto idx = storage.pass_idxs[storage.offset_idx];
passes[idx].active = true;
if (reload_shaders) {
if (storage.offset_idx == 0) {
pipeline_cache[name].pipeline->cleanup();
pipeline_cache[name].pipeline = std::make_unique<Pipeline>(ctx, name);
}
passes[idx].pipeline = pipeline_cache[name].pipeline.get();
}
++storage.offset_idx;
return passes[idx];
}
pipeline = pipeline_cache[name].pipeline.get();
cached = true;
} else {
pipeline_cache[name] = {std::make_unique<Pipeline>(ctx, pass_idx, name)};
pipeline_cache[name] = {std::make_unique<Pipeline>(ctx, name)};
pipeline = pipeline_cache[name].pipeline.get();
}
passes.emplace_back(PassType::Compute, pipeline, name, this, pass_idx, settings, cached);
Expand Down Expand Up @@ -405,7 +427,7 @@ RenderPass& RenderPass::bind_buffer_array(std::vector<Buffer>& buffers) {
}

RenderPass& RenderPass::bind_tlas(const AccelKHR& tlas) {
DIRTY_CHECK(rg->recording);
DIRTY_CHECK(rg->recording || rg->reload_shaders);
pipeline->tlas_info = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR};
pipeline->tlas_info.accelerationStructureCount = 1;
pipeline->tlas_info.pAccelerationStructures = &tlas.accel;
Expand Down Expand Up @@ -526,7 +548,7 @@ RenderPass& RenderPass::copy(const Resource& src, const Resource& dst) {
}

void RenderPass::finalize() {
if (!rg->recording) {
if (!rg->recording && !rg->reload_shaders) {
// Handle resource transitions
transition_resources();
return;
Expand Down Expand Up @@ -882,15 +904,15 @@ void RenderGraph::run(VkCommandBuffer cmd) {
img_sync_resources.resize(passes.size());

// Compile shaders and process resources
if (recording) {
if (recording || reload_shaders) {
auto cmp = [](const std::pair<Shader*, RenderPass*>& a, const std::pair<Shader*, RenderPass*>& b) {
return a.first->filename < b.first->filename;
};
std::set<std::pair<Shader*, RenderPass*>, decltype(cmp)> unique_shaders_set;
std::unordered_map<RenderPass*, std::vector<Shader*>> unique_shaders;
std::unordered_map<RenderPass*, std::vector<Shader*>> existing_shaders;

// Recording -> The pass is active by default
// Recording or reload -> The pass is active by default
for (auto i = beginning_pass_idx; i < ending_pass_idx; i++) {
if (passes[i].gfx_settings) {
for (auto& shader : passes[i].gfx_settings->shaders) {
Expand Down Expand Up @@ -1013,6 +1035,7 @@ void RenderGraph::reset(VkCommandBuffer cmd) {
buffer_sync_resources.clear();
img_sync_resources.clear();
beginning_pass_idx = ending_pass_idx = 0;
reload_shaders = false;
}

void RenderGraph::submit(CommandBuffer& cmd) {
Expand Down
4 changes: 2 additions & 2 deletions src/Framework/RenderGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class RenderGraph {
void destroy();
friend RenderPass;
bool recording = true;
bool reload_shaders = false;
EventPool event_pool;
std::unordered_map<std::string, Buffer*> registered_buffer_pointers;
std::unordered_map<std::string, Shader> shader_cache;
Expand All @@ -58,8 +59,7 @@ class RenderGraph {

struct PipelineStorage {
std::unique_ptr<Pipeline> pipeline;
uint32_t offset_idx; // Offset index relative to the pass_idx the
// pipeline holds
uint32_t offset_idx;
std::vector<uint32_t> pass_idxs;
};
VulkanContext* ctx = nullptr;
Expand Down
18 changes: 11 additions & 7 deletions src/RayTracer/RayTracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,7 @@ float RayTracer::draw_frame() {

bool gui_updated = integrator->gui();
updated |= ImGui::Checkbox("Enable ACES tonemapping", &settings.enable_tonemapping);
if (updated || gui_updated) {
ImGui::Render();
auto t_end = glfwGetTime() * 1000;
auto t_diff = t_end - t_begin;
integrator->updated = true;
return (float)t_diff;
}

ImGui::Checkbox("Show camera statistics", &show_cam_stats);
if (show_cam_stats) {
ImGui::PushItemWidth(170);
Expand All @@ -201,9 +195,19 @@ float RayTracer::draw_frame() {
}
if (ImGui::Button("Reload shaders")) {
// TODO
vkb.rg->reload_shaders = true;
vkb.rg->shader_cache.clear();
updated |= true;
}

if (updated || gui_updated) {
ImGui::Render();
auto t_end = glfwGetTime() * 1000;
auto t_diff = t_end - t_begin;
integrator->updated = true;
return (float)t_diff;
}


uint32_t image_idx = vkb.prepare_frame();

Expand Down

0 comments on commit d3385d0

Please sign in to comment.