Merge branch 'blender-v2.90-release'
This commit is contained in:
commit
2ca006f6c1
|
@ -445,12 +445,10 @@ ccl_device_inline float fast_expf(float x)
|
|||
return fast_exp2f(x / M_LN2_F);
|
||||
}
|
||||
|
||||
#ifndef __KERNEL_GPU__
|
||||
/* MSVC seems to have a code-gen bug here in at least SSE41/AVX
|
||||
* see T78047 for details. */
|
||||
# ifdef _MSC_VER
|
||||
# pragma optimize("", off)
|
||||
# endif
|
||||
#if defined(__KERNEL_CPU__) && !defined(_MSC_VER)
|
||||
/* MSVC seems to have a code-gen bug here in at least SSE41/AVX, see
|
||||
* T78047 and T78869 for details. Just disable for now, it only makes
|
||||
* a small difference in denoising performance. */
|
||||
ccl_device float4 fast_exp2f4(float4 x)
|
||||
{
|
||||
const float4 one = make_float4(1.0f);
|
||||
|
@ -466,14 +464,16 @@ ccl_device float4 fast_exp2f4(float4 x)
|
|||
r = madd4(x, r, make_float4(1.0f));
|
||||
return __int4_as_float4(__float4_as_int4(r) + (m << 23));
|
||||
}
|
||||
# ifdef _MSC_VER
|
||||
# pragma optimize("", on)
|
||||
# endif
|
||||
|
||||
ccl_device_inline float4 fast_expf4(float4 x)
|
||||
{
|
||||
return fast_exp2f4(x / M_LN2_F);
|
||||
}
|
||||
#else
|
||||
ccl_device_inline float4 fast_expf4(float4 x)
|
||||
{
|
||||
return make_float4(fast_expf(x.x), fast_expf(x.y), fast_expf(x.z), fast_expf(x.w));
|
||||
}
|
||||
#endif
|
||||
|
||||
ccl_device_inline float fast_exp10(float x)
|
||||
|
|
|
@ -1144,9 +1144,13 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA
|
|||
int r;
|
||||
GetKeyboardState((PBYTE)state);
|
||||
|
||||
/* No text with control key pressed. */
|
||||
if (state[VK_CONTROL] & 0x80) {
|
||||
utf8_char[0] = '\0';
|
||||
}
|
||||
// Don't call ToUnicodeEx on dead keys as it clears the buffer and so won't allow diacritical
|
||||
// composition.
|
||||
if (MapVirtualKeyW(vk, 2) != 0) {
|
||||
else if (MapVirtualKeyW(vk, 2) != 0) {
|
||||
// todo: ToUnicodeEx can respond with up to 4 utf16 chars (only 2 here).
|
||||
// Could be up to 24 utf8 bytes.
|
||||
if ((r = ToUnicodeEx(
|
||||
|
|
|
@ -531,6 +531,12 @@ void EEVEE_lightcache_free(LightCache *lcache)
|
|||
|
||||
static void eevee_lightbake_context_enable(EEVEE_LightBake *lbake)
|
||||
{
|
||||
if (GPU_use_main_context_workaround() && !BLI_thread_is_main()) {
|
||||
GPU_context_main_lock();
|
||||
DRW_opengl_context_enable();
|
||||
return;
|
||||
}
|
||||
|
||||
if (lbake->gl_context) {
|
||||
DRW_opengl_render_context_enable(lbake->gl_context);
|
||||
if (lbake->gpu_context == NULL) {
|
||||
|
@ -545,6 +551,12 @@ static void eevee_lightbake_context_enable(EEVEE_LightBake *lbake)
|
|||
|
||||
static void eevee_lightbake_context_disable(EEVEE_LightBake *lbake)
|
||||
{
|
||||
if (GPU_use_main_context_workaround() && !BLI_thread_is_main()) {
|
||||
DRW_opengl_context_disable();
|
||||
GPU_context_main_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
if (lbake->gl_context) {
|
||||
DRW_gpu_render_context_disable(lbake->gpu_context);
|
||||
DRW_opengl_render_context_disable(lbake->gl_context);
|
||||
|
@ -697,7 +709,7 @@ wmJob *EEVEE_lightbake_job_create(struct wmWindowManager *wm,
|
|||
lbake->delay = delay;
|
||||
lbake->frame = frame;
|
||||
|
||||
if (lbake->gl_context == NULL) {
|
||||
if (lbake->gl_context == NULL && !GPU_use_main_context_workaround()) {
|
||||
lbake->gl_context = WM_opengl_context_create();
|
||||
wm_window_reset_drawable();
|
||||
}
|
||||
|
@ -742,7 +754,7 @@ void *EEVEE_lightbake_job_data_alloc(struct Main *bmain,
|
|||
lbake->mutex = BLI_mutex_alloc();
|
||||
lbake->frame = frame;
|
||||
|
||||
if (run_as_job) {
|
||||
if (run_as_job && !GPU_use_main_context_workaround()) {
|
||||
lbake->gl_context = WM_opengl_context_create();
|
||||
wm_window_reset_drawable();
|
||||
}
|
||||
|
|
|
@ -2719,6 +2719,12 @@ void DRW_render_context_enable(Render *render)
|
|||
WM_init_opengl();
|
||||
}
|
||||
|
||||
if (GPU_use_main_context_workaround()) {
|
||||
GPU_context_main_lock();
|
||||
DRW_opengl_context_enable();
|
||||
return;
|
||||
}
|
||||
|
||||
void *re_gl_context = RE_gl_context_get(render);
|
||||
|
||||
/* Changing Context */
|
||||
|
@ -2736,6 +2742,12 @@ void DRW_render_context_enable(Render *render)
|
|||
|
||||
void DRW_render_context_disable(Render *render)
|
||||
{
|
||||
if (GPU_use_main_context_workaround()) {
|
||||
DRW_opengl_context_disable();
|
||||
GPU_context_main_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
void *re_gl_context = RE_gl_context_get(render);
|
||||
|
||||
if (re_gl_context != NULL) {
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "GPU_extensions.h"
|
||||
#include "GPU_material.h"
|
||||
#include "GPU_shader.h"
|
||||
|
||||
|
@ -106,6 +107,12 @@ static void drw_deferred_shader_compilation_exec(
|
|||
BLI_assert(gl_context != NULL);
|
||||
#endif
|
||||
|
||||
const bool use_main_context_workaround = GPU_use_main_context_workaround();
|
||||
if (use_main_context_workaround) {
|
||||
BLI_assert(gl_context == DST.gl_context);
|
||||
GPU_context_main_lock();
|
||||
}
|
||||
|
||||
WM_opengl_context_activate(gl_context);
|
||||
|
||||
while (true) {
|
||||
|
@ -154,6 +161,9 @@ static void drw_deferred_shader_compilation_exec(
|
|||
}
|
||||
|
||||
WM_opengl_context_release(gl_context);
|
||||
if (use_main_context_workaround) {
|
||||
GPU_context_main_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
static void drw_deferred_shader_compilation_free(void *custom_data)
|
||||
|
@ -196,6 +206,8 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
|
|||
GPU_material_compile(mat);
|
||||
return;
|
||||
}
|
||||
const bool use_main_context = GPU_use_main_context_workaround();
|
||||
const bool job_own_context = !use_main_context;
|
||||
|
||||
DRWDeferredShader *dsh = MEM_callocN(sizeof(DRWDeferredShader), "Deferred Shader");
|
||||
|
||||
|
@ -227,7 +239,7 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
|
|||
if (old_comp->gl_context) {
|
||||
comp->gl_context = old_comp->gl_context;
|
||||
old_comp->own_context = false;
|
||||
comp->own_context = true;
|
||||
comp->own_context = job_own_context;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,9 +247,14 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
|
|||
|
||||
/* Create only one context. */
|
||||
if (comp->gl_context == NULL) {
|
||||
comp->gl_context = WM_opengl_context_create();
|
||||
WM_opengl_context_activate(DST.gl_context);
|
||||
comp->own_context = true;
|
||||
if (use_main_context) {
|
||||
comp->gl_context = DST.gl_context;
|
||||
}
|
||||
else {
|
||||
comp->gl_context = WM_opengl_context_create();
|
||||
WM_opengl_context_activate(DST.gl_context);
|
||||
}
|
||||
comp->own_context = job_own_context;
|
||||
}
|
||||
|
||||
WM_jobs_customdata_set(wm_job, comp, drw_deferred_shader_compilation_free);
|
||||
|
|
|
@ -42,6 +42,14 @@ void GPU_context_discard(GPUContext *);
|
|||
void GPU_context_active_set(GPUContext *);
|
||||
GPUContext *GPU_context_active_get(void);
|
||||
|
||||
/* Legacy GPU (Intel HD4000 series) do not support sharing GPU objects between GPU
|
||||
* contexts. EEVEE/Workbench can create different contexts for image/preview rendering, baking or
|
||||
* compiling. When a legacy GPU is detected (`GPU_use_main_context_workaround()`) any worker
|
||||
* threads should use the draw manager opengl context and make sure that they are the only one
|
||||
* using it by locking the main context using these two functions. */
|
||||
void GPU_context_main_lock(void);
|
||||
void GPU_context_main_unlock(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -48,7 +48,7 @@ bool GPU_arb_texture_cube_map_array_is_supported(void);
|
|||
bool GPU_mip_render_workaround(void);
|
||||
bool GPU_depth_blitting_workaround(void);
|
||||
bool GPU_unused_fb_slot_workaround(void);
|
||||
bool GPU_context_local_shaders_workaround(void);
|
||||
bool GPU_use_main_context_workaround(void);
|
||||
bool GPU_texture_copy_workaround(void);
|
||||
bool GPU_crappy_amd_driver(void);
|
||||
|
||||
|
|
|
@ -992,21 +992,9 @@ bool GPU_pass_compile(GPUPass *pass, const char *shname)
|
|||
shader = NULL;
|
||||
}
|
||||
}
|
||||
else if (!BLI_thread_is_main() && GPU_context_local_shaders_workaround()) {
|
||||
pass->binary.content = GPU_shader_get_binary(
|
||||
shader, &pass->binary.format, &pass->binary.len);
|
||||
GPU_shader_free(shader);
|
||||
shader = NULL;
|
||||
}
|
||||
|
||||
pass->shader = shader;
|
||||
pass->compiled = true;
|
||||
}
|
||||
else if (pass->binary.content && BLI_thread_is_main()) {
|
||||
pass->shader = GPU_shader_load_from_binary(
|
||||
pass->binary.content, pass->binary.format, pass->binary.len, shname);
|
||||
MEM_SAFE_FREE(pass->binary.content);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
@ -1027,9 +1015,6 @@ static void gpu_pass_free(GPUPass *pass)
|
|||
MEM_SAFE_FREE(pass->geometrycode);
|
||||
MEM_SAFE_FREE(pass->vertexcode);
|
||||
MEM_SAFE_FREE(pass->defines);
|
||||
if (pass->binary.content) {
|
||||
MEM_freeN(pass->binary.content);
|
||||
}
|
||||
MEM_freeN(pass);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,11 +47,6 @@ typedef struct GPUPass {
|
|||
char *defines;
|
||||
uint refcount; /* Orphaned GPUPasses gets freed by the garbage collector. */
|
||||
uint32_t hash; /* Identity hash generated from all GLSL code. */
|
||||
struct {
|
||||
char *content;
|
||||
uint format;
|
||||
int len;
|
||||
} binary;
|
||||
bool compiled; /* Did we already tried to compile the attached GPUShader. */
|
||||
} GPUPass;
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ static std::vector<GLuint> orphaned_buffer_ids;
|
|||
static std::vector<GLuint> orphaned_texture_ids;
|
||||
|
||||
static std::mutex orphans_mutex;
|
||||
static std::mutex main_context_mutex;
|
||||
|
||||
struct GPUContext {
|
||||
GLuint default_vao;
|
||||
|
@ -345,3 +346,13 @@ struct GPUMatrixState *gpu_context_active_matrix_state_get()
|
|||
BLI_assert(active_ctx);
|
||||
return active_ctx->matrix_state;
|
||||
}
|
||||
|
||||
void GPU_context_main_lock(void)
|
||||
{
|
||||
main_context_mutex.lock();
|
||||
}
|
||||
|
||||
void GPU_context_main_unlock(void)
|
||||
{
|
||||
main_context_mutex.unlock();
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ static struct GPUGlobal {
|
|||
bool broken_amd_driver;
|
||||
/* Some crappy Intel drivers don't work well with shaders created in different
|
||||
* rendering contexts. */
|
||||
bool context_local_shaders_workaround;
|
||||
bool use_main_context_workaround;
|
||||
/* Intel drivers exhibit artifacts when using #glCopyImageSubData & workbench anti-aliasing.
|
||||
* (see T76273) */
|
||||
bool texture_copy_workaround;
|
||||
|
@ -225,9 +225,9 @@ bool GPU_unused_fb_slot_workaround(void)
|
|||
return GG.unused_fb_slot_workaround;
|
||||
}
|
||||
|
||||
bool GPU_context_local_shaders_workaround(void)
|
||||
bool GPU_use_main_context_workaround(void)
|
||||
{
|
||||
return GG.context_local_shaders_workaround;
|
||||
return GG.use_main_context_workaround;
|
||||
}
|
||||
|
||||
bool GPU_texture_copy_workaround(void)
|
||||
|
@ -391,12 +391,12 @@ void gpu_extensions_init(void)
|
|||
/* Maybe not all of these drivers have problems with `GLEW_ARB_base_instance`.
|
||||
* But it's hard to test each case. */
|
||||
GG.glew_arb_base_instance_is_supported = false;
|
||||
GG.context_local_shaders_workaround = true;
|
||||
GG.use_main_context_workaround = true;
|
||||
}
|
||||
|
||||
if (strstr(version, "Build 20.19.15.4285")) {
|
||||
/* Somehow fixes armature display issues (see T69743). */
|
||||
GG.context_local_shaders_workaround = true;
|
||||
GG.use_main_context_workaround = true;
|
||||
}
|
||||
}
|
||||
else if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) &&
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "ED_screen.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "GPU_context.h"
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_immediate.h"
|
||||
#include "GPU_state.h"
|
||||
|
@ -998,6 +999,7 @@ void wm_draw_update(bContext *C)
|
|||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
wmWindow *win;
|
||||
|
||||
GPU_context_main_lock();
|
||||
BKE_image_free_unused_gpu_textures();
|
||||
|
||||
for (win = wm->windows.first; win; win = win->next) {
|
||||
|
@ -1035,6 +1037,8 @@ void wm_draw_update(bContext *C)
|
|||
|
||||
/* Draw non-windows (surfaces) */
|
||||
wm_surfaces_iter(C, wm_draw_surface);
|
||||
|
||||
GPU_context_main_unlock();
|
||||
}
|
||||
|
||||
void wm_draw_region_clear(wmWindow *win, ARegion *UNUSED(region))
|
||||
|
|
Loading…
Reference in New Issue