From 21acfbe348a433cb6ef5c422b1da232355fa51ab Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 20 Aug 2022 13:36:12 +0200 Subject: Cleanup: move Cycles display driver context handling to render module This is highly coupled to Blender logic so doesn't belong in Cycles. --- intern/cycles/blender/display_driver.cpp | 139 ++++++++++--------------------- 1 file changed, 42 insertions(+), 97 deletions(-) (limited to 'intern/cycles/blender/display_driver.cpp') 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()) { /* 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(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(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(b_engine_.ptr.data)); - return true; + return RE_engine_gpu_context_enable(reinterpret_cast(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(b_engine_.ptr.data)); + RE_engine_gpu_context_disable(reinterpret_cast(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(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(b_engine_.ptr.data)); +} - DRW_opengl_context_activate(drw_state); - } +void BlenderDisplayDriver::gpu_context_unlock() +{ + RE_engine_gpu_context_unlock(reinterpret_cast(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 -- cgit v1.2.3