GPU: Add Texture Usage Parameter to GPUOffscreen. #106899

Merged
Jeroen Bakker merged 5 commits from Jeroen-Bakker/blender:gpu-offscreen-texture-usage into main 2023-04-14 22:03:03 +02:00
9 changed files with 48 additions and 14 deletions

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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;

View File

@ -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.

View File

@ -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<GPUOffScreen>(__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) {

View File

@ -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");

View File

@ -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;
}

View File

@ -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) {