diff options
author | Brecht Van Lommel <brecht@blender.org> | 2022-08-20 14:36:12 +0300 |
---|---|---|
committer | Brecht Van Lommel <brecht@blender.org> | 2022-08-29 20:45:58 +0300 |
commit | 21acfbe348a433cb6ef5c422b1da232355fa51ab (patch) | |
tree | b66a6a847a153f9f3bf89521e329aa035dadde9c /intern | |
parent | 810e7c032ceb324a51440aae1be5af506c0b9cfb (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.txt | 1 | ||||
-rw-r--r-- | intern/cycles/blender/display_driver.cpp | 139 | ||||
-rw-r--r-- | intern/cycles/blender/display_driver.h | 23 | ||||
-rw-r--r-- | intern/cycles/blender/session.cpp | 4 |
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 ¶ms, /* 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 ¶ms, 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 ¶ms) { - /* 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 ¶ms) * 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 ¶ms) 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)); } |