diff --git a/source/blender/editors/gpencil_legacy/gpencil_fill.c b/source/blender/editors/gpencil_legacy/gpencil_fill.c index d618cc9fece..31daa391845 100644 --- a/source/blender/editors/gpencil_legacy/gpencil_fill.c +++ b/source/blender/editors/gpencil_legacy/gpencil_fill.c @@ -1235,7 +1235,7 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf) char err_out[256] = "unknown"; GPUOffScreen *offscreen = GPU_offscreen_create( - tgpf->sizex, tgpf->sizey, true, GPU_RGBA8, err_out); + tgpf->sizex, tgpf->sizey, true, GPU_RGBA8, GPU_TEXTURE_USAGE_HOST_READ, err_out); if (offscreen == NULL) { printf("GPencil - Fill - Unable to create fill buffer\n"); return false; diff --git a/source/blender/editors/render/render_opengl.cc b/source/blender/editors/render/render_opengl.cc index 076d2cc48b1..97de0f5aede 100644 --- a/source/blender/editors/render/render_opengl.cc +++ b/source/blender/editors/render/render_opengl.cc @@ -757,7 +757,12 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) /* corrects render size with actual size, not every card supports non-power-of-two dimensions */ DRW_opengl_context_enable(); /* Off-screen creation needs to be done in DRW context. */ - ofs = GPU_offscreen_create(sizex, sizey, true, GPU_RGBA16F, err_out); + ofs = GPU_offscreen_create(sizex, + sizey, + true, + GPU_RGBA16F, + GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_HOST_READ, + err_out); DRW_opengl_context_disable(); if (!ofs) { diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c index 384aeccfc4c..95b82131789 100644 --- a/source/blender/editors/screen/screen_draw.c +++ b/source/blender/editors/screen/screen_draw.c @@ -425,7 +425,13 @@ static void screen_preview_draw(const bScreen *screen, int size_x, int size_y) void ED_screen_preview_render(const bScreen *screen, int size_x, int size_y, uint *r_rect) { char err_out[256] = "unknown"; - GPUOffScreen *offscreen = GPU_offscreen_create(size_x, size_y, true, GPU_RGBA8, err_out); + GPUOffScreen *offscreen = GPU_offscreen_create(size_x, + size_y, + true, + GPU_RGBA8, + GPU_TEXTURE_USAGE_SHADER_READ | + GPU_TEXTURE_USAGE_HOST_READ, + err_out); GPU_offscreen_bind(offscreen, true); GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f); diff --git a/source/blender/editors/space_view3d/view3d_draw.cc b/source/blender/editors/space_view3d/view3d_draw.cc index 86a7033d0df..aeef48cb16f 100644 --- a/source/blender/editors/space_view3d/view3d_draw.cc +++ b/source/blender/editors/space_view3d/view3d_draw.cc @@ -1886,7 +1886,12 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph, if (own_ofs) { /* bind */ - ofs = GPU_offscreen_create(sizex, sizey, true, GPU_RGBA8, err_out); + ofs = GPU_offscreen_create(sizex, + sizey, + true, + GPU_RGBA8, + GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_HOST_READ, + err_out); if (ofs == nullptr) { DRW_opengl_context_disable(); return nullptr; diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h index f40144ef8a8..f4a71e0811d 100644 --- a/source/blender/gpu/GPU_framebuffer.h +++ b/source/blender/gpu/GPU_framebuffer.h @@ -588,9 +588,14 @@ typedef struct GPUOffScreen GPUOffScreen; * \a format is the format of the color buffer. * 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. */ -GPUOffScreen *GPU_offscreen_create( - int width, int height, bool with_depth_buffer, eGPUTextureFormat format, char err_out[256]); +GPUOffScreen *GPU_offscreen_create(int width, + int height, + bool with_depth_buffer, + eGPUTextureFormat format, + eGPUTextureUsage usage, + char err_out[256]); /** * Free a #GPUOffScreen. diff --git a/source/blender/gpu/intern/gpu_framebuffer.cc b/source/blender/gpu/intern/gpu_framebuffer.cc index 4720941e1f2..1a8d8518f95 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.cc +++ b/source/blender/gpu/intern/gpu_framebuffer.cc @@ -652,8 +652,12 @@ static GPUFrameBuffer *gpu_offscreen_fb_get(GPUOffScreen *ofs) return gpu_offscreen_fb_get(ofs); } -GPUOffScreen *GPU_offscreen_create( - int width, int height, bool depth, eGPUTextureFormat format, char err_out[256]) +GPUOffScreen *GPU_offscreen_create(int width, + int height, + bool depth, + eGPUTextureFormat format, + eGPUTextureUsage usage, + char err_out[256]) { GPUOffScreen *ofs = MEM_cnew(__func__); @@ -662,7 +666,9 @@ GPUOffScreen *GPU_offscreen_create( height = max_ii(1, height); width = max_ii(1, width); - eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT; + /* Always add GPU_TEXTURE_USAGE_ATTACHMENT for convenience. */ + usage |= GPU_TEXTURE_USAGE_ATTACHMENT; + ofs->color = GPU_texture_create_2d("ofs_color", width, height, 1, format, usage, nullptr); if (depth) { diff --git a/source/blender/python/gpu/gpu_py_offscreen.c b/source/blender/python/gpu/gpu_py_offscreen.c index 6e50a7f323d..f88085edd5a 100644 --- a/source/blender/python/gpu/gpu_py_offscreen.c +++ b/source/blender/python/gpu/gpu_py_offscreen.c @@ -232,7 +232,12 @@ static PyObject *pygpu_offscreen__tp_new(PyTypeObject *UNUSED(self), } if (GPU_context_active_get()) { - ofs = GPU_offscreen_create(width, height, true, pygpu_textureformat.value_found, err_out); + ofs = GPU_offscreen_create(width, + height, + true, + pygpu_textureformat.value_found, + GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_HOST_READ, + err_out); } else { STRNCPY(err_out, "No active GPU context found"); diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 1f8b434d08d..b63756dd886 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -685,7 +685,7 @@ static void wm_draw_region_buffer_create(ARegion *region, bool stereo, bool use_ * depth or multisample buffers. 3D view creates own buffers with * the data it needs. */ GPUOffScreen *offscreen = GPU_offscreen_create( - region->winx, region->winy, false, GPU_RGBA8, NULL); + region->winx, region->winy, false, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ, NULL); if (!offscreen) { WM_report(RPT_ERROR, "Region could not be drawn!"); return; @@ -1151,7 +1151,8 @@ static void wm_draw_window(bContext *C, wmWindow *win) * stereo methods, but it's less efficient than drawing directly. */ const int width = WM_window_pixels_x(win); const int height = WM_window_pixels_y(win); - GPUOffScreen *offscreen = GPU_offscreen_create(width, height, false, GPU_RGBA8, NULL); + GPUOffScreen *offscreen = GPU_offscreen_create( + width, height, false, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ, NULL); if (offscreen) { GPUTexture *texture = GPU_offscreen_color_texture(offscreen); @@ -1226,7 +1227,8 @@ uint *WM_window_pixels_read_offscreen(bContext *C, wmWindow *win, int r_size[2]) r_size[0] = WM_window_pixels_x(win); r_size[1] = WM_window_pixels_y(win); - GPUOffScreen *offscreen = GPU_offscreen_create(r_size[0], r_size[1], false, GPU_RGBA8, NULL); + GPUOffScreen *offscreen = GPU_offscreen_create( + r_size[0], r_size[1], false, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ, NULL); if (UNLIKELY(!offscreen)) { return NULL; } diff --git a/source/blender/windowmanager/xr/intern/wm_xr_session.c b/source/blender/windowmanager/xr/intern/wm_xr_session.c index aefc3afff66..64d687b956a 100644 --- a/source/blender/windowmanager/xr/intern/wm_xr_session.c +++ b/source/blender/windowmanager/xr/intern/wm_xr_session.c @@ -1388,7 +1388,7 @@ bool wm_xr_session_surface_offscreen_ensure(wmXrSurfaceData *surface_data, BLI_assert(format != GPU_R8); offscreen = vp->offscreen = GPU_offscreen_create( - draw_view->width, draw_view->height, true, format, err_out); + draw_view->width, draw_view->height, true, format, GPU_TEXTURE_USAGE_SHADER_READ, err_out); if (offscreen) { viewport = vp->viewport = GPU_viewport_create(); if (!viewport) {