Fix GPU backend deleting resources without an active context
This causes an assert with libepoxy, but was wrong already regardless. Refactor logic to work as follows: * GPU_exit() deletes backend resources * Destroy UI GPU resources with the context active * Call GPU_backend_exit() after deleting the context Ref D15291 Differential Revision: https://developer.blender.org/D15465
This commit is contained in:
@@ -17,8 +17,11 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* GPU backends abstract the differences between different APIs. These must be
|
||||||
|
* initialized before creating contexts, and deleted after the last context is
|
||||||
|
* discarded. GPU_context_create automatically initializes a backend if none
|
||||||
|
* exists yet. */
|
||||||
bool GPU_backend_init_once(void);
|
bool GPU_backend_init_once(void);
|
||||||
void GPU_backend_init(eGPUBackendType backend);
|
|
||||||
void GPU_backend_exit(void);
|
void GPU_backend_exit(void);
|
||||||
bool GPU_backend_supported(eGPUBackendType type);
|
bool GPU_backend_supported(eGPUBackendType type);
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ class VertBuf;
|
|||||||
class GPUBackend {
|
class GPUBackend {
|
||||||
public:
|
public:
|
||||||
virtual ~GPUBackend() = default;
|
virtual ~GPUBackend() = default;
|
||||||
|
virtual void delete_resources() = 0;
|
||||||
|
|
||||||
static GPUBackend *get();
|
static GPUBackend *get();
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "gpu_batch_private.hh"
|
#include "gpu_batch_private.hh"
|
||||||
#include "gpu_context_private.hh"
|
#include "gpu_context_private.hh"
|
||||||
#include "gpu_matrix_private.h"
|
#include "gpu_matrix_private.h"
|
||||||
|
#include "gpu_private.h"
|
||||||
|
|
||||||
#ifdef WITH_OPENGL_BACKEND
|
#ifdef WITH_OPENGL_BACKEND
|
||||||
# include "gl_backend.hh"
|
# include "gl_backend.hh"
|
||||||
@@ -213,20 +214,17 @@ bool GPU_backend_supported(eGPUBackendType type)
|
|||||||
|
|
||||||
bool GPU_backend_init_once()
|
bool GPU_backend_init_once()
|
||||||
{
|
{
|
||||||
if (GPUBackend::get() == nullptr) {
|
if (GPUBackend::get() != nullptr) {
|
||||||
if (!GPU_backend_supported(GPU_BACKEND_OPENGL)) {
|
return true;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
/* TODO: move where it make sense. */
|
|
||||||
GPU_backend_init(GPU_BACKEND_OPENGL);
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPU_backend_init(eGPUBackendType backend_type)
|
const eGPUBackendType backend_type = GPU_BACKEND_OPENGL;
|
||||||
{
|
if (!GPU_backend_supported(backend_type)) {
|
||||||
BLI_assert(g_backend == nullptr);
|
return false;
|
||||||
BLI_assert(GPU_backend_supported(backend_type));
|
}
|
||||||
|
|
||||||
|
static std::mutex backend_init_mutex;
|
||||||
|
std::scoped_lock lock(backend_init_mutex);
|
||||||
|
|
||||||
switch (backend_type) {
|
switch (backend_type) {
|
||||||
#ifdef WITH_OPENGL_BACKEND
|
#ifdef WITH_OPENGL_BACKEND
|
||||||
@@ -243,12 +241,19 @@ void GPU_backend_init(eGPUBackendType backend_type)
|
|||||||
BLI_assert(0);
|
BLI_assert(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gpu_backend_delete_resources()
|
||||||
|
{
|
||||||
|
BLI_assert(backend);
|
||||||
|
g_backend->delete_resources();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_backend_exit()
|
void GPU_backend_exit()
|
||||||
{
|
{
|
||||||
/* TODO: assert no resource left. Currently UI textures are still not freed in their context
|
/* TODO: assert no resource left. */
|
||||||
* correctly. */
|
|
||||||
delete g_backend;
|
delete g_backend;
|
||||||
g_backend = nullptr;
|
g_backend = nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ void GPU_exit(void)
|
|||||||
gpu_shader_dependency_exit();
|
gpu_shader_dependency_exit();
|
||||||
gpu_shader_create_info_exit();
|
gpu_shader_create_info_exit();
|
||||||
|
|
||||||
|
gpu_backend_delete_resources();
|
||||||
|
|
||||||
initialized = false;
|
initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,10 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* gpu_backend.cc */
|
||||||
|
|
||||||
|
void gpu_backend_delete_resources(void);
|
||||||
|
|
||||||
/* gpu_pbvh.c */
|
/* gpu_pbvh.c */
|
||||||
|
|
||||||
void gpu_pbvh_init(void);
|
void gpu_pbvh_init(void);
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ class MTLBackend : public GPUBackend {
|
|||||||
MTLBackend::platform_exit();
|
MTLBackend::platform_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void delete_resources()
|
||||||
|
{
|
||||||
|
/* Delete any resources with context active. */
|
||||||
|
}
|
||||||
|
|
||||||
static bool metal_is_supported();
|
static bool metal_is_supported();
|
||||||
static MTLBackend *get()
|
static MTLBackend *get()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -42,11 +42,15 @@ class GLBackend : public GPUBackend {
|
|||||||
}
|
}
|
||||||
~GLBackend()
|
~GLBackend()
|
||||||
{
|
{
|
||||||
GLTexture::samplers_free();
|
|
||||||
|
|
||||||
GLBackend::platform_exit();
|
GLBackend::platform_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void delete_resources() override
|
||||||
|
{
|
||||||
|
/* Delete any resources with context active. */
|
||||||
|
GLTexture::samplers_free();
|
||||||
|
}
|
||||||
|
|
||||||
static GLBackend *get()
|
static GLBackend *get()
|
||||||
{
|
{
|
||||||
return static_cast<GLBackend *>(GPUBackend::get());
|
return static_cast<GLBackend *>(GPUBackend::get());
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ void GPUTest::SetUp()
|
|||||||
GHOST_GLSettings glSettings = {0};
|
GHOST_GLSettings glSettings = {0};
|
||||||
CLG_init();
|
CLG_init();
|
||||||
ghost_system = GHOST_CreateSystem();
|
ghost_system = GHOST_CreateSystem();
|
||||||
|
GPU_backend_init_once();
|
||||||
ghost_context = GHOST_CreateOpenGLContext(ghost_system, glSettings);
|
ghost_context = GHOST_CreateOpenGLContext(ghost_system, glSettings);
|
||||||
GHOST_ActivateOpenGLContext(ghost_context);
|
GHOST_ActivateOpenGLContext(ghost_context);
|
||||||
context = GPU_context_create(nullptr);
|
context = GPU_context_create(nullptr);
|
||||||
@@ -26,9 +27,9 @@ void GPUTest::SetUp()
|
|||||||
void GPUTest::TearDown()
|
void GPUTest::TearDown()
|
||||||
{
|
{
|
||||||
GPU_exit();
|
GPU_exit();
|
||||||
GPU_backend_exit();
|
|
||||||
GPU_context_discard(context);
|
GPU_context_discard(context);
|
||||||
GHOST_DisposeOpenGLContext(ghost_system, ghost_context);
|
GHOST_DisposeOpenGLContext(ghost_system, ghost_context);
|
||||||
|
GPU_backend_exit();
|
||||||
GHOST_DisposeSystem(ghost_system);
|
GHOST_DisposeSystem(ghost_system);
|
||||||
CLG_exit();
|
CLG_exit();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -576,14 +576,6 @@ void WM_exit_ex(bContext *C, const bool do_python)
|
|||||||
|
|
||||||
BLF_exit();
|
BLF_exit();
|
||||||
|
|
||||||
if (opengl_is_init) {
|
|
||||||
DRW_opengl_context_enable_ex(false);
|
|
||||||
GPU_pass_cache_free();
|
|
||||||
GPU_exit();
|
|
||||||
DRW_opengl_context_disable_ex(false);
|
|
||||||
DRW_opengl_context_destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
BLT_lang_free();
|
BLT_lang_free();
|
||||||
|
|
||||||
ANIM_keyingset_infos_exit();
|
ANIM_keyingset_infos_exit();
|
||||||
@@ -608,13 +600,25 @@ void WM_exit_ex(bContext *C, const bool do_python)
|
|||||||
|
|
||||||
ED_file_exit(); /* for fsmenu */
|
ED_file_exit(); /* for fsmenu */
|
||||||
|
|
||||||
UI_exit();
|
/* Delete GPU resources and context. The UI also uses GPU resources and so
|
||||||
|
* is also deleted with the context active. */
|
||||||
|
if (opengl_is_init) {
|
||||||
|
DRW_opengl_context_enable_ex(false);
|
||||||
|
UI_exit();
|
||||||
|
GPU_pass_cache_free();
|
||||||
|
GPU_exit();
|
||||||
|
DRW_opengl_context_disable_ex(false);
|
||||||
|
DRW_opengl_context_destroy();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
UI_exit();
|
||||||
|
}
|
||||||
|
GPU_backend_exit();
|
||||||
|
|
||||||
BKE_blender_userdef_data_free(&U, false);
|
BKE_blender_userdef_data_free(&U, false);
|
||||||
|
|
||||||
RNA_exit(); /* should be after BPY_python_end so struct python slots are cleared */
|
RNA_exit(); /* should be after BPY_python_end so struct python slots are cleared */
|
||||||
|
|
||||||
GPU_backend_exit();
|
|
||||||
|
|
||||||
wm_ghost_exit();
|
wm_ghost_exit();
|
||||||
|
|
||||||
CTX_free(C);
|
CTX_free(C);
|
||||||
|
|||||||
Reference in New Issue
Block a user