Fix #139443: WM: Clear draw region framebuffers to avoid corruption
This PR adds a clear on creation for draw region framebuffers, which fixes issue https://projects.blender.org/blender/blender/issues/139443. When using the "Lock Interface" option, redrawing is disabled until the rendering process has finished. When the GPU driver does not initialize framebuffer textures with zero, this means that visual corruption can be perceived when resizing the main window while rendering. This fix makes sure that framebuffer textures are initialized with zero on all GPU platforms. Pull Request: https://projects.blender.org/blender/blender/pulls/139445
This commit is contained in:
committed by
Nikita Sirgienko
parent
eb96c2dfb3
commit
282d703f6b
@@ -82,7 +82,7 @@ GPUOffScreen *image_render_begin(const int2 &win_size)
|
||||
|
||||
char err_out[256] = "unknown";
|
||||
GPUOffScreen *offscreen = GPU_offscreen_create(
|
||||
win_size.x, win_size.y, true, GPU_RGBA8, GPU_TEXTURE_USAGE_HOST_READ, err_out);
|
||||
win_size.x, win_size.y, true, GPU_RGBA8, GPU_TEXTURE_USAGE_HOST_READ, false, err_out);
|
||||
if (offscreen == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -768,6 +768,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
|
||||
true,
|
||||
GPU_RGBA16F,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_HOST_READ,
|
||||
false,
|
||||
err_out);
|
||||
DRW_gpu_context_disable();
|
||||
|
||||
|
||||
@@ -2029,6 +2029,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
|
||||
true,
|
||||
desired_format,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_HOST_READ,
|
||||
false,
|
||||
err_out);
|
||||
if (ofs == nullptr) {
|
||||
DRW_gpu_context_disable();
|
||||
|
||||
@@ -640,6 +640,7 @@ struct GPUOffScreen;
|
||||
* Create a #GPUOffScreen with attachment size of \a width by \a height pixels.
|
||||
* If \a with_depth_buffer is true, a depth buffer attachment will also be created.
|
||||
* \a format is the format of the color buffer.
|
||||
* If \a clear is true, the color and depth buffer attachments will be cleared.
|
||||
* If \a err_out is not `nullptr` it will be use to write any configuration error message..
|
||||
* \note This function binds the framebuffer to the active context.
|
||||
* \note `GPU_TEXTURE_USAGE_ATTACHMENT` is added to the usage parameter by default.
|
||||
@@ -649,6 +650,7 @@ GPUOffScreen *GPU_offscreen_create(int width,
|
||||
bool with_depth_buffer,
|
||||
eGPUTextureFormat format,
|
||||
eGPUTextureUsage usage,
|
||||
bool clear,
|
||||
char err_out[256]);
|
||||
|
||||
/**
|
||||
|
||||
@@ -730,6 +730,7 @@ GPUOffScreen *GPU_offscreen_create(int width,
|
||||
bool with_depth_buffer,
|
||||
eGPUTextureFormat format,
|
||||
eGPUTextureUsage usage,
|
||||
bool clear,
|
||||
char err_out[256])
|
||||
{
|
||||
GPUOffScreen *ofs = MEM_callocN<GPUOffScreen>(__func__);
|
||||
@@ -770,6 +771,19 @@ GPUOffScreen *GPU_offscreen_create(int width,
|
||||
GPU_offscreen_free(ofs);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (clear) {
|
||||
float const clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
float clear_depth = 0.0f;
|
||||
GPU_framebuffer_bind(fb);
|
||||
if (with_depth_buffer) {
|
||||
GPU_framebuffer_clear_color_depth(fb, clear_color, clear_depth);
|
||||
}
|
||||
else {
|
||||
GPU_framebuffer_clear_color(fb, clear_color);
|
||||
}
|
||||
}
|
||||
|
||||
GPU_framebuffer_restore();
|
||||
return ofs;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ static void test_immediate_one_plane()
|
||||
GPU_RGBA16F,
|
||||
GPU_TEXTURE_USAGE_ATTACHMENT |
|
||||
GPU_TEXTURE_USAGE_HOST_READ,
|
||||
false,
|
||||
nullptr);
|
||||
BLI_assert(offscreen != nullptr);
|
||||
GPU_offscreen_bind(offscreen, false);
|
||||
@@ -72,6 +73,7 @@ static void test_immediate_two_planes()
|
||||
GPU_RGBA16F,
|
||||
GPU_TEXTURE_USAGE_ATTACHMENT |
|
||||
GPU_TEXTURE_USAGE_HOST_READ,
|
||||
false,
|
||||
nullptr);
|
||||
BLI_assert(offscreen != nullptr);
|
||||
GPU_offscreen_bind(offscreen, false);
|
||||
|
||||
@@ -27,6 +27,7 @@ void blend_test(float4 source_a, float4 source_b, float4 expected_result)
|
||||
GPU_RGBA16F,
|
||||
GPU_TEXTURE_USAGE_ATTACHMENT |
|
||||
GPU_TEXTURE_USAGE_HOST_READ,
|
||||
false,
|
||||
nullptr);
|
||||
BLI_assert(offscreen != nullptr);
|
||||
GPU_offscreen_bind(offscreen, false);
|
||||
|
||||
@@ -25,7 +25,8 @@ template<GPUVertCompType comp_type, GPUVertFetchMode fetch_mode, typename ColorT
|
||||
static void vertex_buffer_fetch_mode(ColorType color)
|
||||
{
|
||||
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_HOST_READ;
|
||||
GPUOffScreen *offscreen = GPU_offscreen_create(Size, Size, false, GPU_RGBA32F, usage, nullptr);
|
||||
GPUOffScreen *offscreen = GPU_offscreen_create(
|
||||
Size, Size, false, GPU_RGBA32F, usage, false, nullptr);
|
||||
BLI_assert(offscreen != nullptr);
|
||||
GPU_offscreen_bind(offscreen, false);
|
||||
GPUTexture *color_texture = GPU_offscreen_color_texture(offscreen);
|
||||
|
||||
@@ -310,6 +310,7 @@ static PyObject *pygpu_offscreen__tp_new(PyTypeObject * /*self*/, PyObject *args
|
||||
true,
|
||||
eGPUTextureFormat(pygpu_textureformat.value_found),
|
||||
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_HOST_READ,
|
||||
false,
|
||||
err_out);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -722,6 +722,7 @@ static void wm_draw_region_buffer_create(Scene *scene,
|
||||
false,
|
||||
desired_format,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ,
|
||||
true,
|
||||
nullptr);
|
||||
if (!offscreen) {
|
||||
WM_global_report(RPT_ERROR, "Region could not be drawn!");
|
||||
@@ -1215,8 +1216,13 @@ static void wm_draw_window(bContext *C, wmWindow *win)
|
||||
* an off-screen texture and then draw it. This used to happen for all
|
||||
* stereo methods, but it's less efficient than drawing directly. */
|
||||
const blender::int2 win_size = WM_window_native_pixel_size(win);
|
||||
GPUOffScreen *offscreen = GPU_offscreen_create(
|
||||
win_size[0], win_size[1], false, desired_format, GPU_TEXTURE_USAGE_SHADER_READ, nullptr);
|
||||
GPUOffScreen *offscreen = GPU_offscreen_create(win_size[0],
|
||||
win_size[1],
|
||||
false,
|
||||
desired_format,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ,
|
||||
false,
|
||||
nullptr);
|
||||
|
||||
if (offscreen) {
|
||||
GPUTexture *texture = GPU_offscreen_color_texture(offscreen);
|
||||
@@ -1371,8 +1377,13 @@ uint8_t *WM_window_pixels_read_from_offscreen(bContext *C, wmWindow *win, int r_
|
||||
/* Determine desired offscreen format depending on HDR availability. */
|
||||
eGPUTextureFormat desired_format = get_hdr_framebuffer_format(WM_window_get_active_scene(win));
|
||||
|
||||
GPUOffScreen *offscreen = GPU_offscreen_create(
|
||||
win_size[0], win_size[1], false, desired_format, GPU_TEXTURE_USAGE_SHADER_READ, nullptr);
|
||||
GPUOffScreen *offscreen = GPU_offscreen_create(win_size[0],
|
||||
win_size[1],
|
||||
false,
|
||||
desired_format,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ,
|
||||
false,
|
||||
nullptr);
|
||||
if (UNLIKELY(!offscreen)) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1406,7 +1417,7 @@ bool WM_window_pixels_read_sample_from_offscreen(bContext *C,
|
||||
}
|
||||
|
||||
GPUOffScreen *offscreen = GPU_offscreen_create(
|
||||
win_size[0], win_size[1], false, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ, nullptr);
|
||||
win_size[0], win_size[1], false, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ, false, nullptr);
|
||||
if (UNLIKELY(!offscreen)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1414,6 +1414,7 @@ bool wm_xr_session_surface_offscreen_ensure(wmXrSurfaceData *surface_data,
|
||||
format,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ |
|
||||
GPU_TEXTURE_USAGE_MEMORY_EXPORT,
|
||||
false,
|
||||
err_out);
|
||||
if (offscreen) {
|
||||
viewport = vp->viewport = GPU_viewport_create();
|
||||
|
||||
Reference in New Issue
Block a user