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/session
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/session')
-rw-r--r--intern/cycles/session/display_driver.h16
-rw-r--r--intern/cycles/session/session.cpp7
-rw-r--r--intern/cycles/session/tile.cpp6
-rw-r--r--intern/cycles/session/tile.h6
4 files changed, 31 insertions, 4 deletions
diff --git a/intern/cycles/session/display_driver.h b/intern/cycles/session/display_driver.h
index 77f89326fd0..c56a82436d9 100644
--- a/intern/cycles/session/display_driver.h
+++ b/intern/cycles/session/display_driver.h
@@ -54,6 +54,8 @@ class DisplayDriver {
}
};
+ virtual void next_tile_begin() = 0;
+
/* Update the render from the rendering thread.
*
* Cycles periodically updates the render to be displayed. For multithreaded updates with
@@ -80,6 +82,9 @@ class DisplayDriver {
virtual bool update_begin(const Params &params, int width, int height) = 0;
virtual void update_end() = 0;
+ /* Optionally flush outstanding display commands before ending the render loop. */
+ virtual void flush(){};
+
virtual half4 *map_texture_buffer() = 0;
virtual void unmap_texture_buffer() = 0;
@@ -97,6 +102,17 @@ class DisplayDriver {
/* Clear the entire buffer before doing partial write to it. */
bool need_clear = false;
+
+ /* Enforce re-creation of the graphics interop object.
+ *
+ * When this field is true then the graphics interop will be re-created no matter what the
+ * rest of the configuration is.
+ * When this field is false the graphics interop will be re-created if the PBO or buffer size
+ * did change.
+ *
+ * This allows to ensure graphics interop is re-created when there is a possibility that an
+ * underlying PBO was re-allocated but did not change its ID. */
+ bool need_recreate = false;
};
virtual GraphicsInterop graphics_interop_get()
diff --git a/intern/cycles/session/session.cpp b/intern/cycles/session/session.cpp
index af5c6b3f1fd..a839303debc 100644
--- a/intern/cycles/session/session.cpp
+++ b/intern/cycles/session/session.cpp
@@ -192,6 +192,8 @@ void Session::run_main_render_loop()
break;
}
}
+
+ path_trace_->flush_display();
}
void Session::run()
@@ -303,7 +305,7 @@ RenderWork Session::run_update_for_next_iteration()
tile_params.update_offset_stride();
- path_trace_->reset(buffer_params_, tile_params);
+ path_trace_->reset(buffer_params_, tile_params, did_reset);
}
const int resolution = render_work.resolution_divider;
@@ -384,7 +386,8 @@ int2 Session::get_effective_tile_size() const
const int tile_size = tile_manager_.compute_render_tile_size(params.tile_size);
const int64_t actual_tile_area = static_cast<int64_t>(tile_size) * tile_size;
- if (actual_tile_area >= image_area) {
+ if (actual_tile_area >= image_area && image_width <= TileManager::MAX_TILE_SIZE &&
+ image_height <= TileManager::MAX_TILE_SIZE) {
return make_int2(image_width, image_height);
}
diff --git a/intern/cycles/session/tile.cpp b/intern/cycles/session/tile.cpp
index 3b8482fa16f..afd1f334120 100644
--- a/intern/cycles/session/tile.cpp
+++ b/intern/cycles/session/tile.cpp
@@ -341,8 +341,10 @@ int TileManager::compute_render_tile_size(const int suggested_tile_size) const
/* Must be a multiple of IMAGE_TILE_SIZE so that we can write render tiles into the image file
* aligned on image tile boundaries. We can't set IMAGE_TILE_SIZE equal to the render tile size
* because too big tile size leads to integer overflow inside OpenEXR. */
- return (suggested_tile_size <= IMAGE_TILE_SIZE) ? suggested_tile_size :
- align_up(suggested_tile_size, IMAGE_TILE_SIZE);
+ const int computed_tile_size = (suggested_tile_size <= IMAGE_TILE_SIZE) ?
+ suggested_tile_size :
+ align_up(suggested_tile_size, IMAGE_TILE_SIZE);
+ return min(computed_tile_size, MAX_TILE_SIZE);
}
void TileManager::reset_scheduling(const BufferParams &params, int2 tile_size)
diff --git a/intern/cycles/session/tile.h b/intern/cycles/session/tile.h
index eace148eb0a..7c8f7570d3e 100644
--- a/intern/cycles/session/tile.h
+++ b/intern/cycles/session/tile.h
@@ -122,6 +122,12 @@ class TileManager {
/* Tile size in the image file. */
static const int IMAGE_TILE_SIZE = 128;
+ /* Maximum supported tile size.
+ * Needs to be safe from allocation on a GPU point of view: the display driver needs to be able
+ * to allocate texture with the side size of this value.
+ * Use conservative value which is safe for most of OpenGL drivers and GPUs. */
+ static const int MAX_TILE_SIZE = 8192;
+
protected:
/* Get tile configuration for its index.
* The tile index must be within [0, state_.tile_state_). */