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
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brecht@blender.org>2022-08-20 14:36:12 +0300
committerBrecht Van Lommel <brecht@blender.org>2022-08-29 20:45:58 +0300
commit21acfbe348a433cb6ef5c422b1da232355fa51ab (patch)
treeb66a6a847a153f9f3bf89521e329aa035dadde9c /intern
parent810e7c032ceb324a51440aae1be5af506c0b9cfb (diff)
Cleanup: move Cycles display driver context handling to render module
This is highly coupled to Blender logic so doesn't belong in Cycles.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/CMakeLists.txt1
-rw-r--r--intern/cycles/blender/display_driver.cpp139
-rw-r--r--intern/cycles/blender/display_driver.h23
-rw-r--r--intern/cycles/blender/session.cpp4
4 files changed, 54 insertions, 113 deletions
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index 72f8a4cc15d..24bc165c708 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -9,6 +9,7 @@ set(INC
../../../source/blender/makesrna
../../../source/blender/blenlib
../../../source/blender/gpu
+ ../../../source/blender/render
${CMAKE_BINARY_DIR}/source/blender/makesrna/intern
)
diff --git a/intern/cycles/blender/display_driver.cpp b/intern/cycles/blender/display_driver.cpp
index 30ad3ecad51..e2be4f85a9b 100644
--- a/intern/cycles/blender/display_driver.cpp
+++ b/intern/cycles/blender/display_driver.cpp
@@ -9,21 +9,7 @@
#include "GPU_platform.h"
-extern "C" {
-struct RenderEngine;
-
-bool RE_engine_has_render_context(struct RenderEngine *engine);
-void RE_engine_render_context_enable(struct RenderEngine *engine);
-void RE_engine_render_context_disable(struct RenderEngine *engine);
-
-bool DRW_opengl_context_release();
-void DRW_opengl_context_activate(bool drw_state);
-
-void *WM_opengl_context_create();
-void WM_opengl_context_activate(void *gl_context);
-void WM_opengl_context_dispose(void *gl_context);
-void WM_opengl_context_release(void *context);
-}
+#include "RE_engine.h"
CCL_NAMESPACE_BEGIN
@@ -559,18 +545,21 @@ struct BlenderDisplayDriver::Tiles {
}
};
-BlenderDisplayDriver::BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene)
+BlenderDisplayDriver::BlenderDisplayDriver(BL::RenderEngine &b_engine,
+ BL::Scene &b_scene,
+ const bool background)
: b_engine_(b_engine),
+ background_(background),
display_shader_(BlenderDisplayShader::create(b_engine, b_scene)),
tiles_(make_unique<Tiles>())
{
/* Create context while on the main thread. */
- gl_context_create();
+ gpu_context_create();
}
BlenderDisplayDriver::~BlenderDisplayDriver()
{
- gl_resources_destroy();
+ gpu_resources_destroy();
}
/* --------------------------------------------------------------------
@@ -601,12 +590,12 @@ bool BlenderDisplayDriver::update_begin(const Params &params,
/* Note that it's the responsibility of BlenderDisplayDriver to ensure updating and drawing
* the texture does not happen at the same time. This is achieved indirectly.
*
- * When enabling the OpenGL context, it uses an internal mutex lock DST.gl_context_lock.
+ * When enabling the OpenGL context, it uses an internal mutex lock DST.gpu_context_lock.
* This same lock is also held when do_draw() is called, which together ensure mutual
* exclusion.
*
* This locking is not performed on the Cycles side, because that would cause lock inversion. */
- if (!gl_context_enable()) {
+ if (!gpu_context_enable()) {
return false;
}
@@ -627,13 +616,13 @@ bool BlenderDisplayDriver::update_begin(const Params &params,
if (!tiles_->gl_resources_ensure()) {
tiles_->gl_resources_destroy();
- gl_context_disable();
+ gpu_context_disable();
return false;
}
if (!tiles_->current_tile.gl_resources_ensure()) {
tiles_->current_tile.gl_resources_destroy();
- gl_context_disable();
+ gpu_context_disable();
return false;
}
@@ -712,7 +701,7 @@ void BlenderDisplayDriver::update_end()
* On some older GPUs on macOS, there is a driver crash when updating the texture for viewport
* renders while Blender is drawing. As a workaround update texture during draw, under assumption
* that there is no graphics interop on macOS and viewport render has a single tile. */
- if (use_gl_context_ &&
+ if (!background_ &&
GPU_type_matches_ex(GPU_DEVICE_NVIDIA, GPU_OS_MAC, GPU_DRIVER_ANY, GPU_BACKEND_ANY)) {
tiles_->current_tile.need_update_texture_pixels = true;
}
@@ -723,7 +712,7 @@ void BlenderDisplayDriver::update_end()
gl_upload_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
- gl_context_disable();
+ gpu_context_disable();
}
/* --------------------------------------------------------------------
@@ -771,12 +760,12 @@ BlenderDisplayDriver::GraphicsInterop BlenderDisplayDriver::graphics_interop_get
void BlenderDisplayDriver::graphics_interop_activate()
{
- gl_context_enable();
+ gpu_context_enable();
}
void BlenderDisplayDriver::graphics_interop_deactivate()
{
- gl_context_disable();
+ gpu_context_disable();
}
/* --------------------------------------------------------------------
@@ -910,7 +899,7 @@ void BlenderDisplayDriver::flush()
* If we don't do this, the NVIDIA driver hangs for a few seconds for when ending 3D viewport
* rendering, for unknown reasons. This was found with NVIDIA driver version 470.73 and a Quadro
* RTX 6000 on Linux. */
- if (!gl_context_enable()) {
+ if (!gpu_context_enable()) {
return;
}
@@ -922,15 +911,12 @@ void BlenderDisplayDriver::flush()
glWaitSync((GLsync)gl_render_sync_, 0, GL_TIMEOUT_IGNORED);
}
- gl_context_disable();
+ gpu_context_disable();
}
void BlenderDisplayDriver::draw(const Params &params)
{
- /* See do_update_begin() for why no locking is required here. */
- if (use_gl_context_) {
- gl_context_mutex_.lock();
- }
+ gpu_context_lock();
if (need_clear_) {
/* Texture is requested to be cleared and was not yet cleared.
@@ -938,9 +924,7 @@ void BlenderDisplayDriver::draw(const Params &params)
* Do early return which should be equivalent of drawing all-zero texture.
* Watch out for the lock though so that the clear happening during update is properly
* synchronized here. */
- if (use_gl_context_) {
- gl_context_mutex_.unlock();
- }
+ gpu_context_unlock();
return;
}
@@ -996,94 +980,55 @@ void BlenderDisplayDriver::draw(const Params &params)
gl_render_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
+ gpu_context_unlock();
+
VLOG_DEVICE_STATS << "Display driver number of textures: " << GLTexture::num_used;
VLOG_DEVICE_STATS << "Display driver number of PBOs: " << GLPixelBufferObject::num_used;
-
- if (use_gl_context_) {
- gl_context_mutex_.unlock();
- }
}
-void BlenderDisplayDriver::gl_context_create()
+void BlenderDisplayDriver::gpu_context_create()
{
- /* When rendering in viewport there is no render context available via engine.
- * Check whether own context is to be created here.
- *
- * NOTE: If the `b_engine_`'s context is not available, we are expected to be on a main thread
- * here. */
- use_gl_context_ = !RE_engine_has_render_context(
- reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
-
- if (use_gl_context_) {
- const bool drw_state = DRW_opengl_context_release();
- gl_context_ = WM_opengl_context_create();
- if (gl_context_) {
- /* On Windows an old context is restored after creation, and subsequent release of context
- * generates a Win32 error. Harmless for users, but annoying to have possible misleading
- * error prints in the console. */
-#ifndef _WIN32
- WM_opengl_context_release(gl_context_);
-#endif
- }
- else {
- LOG(ERROR) << "Error creating OpenGL context.";
- }
-
- DRW_opengl_context_activate(drw_state);
+ if (!RE_engine_gpu_context_create(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data))) {
+ LOG(ERROR) << "Error creating OpenGL context.";
}
}
-bool BlenderDisplayDriver::gl_context_enable()
+bool BlenderDisplayDriver::gpu_context_enable()
{
- if (use_gl_context_) {
- if (!gl_context_) {
- return false;
- }
- gl_context_mutex_.lock();
- WM_opengl_context_activate(gl_context_);
- return true;
- }
-
- RE_engine_render_context_enable(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
- return true;
+ return RE_engine_gpu_context_enable(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
}
-void BlenderDisplayDriver::gl_context_disable()
+void BlenderDisplayDriver::gpu_context_disable()
{
- if (use_gl_context_) {
- if (gl_context_) {
- WM_opengl_context_release(gl_context_);
- gl_context_mutex_.unlock();
- }
- return;
- }
-
- RE_engine_render_context_disable(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
+ RE_engine_gpu_context_disable(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
}
-void BlenderDisplayDriver::gl_context_dispose()
+void BlenderDisplayDriver::gpu_context_destroy()
{
- if (gl_context_) {
- const bool drw_state = DRW_opengl_context_release();
+ RE_engine_gpu_context_destroy(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
+}
- WM_opengl_context_activate(gl_context_);
- WM_opengl_context_dispose(gl_context_);
+void BlenderDisplayDriver::gpu_context_lock()
+{
+ RE_engine_gpu_context_lock(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
+}
- DRW_opengl_context_activate(drw_state);
- }
+void BlenderDisplayDriver::gpu_context_unlock()
+{
+ RE_engine_gpu_context_unlock(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
}
-void BlenderDisplayDriver::gl_resources_destroy()
+void BlenderDisplayDriver::gpu_resources_destroy()
{
- gl_context_enable();
+ gpu_context_enable();
tiles_->current_tile.gl_resources_destroy();
tiles_->finished_tiles.gl_resources_destroy_and_clear();
tiles_->gl_resources_destroy();
- gl_context_disable();
+ gpu_context_disable();
- gl_context_dispose();
+ gpu_context_destroy();
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/display_driver.h b/intern/cycles/blender/display_driver.h
index 58867d08e19..4df40269daf 100644
--- a/intern/cycles/blender/display_driver.h
+++ b/intern/cycles/blender/display_driver.h
@@ -89,7 +89,7 @@ class BlenderDisplaySpaceShader : public BlenderDisplayShader {
/* Display driver implementation which is specific for Blender viewport integration. */
class BlenderDisplayDriver : public DisplayDriver {
public:
- BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene);
+ BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene, const bool background);
~BlenderDisplayDriver();
virtual void graphics_interop_activate() override;
@@ -115,23 +115,18 @@ class BlenderDisplayDriver : public DisplayDriver {
virtual void flush() override;
/* Helper function which allocates new GPU context. */
- void gl_context_create();
- bool gl_context_enable();
- void gl_context_disable();
- void gl_context_dispose();
+ void gpu_context_create();
+ bool gpu_context_enable();
+ void gpu_context_disable();
+ void gpu_context_destroy();
+ void gpu_context_lock();
+ void gpu_context_unlock();
/* Destroy all GPU resources which are being used by this object. */
- void gl_resources_destroy();
+ void gpu_resources_destroy();
BL::RenderEngine b_engine_;
-
- /* OpenGL context which is used the render engine doesn't have its own. */
- void *gl_context_ = nullptr;
- /* The when Blender RenderEngine side context is not available and the DisplayDriver is to create
- * its own context. */
- bool use_gl_context_ = false;
- /* Mutex used to guard the `gl_context_`. */
- thread_mutex gl_context_mutex_;
+ bool background_;
/* Content of the display is to be filled with zeroes. */
std::atomic<bool> need_clear_ = true;
diff --git a/intern/cycles/blender/session.cpp b/intern/cycles/blender/session.cpp
index e1da85b84ff..5954d5fb572 100644
--- a/intern/cycles/blender/session.cpp
+++ b/intern/cycles/blender/session.cpp
@@ -1059,8 +1059,8 @@ void BlenderSession::ensure_display_driver_if_needed()
return;
}
- unique_ptr<BlenderDisplayDriver> display_driver = make_unique<BlenderDisplayDriver>(b_engine,
- b_scene);
+ unique_ptr<BlenderDisplayDriver> display_driver = make_unique<BlenderDisplayDriver>(
+ b_engine, b_scene, background);
display_driver_ = display_driver.get();
session->set_display_driver(move(display_driver));
}