Skip to content

Commit

Permalink
Allow to manually reset spatial radiance cache
Browse files Browse the repository at this point in the history
  • Loading branch information
sergcpp committed May 31, 2024
1 parent 8ed5b28 commit fe3f1db
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 1 deletion.
7 changes: 7 additions & 0 deletions RendererBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,13 @@ class RendererBase {
const SceneBase &scene,
const std::function<void(int, int, ParallelForFunction &&)> &parallel_for = parallel_for_serial) = 0;

/** @brief Reset spatial radiance cache
@param scene reference to a scene
*/
virtual void ResetSpatialCache(
const SceneBase &scene,
const std::function<void(int, int, ParallelForFunction &&)> &parallel_for = parallel_for_serial) = 0;

/// Structure that holds render timings (in microseconds)
struct stats_t {
unsigned long long time_primary_ray_gen_us;
Expand Down
19 changes: 19 additions & 0 deletions internal/RendererCPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ template <typename SIMDPolicy> class Renderer : public RendererBase, private SIM
void UpdateSpatialCache(const SceneBase &scene, RegionContext &region) override;
void ResolveSpatialCache(const SceneBase &scene,
const std::function<void(int, int, ParallelForFunction &&)> &parallel_for) override;
void ResetSpatialCache(const SceneBase &scene,
const std::function<void(int, int, ParallelForFunction &&)> &parallel_for) override;

void GetStats(stats_t &st) override { st = stats_; }
void ResetStats() override { stats_ = {0}; }
Expand Down Expand Up @@ -1197,6 +1199,23 @@ void Ray::Cpu::Renderer<SIMDPolicy>::ResolveSpatialCache(
}
}

template <typename SIMDPolicy>
void Ray::Cpu::Renderer<SIMDPolicy>::ResetSpatialCache(
const SceneBase &scene, const std::function<void(int, int, ParallelForFunction &&)> &parallel_for) {
const auto &s = dynamic_cast<const Cpu::Scene &>(scene);

std::shared_lock<std::shared_timed_mutex> scene_lock(s.mtx_);

static const int ResetPortion = 32768 * 4;
assert((s.spatial_cache_entries_.size() % ResetPortion) == 0);
const int JobsCount = int(s.spatial_cache_entries_.size() / ResetPortion);

parallel_for(0, JobsCount, [&](const int i) {
auto it = begin(s.spatial_cache_voxels_prev_) + i * ResetPortion;
std::fill(it, it + ResetPortion, packed_cache_voxel_t{});
});
}

