From abf4c4d9ef64d38336daada108d47db2215758ba Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 1 Feb 2024 20:32:24 +0100 Subject: [PATCH] Refactor: Change functions to retrieve GPU textures from images * For materials with UDIM tiles support, get array and mapping in one call * For viewers that can use render results, add a dedicated function * Fix potential use of render results in stencil overlay and grease pencil Pull Request: https://projects.blender.org/blender/blender/pulls/117563 --- source/blender/blenkernel/BKE_image.h | 28 +++++-- source/blender/blenkernel/intern/image_gpu.cc | 81 +++++++++++-------- .../draw/engines/eevee_next/eevee_lookdev.cc | 2 +- .../draw/engines/gpencil/gpencil_draw_data.cc | 11 +-- .../draw/engines/gpencil/gpencil_material.hh | 9 +-- .../draw/engines/overlay/overlay_edit_uv.cc | 27 +------ .../draw/engines/overlay/overlay_image.cc | 17 ++-- .../draw/engines/overlay/overlay_paint.cc | 2 +- .../draw/engines/overlay/overlay_private.hh | 5 -- .../workbench/workbench_mesh_passes.cc | 26 +++--- .../blender/draw/intern/draw_manager_data.cc | 19 ++--- source/blender/draw/intern/draw_pass.hh | 21 +++-- .../blender/makesrna/intern/rna_image_api.cc | 2 +- source/blender/python/gpu/gpu_py_texture.cc | 2 +- 14 files changed, 112 insertions(+), 140 deletions(-) diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index d7799c146f9..5252dfa7e7b 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -518,8 +518,7 @@ void BKE_image_ensure_gpu_texture(struct Image *image, struct ImageUser *iuser); /** * Get the #GPUTexture for a given `Image`. * - * `iuser` and `ibuf` are mutual exclusive parameters. The caller can pass the `ibuf` when already - * available. It is also required when requesting the #GPUTexture for a render result. + * * * The requested GPU texture will be cached for subsequent calls, but only a single layer, pass, * and view can be cached at a time, so the cache should be invalidated in operators and RNA @@ -530,11 +529,26 @@ void BKE_image_ensure_gpu_texture(struct Image *image, struct ImageUser *iuser); * calling BKE_image_ensure_gpu_texture. This is a workaround until image can support a more * complete caching system. */ -struct GPUTexture *BKE_image_get_gpu_texture(struct Image *image, - struct ImageUser *iuser, - struct ImBuf *ibuf); -struct GPUTexture *BKE_image_get_gpu_tiles(struct Image *image, struct ImageUser *iuser); -struct GPUTexture *BKE_image_get_gpu_tilemap(struct Image *image, struct ImageUser *iuser); +struct GPUTexture *BKE_image_get_gpu_texture(struct Image *image, struct ImageUser *iuser); + +/* + * Like BKE_image_get_gpu_texture, but can also get render or compositing result. + */ +struct GPUTexture *BKE_image_get_gpu_viewer_texture(struct Image *image, struct ImageUser *iuser); + +/* + * Like BKE_image_get_gpu_texture, but can also return array and tile mapping texture for UDIM + * tiles as used in material shaders. + */ +typedef struct ImageGPUTextures { + struct GPUTexture *texture; + struct GPUTexture *tile_mapping; +} ImageGPUTextures; + +ImageGPUTextures BKE_image_get_gpu_material_texture(struct Image *image, + struct ImageUser *iuser, + const bool use_tile_mapping); + /** * Is the alpha of the `GPUTexture` for a given image/ibuf premultiplied. */ diff --git a/source/blender/blenkernel/intern/image_gpu.cc b/source/blender/blenkernel/intern/image_gpu.cc index b8e832681b2..51d79f709ae 100644 --- a/source/blender/blenkernel/intern/image_gpu.cc +++ b/source/blender/blenkernel/intern/image_gpu.cc @@ -351,13 +351,15 @@ void BKE_image_ensure_gpu_texture(Image *image, ImageUser *image_user) } } -static GPUTexture *image_get_gpu_texture(Image *ima, - ImageUser *iuser, - ImBuf *ibuf, - eGPUTextureTarget textarget) +static ImageGPUTextures image_get_gpu_texture(Image *ima, + ImageUser *iuser, + const bool use_viewers, + const bool use_tile_mapping) { + ImageGPUTextures result = {}; + if (ima == nullptr) { - return nullptr; + return result; } /* Free any unused GPU textures, since we know we are in a thread with OpenGL @@ -396,6 +398,11 @@ static GPUTexture *image_get_gpu_texture(Image *ima, /* Tag as in active use for garbage collector. */ BKE_image_tag_time(ima); + /* Test if we need to get a tiled array texture. */ + eGPUTextureTarget textarget = (use_tile_mapping && ima->source == IMA_SRC_TILED) ? + TEXTARGET_2D_ARRAY : + TEXTARGET_2D; + /* Test if we already have a texture. */ int current_view = iuser ? iuser->multi_index : 0; if (current_view >= 2) { @@ -403,7 +410,9 @@ static GPUTexture *image_get_gpu_texture(Image *ima, } GPUTexture **tex = get_image_gpu_texture_ptr(ima, textarget, current_view); if (*tex) { - return *tex; + result.texture = *tex; + result.tile_mapping = *get_image_gpu_texture_ptr(ima, TEXTARGET_TILE_MAPPING, current_view); + return result; } /* Check if we have a valid image. If not, we return a dummy @@ -411,32 +420,38 @@ static GPUTexture *image_get_gpu_texture(Image *ima, ImageTile *tile = BKE_image_get_tile(ima, 0); if (tile == nullptr) { *tex = image_gpu_texture_error_create(textarget); - return *tex; + result.texture = *tex; + return result; } /* check if we have a valid image buffer */ - ImBuf *ibuf_intern = ibuf; - if (ibuf_intern == nullptr) { - ibuf_intern = BKE_image_acquire_ibuf(ima, iuser, nullptr); - if (ibuf_intern == nullptr) { - *tex = image_gpu_texture_error_create(textarget); - return *tex; - } + void *lock; + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, (use_viewers) ? &lock : nullptr); + if (ibuf == nullptr) { + BKE_image_release_ibuf(ima, ibuf, (use_viewers) ? &lock : nullptr); + *tex = image_gpu_texture_error_create(textarget); + result.texture = *tex; + + return result; } if (textarget == TEXTARGET_2D_ARRAY) { - *tex = gpu_texture_create_tile_array(ima, ibuf_intern); - } - else if (textarget == TEXTARGET_TILE_MAPPING) { - *tex = gpu_texture_create_tile_mapping(ima, iuser ? iuser->multiview_eye : 0); + /* For materials, array and tile mapping in case there are UDIM tiles. */ + *tex = gpu_texture_create_tile_array(ima, ibuf); + result.texture = *tex; + + GPUTexture **tile_mapping_tex = get_image_gpu_texture_ptr( + ima, TEXTARGET_TILE_MAPPING, current_view); + *tile_mapping_tex = gpu_texture_create_tile_mapping(ima, iuser ? iuser->multiview_eye : 0); + result.tile_mapping = *tile_mapping_tex; } else { + /* Single image texture. */ const bool use_high_bitdepth = (ima->flag & IMA_HIGH_BITDEPTH); - const bool store_premultiplied = BKE_image_has_gpu_texture_premultiplied_alpha(ima, - ibuf_intern); + const bool store_premultiplied = BKE_image_has_gpu_texture_premultiplied_alpha(ima, ibuf); - *tex = IMB_create_gpu_texture( - ima->id.name + 2, ibuf_intern, use_high_bitdepth, store_premultiplied); + *tex = IMB_create_gpu_texture(ima->id.name + 2, ibuf, use_high_bitdepth, store_premultiplied); + result.texture = *tex; if (*tex) { GPU_texture_extend_mode(*tex, GPU_SAMPLER_EXTEND_MODE_REPEAT); @@ -455,29 +470,29 @@ static GPUTexture *image_get_gpu_texture(Image *ima, } if (*tex) { - GPU_texture_original_size_set(*tex, ibuf_intern->x, ibuf_intern->y); + GPU_texture_original_size_set(*tex, ibuf->x, ibuf->y); } - if (ibuf != ibuf_intern) { - BKE_image_release_ibuf(ima, ibuf_intern, nullptr); - } + BKE_image_release_ibuf(ima, ibuf, (use_viewers) ? &lock : nullptr); - return *tex; + return result; } -GPUTexture *BKE_image_get_gpu_texture(Image *image, ImageUser *iuser, ImBuf *ibuf) +GPUTexture *BKE_image_get_gpu_texture(Image *image, ImageUser *iuser) { - return image_get_gpu_texture(image, iuser, ibuf, TEXTARGET_2D); + return image_get_gpu_texture(image, iuser, false, false).texture; } -GPUTexture *BKE_image_get_gpu_tiles(Image *image, ImageUser *iuser) +GPUTexture *BKE_image_get_gpu_viewer_texture(Image *image, ImageUser *iuser) { - return image_get_gpu_texture(image, iuser, nullptr, TEXTARGET_2D_ARRAY); + return image_get_gpu_texture(image, iuser, true, false).texture; } -GPUTexture *BKE_image_get_gpu_tilemap(Image *image, ImageUser *iuser) +ImageGPUTextures BKE_image_get_gpu_material_texture(Image *image, + ImageUser *iuser, + const bool use_tile_mapping) { - return image_get_gpu_texture(image, iuser, nullptr, TEXTARGET_TILE_MAPPING); + return image_get_gpu_texture(image, iuser, false, use_tile_mapping); } /** \} */ diff --git a/source/blender/draw/engines/eevee_next/eevee_lookdev.cc b/source/blender/draw/engines/eevee_next/eevee_lookdev.cc index 4d54859402e..b3caa771c55 100644 --- a/source/blender/draw/engines/eevee_next/eevee_lookdev.cc +++ b/source/blender/draw/engines/eevee_next/eevee_lookdev.cc @@ -71,7 +71,7 @@ LookdevWorld::LookdevWorld() /* TODO: This works around the issue that the first time the texture is accessed the image would * overwrite the set GPU texture. A better solution would be to use image data-blocks as part of * the studio-lights, but that requires a larger refactoring. */ - BKE_image_get_gpu_texture(&image, &environment_storage->iuser, nullptr); + BKE_image_get_gpu_texture(&image, &environment_storage->iuser); /* Create a dummy image data block to hold GPU textures generated by studio-lights. */ STRNCPY(world.id.name, "WOLookdev"); diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_data.cc b/source/blender/draw/engines/gpencil/gpencil_draw_data.cc index bfedf05361f..4b45b53e355 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_data.cc +++ b/source/blender/draw/engines/gpencil/gpencil_draw_data.cc @@ -41,18 +41,11 @@ static GPENCIL_MaterialPool *gpencil_material_pool_add(GPENCIL_PrivateData *pd) static GPUTexture *gpencil_image_texture_get(Image *image, bool *r_alpha_premult) { - ImBuf *ibuf; ImageUser iuser = {nullptr}; GPUTexture *gpu_tex = nullptr; - void *lock; - ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock); - - if (ibuf != nullptr && ibuf->byte_buffer.data != nullptr) { - gpu_tex = BKE_image_get_gpu_texture(image, &iuser, ibuf); - *r_alpha_premult = (image->alpha_mode == IMA_ALPHA_PREMUL); - } - BKE_image_release_ibuf(image, ibuf, lock); + gpu_tex = BKE_image_get_gpu_texture(image, &iuser); + *r_alpha_premult = (gpu_tex) ? (image->alpha_mode == IMA_ALPHA_PREMUL) : false; return gpu_tex; } diff --git a/source/blender/draw/engines/gpencil/gpencil_material.hh b/source/blender/draw/engines/gpencil/gpencil_material.hh index 530ef578769..8b6e4c0336a 100644 --- a/source/blender/draw/engines/gpencil/gpencil_material.hh +++ b/source/blender/draw/engines/gpencil/gpencil_material.hh @@ -89,10 +89,8 @@ class MaterialModule { /* Returns the correct flag for this texture. */ gpMaterialFlag texture_sync(::Image *image, gpMaterialFlag use_flag, gpMaterialFlag premul_flag) { - ImBuf *ibuf; ImageUser iuser = {nullptr}; GPUTexture *gpu_tex = nullptr; - void *lock; bool premul = false; if (image == nullptr) { @@ -100,13 +98,10 @@ class MaterialModule { return GP_FLAG_NONE; } - ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock); - - if (ibuf != nullptr) { - gpu_tex = BKE_image_get_gpu_texture(image, &iuser, ibuf); + gpu_tex = BKE_image_get_gpu_texture(image, &iuser); + if (gpu_tex) { premul = (image->alpha_mode == IMA_ALPHA_PREMUL) != 0; } - BKE_image_release_ibuf(image, ibuf, lock); texture_pool_.append(gpu_tex); diff --git a/source/blender/draw/engines/overlay/overlay_edit_uv.cc b/source/blender/draw/engines/overlay/overlay_edit_uv.cc index 2178658186f..52adc006fcb 100644 --- a/source/blender/draw/engines/overlay/overlay_edit_uv.cc +++ b/source/blender/draw/engines/overlay/overlay_edit_uv.cc @@ -354,24 +354,15 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata) if (pd->edit_uv.do_stencil_overlay) { const Brush *brush = BKE_paint_brush(&ts->imapaint.paint); ::Image *stencil_image = brush->clone.image; - ImBuf *stencil_ibuf = BKE_image_acquire_ibuf( - stencil_image, nullptr, &pd->edit_uv.stencil_lock); + GPUTexture *stencil_texture = BKE_image_get_gpu_texture(stencil_image, nullptr); - if (stencil_ibuf == nullptr) { - pd->edit_uv.stencil_ibuf = nullptr; - pd->edit_uv.stencil_image = nullptr; - } - else { + if (stencil_texture != nullptr) { DRW_PASS_CREATE(psl->edit_uv_stencil_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ALPHA_PREMUL); GPUShader *sh = OVERLAY_shader_edit_uv_stencil_image(); GPUBatch *geom = DRW_cache_quad_get(); DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->edit_uv_stencil_ps); - pd->edit_uv.stencil_ibuf = stencil_ibuf; - pd->edit_uv.stencil_image = stencil_image; - GPUTexture *stencil_texture = BKE_image_get_gpu_texture( - stencil_image, nullptr, stencil_ibuf); DRW_shgroup_uniform_texture(grp, "imgTexture", stencil_texture); DRW_shgroup_uniform_bool_copy(grp, "imgPremultiplied", true); DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", true); @@ -380,7 +371,8 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata) float size_image[2]; BKE_image_get_size_fl(image, nullptr, size_image); - float size_stencil_image[2] = {float(stencil_ibuf->x), float(stencil_ibuf->y)}; + float size_stencil_image[2] = {float(GPU_texture_original_width(stencil_texture)), + float(GPU_texture_original_height(stencil_texture))}; float obmat[4][4]; unit_m4(obmat); @@ -392,10 +384,6 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata) DRW_shgroup_call_obmat(grp, geom, obmat); } } - else { - pd->edit_uv.stencil_ibuf = nullptr; - pd->edit_uv.stencil_image = nullptr; - } if (pd->edit_uv.do_mask_overlay) { const bool is_combined_overlay = pd->edit_uv.mask_overlay_mode == MASK_OVERLAY_COMBINED; @@ -545,13 +533,6 @@ static void OVERLAY_edit_uv_draw_finish(OVERLAY_Data *vedata) OVERLAY_StorageList *stl = vedata->stl; OVERLAY_PrivateData *pd = stl->pd; - if (pd->edit_uv.stencil_ibuf) { - BKE_image_release_ibuf( - pd->edit_uv.stencil_image, pd->edit_uv.stencil_ibuf, pd->edit_uv.stencil_lock); - pd->edit_uv.stencil_image = nullptr; - pd->edit_uv.stencil_ibuf = nullptr; - } - DRW_TEXTURE_FREE_SAFE(pd->edit_uv.mask_texture); } diff --git a/source/blender/draw/engines/overlay/overlay_image.cc b/source/blender/draw/engines/overlay/overlay_image.cc index e3f89d592f5..60d14bdbb10 100644 --- a/source/blender/draw/engines/overlay/overlay_image.cc +++ b/source/blender/draw/engines/overlay/overlay_image.cc @@ -129,7 +129,6 @@ static GPUTexture *image_camera_background_texture_get(CameraBGImage *bgpic, bool *r_use_alpha_premult, bool *r_use_view_transform) { - void *lock; Image *image = bgpic->ima; ImageUser *iuser = &bgpic->iuser; MovieClip *clip = nullptr; @@ -158,22 +157,16 @@ static GPUTexture *image_camera_background_texture_get(CameraBGImage *bgpic, camera_background_images_stereo_setup(scene, draw_ctx->v3d, image, iuser); iuser->scene = draw_ctx->scene; - ImBuf *ibuf = BKE_image_acquire_ibuf(image, iuser, &lock); - if (ibuf == nullptr) { - BKE_image_release_ibuf(image, ibuf, lock); - iuser->scene = nullptr; - return nullptr; - } - width = ibuf->x; - height = ibuf->y; - tex = BKE_image_get_gpu_texture(image, iuser, ibuf); - BKE_image_release_ibuf(image, ibuf, lock); + tex = BKE_image_get_gpu_viewer_texture(image, iuser); iuser->scene = nullptr; if (tex == nullptr) { return nullptr; } + width = GPU_texture_original_width(tex); + height = GPU_texture_original_height(tex); + aspect_x = bgpic->ima->aspx; aspect_y = bgpic->ima->aspy; break; @@ -381,7 +374,7 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob) if (ima != nullptr) { ImageUser iuser = *ob->iuser; camera_background_images_stereo_setup(draw_ctx->scene, draw_ctx->v3d, ima, &iuser); - tex = BKE_image_get_gpu_texture(ima, &iuser, nullptr); + tex = BKE_image_get_gpu_texture(ima, &iuser); if (tex) { size[0] = GPU_texture_original_width(tex); size[1] = GPU_texture_original_height(tex); diff --git a/source/blender/draw/engines/overlay/overlay_paint.cc b/source/blender/draw/engines/overlay/overlay_paint.cc index 3dc89e34cd5..da5168862ca 100644 --- a/source/blender/draw/engines/overlay/overlay_paint.cc +++ b/source/blender/draw/engines/overlay/overlay_paint.cc @@ -139,7 +139,7 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata) state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA; DRW_PASS_CREATE(psl->paint_color_ps, state | pd->clipping_state); - GPUTexture *tex = BKE_image_get_gpu_texture(imapaint->stencil, nullptr, nullptr); + GPUTexture *tex = BKE_image_get_gpu_texture(imapaint->stencil, nullptr); const bool mask_premult = (imapaint->stencil->alpha_mode == IMA_ALPHA_PREMUL); const bool mask_inverted = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) != 0; diff --git a/source/blender/draw/engines/overlay/overlay_private.hh b/source/blender/draw/engines/overlay/overlay_private.hh index 2e24fd39c87..e528b779211 100644 --- a/source/blender/draw/engines/overlay/overlay_private.hh +++ b/source/blender/draw/engines/overlay/overlay_private.hh @@ -409,11 +409,6 @@ struct OVERLAY_PrivateData { ListBase totals; float total_area_ratio; - /* stencil overlay */ - Image *stencil_image; - ImBuf *stencil_ibuf; - void *stencil_lock; - /* mask overlay */ Mask *mask; eMaskOverlayMode mask_overlay_mode; diff --git a/source/blender/draw/engines/workbench/workbench_mesh_passes.cc b/source/blender/draw/engines/workbench/workbench_mesh_passes.cc index b9de4da1ff9..71ce659385a 100644 --- a/source/blender/draw/engines/workbench/workbench_mesh_passes.cc +++ b/source/blender/draw/engines/workbench/workbench_mesh_passes.cc @@ -66,27 +66,19 @@ PassMain::Sub &MeshPass::get_subpass( is_empty_ = false; if (image) { - GPUTexture *texture = nullptr; - GPUTexture *tilemap = nullptr; - if (image->source == IMA_SRC_TILED) { - texture = BKE_image_get_gpu_tiles(image, iuser); - tilemap = BKE_image_get_gpu_tilemap(image, iuser); - } - else { - texture = BKE_image_get_gpu_texture(image, iuser, nullptr); - } - if (texture) { + ImageGPUTextures gputex = BKE_image_get_gpu_material_texture(image, iuser, true); + if (gputex.texture) { auto add_cb = [&] { PassMain::Sub *sub_pass = passes_[int(geometry_type)][int(eShaderType::TEXTURE)]; sub_pass = &sub_pass->sub(image->id.name); - if (tilemap) { - sub_pass->bind_texture(WB_TILE_ARRAY_SLOT, texture, sampler_state); - sub_pass->bind_texture(WB_TILE_DATA_SLOT, tilemap); + if (gputex.tile_mapping) { + sub_pass->bind_texture(WB_TILE_ARRAY_SLOT, gputex.texture, sampler_state); + sub_pass->bind_texture(WB_TILE_DATA_SLOT, gputex.tile_mapping); } else { - sub_pass->bind_texture(WB_TEXTURE_SLOT, texture, sampler_state); + sub_pass->bind_texture(WB_TEXTURE_SLOT, gputex.texture, sampler_state); } - sub_pass->push_constant("isImageTile", tilemap != nullptr); + sub_pass->push_constant("isImageTile", gputex.tile_mapping != nullptr); sub_pass->push_constant("imagePremult", image && image->alpha_mode == IMA_ALPHA_PREMUL); /* TODO(@pragma37): This setting should be exposed on the user side, * either as a global parameter (and set it here) @@ -99,8 +91,8 @@ PassMain::Sub &MeshPass::get_subpass( return sub_pass; }; - return *texture_subpass_map_.lookup_or_add_cb(TextureSubPassKey(texture, geometry_type), - add_cb); + return *texture_subpass_map_.lookup_or_add_cb( + TextureSubPassKey(gputex.texture, geometry_type), add_cb); } } diff --git a/source/blender/draw/intern/draw_manager_data.cc b/source/blender/draw/intern/draw_manager_data.cc index 51cb933a5ee..662e324d5c9 100644 --- a/source/blender/draw/intern/draw_manager_data.cc +++ b/source/blender/draw/intern/draw_manager_data.cc @@ -1803,18 +1803,15 @@ void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, GPUMaterial *mater /* Bind all textures needed by the material. */ LISTBASE_FOREACH (GPUMaterialTexture *, tex, &textures) { if (tex->ima) { - /* Image */ - GPUTexture *gputex; + const bool use_tile_mapping = tex->tiled_mapping_name[0]; ImageUser *iuser = tex->iuser_available ? &tex->iuser : nullptr; - if (tex->tiled_mapping_name[0]) { - gputex = BKE_image_get_gpu_tiles(tex->ima, iuser); - drw_shgroup_material_texture(grp, gputex, tex->sampler_name, tex->sampler_state); - gputex = BKE_image_get_gpu_tilemap(tex->ima, iuser); - drw_shgroup_material_texture(grp, gputex, tex->tiled_mapping_name, tex->sampler_state); - } - else { - gputex = BKE_image_get_gpu_texture(tex->ima, iuser, nullptr); - drw_shgroup_material_texture(grp, gputex, tex->sampler_name, tex->sampler_state); + ImageGPUTextures gputex = BKE_image_get_gpu_material_texture( + tex->ima, iuser, use_tile_mapping); + + drw_shgroup_material_texture(grp, gputex.texture, tex->sampler_name, tex->sampler_state); + if (gputex.tile_mapping) { + drw_shgroup_material_texture( + grp, gputex.tile_mapping, tex->tiled_mapping_name, tex->sampler_state); } } else if (tex->colorband) { diff --git a/source/blender/draw/intern/draw_pass.hh b/source/blender/draw/intern/draw_pass.hh index f02e87855a9..ed73bc339b5 100644 --- a/source/blender/draw/intern/draw_pass.hh +++ b/source/blender/draw/intern/draw_pass.hh @@ -923,20 +923,17 @@ template inline void PassBase::material_set(Manager &manager, GPUMat for (GPUMaterialTexture *tex : ListBaseWrapper(textures)) { if (tex->ima) { /* Image */ + const bool use_tile_mapping = tex->tiled_mapping_name[0]; ImageUser *iuser = tex->iuser_available ? &tex->iuser : nullptr; - if (tex->tiled_mapping_name[0]) { - GPUTexture *tiles = BKE_image_get_gpu_tiles(tex->ima, iuser); - manager.acquire_texture(tiles); - bind_texture(tex->sampler_name, tiles, tex->sampler_state); + ImageGPUTextures gputex = BKE_image_get_gpu_material_texture( + tex->ima, iuser, use_tile_mapping); - GPUTexture *tile_map = BKE_image_get_gpu_tilemap(tex->ima, iuser); - manager.acquire_texture(tile_map); - bind_texture(tex->tiled_mapping_name, tile_map, tex->sampler_state); - } - else { - GPUTexture *texture = BKE_image_get_gpu_texture(tex->ima, iuser, nullptr); - manager.acquire_texture(texture); - bind_texture(tex->sampler_name, texture, tex->sampler_state); + manager.acquire_texture(gputex.texture); + bind_texture(tex->sampler_name, gputex.texture, tex->sampler_state); + + if (gputex.tile_mapping) { + manager.acquire_texture(gputex.tile_mapping); + bind_texture(tex->tiled_mapping_name, gputex.tile_mapping, tex->sampler_state); } } else if (tex->colorband) { diff --git a/source/blender/makesrna/intern/rna_image_api.cc b/source/blender/makesrna/intern/rna_image_api.cc index 06a5cb3ac81..9893287485a 100644 --- a/source/blender/makesrna/intern/rna_image_api.cc +++ b/source/blender/makesrna/intern/rna_image_api.cc @@ -213,7 +213,7 @@ static int rna_Image_gl_load( BKE_image_multilayer_index(image->rr, &iuser); } - GPUTexture *tex = BKE_image_get_gpu_texture(image, &iuser, nullptr); + GPUTexture *tex = BKE_image_get_gpu_texture(image, &iuser); if (tex == nullptr) { BKE_reportf(reports, RPT_ERROR, "Failed to load image texture '%s'", image->id.name + 2); diff --git a/source/blender/python/gpu/gpu_py_texture.cc b/source/blender/python/gpu/gpu_py_texture.cc index 98cc85310e0..7ad3a1f91f4 100644 --- a/source/blender/python/gpu/gpu_py_texture.cc +++ b/source/blender/python/gpu/gpu_py_texture.cc @@ -672,7 +672,7 @@ static PyObject *pygpu_texture_from_image(PyObject * /*self*/, PyObject *arg) ImageUser iuser; BKE_imageuser_default(&iuser); - GPUTexture *tex = BKE_image_get_gpu_texture(ima, &iuser, nullptr); + GPUTexture *tex = BKE_image_get_gpu_texture(ima, &iuser); return BPyGPUTexture_CreatePyObject(tex, true); }