Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brecht@blender.org>2022-01-06 18:41:44 +0300
committerBrecht Van Lommel <brecht@blender.org>2022-01-07 19:20:04 +0300
commitae28d90578be516bf81f3532846c29f9985f1085 (patch)
treec34a11d1d63829beb4178fcfcd59ab895729d18b /intern/cycles/integrator
parentefe3d60a2c8306aefd41bc304548da35b67c252c (diff)
Fix T93350: Cycles renders shows black during rendering huge resolutions
The root of the issue is caused by Cycles ignoring OpenGL limitation on the maximum resolution of textures: Cycles was allocating texture of the final render resolution. It was exceeding limitation on certain GPUs and driver. The idea is simple: use multiple textures for the display, each of which will fit into OpenGL limitations. There is some code which allows the display driver to know when to start the new tile. Also added some code to allow force graphics interop to be re-created. The latter one ended up not used in the final version of the patch, but it might be helpful for other drivers implementation. The tile size is limited to 8K now as it is the safest size for textures on many GPUs and OpenGL drivers. This is an updated fix with a workaround for freezing with the NVIDIA driver on Linux. Differential Revision: https://developer.blender.org/D13385
Diffstat (limited to 'intern/cycles/integrator')
-rw-r--r--intern/cycles/integrator/path_trace.cpp20
-rw-r--r--intern/cycles/integrator/path_trace.h7
-rw-r--r--intern/cycles/integrator/path_trace_display.cpp16
-rw-r--r--intern/cycles/integrator/path_trace_display.h12
-rw-r--r--intern/cycles/integrator/path_trace_work.cpp8
-rw-r--r--intern/cycles/integrator/path_trace_work_gpu.cpp6
6 files changed, 51 insertions, 18 deletions
diff --git a/intern/cycles/integrator/path_trace.cpp b/intern/cycles/integrator/path_trace.cpp
index bdc18b1c0a1..0b55d1078a8 100644
--- a/intern/cycles/integrator/path_trace.cpp
+++ b/intern/cycles/integrator/path_trace.cpp
@@ -115,7 +115,9 @@ bool PathTrace::ready_to_reset()
return false;
}
-void PathTrace::reset(const BufferParams &full_params, const BufferParams &big_tile_params)
+void PathTrace::reset(const BufferParams &full_params,
+ const BufferParams &big_tile_params,
+ const bool reset_rendering)
{
if (big_tile_params_.modified(big_tile_params)) {
big_tile_params_ = big_tile_params;
@@ -128,7 +130,7 @@ void PathTrace::reset(const BufferParams &full_params, const BufferParams &big_t
* It is requires to inform about reset whenever it happens, so that the redraw state tracking is
* properly updated. */
if (display_) {
- display_->reset(full_params);
+ display_->reset(big_tile_params, reset_rendering);
}
render_state_.has_denoised_result = false;
@@ -594,6 +596,15 @@ void PathTrace::draw()
did_draw_after_reset_ |= display_->draw();
}
+void PathTrace::flush_display()
+{
+ if (!display_) {
+ return;
+ }
+
+ display_->flush();
+}
+
void PathTrace::update_display(const RenderWork &render_work)
{
if (!render_work.display.update) {
@@ -622,9 +633,8 @@ void PathTrace::update_display(const RenderWork &render_work)
if (display_) {
VLOG(3) << "Perform copy to GPUDisplay work.";
- const int resolution_divider = render_work.resolution_divider;
- const int texture_width = max(1, full_params_.width / resolution_divider);
- const int texture_height = max(1, full_params_.height / resolution_divider);
+ const int texture_width = render_state_.effective_big_tile_params.window_width;
+ const int texture_height = render_state_.effective_big_tile_params.window_height;
if (!display_->update_begin(texture_width, texture_height)) {
LOG(ERROR) << "Error beginning GPUDisplay update.";
return;
diff --git a/intern/cycles/integrator/path_trace.h b/intern/cycles/integrator/path_trace.h
index 9b079352a63..bb41c8c3210 100644
--- a/intern/cycles/integrator/path_trace.h
+++ b/intern/cycles/integrator/path_trace.h
@@ -72,7 +72,9 @@ class PathTrace {
* render result. */
bool ready_to_reset();
- void reset(const BufferParams &full_params, const BufferParams &big_tile_params);
+ void reset(const BufferParams &full_params,
+ const BufferParams &big_tile_params,
+ bool reset_rendering);
void device_free();
@@ -112,6 +114,9 @@ class PathTrace {
/* Perform drawing of the current state of the DisplayDriver. */
void draw();
+ /* Flush outstanding display commands before ending the render loop. */
+ void flush_display();
+
/* Cancel rendering process as soon as possible, without waiting for full tile to be sampled.
* Used in cases like reset of render session.
*
diff --git a/intern/cycles/integrator/path_trace_display.cpp b/intern/cycles/integrator/path_trace_display.cpp
index c1cade923b1..4af622065c2 100644
--- a/intern/cycles/integrator/path_trace_display.cpp
+++ b/intern/cycles/integrator/path_trace_display.cpp
@@ -26,15 +26,20 @@ PathTraceDisplay::PathTraceDisplay(unique_ptr<DisplayDriver> driver) : driver_(m
{
}
-void PathTraceDisplay::reset(const BufferParams &buffer_params)
+void PathTraceDisplay::reset(const BufferParams &buffer_params, const bool reset_rendering)
{
thread_scoped_lock lock(mutex_);
- params_.full_offset = make_int2(buffer_params.full_x, buffer_params.full_y);
+ params_.full_offset = make_int2(buffer_params.full_x + buffer_params.window_x,
+ buffer_params.full_y + buffer_params.window_y);
params_.full_size = make_int2(buffer_params.full_width, buffer_params.full_height);
- params_.size = make_int2(buffer_params.width, buffer_params.height);
+ params_.size = make_int2(buffer_params.window_width, buffer_params.window_height);
texture_state_.is_outdated = true;
+
+ if (!reset_rendering) {
+ driver_->next_tile_begin();
+ }
}
void PathTraceDisplay::mark_texture_updated()
@@ -248,4 +253,9 @@ bool PathTraceDisplay::draw()
return !is_outdated;
}
+void PathTraceDisplay::flush()
+{
+ driver_->flush();
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/integrator/path_trace_display.h b/intern/cycles/integrator/path_trace_display.h
index 47014f43afa..b9aff5f6000 100644
--- a/intern/cycles/integrator/path_trace_display.h
+++ b/intern/cycles/integrator/path_trace_display.h
@@ -38,14 +38,17 @@ class BufferParams;
class PathTraceDisplay {
public:
- PathTraceDisplay(unique_ptr<DisplayDriver> driver);
+ explicit PathTraceDisplay(unique_ptr<DisplayDriver> driver);
virtual ~PathTraceDisplay() = default;
/* Reset the display for the new state of render session. Is called whenever session is reset,
* which happens on changes like viewport navigation or viewport dimension change.
*
- * This call will configure parameters for a changed buffer and reset the texture state. */
- void reset(const BufferParams &buffer_params);
+ * This call will configure parameters for a changed buffer and reset the texture state.
+ *
+ * When the `reset_rendering` a complete displat reset happens. When it is false reset happens
+ * for a new state of the buffer parameters which is assumed to correspond to the next tile. */
+ void reset(const BufferParams &buffer_params, bool reset_rendering);
/* --------------------------------------------------------------------
* Update procedure.
@@ -151,6 +154,9 @@ class PathTraceDisplay {
* Returns true if this call did draw an updated state of the texture. */
bool draw();
+ /* Flush outstanding display commands before ending the render loop. */
+ void flush();
+
private:
/* Display driver implemented by the host application. */
unique_ptr<DisplayDriver> driver_;
diff --git a/intern/cycles/integrator/path_trace_work.cpp b/intern/cycles/integrator/path_trace_work.cpp
index b0c40cfe15c..4ecc7d775ee 100644
--- a/intern/cycles/integrator/path_trace_work.cpp
+++ b/intern/cycles/integrator/path_trace_work.cpp
@@ -194,10 +194,10 @@ PassAccessor::Destination PathTraceWork::get_display_destination_template(
PassAccessor::Destination destination(film_->get_display_pass());
const int2 display_texture_size = display->get_texture_size();
- const int texture_x = effective_buffer_params_.full_x - effective_full_params_.full_x +
- effective_buffer_params_.window_x;
- const int texture_y = effective_buffer_params_.full_y - effective_full_params_.full_y +
- effective_buffer_params_.window_y;
+ const int texture_x = effective_buffer_params_.full_x - effective_big_tile_params_.full_x +
+ effective_buffer_params_.window_x - effective_big_tile_params_.window_x;
+ const int texture_y = effective_buffer_params_.full_y - effective_big_tile_params_.full_y +
+ effective_buffer_params_.window_y - effective_big_tile_params_.window_y;
destination.offset = texture_y * display_texture_size.x + texture_x;
destination.stride = display_texture_size.x;
diff --git a/intern/cycles/integrator/path_trace_work_gpu.cpp b/intern/cycles/integrator/path_trace_work_gpu.cpp
index e5062c6c47e..7a13447f2cf 100644
--- a/intern/cycles/integrator/path_trace_work_gpu.cpp
+++ b/intern/cycles/integrator/path_trace_work_gpu.cpp
@@ -875,8 +875,10 @@ void PathTraceWorkGPU::copy_to_display_naive(PathTraceDisplay *display,
const int final_width = buffers_->params.window_width;
const int final_height = buffers_->params.window_height;
- const int texture_x = full_x - effective_full_params_.full_x + effective_buffer_params_.window_x;
- const int texture_y = full_y - effective_full_params_.full_y + effective_buffer_params_.window_y;
+ const int texture_x = full_x - effective_big_tile_params_.full_x +
+ effective_buffer_params_.window_x - effective_big_tile_params_.window_x;
+ const int texture_y = full_y - effective_big_tile_params_.full_y +
+ effective_buffer_params_.window_y - effective_big_tile_params_.window_y;
/* Re-allocate display memory if needed, and make sure the device pointer is allocated.
*