template <typename SIMDPolicy>
void Ray::Cpu::Renderer<SIMDPolicy>::UpdateFilterTable(ePixelFilter filter, float filter_width) {
float (*filter_func)(float v, float width);
Expand Down
78 changes: 78 additions & 0 deletions internal/RendererDX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1669,6 +1669,84 @@ void Ray::Dx::Renderer::ResolveSpatialCache(const SceneBase &scene,
#endif
}

void Ray::Dx::Renderer::ResetSpatialCache(const SceneBase &scene,
const std::function<void(int, int, ParallelForFunction &&)> &) {
if (!use_spatial_cache_) {
return;
}

const auto &s = dynamic_cast<const Dx::Scene &>(scene);

#if !RUN_IN_LOCKSTEP
if (ctx_->in_flight_fence(ctx_->backend_frame)->GetCompletedValue() < ctx_->fence_values[ctx_->backend_frame]) {
HRESULT hr = ctx_->in_flight_fence(ctx_->backend_frame)
->SetEventOnCompletion(ctx_->fence_values[ctx_->backend_frame], ctx_->fence_event());
if (FAILED(hr)) {
return;
}

WaitForSingleObject(ctx_->fence_event(), INFINITE);
}

++ctx_->fence_values[ctx_->backend_frame];
#endif

ctx_->ReadbackTimestampQueries(ctx_->backend_frame);
ctx_->DestroyDeferredResources(ctx_->backend_frame);
ctx_->default_descr_alloc()->Reset();
ctx_->uniform_data_buf_offs[ctx_->backend_frame] = 0;

#if RUN_IN_LOCKSTEP
CommandBuffer cmd_buf = BegSingleTimeCommands(ctx_->api(), ctx_->device(), ctx_->temp_command_pool());
#else
ID3D12CommandAllocator *cmd_alloc = ctx_->draw_cmd_alloc(ctx_->backend_frame);
CommandBuffer cmd_buf = ctx_->draw_cmd_buf();

HRESULT hr = cmd_alloc->Reset();
if (FAILED(hr)) {
ctx_->log()->Error("Failed to reset command allocator!");
}

hr = cmd_buf->Reset(cmd_alloc, nullptr);
if (FAILED(hr)) {
ctx_->log()->Error("Failed to reset command list!");
return;
}
#endif

{ // Reset spatial cache
DebugMarker _(ctx_.get(), cmd_buf, "ResetSpatialCache");
s.spatial_cache_voxels_prev_.buf().Fill(0, s.spatial_cache_voxels_prev_.buf().size(), 0, cmd_buf);
}

#if RUN_IN_LOCKSTEP
EndSingleTimeCommands(ctx_->api(), ctx_->device(), ctx_->graphics_queue(), cmd_buf, ctx_->temp_command_pool());
#else
ctx_->ResolveTimestampQueries(ctx_->backend_frame);

hr = cmd_buf->Close();
if (FAILED(hr)) {
return;
}

const int prev_frame = (ctx_->backend_frame + MaxFramesInFlight - 1) % MaxFramesInFlight;

ID3D12CommandList *pp_cmd_bufs[] = {cmd_buf};
ctx_->graphics_queue()->ExecuteCommandLists(1, pp_cmd_bufs);

hr = ctx_->graphics_queue()->Signal(ctx_->in_flight_fence(ctx_->backend_frame),
ctx_->fence_values[ctx_->backend_frame]);
if (FAILED(hr)) {
return;
}

ctx_->render_finished_semaphore_is_set[ctx_->backend_frame] = true;
ctx_->render_finished_semaphore_is_set[prev_frame] = false;

ctx_->backend_frame = (ctx_->backend_frame + 1) % MaxFramesInFlight;
#endif
}

Ray::color_data_rgba_t Ray::Dx::Renderer::get_pixels_ref(const bool tonemap) const {
if (frame_dirty_ || pixel_readback_is_tonemapped_ != tonemap) {
CommandBuffer cmd_buf = BegSingleTimeCommands(ctx_->api(), ctx_->device(), ctx_->temp_command_pool());
Expand Down
2 changes: 2 additions & 0 deletions internal/RendererGPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,8 @@ class Renderer : public RendererBase {
void UpdateSpatialCache(const SceneBase &scene, RegionContext &region) override;
void ResolveSpatialCache(const SceneBase &scene,
const std::function<void(int, int, ParallelForFunction &&)> &parallel_for) override;
void ResetSpatialCache(const SceneBase &scene,
const std::function<void(int, int, ParallelForFunction &&)> &parallel_for) override;

void GetStats(stats_t &st) override { st = stats_; }
void ResetStats() override { stats_ = {0}; }
Expand Down
69 changes: 69 additions & 0 deletions internal/RendererVK.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1709,6 +1709,75 @@ void Ray::Vk::Renderer::ResolveSpatialCache(const SceneBase &scene,
#endif
}

void Ray::Vk::Renderer::ResetSpatialCache(const SceneBase &scene,
const std::function<void(int, int, ParallelForFunction &&)> &) {
if (!use_spatial_cache_) {
return;
}

const auto &s = dynamic_cast<const Vk::Scene &>(scene);

#if !RUN_IN_LOCKSTEP
ctx_->api().vkWaitForFences(ctx_->device(), 1, &ctx_->in_flight_fence(ctx_->backend_frame), VK_TRUE, UINT64_MAX);
ctx_->api().vkResetFences(ctx_->device(), 1, &ctx_->in_flight_fence(ctx_->backend_frame));
#endif

ctx_->ReadbackTimestampQueries(ctx_->backend_frame);
ctx_->DestroyDeferredResources(ctx_->backend_frame);
ctx_->default_descr_alloc()->Reset();

#if RUN_IN_LOCKSTEP
CommandBuffer cmd_buf = BegSingleTimeCommands(ctx_->api(), ctx_->device(), ctx_->temp_command_pool());
#else
VkCommandBufferBeginInfo begin_info = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO};
begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;

ctx_->api().vkBeginCommandBuffer(ctx_->draw_cmd_buf(ctx_->backend_frame), &begin_info);
CommandBuffer cmd_buf = ctx_->draw_cmd_buf(ctx_->backend_frame);
#endif

{ // Reset spatial cache
DebugMarker _(ctx_.get(), cmd_buf, "ResetSpatialCache");
s.spatial_cache_voxels_prev_.buf().Fill(0, s.spatial_cache_voxels_prev_.buf().size(), 0, cmd_buf);
}

#if RUN_IN_LOCKSTEP
EndSingleTimeCommands(ctx_->api(), ctx_->device(), ctx_->graphics_queue(), cmd_buf, ctx_->temp_command_pool());
#else
ctx_->api().vkEndCommandBuffer(cmd_buf);

const int prev_frame = (ctx_->backend_frame + MaxFramesInFlight - 1) % MaxFramesInFlight;

VkSubmitInfo submit_info = {VK_STRUCTURE_TYPE_SUBMIT_INFO};

const VkSemaphore wait_semaphores[] = {ctx_->render_finished_semaphore(prev_frame)};
const VkPipelineStageFlags wait_stages[] = {VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};

if (ctx_->render_finished_semaphore_is_set[prev_frame]) {
submit_info.waitSemaphoreCount = 1;
submit_info.pWaitSemaphores = wait_semaphores;
submit_info.pWaitDstStageMask = wait_stages;
}

submit_info.commandBufferCount = 1;
submit_info.pCommandBuffers = &ctx_->draw_cmd_buf(ctx_->backend_frame);

submit_info.signalSemaphoreCount = 1;
submit_info.pSignalSemaphores = &ctx_->render_finished_semaphore(ctx_->backend_frame);

const VkResult res =
ctx_->api().vkQueueSubmit(ctx_->graphics_queue(), 1, &submit_info, ctx_->in_flight_fence(ctx_->backend_frame));
if (res != VK_SUCCESS) {
ctx_->log()->Error("Failed to submit into a queue!");
}

ctx_->render_finished_semaphore_is_set[ctx_->backend_frame] = true;
ctx_->render_finished_semaphore_is_set[prev_frame] = false;

ctx_->backend_frame = (ctx_->backend_frame + 1) % MaxFramesInFlight;
#endif
}

Ray::color_data_rgba_t Ray::Vk::Renderer::get_pixels_ref(const bool tonemap) const {
if (frame_dirty_ || pixel_readback_is_tonemapped_ != tonemap) {
CommandBuffer cmd_buf = BegSingleTimeCommands(ctx_->api(), ctx_->device(), ctx_->temp_command_pool());
Expand Down
2 changes: 1 addition & 1 deletion internal/SceneGPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -1611,7 +1611,7 @@ inline std::vector<Ray::color_rgba8_t> Ray::NS::Scene::CalcSkyEnvTexture(const a
{ // Write sky image
CommandBuffer cmd_buf = BegSingleTimeCommands(ctx_->api(), ctx_->device(), ctx_->temp_command_pool());

const TransitionInfo res_transition = {&temp_img, eResState::CopyDst};
const TransitionInfo res_transition = {&temp_img, ResStateForClear};
TransitionResourceStates(cmd_buf, AllStages, AllStages, {&res_transition, 1});

static const float rgba[4] = {};
Expand Down

0 comments on commit fe3f1db

Please sign in to comment.