GPU: Explicit Texture Usage Flags for enabling GPU Backend optimizations.

Texture usage flags can now be provided during texture creation specifying
the ways in which a texture can be used. This allows the GPU backends to
perform contextual optimizations which were not previously possible. This
includes enablement of hardware lossless compression which can result in
a 15%+ performance uplift for bandwidth-limited scenes on hardware such
as Apple-Silicon using Metal.

GPU_TEXTURE_USAGE_GENERAL can be used by default if usage is not known
ahead of time. Patch will also be relevant for the Vulkan backend.

Authored by Apple: Michael Parkin-White

Ref T96261

Reviewed By: fclem
Differential Revision: https://developer.blender.org/D15967
This commit is contained in:
Jason Fielder 2022-12-08 23:30:57 +01:00 committed by Clément Foucault
parent 359d98423e
commit 2e61c446ac
Notes: blender-bot 2023-02-14 02:27:56 +01:00
Referenced by issue #96261, Metal Viewport
45 changed files with 1072 additions and 339 deletions

View File

@ -337,10 +337,12 @@ static bool addGPULut1D2D(OCIO_GPUTextures &textures,
* It depends on more than height. So check instead by looking at the source. */
std::string sampler1D_name = std::string("sampler1D ") + sampler_name;
if (strstr(shader_desc->getShaderText(), sampler1D_name.c_str()) != nullptr) {
lut.texture = GPU_texture_create_1d(texture_name, width, 1, format, values);
lut.texture = GPU_texture_create_1d_ex(
texture_name, width, 1, format, GPU_TEXTURE_USAGE_SHADER_READ, values);
}
else {
lut.texture = GPU_texture_create_2d(texture_name, width, height, 1, format, values);
lut.texture = GPU_texture_create_2d_ex(
texture_name, width, height, 1, format, GPU_TEXTURE_USAGE_SHADER_READ, values);
}
if (lut.texture == nullptr) {
return false;
@ -372,8 +374,15 @@ static bool addGPULut3D(OCIO_GPUTextures &textures,
}
OCIO_GPULutTexture lut;
lut.texture = GPU_texture_create_3d(
texture_name, edgelen, edgelen, edgelen, 1, GPU_RGB16F, GPU_DATA_FLOAT, values);
lut.texture = GPU_texture_create_3d_ex(texture_name,
edgelen,
edgelen,
edgelen,
1,
GPU_RGB16F,
GPU_DATA_FLOAT,
GPU_TEXTURE_USAGE_SHADER_READ,
values);
if (lut.texture == nullptr) {
return false;
}
@ -442,7 +451,8 @@ static bool createGPUCurveMapping(OCIO_GPUCurveMappping &curvemap,
if (curve_mapping_settings) {
int lut_size = curve_mapping_settings->lut_size;
curvemap.texture = GPU_texture_create_1d("OCIOCurveMap", lut_size, 1, GPU_RGBA16F, nullptr);
curvemap.texture = GPU_texture_create_1d_ex(
"OCIOCurveMap", lut_size, 1, GPU_RGBA16F, GPU_TEXTURE_USAGE_SHADER_READ, nullptr);
GPU_texture_filter_mode(curvemap.texture, false);
GPU_texture_wrap_mode(curvemap.texture, false, true);

View File

@ -1199,7 +1199,8 @@ void blf_glyph_draw(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, const int x,
if (gc->texture) {
GPU_texture_free(gc->texture);
}
gc->texture = GPU_texture_create_2d(__func__, w, h, 1, GPU_R8, NULL);
gc->texture = GPU_texture_create_2d_ex(
__func__, w, h, 1, GPU_R8, GPU_TEXTURE_USAGE_SHADER_READ, NULL);
gc->bitmap_len_landed = 0;
}

View File

@ -111,7 +111,8 @@ static GPUTexture *gpu_texture_create_tile_mapping(Image *ima, const int multivi
tile_info[3] = tile_runtime->tilearray_size[1] / array_h;
}
GPUTexture *tex = GPU_texture_create_1d_array(ima->id.name + 2, width, 2, 1, GPU_RGBA32F, data);
GPUTexture *tex = GPU_texture_create_1d_array_ex(
ima->id.name + 2, width, 2, 1, GPU_RGBA32F, GPU_TEXTURE_USAGE_SHADER_READ, data);
GPU_texture_mipmap_mode(tex, false, false);
MEM_freeN(data);

View File

@ -478,8 +478,13 @@ static void studiolight_create_equirect_radiance_gputexture(StudioLight *sl)
BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EXTERNAL_IMAGE_LOADED);
ImBuf *ibuf = sl->equirect_radiance_buffer;
sl->equirect_radiance_gputexture = GPU_texture_create_2d(
"studiolight_radiance", ibuf->x, ibuf->y, 1, GPU_RGBA16F, ibuf->rect_float);
sl->equirect_radiance_gputexture = GPU_texture_create_2d_ex("studiolight_radiance",
ibuf->x,
ibuf->y,
1,
GPU_RGBA16F,
GPU_TEXTURE_USAGE_SHADER_READ,
ibuf->rect_float);
GPUTexture *tex = sl->equirect_radiance_gputexture;
GPU_texture_filter_mode(tex, true);
GPU_texture_wrap_mode(tex, true, true);
@ -499,7 +504,8 @@ static void studiolight_create_matcap_gputexture(StudioLightImage *sli)
copy_v3_v3(*offset3, *offset4);
}
sli->gputexture = GPU_texture_create_2d("matcap", ibuf->x, ibuf->y, 1, GPU_R11F_G11F_B10F, NULL);
sli->gputexture = GPU_texture_create_2d_ex(
"matcap", ibuf->x, ibuf->y, 1, GPU_R11F_G11F_B10F, GPU_TEXTURE_USAGE_SHADER_READ, NULL);
GPU_texture_update(sli->gputexture, GPU_DATA_FLOAT, gpu_matcap_3components);
MEM_SAFE_FREE(gpu_matcap_3components);
@ -533,8 +539,13 @@ static void studiolight_create_equirect_irradiance_gputexture(StudioLight *sl)
if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) {
BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECT_IRRADIANCE_IMAGE_CALCULATED);
ImBuf *ibuf = sl->equirect_irradiance_buffer;
sl->equirect_irradiance_gputexture = GPU_texture_create_2d(
"studiolight_irradiance", ibuf->x, ibuf->y, 1, GPU_RGBA16F, ibuf->rect_float);
sl->equirect_irradiance_gputexture = GPU_texture_create_2d_ex("studiolight_irradiance",
ibuf->x,
ibuf->y,
1,
GPU_RGBA16F,
GPU_TEXTURE_USAGE_SHADER_READ,
ibuf->rect_float);
GPUTexture *tex = sl->equirect_irradiance_gputexture;
GPU_texture_filter_mode(tex, true);
GPU_texture_wrap_mode(tex, true, true);

View File

@ -362,9 +362,13 @@ static void dof_bokeh_pass_init(EEVEE_FramebufferList *fbl,
DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropyInv", fx->dof_bokeh_aniso_inv);
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
fx->dof_bokeh_gather_lut_tx = DRW_texture_pool_query_2d(UNPACK2(res), GPU_RG16F, owner);
fx->dof_bokeh_scatter_lut_tx = DRW_texture_pool_query_2d(UNPACK2(res), GPU_R16F, owner);
fx->dof_bokeh_resolve_lut_tx = DRW_texture_pool_query_2d(UNPACK2(res), GPU_R16F, owner);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
fx->dof_bokeh_gather_lut_tx = DRW_texture_pool_query_2d_ex(
UNPACK2(res), GPU_RG16F, usage, owner);
fx->dof_bokeh_scatter_lut_tx = DRW_texture_pool_query_2d_ex(
UNPACK2(res), GPU_R16F, usage, owner);
fx->dof_bokeh_resolve_lut_tx = DRW_texture_pool_query_2d_ex(
UNPACK2(res), GPU_R16F, usage, owner);
GPU_framebuffer_ensure_config(&fbl->dof_bokeh_fb,
{
@ -398,8 +402,10 @@ static void dof_setup_pass_init(EEVEE_FramebufferList *fbl,
DRW_shgroup_uniform_float_copy(grp, "bokehMaxSize", fx->dof_bokeh_max_size);
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
fx->dof_half_res_color_tx = DRW_texture_pool_query_2d(UNPACK2(res), COLOR_FORMAT, owner);
fx->dof_half_res_coc_tx = DRW_texture_pool_query_2d(UNPACK2(res), GPU_RG16F, owner);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
fx->dof_half_res_color_tx = DRW_texture_pool_query_2d_ex(
UNPACK2(res), COLOR_FORMAT, usage, owner);
fx->dof_half_res_coc_tx = DRW_texture_pool_query_2d_ex(UNPACK2(res), GPU_RG16F, usage, owner);
GPU_framebuffer_ensure_config(&fbl->dof_setup_fb,
{
@ -429,8 +435,11 @@ static void dof_flatten_tiles_pass_init(EEVEE_FramebufferList *fbl,
grp, "halfResCocBuffer", &fx->dof_half_res_coc_tx, NO_FILTERING);
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
fx->dof_coc_tiles_fg_tx = DRW_texture_pool_query_2d(UNPACK2(res), FG_TILE_FORMAT, owner);
fx->dof_coc_tiles_bg_tx = DRW_texture_pool_query_2d(UNPACK2(res), BG_TILE_FORMAT, owner);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
fx->dof_coc_tiles_fg_tx = DRW_texture_pool_query_2d_ex(
UNPACK2(res), FG_TILE_FORMAT, usage, owner);
fx->dof_coc_tiles_bg_tx = DRW_texture_pool_query_2d_ex(
UNPACK2(res), BG_TILE_FORMAT, usage, owner);
GPU_framebuffer_ensure_config(&fbl->dof_flatten_tiles_fb,
{
@ -468,9 +477,11 @@ static void dof_dilate_tiles_pass_init(EEVEE_FramebufferList *fbl,
DRW_shgroup_uniform_int(grp, "ringWidthMultiplier", &fx->dof_dilate_ring_width_multiplier, 1);
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
}
fx->dof_coc_dilated_tiles_fg_tx = DRW_texture_pool_query_2d(UNPACK2(res), FG_TILE_FORMAT, owner);
fx->dof_coc_dilated_tiles_bg_tx = DRW_texture_pool_query_2d(UNPACK2(res), BG_TILE_FORMAT, owner);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
fx->dof_coc_dilated_tiles_fg_tx = DRW_texture_pool_query_2d_ex(
UNPACK2(res), FG_TILE_FORMAT, usage, owner);
fx->dof_coc_dilated_tiles_bg_tx = DRW_texture_pool_query_2d_ex(
UNPACK2(res), BG_TILE_FORMAT, usage, owner);
GPU_framebuffer_ensure_config(&fbl->dof_dilate_tiles_fb,
{
@ -563,7 +574,9 @@ static void dof_reduce_pass_init(EEVEE_FramebufferList *fbl,
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
void *owner = (void *)&EEVEE_depth_of_field_init;
fx->dof_downsample_tx = DRW_texture_pool_query_2d(UNPACK2(quater_res), COLOR_FORMAT, owner);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
fx->dof_downsample_tx = DRW_texture_pool_query_2d_ex(
UNPACK2(quater_res), COLOR_FORMAT, usage, owner);
GPU_framebuffer_ensure_config(&fbl->dof_downsample_fb,
{
@ -593,7 +606,9 @@ static void dof_reduce_pass_init(EEVEE_FramebufferList *fbl,
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
void *owner = (void *)&EEVEE_depth_of_field_init;
fx->dof_scatter_src_tx = DRW_texture_pool_query_2d(UNPACK2(res), GPU_R11F_G11F_B10F, owner);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
fx->dof_scatter_src_tx = DRW_texture_pool_query_2d_ex(
UNPACK2(res), GPU_R11F_G11F_B10F, usage, owner);
}
{
@ -622,10 +637,12 @@ static void dof_reduce_pass_init(EEVEE_FramebufferList *fbl,
if (txl->dof_reduced_color == NULL) {
/* Color needs to be signed format here. See note in shader for explanation. */
/* Do not use texture pool because of needs mipmaps. */
txl->dof_reduced_color = GPU_texture_create_2d(
"dof_reduced_color", UNPACK2(res), mip_count, GPU_RGBA16F, NULL);
txl->dof_reduced_coc = GPU_texture_create_2d(
"dof_reduced_coc", UNPACK2(res), mip_count, GPU_R16F, NULL);
eGPUTextureUsage tex_flags = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW;
txl->dof_reduced_color = GPU_texture_create_2d_ex(
"dof_reduced_color", UNPACK2(res), mip_count, GPU_RGBA16F, tex_flags, NULL);
txl->dof_reduced_coc = GPU_texture_create_2d_ex(
"dof_reduced_coc", UNPACK2(res), mip_count, GPU_R16F, tex_flags, NULL);
}
GPU_framebuffer_ensure_config(&fbl->dof_reduce_fb,
@ -681,8 +698,10 @@ static void dof_gather_pass_init(EEVEE_FramebufferList *fbl,
/* Reuse textures from the setup pass. */
/* NOTE: We could use the texture pool do that for us but it does not track usage and it might
* backfire (it does in practice). */
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
fx->dof_fg_holefill_color_tx = fx->dof_half_res_color_tx;
fx->dof_fg_holefill_weight_tx = DRW_texture_pool_query_2d(UNPACK2(res), GPU_R16F, owner);
fx->dof_fg_holefill_weight_tx = DRW_texture_pool_query_2d_ex(
UNPACK2(res), GPU_R16F, usage, owner);
GPU_framebuffer_ensure_config(&fbl->dof_gather_fg_holefill_fb,
{
@ -714,9 +733,9 @@ static void dof_gather_pass_init(EEVEE_FramebufferList *fbl,
negate_v2(fx->dof_bokeh_aniso);
}
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
fx->dof_fg_color_tx = DRW_texture_pool_query_2d(UNPACK2(res), COLOR_FORMAT, owner);
fx->dof_fg_weight_tx = DRW_texture_pool_query_2d(UNPACK2(res), GPU_R16F, owner);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
fx->dof_fg_color_tx = DRW_texture_pool_query_2d_ex(UNPACK2(res), COLOR_FORMAT, usage, owner);
fx->dof_fg_weight_tx = DRW_texture_pool_query_2d_ex(UNPACK2(res), GPU_R16F, usage, owner);
/* Reuse textures from the setup pass. */
/* NOTE: We could use the texture pool do that for us but it does not track usage and it might
* backfire (it does in practice). */
@ -752,8 +771,9 @@ static void dof_gather_pass_init(EEVEE_FramebufferList *fbl,
}
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
fx->dof_bg_color_tx = DRW_texture_pool_query_2d(UNPACK2(res), COLOR_FORMAT, owner);
fx->dof_bg_weight_tx = DRW_texture_pool_query_2d(UNPACK2(res), GPU_R16F, owner);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
fx->dof_bg_color_tx = DRW_texture_pool_query_2d_ex(UNPACK2(res), COLOR_FORMAT, usage, owner);
fx->dof_bg_weight_tx = DRW_texture_pool_query_2d_ex(UNPACK2(res), GPU_R16F, usage, owner);
/* Reuse, since only used for scatter. Foreground is processed before background. */
fx->dof_bg_occlusion_tx = fx->dof_fg_occlusion_tx;

View File

@ -327,6 +327,8 @@ LightCache *EEVEE_lightcache_create(const int grid_len,
const int vis_size,
const int irr_size[3])
{
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_HOST_READ;
LightCache *light_cache = MEM_callocN(sizeof(LightCache), "LightCache");
light_cache->version = LIGHTCACHE_STATIC_VERSION;
@ -335,8 +337,8 @@ LightCache *EEVEE_lightcache_create(const int grid_len,
light_cache->cube_data = MEM_callocN(sizeof(EEVEE_LightProbe) * cube_len, "EEVEE_LightProbe");
light_cache->grid_data = MEM_callocN(sizeof(EEVEE_LightGrid) * grid_len, "EEVEE_LightGrid");
light_cache->grid_tx.tex = DRW_texture_create_2d_array(
irr_size[0], irr_size[1], irr_size[2], IRRADIANCE_FORMAT, DRW_TEX_FILTER, NULL);
light_cache->grid_tx.tex = DRW_texture_create_2d_array_ex(
irr_size[0], irr_size[1], irr_size[2], IRRADIANCE_FORMAT, usage, DRW_TEX_FILTER, NULL);
light_cache->grid_tx.tex_size[0] = irr_size[0];
light_cache->grid_tx.tex_size[1] = irr_size[1];
light_cache->grid_tx.tex_size[2] = irr_size[2];
@ -345,12 +347,12 @@ LightCache *EEVEE_lightcache_create(const int grid_len,
/* Try to create a cubemap array. */
DRWTextureFlag cube_texflag = DRW_TEX_FILTER | DRW_TEX_MIPMAP;
light_cache->cube_tx.tex = DRW_texture_create_cube_array(
cube_size, cube_len, GPU_R11F_G11F_B10F, cube_texflag, NULL);
light_cache->cube_tx.tex = DRW_texture_create_cube_array_ex(
cube_size, cube_len, GPU_R11F_G11F_B10F, usage, cube_texflag, NULL);
if (light_cache->cube_tx.tex == NULL) {
/* Try fallback to 2D array. */
light_cache->cube_tx.tex = DRW_texture_create_2d_array(
cube_size, cube_size, cube_len * 6, GPU_R11F_G11F_B10F, cube_texflag, NULL);
light_cache->cube_tx.tex = DRW_texture_create_2d_array_ex(
cube_size, cube_size, cube_len * 6, GPU_R11F_G11F_B10F, usage, cube_texflag, NULL);
}
light_cache->cube_tx.tex_size[0] = cube_size;
@ -393,8 +395,13 @@ static bool eevee_lightcache_static_load(LightCache *lcache)
}
if (lcache->grid_tx.tex == NULL) {
lcache->grid_tx.tex = GPU_texture_create_2d_array(
"lightcache_irradiance", UNPACK3(lcache->grid_tx.tex_size), 1, IRRADIANCE_FORMAT, NULL);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
lcache->grid_tx.tex = GPU_texture_create_2d_array_ex("lightcache_irradiance",
UNPACK3(lcache->grid_tx.tex_size),
1,
IRRADIANCE_FORMAT,
usage,
NULL);
GPU_texture_update(lcache->grid_tx.tex, GPU_DATA_UBYTE, lcache->grid_tx.data);
if (lcache->grid_tx.tex == NULL) {
@ -406,21 +413,27 @@ static bool eevee_lightcache_static_load(LightCache *lcache)
}
if (lcache->cube_tx.tex == NULL) {
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_HOST_READ;
/* Try to create a cubemap array. */
lcache->cube_tx.tex = GPU_texture_create_cube_array("lightcache_cubemaps",
lcache->cube_tx.tex_size[0],
lcache->cube_tx.tex_size[2] / 6,
lcache->mips_len + 1,
GPU_R11F_G11F_B10F,
NULL);
lcache->cube_tx.tex = GPU_texture_create_cube_array_ex("lightcache_cubemaps",
lcache->cube_tx.tex_size[0],
lcache->cube_tx.tex_size[2] / 6,
lcache->mips_len + 1,
GPU_R11F_G11F_B10F,
usage,
NULL);
if (lcache->cube_tx.tex == NULL) {
/* Try fallback to 2D array. */
lcache->cube_tx.tex = GPU_texture_create_2d_array("lightcache_cubemaps_fallback",
UNPACK3(lcache->cube_tx.tex_size),
lcache->mips_len + 1,
GPU_R11F_G11F_B10F,
NULL);
lcache->cube_tx.tex = GPU_texture_create_2d_array_ex("lightcache_cubemaps_fallback",
UNPACK3(lcache->cube_tx.tex_size),
lcache->mips_len + 1,
GPU_R11F_G11F_B10F,
usage,
NULL);
}
if (lcache->cube_tx.tex == NULL) {
@ -669,9 +682,11 @@ static void eevee_lightbake_count_probes(EEVEE_LightBake *lbake)
static void eevee_lightbake_create_render_target(EEVEE_LightBake *lbake, int rt_res)
{
lbake->rt_depth = DRW_texture_create_cube(rt_res, GPU_DEPTH_COMPONENT24, 0, NULL);
lbake->rt_color = DRW_texture_create_cube(
rt_res, GPU_RGBA16F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW;
lbake->rt_depth = DRW_texture_create_cube_ex(rt_res, GPU_DEPTH_COMPONENT24, usage, 0, NULL);
lbake->rt_color = DRW_texture_create_cube_ex(
rt_res, GPU_RGBA16F, usage, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
for (int i = 0; i < 6; i++) {
GPU_framebuffer_ensure_config(&lbake->rt_fb[i],
@ -697,12 +712,13 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
lbake->cube_prb = MEM_callocN(sizeof(LightProbe *) * lbake->cube_len, "EEVEE Cube visgroup ptr");
lbake->grid_prb = MEM_callocN(sizeof(LightProbe *) * lbake->grid_len, "EEVEE Grid visgroup ptr");
lbake->grid_prev = DRW_texture_create_2d_array(lbake->irr_size[0],
lbake->irr_size[1],
lbake->irr_size[2],
IRRADIANCE_FORMAT,
DRW_TEX_FILTER,
NULL);
lbake->grid_prev = DRW_texture_create_2d_array_ex(lbake->irr_size[0],
lbake->irr_size[1],
lbake->irr_size[2],
IRRADIANCE_FORMAT,
GPU_TEXTURE_USAGE_SHADER_READ,
DRW_TEX_FILTER,
NULL);
/* Ensure Light Cache is ready to accept new data. If not recreate one.
* WARNING: All the following must be threadsafe. It's currently protected
@ -983,12 +999,13 @@ static void eevee_lightbake_copy_irradiance(EEVEE_LightBake *lbake, LightCache *
/* Copy texture by reading back and re-uploading it. */
float *tex = GPU_texture_read(lcache->grid_tx.tex, GPU_DATA_FLOAT, 0);
lbake->grid_prev = DRW_texture_create_2d_array(lbake->irr_size[0],
lbake->irr_size[1],
lbake->irr_size[2],
IRRADIANCE_FORMAT,
DRW_TEX_FILTER,
tex);
lbake->grid_prev = DRW_texture_create_2d_array_ex(lbake->irr_size[0],
lbake->irr_size[1],
lbake->irr_size[2],
IRRADIANCE_FORMAT,
GPU_TEXTURE_USAGE_SHADER_READ,
DRW_TEX_FILTER,
tex);
MEM_freeN(tex);
}

View File

@ -64,17 +64,17 @@ int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *veda
1 + ((int)fs_size[0] / EEVEE_VELOCITY_TILE_SIZE),
1 + ((int)fs_size[1] / EEVEE_VELOCITY_TILE_SIZE),
};
effects->velocity_tiles_x_tx = DRW_texture_pool_query_2d(
tx_size[0], fs_size[1], GPU_RGBA16, &draw_engine_eevee_type);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
effects->velocity_tiles_x_tx = DRW_texture_pool_query_2d_ex(
tx_size[0], fs_size[1], GPU_RGBA16, usage, &draw_engine_eevee_type);
GPU_framebuffer_ensure_config(&fbl->velocity_tiles_fb[0],
{
GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(effects->velocity_tiles_x_tx),
});
effects->velocity_tiles_tx = DRW_texture_pool_query_2d(
tx_size[0], tx_size[1], GPU_RGBA16, &draw_engine_eevee_type);
effects->velocity_tiles_tx = DRW_texture_pool_query_2d_ex(
tx_size[0], tx_size[1], GPU_RGBA16, usage, &draw_engine_eevee_type);
GPU_framebuffer_ensure_config(&fbl->velocity_tiles_fb[1],
{
GPU_ATTACHMENT_NONE,

View File

@ -166,8 +166,9 @@ void DepthOfField::sync()
/* Now that we know the maximum render resolution of every view, using depth of field, allocate
* the reduced buffers. Color needs to be signed format here. See note in shader for
* explanation. Do not use texture pool because of needs mipmaps. */
reduced_color_tx_.ensure_2d(GPU_RGBA16F, reduce_size, nullptr, DOF_MIP_COUNT);
reduced_coc_tx_.ensure_2d(GPU_R16F, reduce_size, nullptr, DOF_MIP_COUNT);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
reduced_color_tx_.ensure_2d(GPU_RGBA16F, reduce_size, usage, nullptr, DOF_MIP_COUNT);
reduced_coc_tx_.ensure_2d(GPU_R16F, reduce_size, usage, nullptr, DOF_MIP_COUNT);
reduced_color_tx_.ensure_mip_views();
reduced_coc_tx_.ensure_mip_views();

View File

@ -24,7 +24,8 @@ void HiZBuffer::sync()
int2 hiz_extent = math::ceil_to_multiple(render_extent, int2(1u << (HIZ_MIP_COUNT - 1)));
int2 dispatch_size = math::divide_ceil(hiz_extent, int2(HIZ_GROUP_SIZE));
hiz_tx_.ensure_2d(GPU_R32F, hiz_extent, nullptr, HIZ_MIP_COUNT);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_SHADER_WRITE;
hiz_tx_.ensure_2d(GPU_R32F, hiz_extent, usage, nullptr, HIZ_MIP_COUNT);
hiz_tx_.ensure_mip_views();
GPU_texture_mipmap_mode(hiz_tx_, true, false);

View File

@ -107,7 +107,13 @@ class UtilityTexture : public Texture {
static constexpr int layer_count = 4 + UTIL_BTDF_LAYER_COUNT;
public:
UtilityTexture() : Texture("UtilityTx", GPU_RGBA16F, int2(lut_size), layer_count, nullptr)
UtilityTexture()
: Texture("UtilityTx",
GPU_RGBA16F,
GPU_TEXTURE_USAGE_SHADER_READ,
int2(lut_size),
layer_count,
nullptr)
{
#ifdef RUNTIME_LUT_CREATION
float *bsdf_ggx_lut = EEVEE_lut_update_ggx_brdf(lut_size);

View File

@ -40,13 +40,16 @@ void GPENCIL_antialiasing_init(struct GPENCIL_Data *vedata)
return;
}
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
if (txl->smaa_search_tx == NULL) {
txl->smaa_search_tx = GPU_texture_create_2d(
"smaa_search", SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT, 1, GPU_R8, NULL);
txl->smaa_search_tx = GPU_texture_create_2d_ex(
"smaa_search", SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT, 1, GPU_R8, usage, NULL);
GPU_texture_update(txl->smaa_search_tx, GPU_DATA_UBYTE, searchTexBytes);
txl->smaa_area_tx = GPU_texture_create_2d(
"smaa_area", AREATEX_WIDTH, AREATEX_HEIGHT, 1, GPU_RG8, NULL);
txl->smaa_area_tx = GPU_texture_create_2d_ex(
"smaa_area", AREATEX_WIDTH, AREATEX_HEIGHT, 1, GPU_RG8, usage, NULL);
GPU_texture_update(txl->smaa_area_tx, GPU_DATA_UBYTE, areaTexBytes);
GPU_texture_filter_mode(txl->smaa_search_tx, true);
@ -54,10 +57,10 @@ void GPENCIL_antialiasing_init(struct GPENCIL_Data *vedata)
}
{
pd->smaa_edge_tx = DRW_texture_pool_query_2d(
size[0], size[1], GPU_RG8, &draw_engine_gpencil_type);
pd->smaa_weight_tx = DRW_texture_pool_query_2d(
size[0], size[1], GPU_RGBA8, &draw_engine_gpencil_type);
pd->smaa_edge_tx = DRW_texture_pool_query_2d_ex(
size[0], size[1], GPU_RG8, usage, &draw_engine_gpencil_type);
pd->smaa_weight_tx = DRW_texture_pool_query_2d_ex(
size[0], size[1], GPU_RGBA8, usage, &draw_engine_gpencil_type);
GPU_framebuffer_ensure_config(&fbl->smaa_edge_fb,
{

View File

@ -109,7 +109,8 @@ class SpaceImageAccessor : public AbstractSpaceAccessor {
BLI_assert(image->type == IMA_TYPE_R_RESULT);
float zero[4] = {0, 0, 0, 0};
*r_gpu_texture = GPU_texture_create_2d(__func__, 1, 1, 0, GPU_RGBA16F, zero);
*r_gpu_texture = GPU_texture_create_2d_ex(
__func__, 1, 1, 0, GPU_RGBA16F, GPU_TEXTURE_USAGE_SHADER_READ, zero);
*r_owns_texture = true;
return;
}
@ -121,13 +122,23 @@ class SpaceImageAccessor : public AbstractSpaceAccessor {
BLI_assert_msg(0, "Integer based depth buffers not supported");
}
else if (image_buffer->zbuf_float) {
*r_gpu_texture = GPU_texture_create_2d(
__func__, image_buffer->x, image_buffer->y, 0, GPU_R16F, image_buffer->zbuf_float);
*r_gpu_texture = GPU_texture_create_2d_ex(__func__,
image_buffer->x,
image_buffer->y,
0,
GPU_R16F,
GPU_TEXTURE_USAGE_SHADER_READ,
image_buffer->zbuf_float);
*r_owns_texture = true;
}
else if (image_buffer->rect_float && image_buffer->channels == 1) {
*r_gpu_texture = GPU_texture_create_2d(
__func__, image_buffer->x, image_buffer->y, 0, GPU_R16F, image_buffer->rect_float);
*r_gpu_texture = GPU_texture_create_2d_ex(__func__,
image_buffer->x,
image_buffer->y,
0,
GPU_R16F,
GPU_TEXTURE_USAGE_SHADER_READ,
image_buffer->rect_float);
*r_owns_texture = true;
}
}

View File

@ -80,7 +80,8 @@ static GPUTexture *edit_uv_mask_texture(
/* Free memory. */
BKE_maskrasterize_handle_free(handle);
GPUTexture *texture = GPU_texture_create_2d(mask->id.name, width, height, 1, GPU_R16F, buffer);
GPUTexture *texture = GPU_texture_create_2d_ex(
mask->id.name, width, height, 1, GPU_R16F, GPU_TEXTURE_USAGE_SHADER_READ, buffer);
MEM_freeN(buffer);
return texture;
}

View File

@ -59,8 +59,9 @@ static void select_engine_framebuffer_setup(void)
GPU_framebuffer_texture_attach(e_data.framebuffer_select_id, dtxl->depth, 0, 0);
if (e_data.texture_u32 == NULL) {
e_data.texture_u32 = GPU_texture_create_2d(
"select_buf_ids", size[0], size[1], 1, GPU_R32UI, NULL);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
e_data.texture_u32 = GPU_texture_create_2d_ex(
"select_buf_ids", size[0], size[1], 1, GPU_R32UI, usage, NULL);
GPU_framebuffer_texture_attach(e_data.framebuffer_select_id, e_data.texture_u32, 0, 0);
GPU_framebuffer_check_valid(e_data.framebuffer_select_id, NULL);

View File

@ -194,19 +194,21 @@ void workbench_antialiasing_engine_init(WORKBENCH_Data *vedata)
if (wpd->taa_sample_len > 0) {
workbench_taa_jitter_init();
DRW_texture_ensure_fullscreen_2d(&txl->history_buffer_tx, GPU_RGBA16F, DRW_TEX_FILTER);
DRW_texture_ensure_fullscreen_2d(&txl->depth_buffer_tx, GPU_DEPTH24_STENCIL8, 0);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
DRW_texture_ensure_fullscreen_2d_ex(
&txl->history_buffer_tx, GPU_RGBA16F, usage, DRW_TEX_FILTER);
DRW_texture_ensure_fullscreen_2d_ex(&txl->depth_buffer_tx, GPU_DEPTH24_STENCIL8, usage, 0);
const bool in_front_history = workbench_in_front_history_needed(vedata);
if (in_front_history) {
DRW_texture_ensure_fullscreen_2d(&txl->depth_buffer_in_front_tx, GPU_DEPTH24_STENCIL8, 0);
DRW_texture_ensure_fullscreen_2d_ex(
&txl->depth_buffer_in_front_tx, GPU_DEPTH24_STENCIL8, usage, 0);
}
else {
DRW_TEXTURE_FREE_SAFE(txl->depth_buffer_in_front_tx);
}
wpd->smaa_edge_tx = DRW_texture_pool_query_fullscreen(GPU_RG8, owner);
wpd->smaa_weight_tx = DRW_texture_pool_query_fullscreen(GPU_RGBA8, owner);
wpd->smaa_edge_tx = DRW_texture_pool_query_fullscreen_ex(GPU_RG8, usage, owner);
wpd->smaa_weight_tx = DRW_texture_pool_query_fullscreen_ex(GPU_RGBA8, usage, owner);
GPU_framebuffer_ensure_config(&fbl->antialiasing_fb,
{
@ -234,12 +236,12 @@ void workbench_antialiasing_engine_init(WORKBENCH_Data *vedata)
/* TODO: could be shared for all viewports. */
if (txl->smaa_search_tx == NULL) {
txl->smaa_search_tx = GPU_texture_create_2d(
"smaa_search", SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT, 1, GPU_R8, NULL);
txl->smaa_search_tx = GPU_texture_create_2d_ex(
"smaa_search", SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT, 1, GPU_R8, usage, NULL);
GPU_texture_update(txl->smaa_search_tx, GPU_DATA_UBYTE, searchTexBytes);
txl->smaa_area_tx = GPU_texture_create_2d(
"smaa_area", AREATEX_WIDTH, AREATEX_HEIGHT, 1, GPU_RG8, NULL);
txl->smaa_area_tx = GPU_texture_create_2d_ex(
"smaa_area", AREATEX_WIDTH, AREATEX_HEIGHT, 1, GPU_RG8, usage, NULL);
GPU_texture_update(txl->smaa_area_tx, GPU_DATA_UBYTE, areaTexBytes);
GPU_texture_filter_mode(txl->smaa_search_tx, true);

View File

@ -64,9 +64,12 @@ static bool workbench_render_framebuffers_init(void)
/* When doing a multi view rendering the first view will allocate the buffers
* the other views will reuse these buffers */
if (dtxl->color == NULL) {
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
BLI_assert(dtxl->depth == NULL);
dtxl->color = GPU_texture_create_2d("txl.color", UNPACK2(size), 1, GPU_RGBA16F, NULL);
dtxl->depth = GPU_texture_create_2d("txl.depth", UNPACK2(size), 1, GPU_DEPTH24_STENCIL8, NULL);
dtxl->color = GPU_texture_create_2d_ex(
"txl.color", UNPACK2(size), 1, GPU_RGBA16F, usage, NULL);
dtxl->depth = GPU_texture_create_2d_ex(
"txl.depth", UNPACK2(size), 1, GPU_DEPTH24_STENCIL8, usage, NULL);
}
if (!(dtxl->depth && dtxl->color)) {

View File

@ -28,13 +28,15 @@ void workbench_volume_engine_init(WORKBENCH_Data *vedata)
WORKBENCH_TextureList *txl = vedata->txl;
if (txl->dummy_volume_tx == NULL) {
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
txl->dummy_volume_tx = GPU_texture_create_3d(
"dummy_volume", 1, 1, 1, 1, GPU_RGBA8, GPU_DATA_FLOAT, zero);
txl->dummy_shadow_tx = GPU_texture_create_3d(
"dummy_shadow", 1, 1, 1, 1, GPU_RGBA8, GPU_DATA_FLOAT, one);
txl->dummy_coba_tx = GPU_texture_create_1d("dummy_coba", 1, 1, GPU_RGBA8, zero);
txl->dummy_volume_tx = GPU_texture_create_3d_ex(
"dummy_volume", 1, 1, 1, 1, GPU_RGBA8, GPU_DATA_FLOAT, usage, zero);
txl->dummy_shadow_tx = GPU_texture_create_3d_ex(
"dummy_shadow", 1, 1, 1, 1, GPU_RGBA8, GPU_DATA_FLOAT, usage, one);
txl->dummy_coba_tx = GPU_texture_create_1d_ex("dummy_coba", 1, 1, GPU_RGBA8, usage, zero);
}
}

View File

@ -469,17 +469,19 @@ class Texture : NonCopyable {
Texture(const char *name,
eGPUTextureFormat format,
eGPUTextureUsage usage,
int extent,
float *data = nullptr,
bool cubemap = false,
int mip_len = 1)
: name_(name)
{
tx_ = create(extent, 0, 0, mip_len, format, data, false, cubemap);
tx_ = create(extent, 0, 0, mip_len, format, usage, data, false, cubemap);
}
Texture(const char *name,
eGPUTextureFormat format,
eGPUTextureUsage usage,
int extent,
int layers,
float *data = nullptr,
@ -487,38 +489,41 @@ class Texture : NonCopyable {
int mip_len = 1)
: name_(name)
{
tx_ = create(extent, layers, 0, mip_len, format, data, true, cubemap);
tx_ = create(extent, layers, 0, mip_len, format, usage, data, true, cubemap);
}
Texture(const char *name,
eGPUTextureFormat format,
eGPUTextureUsage usage,
int2 extent,
float *data = nullptr,
int mip_len = 1)
: name_(name)
{
tx_ = create(UNPACK2(extent), 0, mip_len, format, data, false, false);
tx_ = create(UNPACK2(extent), 0, mip_len, format, usage, data, false, false);
}
Texture(const char *name,
eGPUTextureFormat format,
eGPUTextureUsage usage,
int2 extent,
int layers,
float *data = nullptr,
int mip_len = 1)
: name_(name)
{
tx_ = create(UNPACK2(extent), layers, mip_len, format, data, true, false);
tx_ = create(UNPACK2(extent), layers, mip_len, format, usage, data, true, false);
}
Texture(const char *name,
eGPUTextureFormat format,
eGPUTextureUsage usage,
int3 extent,
float *data = nullptr,
int mip_len = 1)
: name_(name)
{
tx_ = create(UNPACK3(extent), mip_len, format, data, false, false);
tx_ = create(UNPACK3(extent), mip_len, format, usage, data, false, false);
}
~Texture()
@ -553,66 +558,94 @@ class Texture : NonCopyable {
* Ensure the texture has the correct properties. Recreating it if needed.
* Return true if a texture has been created.
*/
bool ensure_1d(eGPUTextureFormat format, int extent, float *data = nullptr, int mip_len = 1)
bool ensure_1d(eGPUTextureFormat format,
int extent,
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_GENERAL,
float *data = nullptr,
int mip_len = 1)
{
return ensure_impl(extent, 0, 0, mip_len, format, data, false, false);
return ensure_impl(extent, 0, 0, mip_len, format, usage, data, false, false);
}
/**
* Ensure the texture has the correct properties. Recreating it if needed.
* Return true if a texture has been created.
*/
bool ensure_1d_array(
eGPUTextureFormat format, int extent, int layers, float *data = nullptr, int mip_len = 1)
bool ensure_1d_array(eGPUTextureFormat format,
int extent,
int layers,
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_GENERAL,
float *data = nullptr,
int mip_len = 1)
{
return ensure_impl(extent, layers, 0, mip_len, format, data, true, false);
return ensure_impl(extent, layers, 0, mip_len, format, usage, data, true, false);
}
/**
* Ensure the texture has the correct properties. Recreating it if needed.
* Return true if a texture has been created.
*/
bool ensure_2d(eGPUTextureFormat format, int2 extent, float *data = nullptr, int mip_len = 1)
bool ensure_2d(eGPUTextureFormat format,
int2 extent,
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_GENERAL,
float *data = nullptr,
int mip_len = 1)
{
return ensure_impl(UNPACK2(extent), 0, mip_len, format, data, false, false);
return ensure_impl(UNPACK2(extent), 0, mip_len, format, usage, data, false, false);
}
/**
* Ensure the texture has the correct properties. Recreating it if needed.
* Return true if a texture has been created.
*/
bool ensure_2d_array(
eGPUTextureFormat format, int2 extent, int layers, float *data = nullptr, int mip_len = 1)
bool ensure_2d_array(eGPUTextureFormat format,
int2 extent,
int layers,
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_GENERAL,
float *data = nullptr,
int mip_len = 1)
{
return ensure_impl(UNPACK2(extent), layers, mip_len, format, data, true, false);
return ensure_impl(UNPACK2(extent), layers, mip_len, format, usage, data, true, false);
}
/**
* Ensure the texture has the correct properties. Recreating it if needed.
* Return true if a texture has been created.
*/
bool ensure_3d(eGPUTextureFormat format, int3 extent, float *data = nullptr, int mip_len = 1)
bool ensure_3d(eGPUTextureFormat format,
int3 extent,
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_GENERAL,
float *data = nullptr,
int mip_len = 1)
{
return ensure_impl(UNPACK3(extent), mip_len, format, data, false, false);
return ensure_impl(UNPACK3(extent), mip_len, format, usage, data, false, false);
}
/**
* Ensure the texture has the correct properties. Recreating it if needed.
* Return true if a texture has been created.
*/
bool ensure_cube(eGPUTextureFormat format, int extent, float *data = nullptr, int mip_len = 1)
bool ensure_cube(eGPUTextureFormat format,
int extent,
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_GENERAL,
float *data = nullptr,
int mip_len = 1)
{
return ensure_impl(extent, extent, 0, mip_len, format, data, false, true);
return ensure_impl(extent, extent, 0, mip_len, format, usage, data, false, true);
}
/**
* Ensure the texture has the correct properties. Recreating it if needed.
* Return true if a texture has been created.
*/
bool ensure_cube_array(
eGPUTextureFormat format, int extent, int layers, float *data = nullptr, int mip_len = 1)
bool ensure_cube_array(eGPUTextureFormat format,
int extent,
int layers,
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_GENERAL,
float *data = nullptr,
int mip_len = 1)
{
return ensure_impl(extent, extent, layers, mip_len, format, data, false, true);
return ensure_impl(extent, extent, layers, mip_len, format, usage, data, false, true);
}
/**
@ -807,6 +840,7 @@ class Texture : NonCopyable {
int d = 0,
int mip_len = 1,
eGPUTextureFormat format = GPU_RGBA8,
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_GENERAL,
float *data = nullptr,
bool layered = false,
bool cubemap = false)
@ -822,7 +856,7 @@ class Texture : NonCopyable {
}
}
if (tx_ == nullptr) {
tx_ = create(w, h, d, mip_len, format, data, layered, cubemap);
tx_ = create(w, h, d, mip_len, format, usage, data, layered, cubemap);
return true;
}
return false;
@ -833,35 +867,37 @@ class Texture : NonCopyable {
int d,
int mip_len,
eGPUTextureFormat format,
eGPUTextureUsage usage,
float *data,
bool layered,
bool cubemap)
{
if (h == 0) {
return GPU_texture_create_1d(name_, w, mip_len, format, data);
return GPU_texture_create_1d_ex(name_, w, mip_len, format, usage, data);
}
else if (cubemap) {
if (layered) {
return GPU_texture_create_cube_array(name_, w, d, mip_len, format, data);
return GPU_texture_create_cube_array_ex(name_, w, d, mip_len, format, usage, data);
}
else {
return GPU_texture_create_cube(name_, w, mip_len, format, data);
return GPU_texture_create_cube_ex(name_, w, mip_len, format, usage, data);
}
}
else if (d == 0) {
if (layered) {
return GPU_texture_create_1d_array(name_, w, h, mip_len, format, data);
return GPU_texture_create_1d_array_ex(name_, w, h, mip_len, format, usage, data);
}
else {
return GPU_texture_create_2d(name_, w, h, mip_len, format, data);
return GPU_texture_create_2d_ex(name_, w, h, mip_len, format, usage, data);
}
}
else {
if (layered) {
return GPU_texture_create_2d_array(name_, w, h, d, mip_len, format, data);
return GPU_texture_create_2d_array_ex(name_, w, h, d, mip_len, format, usage, data);
}
else {
return GPU_texture_create_3d(name_, w, h, d, mip_len, format, GPU_DATA_FLOAT, data);
return GPU_texture_create_3d_ex(
name_, w, h, d, mip_len, format, GPU_DATA_FLOAT, usage, data);
}
}
}
@ -872,12 +908,14 @@ class TextureFromPool : public Texture, NonMovable {
TextureFromPool(const char *name = "gpu::Texture") : Texture(name){};
/* Always use `release()` after rendering. */
void acquire(int2 extent, eGPUTextureFormat format)
void acquire(int2 extent,
eGPUTextureFormat format,
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_GENERAL)
{
BLI_assert(this->tx_ == nullptr);
this->tx_ = DRW_texture_pool_texture_acquire(
DST.vmempool->texture_pool, UNPACK2(extent), format);
DST.vmempool->texture_pool, UNPACK2(extent), format, usage);
}
void release()
@ -910,13 +948,13 @@ class TextureFromPool : public Texture, NonMovable {
}
/** Remove methods that are forbidden with this type of textures. */
bool ensure_1d(int, int, eGPUTextureFormat, float *) = delete;
bool ensure_1d_array(int, int, int, eGPUTextureFormat, float *) = delete;
bool ensure_2d(int, int, int, eGPUTextureFormat, float *) = delete;
bool ensure_2d_array(int, int, int, int, eGPUTextureFormat, float *) = delete;
bool ensure_3d(int, int, int, int, eGPUTextureFormat, float *) = delete;
bool ensure_cube(int, int, eGPUTextureFormat, float *) = delete;
bool ensure_cube_array(int, int, int, eGPUTextureFormat, float *) = delete;
bool ensure_1d(int, int, eGPUTextureFormat, eGPUTextureUsage, float *) = delete;
bool ensure_1d_array(int, int, int, eGPUTextureFormat, eGPUTextureUsage, float *) = delete;
bool ensure_2d(int, int, int, eGPUTextureFormat, eGPUTextureUsage, float *) = delete;
bool ensure_2d_array(int, int, int, int, eGPUTextureFormat, eGPUTextureUsage, float *) = delete;
bool ensure_3d(int, int, int, int, eGPUTextureFormat, eGPUTextureUsage, float *) = delete;
bool ensure_cube(int, int, eGPUTextureFormat, eGPUTextureUsage, float *) = delete;
bool ensure_cube_array(int, int, int, eGPUTextureFormat, eGPUTextureUsage, float *) = delete;
void filter_mode(bool) = delete;
void free() = delete;
GPUTexture *mip_view(int) = delete;

View File

@ -179,6 +179,61 @@ void DRW_texture_ensure_fullscreen_2d(struct GPUTexture **tex,
void DRW_texture_ensure_2d(
struct GPUTexture **tex, int w, int h, eGPUTextureFormat format, DRWTextureFlag flags);
/* Explicit parameter variants. */
struct GPUTexture *DRW_texture_pool_query_2d_ex(
int w, int h, eGPUTextureFormat format, eGPUTextureUsage usage, DrawEngineType *engine_type);
struct GPUTexture *DRW_texture_pool_query_fullscreen_ex(eGPUTextureFormat format,
eGPUTextureUsage usage,
DrawEngineType *engine_type);
struct GPUTexture *DRW_texture_create_1d_ex(int w,
eGPUTextureFormat format,
eGPUTextureUsage usage_flags,
DRWTextureFlag flags,
const float *fpixels);
struct GPUTexture *DRW_texture_create_2d_ex(int w,
int h,
eGPUTextureFormat format,
eGPUTextureUsage usage_flags,
DRWTextureFlag flags,
const float *fpixels);
struct GPUTexture *DRW_texture_create_2d_array_ex(int w,
int h,
int d,
eGPUTextureFormat format,
eGPUTextureUsage usage_flags,
DRWTextureFlag flags,
const float *fpixels);
struct GPUTexture *DRW_texture_create_3d_ex(int w,
int h,
int d,
eGPUTextureFormat format,
eGPUTextureUsage usage_flags,
DRWTextureFlag flags,
const float *fpixels);
struct GPUTexture *DRW_texture_create_cube_ex(int w,
eGPUTextureFormat format,
eGPUTextureUsage usage_flags,
DRWTextureFlag flags,
const float *fpixels);
struct GPUTexture *DRW_texture_create_cube_array_ex(int w,
int d,
eGPUTextureFormat format,
eGPUTextureUsage usage_flags,
DRWTextureFlag flags,
const float *fpixels);
void DRW_texture_ensure_fullscreen_2d_ex(struct GPUTexture **tex,
eGPUTextureFormat format,
eGPUTextureUsage usage,
DRWTextureFlag flags);
void DRW_texture_ensure_2d_ex(struct GPUTexture **tex,
int w,
int h,
eGPUTextureFormat format,
eGPUTextureUsage usage,
DRWTextureFlag flags);
void DRW_texture_generate_mipmaps(struct GPUTexture *tex);
void DRW_texture_free(struct GPUTexture *tex);
#define DRW_TEXTURE_FREE_SAFE(tex) \

View File

@ -307,12 +307,13 @@ static DRWVolumeGrid *volume_grid_cache_get(const Volume *volume,
/* Create GPU texture. */
eGPUTextureFormat format = (channels == 3) ? GPU_RGB16F : GPU_R16F;
cache_grid->texture = GPU_texture_create_3d("volume_grid",
UNPACK3(dense_grid.resolution),
1,
format,
GPU_DATA_FLOAT,
dense_grid.voxels);
cache_grid->texture = GPU_texture_create_3d_ex("volume_grid",
UNPACK3(dense_grid.resolution),
1,
format,
GPU_DATA_FLOAT,
GPU_TEXTURE_USAGE_SHADER_READ,
dense_grid.voxels);
/* The texture can be null if the resolution along one axis is larger than
* GL_MAX_3D_TEXTURE_SIZE. */
if (cache_grid->texture != nullptr) {

View File

@ -219,7 +219,8 @@ void DRW_globals_update(void)
BKE_colorband_evaluate_table_rgba(&ramp, &colors, &col_size);
G_draw.ramp = GPU_texture_create_1d("ramp", col_size, 1, GPU_RGBA8, colors);
G_draw.ramp = GPU_texture_create_1d_ex(
"ramp", col_size, 1, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ, colors);
MEM_freeN(colors);
}
@ -476,5 +477,6 @@ static GPUTexture *DRW_create_weight_colorramp_texture(void)
pixels[i][3] = 1.0f;
}
return GPU_texture_create_1d("weight_color_ramp", 256, 1, GPU_SRGB8_A8, pixels[0]);
return GPU_texture_create_1d_ex(
"weight_color_ramp", 256, 1, GPU_SRGB8_A8, GPU_TEXTURE_USAGE_SHADER_READ, pixels[0]);
}

View File

@ -438,8 +438,10 @@ void DRW_curves_update()
* Do chunks of maximum 2048 * 2048 hair points. */
int width = 2048;
int height = min_ii(width, 1 + max_size / width);
GPUTexture *tex = DRW_texture_pool_query_2d(
width, height, GPU_RGBA32F, (DrawEngineType *)DRW_curves_update);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_SHADER_WRITE;
GPUTexture *tex = DRW_texture_pool_query_2d_ex(
width, height, GPU_RGBA32F, usage, (DrawEngineType *)DRW_curves_update);
g_tf_target_height = height;
g_tf_target_width = width;
@ -497,8 +499,10 @@ void DRW_curves_update()
if (!GPU_framebuffer_check_valid(prev_fb, errorOut)) {
int width = 64;
int height = 64;
GPUTexture *tex = DRW_texture_pool_query_2d(
width, height, GPU_DEPTH_COMPONENT32F, (DrawEngineType *)DRW_hair_update);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
GPUTexture *tex = DRW_texture_pool_query_2d_ex(
width, height, GPU_DEPTH_COMPONENT32F, usage, (DrawEngineType *)DRW_hair_update);
g_tf_target_height = height;
g_tf_target_width = width;

View File

@ -106,7 +106,8 @@ static GPUTexture *create_transfer_function(int type, const struct ColorBand *co
break;
}
GPUTexture *tex = GPU_texture_create_1d("transf_func", TFUNC_WIDTH, 1, GPU_SRGB8_A8, data);
GPUTexture *tex = GPU_texture_create_1d_ex(
"transf_func", TFUNC_WIDTH, 1, GPU_SRGB8_A8, GPU_TEXTURE_USAGE_SHADER_READ, data);
MEM_freeN(data);
@ -178,8 +179,13 @@ static GPUTexture *create_volume_texture(const int dim[3],
}
while (1) {
tex = GPU_texture_create_3d(
"volume", UNPACK3(final_dim), 1, texture_format, data_format, NULL);
tex = GPU_texture_create_3d_ex("volume",
UNPACK3(final_dim),
1,
texture_format,
data_format,
GPU_TEXTURE_USAGE_SHADER_READ,
NULL);
if (tex != NULL) {
break;
@ -502,12 +508,27 @@ void DRW_smoke_ensure_velocity(FluidModifierData *fmd)
}
if (!fds->tex_velocity_x) {
fds->tex_velocity_x = GPU_texture_create_3d(
"velx", UNPACK3(fds->res), 1, GPU_R16F, GPU_DATA_FLOAT, vel_x);
fds->tex_velocity_y = GPU_texture_create_3d(
"vely", UNPACK3(fds->res), 1, GPU_R16F, GPU_DATA_FLOAT, vel_y);
fds->tex_velocity_z = GPU_texture_create_3d(
"velz", UNPACK3(fds->res), 1, GPU_R16F, GPU_DATA_FLOAT, vel_z);
fds->tex_velocity_x = GPU_texture_create_3d_ex("velx",
UNPACK3(fds->res),
1,
GPU_R16F,
GPU_DATA_FLOAT,
GPU_TEXTURE_USAGE_SHADER_READ,
vel_x);
fds->tex_velocity_y = GPU_texture_create_3d_ex("vely",
UNPACK3(fds->res),
1,
GPU_R16F,
GPU_DATA_FLOAT,
GPU_TEXTURE_USAGE_SHADER_READ,
vel_y);
fds->tex_velocity_z = GPU_texture_create_3d_ex("velz",
UNPACK3(fds->res),
1,
GPU_R16F,
GPU_DATA_FLOAT,
GPU_TEXTURE_USAGE_SHADER_READ,
vel_z);
BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_velocity_x));
BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_velocity_y));
BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_velocity_z));

View File

@ -334,8 +334,9 @@ void DRW_hair_update()
* Do chunks of maximum 2048 * 2048 hair points. */
int width = 2048;
int height = min_ii(width, 1 + max_size / width);
GPUTexture *tex = DRW_texture_pool_query_2d(
width, height, GPU_RGBA32F, (DrawEngineType *)DRW_hair_update);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
GPUTexture *tex = DRW_texture_pool_query_2d_ex(
width, height, GPU_RGBA32F, usage, (DrawEngineType *)DRW_hair_update);
g_tf_target_height = height;
g_tf_target_width = width;
@ -392,8 +393,10 @@ void DRW_hair_update()
if (!GPU_framebuffer_check_valid(prev_fb, errorOut)) {
int width = 64;
int height = 64;
GPUTexture *tex = DRW_texture_pool_query_2d(
width, height, GPU_DEPTH_COMPONENT32F, (DrawEngineType *)DRW_hair_update);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_SHADER_WRITE;
GPUTexture *tex = DRW_texture_pool_query_2d_ex(
width, height, GPU_DEPTH_COMPONENT32F, usage, (DrawEngineType *)DRW_hair_update);
g_tf_target_height = height;
g_tf_target_width = width;

View File

@ -2337,8 +2337,9 @@ static void draw_select_framebuffer_depth_only_setup(const int size[2])
}
if (g_select_buffer.texture_depth == NULL) {
g_select_buffer.texture_depth = GPU_texture_create_2d(
"select_depth", size[0], size[1], 1, GPU_DEPTH_COMPONENT24, NULL);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
g_select_buffer.texture_depth = GPU_texture_create_2d_ex(
"select_depth", size[0], size[1], 1, GPU_DEPTH_COMPONENT24, usage, NULL);
GPU_framebuffer_texture_attach(
g_select_buffer.framebuffer_depth_only, g_select_buffer.texture_depth, 0, 0);

View File

@ -64,13 +64,36 @@ void drw_texture_set_parameters(GPUTexture *tex, DRWTextureFlag flags)
GPU_texture_compare_mode(tex, flags & DRW_TEX_COMPARE);
}
GPUTexture *DRW_texture_create_1d_ex(int w,
eGPUTextureFormat format,
eGPUTextureUsage usage,
DRWTextureFlag flags,
const float *fpixels)
{
int mip_len = (flags & DRW_TEX_MIPMAP) ? 9999 : 1;
GPUTexture *tex = GPU_texture_create_1d_ex(__func__, w, mip_len, format, usage, fpixels);
drw_texture_set_parameters(tex, flags);
return tex;
}
GPUTexture *DRW_texture_create_1d(int w,
eGPUTextureFormat format,
DRWTextureFlag flags,
const float *fpixels)
{
return DRW_texture_create_1d_ex(w, format, GPU_TEXTURE_USAGE_GENERAL, flags, fpixels);
}
GPUTexture *DRW_texture_create_2d_ex(int w,
int h,
eGPUTextureFormat format,
eGPUTextureUsage usage,
DRWTextureFlag flags,
const float *fpixels)
{
int mip_len = (flags & DRW_TEX_MIPMAP) ? 9999 : 1;
GPUTexture *tex = GPU_texture_create_1d(__func__, w, mip_len, format, fpixels);
GPUTexture *tex = GPU_texture_create_2d_ex(__func__, w, h, mip_len, format, usage, fpixels);
drw_texture_set_parameters(tex, flags);
return tex;
@ -78,9 +101,21 @@ GPUTexture *DRW_texture_create_1d(int w,
GPUTexture *DRW_texture_create_2d(
int w, int h, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels)
{
return DRW_texture_create_2d_ex(w, h, format, GPU_TEXTURE_USAGE_GENERAL, flags, fpixels);
}
GPUTexture *DRW_texture_create_2d_array_ex(int w,
int h,
int d,
eGPUTextureFormat format,
eGPUTextureUsage usage,
DRWTextureFlag flags,
const float *fpixels)
{
int mip_len = (flags & DRW_TEX_MIPMAP) ? 9999 : 1;
GPUTexture *tex = GPU_texture_create_2d(__func__, w, h, mip_len, format, fpixels);
GPUTexture *tex = GPU_texture_create_2d_array_ex(
__func__, w, h, d, mip_len, format, usage, fpixels);
drw_texture_set_parameters(tex, flags);
return tex;
@ -88,9 +123,22 @@ GPUTexture *DRW_texture_create_2d(
GPUTexture *DRW_texture_create_2d_array(
int w, int h, int d, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels)
{
return DRW_texture_create_2d_array_ex(
w, h, d, format, GPU_TEXTURE_USAGE_GENERAL, flags, fpixels);
}
GPUTexture *DRW_texture_create_3d_ex(int w,
int h,
int d,
eGPUTextureFormat format,
eGPUTextureUsage usage,
DRWTextureFlag flags,
const float *fpixels)
{
int mip_len = (flags & DRW_TEX_MIPMAP) ? 9999 : 1;
GPUTexture *tex = GPU_texture_create_2d_array(__func__, w, h, d, mip_len, format, fpixels);
GPUTexture *tex = GPU_texture_create_3d_ex(
__func__, w, h, d, mip_len, format, GPU_DATA_FLOAT, usage, fpixels);
drw_texture_set_parameters(tex, flags);
return tex;
@ -99,11 +147,18 @@ GPUTexture *DRW_texture_create_2d_array(
GPUTexture *DRW_texture_create_3d(
int w, int h, int d, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels)
{
int mip_len = (flags & DRW_TEX_MIPMAP) ? 9999 : 1;
GPUTexture *tex = GPU_texture_create_3d(
__func__, w, h, d, mip_len, format, GPU_DATA_FLOAT, fpixels);
drw_texture_set_parameters(tex, flags);
return DRW_texture_create_3d_ex(w, h, d, format, GPU_TEXTURE_USAGE_GENERAL, flags, fpixels);
}
GPUTexture *DRW_texture_create_cube_ex(int w,
eGPUTextureFormat format,
eGPUTextureUsage usage,
DRWTextureFlag flags,
const float *fpixels)
{
int mip_len = (flags & DRW_TEX_MIPMAP) ? 9999 : 1;
GPUTexture *tex = GPU_texture_create_cube_ex(__func__, w, mip_len, format, usage, fpixels);
drw_texture_set_parameters(tex, flags);
return tex;
}
@ -111,9 +166,20 @@ GPUTexture *DRW_texture_create_cube(int w,
eGPUTextureFormat format,
DRWTextureFlag flags,
const float *fpixels)
{
return DRW_texture_create_cube_ex(w, format, GPU_TEXTURE_USAGE_GENERAL, flags, fpixels);
}
GPUTexture *DRW_texture_create_cube_array_ex(int w,
int d,
eGPUTextureFormat format,
eGPUTextureUsage usage,
DRWTextureFlag flags,
const float *fpixels)
{
int mip_len = (flags & DRW_TEX_MIPMAP) ? 9999 : 1;
GPUTexture *tex = GPU_texture_create_cube(__func__, w, mip_len, format, fpixels);
GPUTexture *tex = GPU_texture_create_cube_array_ex(
__func__, w, d, mip_len, format, usage, fpixels);
drw_texture_set_parameters(tex, flags);
return tex;
}
@ -121,9 +187,16 @@ GPUTexture *DRW_texture_create_cube(int w,
GPUTexture *DRW_texture_create_cube_array(
int w, int d, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels)
{
int mip_len = (flags & DRW_TEX_MIPMAP) ? 9999 : 1;
GPUTexture *tex = GPU_texture_create_cube_array(__func__, w, d, mip_len, format, fpixels);
drw_texture_set_parameters(tex, flags);
return DRW_texture_create_cube_array_ex(w, d, format, GPU_TEXTURE_USAGE_GENERAL, flags, fpixels);
}
GPUTexture *DRW_texture_pool_query_2d_ex(
int w, int h, eGPUTextureFormat format, eGPUTextureUsage usage, DrawEngineType *engine_type)
{
BLI_assert(drw_texture_format_supports_framebuffer(format));
GPUTexture *tex = DRW_texture_pool_query(
DST.vmempool->texture_pool, w, h, format, usage, engine_type);
return tex;
}
@ -132,35 +205,57 @@ GPUTexture *DRW_texture_pool_query_2d(int w,
eGPUTextureFormat format,
DrawEngineType *engine_type)
{
BLI_assert(drw_texture_format_supports_framebuffer(format));
GPUTexture *tex = DRW_texture_pool_query(DST.vmempool->texture_pool, w, h, format, engine_type);
return DRW_texture_pool_query_2d_ex(w, h, format, GPU_TEXTURE_USAGE_GENERAL, engine_type);
}
return tex;
GPUTexture *DRW_texture_pool_query_fullscreen_ex(eGPUTextureFormat format,
eGPUTextureUsage usage,
DrawEngineType *engine_type)
{
const float *size = DRW_viewport_size_get();
return DRW_texture_pool_query_2d_ex((int)size[0], (int)size[1], format, usage, engine_type);
}
GPUTexture *DRW_texture_pool_query_fullscreen(eGPUTextureFormat format,
DrawEngineType *engine_type)
{
const float *size = DRW_viewport_size_get();
return DRW_texture_pool_query_2d((int)size[0], (int)size[1], format, engine_type);
return DRW_texture_pool_query_fullscreen_ex(format, GPU_TEXTURE_USAGE_GENERAL, engine_type);
}
void DRW_texture_ensure_fullscreen_2d_ex(GPUTexture **tex,
eGPUTextureFormat format,
eGPUTextureUsage usage,
DRWTextureFlag flags)
{
if (*(tex) == NULL) {
const float *size = DRW_viewport_size_get();
*(tex) = DRW_texture_create_2d_ex((int)size[0], (int)size[1], format, usage, flags, NULL);
}
}
void DRW_texture_ensure_fullscreen_2d(GPUTexture **tex,
eGPUTextureFormat format,
DRWTextureFlag flags)
{
DRW_texture_ensure_fullscreen_2d_ex(tex, format, GPU_TEXTURE_USAGE_GENERAL, flags);
}
void DRW_texture_ensure_2d_ex(GPUTexture **tex,
int w,
int h,
eGPUTextureFormat format,
eGPUTextureUsage usage,
DRWTextureFlag flags)
{
if (*(tex) == NULL) {
const float *size = DRW_viewport_size_get();
*(tex) = DRW_texture_create_2d((int)size[0], (int)size[1], format, flags, NULL);
*(tex) = DRW_texture_create_2d_ex(w, h, format, usage, flags, NULL);
}
}
void DRW_texture_ensure_2d(
GPUTexture **tex, int w, int h, eGPUTextureFormat format, DRWTextureFlag flags)
{
if (*(tex) == NULL) {
*(tex) = DRW_texture_create_2d(w, h, format, flags, NULL);
}
DRW_texture_ensure_2d_ex(tex, w, h, format, GPU_TEXTURE_USAGE_GENERAL, flags);
}
void DRW_texture_generate_mipmaps(GPUTexture *tex)

View File

@ -42,9 +42,18 @@ void DRW_texture_pool_free(DRWTexturePool *pool)
delete pool;
}
GPUTexture *DRW_texture_pool_query(
DRWTexturePool *pool, int width, int height, eGPUTextureFormat format, void *user)
GPUTexture *DRW_texture_pool_query(DRWTexturePool *pool,
int width,
int height,
eGPUTextureFormat format,
eGPUTextureUsage usage,
void *user)
{
/* Texture pools have an implicit usage as a texture attachment*/
BLI_assert_msg(usage & GPU_TEXTURE_USAGE_ATTACHMENT,
"Pool textures must be of usage type attachment.");
usage = usage | GPU_TEXTURE_USAGE_ATTACHMENT;
int user_id = pool->last_user_id;
/* Try cached value. */
if (user_id != -1) {
@ -74,7 +83,8 @@ GPUTexture *DRW_texture_pool_query(
/* If everything matches reuse the texture. */
if ((GPU_texture_format(handle.texture) == format) &&
(GPU_texture_width(handle.texture) == width) &&
(GPU_texture_height(handle.texture) == height)) {
(GPU_texture_height(handle.texture) == height) &&
(GPU_texture_usage(handle.texture) == usage)) {
handle.users_bits |= user_bit;
return handle.texture;
}
@ -88,7 +98,7 @@ GPUTexture *DRW_texture_pool_query(
DRWTexturePoolHandle handle;
handle.users_bits = user_bit;
handle.texture = GPU_texture_create_2d(name, width, height, 1, format, nullptr);
handle.texture = GPU_texture_create_2d_ex(name, width, height, 1, format, usage, nullptr);
pool->handles.append(handle);
/* Doing filtering for depth does not make sense when not doing shadow mapping,
* and enabling texture filtering on integer texture make them unreadable. */
@ -98,10 +108,8 @@ GPUTexture *DRW_texture_pool_query(
return handle.texture;
}
GPUTexture *DRW_texture_pool_texture_acquire(DRWTexturePool *pool,
int width,
int height,
eGPUTextureFormat format)
GPUTexture *DRW_texture_pool_texture_acquire(
DRWTexturePool *pool, int width, int height, eGPUTextureFormat format, eGPUTextureUsage usage)
{
GPUTexture *tmp_tex = nullptr;
int64_t found_index = 0;
@ -109,7 +117,7 @@ GPUTexture *DRW_texture_pool_texture_acquire(DRWTexturePool *pool,
auto texture_match = [&](GPUTexture *tex) -> bool {
/* TODO(@fclem): We could reuse texture using texture views if the formats are compatible. */
return (GPU_texture_format(tex) == format) && (GPU_texture_width(tex) == width) &&
(GPU_texture_height(tex) == height);
(GPU_texture_height(tex) == height) && (GPU_texture_usage(tex) == usage);
};
/* Search released texture first. */
@ -146,7 +154,7 @@ GPUTexture *DRW_texture_pool_texture_acquire(DRWTexturePool *pool,
int texture_id = pool->handles.size();
SNPRINTF(name, "DRW_tex_pool_%d", texture_id);
}
tmp_tex = GPU_texture_create_2d(name, width, height, 1, format, nullptr);
tmp_tex = GPU_texture_create_2d_ex(name, width, height, 1, format, usage, nullptr);
}
pool->tmp_tex_acquired.append(tmp_tex);

View File

@ -28,15 +28,18 @@ void DRW_texture_pool_free(DRWTexturePool *pool);
* If no texture was found, create one and add it to the pool.
* DEPRECATED: Use DRW_texture_pool_texture_acquire instead and do it just before rendering.
*/
GPUTexture *DRW_texture_pool_query(
DRWTexturePool *pool, int width, int height, eGPUTextureFormat format, void *user);
GPUTexture *DRW_texture_pool_query(DRWTexturePool *pool,
int width,
int height,
eGPUTextureFormat format,
eGPUTextureUsage usage,
void *user);
/**
* Returns a temporary texture that needs to be released after use. Texture content is undefined.
*/
GPUTexture *DRW_texture_pool_texture_acquire(DRWTexturePool *pool,
int width,
int height,
eGPUTextureFormat format);
GPUTexture *DRW_texture_pool_texture_acquire(
DRWTexturePool *pool, int width, int height, eGPUTextureFormat format, eGPUTextureUsage usage);
/**
* Releases a previously acquired texture.
*/

View File

@ -70,10 +70,10 @@ static void drw_volume_globals_init()
{
const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
g_data.dummy_zero = GPU_texture_create_3d(
"dummy_zero", 1, 1, 1, 1, GPU_RGBA8, GPU_DATA_FLOAT, zero);
g_data.dummy_one = GPU_texture_create_3d(
"dummy_one", 1, 1, 1, 1, GPU_RGBA8, GPU_DATA_FLOAT, one);
g_data.dummy_zero = GPU_texture_create_3d_ex(
"dummy_zero", 1, 1, 1, 1, GPU_RGBA8, GPU_DATA_FLOAT, GPU_TEXTURE_USAGE_SHADER_READ, zero);
g_data.dummy_one = GPU_texture_create_3d_ex(
"dummy_one", 1, 1, 1, 1, GPU_RGBA8, GPU_DATA_FLOAT, GPU_TEXTURE_USAGE_SHADER_READ, one);
GPU_texture_wrap_mode(g_data.dummy_zero, true, true);
GPU_texture_wrap_mode(g_data.dummy_one, true, true);

View File

@ -912,14 +912,20 @@ void UI_icons_reload_internal_textures(void)
icongltex.invw = 1.0f / b32buf->x;
icongltex.invh = 1.0f / b32buf->y;
icongltex.tex[0] = GPU_texture_create_2d("icons", b32buf->x, b32buf->y, 2, GPU_RGBA8, NULL);
icongltex.tex[0] = GPU_texture_create_2d_ex(
"icons", b32buf->x, b32buf->y, 2, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ, NULL);
GPU_texture_update_mipmap(icongltex.tex[0], 0, GPU_DATA_UBYTE, b32buf->rect);
GPU_texture_update_mipmap(icongltex.tex[0], 1, GPU_DATA_UBYTE, b16buf->rect);
}
if (need_icons_with_border && icongltex.tex[1] == NULL) {
icongltex.tex[1] = GPU_texture_create_2d(
"icons_border", b32buf_border->x, b32buf_border->y, 2, GPU_RGBA8, NULL);
icongltex.tex[1] = GPU_texture_create_2d_ex("icons_border",
b32buf_border->x,
b32buf_border->y,
2,
GPU_RGBA8,
GPU_TEXTURE_USAGE_SHADER_READ,
NULL);
GPU_texture_update_mipmap(icongltex.tex[1], 0, GPU_DATA_UBYTE, b32buf_border->rect);
GPU_texture_update_mipmap(icongltex.tex[1], 1, GPU_DATA_UBYTE, b16buf_border->rect);
}

View File

@ -334,8 +334,9 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
if (!target->overlay_texture) {
eGPUTextureFormat format = col ? GPU_RGBA8 : GPU_R8;
target->overlay_texture = GPU_texture_create_2d(
"paint_cursor_overlay", size, size, 1, format, nullptr);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
target->overlay_texture = GPU_texture_create_2d_ex(
"paint_cursor_overlay", size, size, 1, format, usage, nullptr);
GPU_texture_update(target->overlay_texture, GPU_DATA_UBYTE, buffer);
if (!col) {
@ -452,8 +453,9 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
BLI_task_parallel_range(0, size, &data, load_tex_cursor_task_cb, &settings);
if (!cursor_snap.overlay_texture) {
cursor_snap.overlay_texture = GPU_texture_create_2d(
"cursor_snap_overaly", size, size, 1, GPU_R8, nullptr);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
cursor_snap.overlay_texture = GPU_texture_create_2d_ex(
"cursor_snap_overaly", size, size, 1, GPU_R8, usage, nullptr);
GPU_texture_update(cursor_snap.overlay_texture, GPU_DATA_UBYTE, buffer);
GPU_texture_swizzle_set(cursor_snap.overlay_texture, "rrrr");

View File

@ -1196,8 +1196,13 @@ static void draw_plane_marker_image(Scene *scene,
GPU_blend(GPU_BLEND_ALPHA);
}
GPUTexture *texture = GPU_texture_create_2d(
"plane_marker_image", ibuf->x, ibuf->y, 1, GPU_RGBA8, NULL);
GPUTexture *texture = GPU_texture_create_2d_ex("plane_marker_image",
ibuf->x,
ibuf->y,
1,
GPU_RGBA8,
GPU_TEXTURE_USAGE_SHADER_READ,
NULL);
GPU_texture_update(texture, GPU_DATA_UBYTE, display_buffer);
GPU_texture_filter_mode(texture, false);

View File

@ -1907,9 +1907,9 @@ static void sequencer_draw_display_buffer(const bContext *C,
GPU_matrix_push_projection();
GPU_matrix_identity_projection_set();
}
GPUTexture *texture = GPU_texture_create_2d(
"seq_display_buf", ibuf->x, ibuf->y, 1, format, NULL);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
GPUTexture *texture = GPU_texture_create_2d_ex(
"seq_display_buf", ibuf->x, ibuf->y, 1, format, usage, NULL);
GPU_texture_update(texture, data, display_buffer);
GPU_texture_filter_mode(texture, false);

View File

@ -186,14 +186,39 @@ typedef enum eGPUDataFormat {
GPU_DATA_HALF_FLOAT
} eGPUDataFormat;
/** Texture usage flags.
* Texture usage flags allow backend implementations to contextually optimise texture resources.
* Any texture with an explicit flag should not perform operations which are not explicitly
* specified in the usage flags. If usage is unknown upfront, then GPU_TEXTURE_USAGE_GENERAL can be
* used.
*
* NOTE: These usage flags act as hints for the backend implementations. There may be no benefit in
* some circumstances, and certain resource types may insert additional usage as required. However,
* explicit usage can ensure that hardware features such as render target/texture compression can
* be used. For explicit APIs such as Metal/Vulkan, texture usage needs to be specified up-front.
*/
typedef enum eGPUTextureUsage {
/* Whether texture is sampled or read during a shader. */
GPU_TEXTURE_USAGE_SHADER_READ = (1 << 0),
/* Whether the texture is written to by a shader using imageStore. */
GPU_TEXTURE_USAGE_SHADER_WRITE = (1 << 1),
/* Whether a texture is used as an attachment in a framebuffer. */
GPU_TEXTURE_USAGE_ATTACHMENT = (1 << 2),
GPU_TEXTURE_USAGE_GENERAL = 0xFF
/* Whether the texture is used as a texture view, uses mip-map layer adjustment,
* OR, uses swizzle access masks. Mip-map base layer adjustment and texture channel swizzling
* requires a texture view under-the-hood. */
GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW = (1 << 3),
/* Whether a texture can be allocated without any backing memory. It is used as an
* attachment to store data, but is not needed by any future passes.
* This usage mode should be used in scenarios where an attachment has no previous
* contents and is not stored after a render pass. */
GPU_TEXTURE_USAGE_MEMORYLESS = (1 << 4),
/* Whether the texture needs to be read from by the CPU. */
GPU_TEXTURE_USAGE_HOST_READ = (1 << 5),
GPU_TEXTURE_USAGE_GENERAL = 0xFF,
} eGPUTextureUsage;
ENUM_OPERATORS(eGPUTextureUsage, GPU_TEXTURE_USAGE_GENERAL)
ENUM_OPERATORS(eGPUTextureUsage, GPU_TEXTURE_USAGE_GENERAL);
unsigned int GPU_texture_memory_usage_get(void);
@ -201,14 +226,72 @@ unsigned int GPU_texture_memory_usage_get(void);
* \note \a data is expected to be float. If the \a format is not compatible with float data or if
* the data is not in float format, use GPU_texture_update to upload the data with the right data
* format.
* \a mip_len is the number of mip level to allocate. It must be >= 1.
* NOTE: _ex variants of texure creation functions allow specification of explicit usage for
* optimal performance. Using standard texture creation will use the `GPU_TEXTURE_USAGE_GENERAL`.
*
* Textures created via other means will either inherit usage from the source resource, or also
* be initialised with `GPU_TEXTURE_USAGE_GENERAL`.
*
* flag. \a mips is the number of mip level to allocate. It must be >= 1.
*/
GPUTexture *GPU_texture_create_1d_ex(const char *name,
int w,
int mip_len,
eGPUTextureFormat format,
eGPUTextureUsage usage_flags,
const float *data);
GPUTexture *GPU_texture_create_1d_array_ex(const char *name,
int w,
int h,
int mip_len,
eGPUTextureFormat format,
eGPUTextureUsage usage_flags,
const float *data);
GPUTexture *GPU_texture_create_2d_ex(const char *name,
int w,
int h,
int mips,
eGPUTextureFormat format,
eGPUTextureUsage usage_flags,
const float *data);
GPUTexture *GPU_texture_create_2d_array_ex(const char *name,
int w,
int h,
int d,
int mip_len,
eGPUTextureFormat format,
eGPUTextureUsage usage_flags,
const float *data);
GPUTexture *GPU_texture_create_3d_ex(const char *name,
int w,
int h,
int d,
int mip_len,
eGPUTextureFormat texture_format,
eGPUDataFormat data_format,
eGPUTextureUsage usage_flags,
const void *data);
GPUTexture *GPU_texture_create_cube_ex(const char *name,
int w,
int mip_len,
eGPUTextureFormat format,
eGPUTextureUsage usage_flags,
const float *data);
GPUTexture *GPU_texture_create_cube_array_ex(const char *name,
int w,
int d,
int mip_len,
eGPUTextureFormat format,
eGPUTextureUsage usage_flags,
const float *data);
/* Standard texture functions. */
GPUTexture *GPU_texture_create_1d(
const char *name, int w, int mip_len, eGPUTextureFormat format, const float *data);
GPUTexture *GPU_texture_create_1d_array(
const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data);
GPUTexture *GPU_texture_create_2d(
const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data);
const char *name, int w, int h, int mips, eGPUTextureFormat format, const float *data);
GPUTexture *GPU_texture_create_2d_array(const char *name,
int w,
int h,
@ -229,6 +312,9 @@ GPUTexture *GPU_texture_create_cube(
GPUTexture *GPU_texture_create_cube_array(
const char *name, int w, int d, int mip_len, eGPUTextureFormat format, const float *data);
/* Fetch Usage. */
eGPUTextureUsage GPU_texture_usage(const GPUTexture *texture);
/* Special textures. */
GPUTexture *GPU_texture_create_from_vertbuf(const char *name, struct GPUVertBuf *vert);
@ -238,8 +324,16 @@ GPUTexture *GPU_texture_create_from_vertbuf(const char *name, struct GPUVertBuf
/**
* DDS texture loading. Return NULL if support is not available.
*/
GPUTexture *GPU_texture_create_compressed_2d_ex(const char *name,
int w,
int h,
int miplen,
eGPUTextureFormat format,
eGPUTextureUsage usage,
const void *data);
GPUTexture *GPU_texture_create_compressed_2d(
const char *name, int w, int h, int miplen, eGPUTextureFormat format, const void *data);
/**
* Create an error texture that will bind an invalid texture (pink) at draw time.
*/

View File

@ -622,11 +622,12 @@ GPUOffScreen *GPU_offscreen_create(
height = max_ii(1, height);
width = max_ii(1, width);
ofs->color = GPU_texture_create_2d("ofs_color", width, height, 1, format, nullptr);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
ofs->color = GPU_texture_create_2d_ex("ofs_color", width, height, 1, format, usage, nullptr);
if (depth) {
ofs->depth = GPU_texture_create_2d(
"ofs_depth", width, height, 1, GPU_DEPTH24_STENCIL8, nullptr);
ofs->depth = GPU_texture_create_2d_ex(
"ofs_depth", width, height, 1, GPU_DEPTH24_STENCIL8, usage, nullptr);
}
if ((depth && !ofs->depth) || !ofs->color) {

View File

@ -175,8 +175,13 @@ static void gpu_material_ramp_texture_build(GPUMaterial *mat)
GPUColorBandBuilder *builder = mat->coba_builder;
mat->coba_tex = GPU_texture_create_1d_array(
"mat_ramp", CM_TABLE + 1, builder->current_layer, 1, GPU_RGBA16F, (float *)builder->pixels);
mat->coba_tex = GPU_texture_create_1d_array_ex("mat_ramp",
CM_TABLE + 1,
builder->current_layer,
1,
GPU_RGBA16F,
GPU_TEXTURE_USAGE_SHADER_READ,
(float *)builder->pixels);
MEM_freeN(builder);
mat->coba_builder = NULL;
@ -544,8 +549,12 @@ struct GPUUniformBuf *GPU_material_sss_profile_get(GPUMaterial *material,
GPU_texture_free(material->sss_tex_profile);
}
material->sss_tex_profile = GPU_texture_create_1d(
"sss_tex_profile", 64, 1, GPU_RGBA16F, translucence_profile);
material->sss_tex_profile = GPU_texture_create_1d_ex("sss_tex_profile",
64,
1,
GPU_RGBA16F,
GPU_TEXTURE_USAGE_SHADER_READ,
translucence_profile);
MEM_freeN(translucence_profile);

View File

@ -34,6 +34,8 @@ Texture::Texture(const char *name)
for (int i = 0; i < ARRAY_SIZE(fb_); i++) {
fb_[i] = nullptr;
}
gpu_image_usage_flags_ = GPU_TEXTURE_USAGE_GENERAL;
}
Texture::~Texture()
@ -173,6 +175,11 @@ bool Texture::init_view(const GPUTexture *src_,
return this->init_internal(src_, mip_start, layer_start);
}
void Texture::usage_set(eGPUTextureUsage usage_flags)
{
gpu_image_usage_flags_ = usage_flags;
}
/** \} */
/* -------------------------------------------------------------------- */
@ -240,6 +247,7 @@ static inline GPUTexture *gpu_texture_create(const char *name,
int mip_len,
eGPUTextureFormat tex_format,
eGPUDataFormat data_format,
eGPUTextureUsage usage,
const void *pixels)
{
BLI_assert(mip_len > 0);
@ -265,6 +273,9 @@ static inline GPUTexture *gpu_texture_create(const char *name,
break;
}
/* Assign usage. */
tex->usage_set(usage);
if (!success) {
delete tex;
return nullptr;
@ -275,70 +286,105 @@ static inline GPUTexture *gpu_texture_create(const char *name,
return reinterpret_cast<GPUTexture *>(tex);
}
GPUTexture *GPU_texture_create_1d(
const char *name, int w, int mip_len, eGPUTextureFormat format, const float *data)
{
return gpu_texture_create(name, w, 0, 0, GPU_TEXTURE_1D, mip_len, format, GPU_DATA_FLOAT, data);
}
GPUTexture *GPU_texture_create_1d_array(
const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data)
GPUTexture *GPU_texture_create_1d_ex(const char *name,
int w,
int mip_len,
eGPUTextureFormat format,
eGPUTextureUsage usage,
const float *data)
{
return gpu_texture_create(
name, w, h, 0, GPU_TEXTURE_1D_ARRAY, mip_len, format, GPU_DATA_FLOAT, data);
name, w, 0, 0, GPU_TEXTURE_1D, mip_len, format, GPU_DATA_FLOAT, usage, data);
}
GPUTexture *GPU_texture_create_2d(
const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data)
{
return gpu_texture_create(name, w, h, 0, GPU_TEXTURE_2D, mip_len, format, GPU_DATA_FLOAT, data);
}
GPUTexture *GPU_texture_create_2d_array(const char *name,
int w,
int h,
int d,
int mip_len,
eGPUTextureFormat format,
const float *data)
GPUTexture *GPU_texture_create_1d_array_ex(const char *name,
int w,
int h,
int mip_len,
eGPUTextureFormat format,
eGPUTextureUsage usage,
const float *data)
{
return gpu_texture_create(
name, w, h, d, GPU_TEXTURE_2D_ARRAY, mip_len, format, GPU_DATA_FLOAT, data);
name, w, h, 0, GPU_TEXTURE_1D_ARRAY, mip_len, format, GPU_DATA_FLOAT, usage, data);
}
GPUTexture *GPU_texture_create_3d(const char *name,
int w,
int h,
int d,
int mip_len,
eGPUTextureFormat texture_format,
eGPUDataFormat data_format,
const void *data)
GPUTexture *GPU_texture_create_2d_ex(const char *name,
int w,
int h,
int mip_len,
eGPUTextureFormat format,
eGPUTextureUsage usage,
const float *data)
{
return gpu_texture_create(
name, w, h, d, GPU_TEXTURE_3D, mip_len, texture_format, data_format, data);
name, w, h, 0, GPU_TEXTURE_2D, mip_len, format, GPU_DATA_FLOAT, usage, data);
}
GPUTexture *GPU_texture_create_cube(
const char *name, int w, int mip_len, eGPUTextureFormat format, const float *data)
GPUTexture *GPU_texture_create_2d_array_ex(const char *name,
int w,
int h,
int d,
int mip_len,
eGPUTextureFormat format,
eGPUTextureUsage usage,
const float *data)
{
return gpu_texture_create(
name, w, w, 0, GPU_TEXTURE_CUBE, mip_len, format, GPU_DATA_FLOAT, data);
name, w, h, d, GPU_TEXTURE_2D_ARRAY, mip_len, format, GPU_DATA_FLOAT, usage, data);
}
GPUTexture *GPU_texture_create_cube_array(
const char *name, int w, int d, int mip_len, eGPUTextureFormat format, const float *data)
GPUTexture *GPU_texture_create_3d_ex(const char *name,
int w,
int h,
int d,
int mip_len,
eGPUTextureFormat texture_format,
eGPUDataFormat data_format,
eGPUTextureUsage usage,
const void *data)
{
return gpu_texture_create(
name, w, w, d, GPU_TEXTURE_CUBE_ARRAY, mip_len, format, GPU_DATA_FLOAT, data);
name, w, h, d, GPU_TEXTURE_3D, mip_len, texture_format, data_format, usage, data);
}
GPUTexture *GPU_texture_create_compressed_2d(
const char *name, int w, int h, int miplen, eGPUTextureFormat tex_format, const void *data)
GPUTexture *GPU_texture_create_cube_ex(const char *name,
int w,
int mip_len,
eGPUTextureFormat format,
eGPUTextureUsage usage,
const float *data)
{
return gpu_texture_create(
name, w, w, 0, GPU_TEXTURE_CUBE, mip_len, format, GPU_DATA_FLOAT, usage, data);
}
GPUTexture *GPU_texture_create_cube_array_ex(const char *name,
int w,
int d,
int mip_len,
eGPUTextureFormat format,
eGPUTextureUsage usage,
const float *data)
{
return gpu_texture_create(
name, w, w, d, GPU_TEXTURE_CUBE_ARRAY, mip_len, format, GPU_DATA_FLOAT, usage, data);
}
GPUTexture *GPU_texture_create_compressed_2d_ex(const char *name,
int w,
int h,
int miplen,
eGPUTextureFormat tex_format,
eGPUTextureUsage usage,
const void *data)
{
Texture *tex = GPUBackend::get()->texture_alloc(name);
bool success = tex->init_2D(w, h, 0, miplen, tex_format);
/* Assign usage. */
tex->usage_set(usage);
if (!success) {
delete tex;
return nullptr;
@ -358,6 +404,70 @@ GPUTexture *GPU_texture_create_compressed_2d(
return reinterpret_cast<GPUTexture *>(tex);
}
GPUTexture *GPU_texture_create_1d(
const char *name, int w, int mip_len, eGPUTextureFormat format, const float *data)
{
return GPU_texture_create_1d_ex(name, w, mip_len, format, GPU_TEXTURE_USAGE_GENERAL, data);
}
GPUTexture *GPU_texture_create_1d_array(
const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data)
{
return GPU_texture_create_1d_array_ex(
name, w, h, mip_len, format, GPU_TEXTURE_USAGE_GENERAL, data);
}
GPUTexture *GPU_texture_create_2d(
const char *name, int w, int h, int mips, eGPUTextureFormat format, const float *data)
{
return GPU_texture_create_2d_ex(name, w, h, mips, format, GPU_TEXTURE_USAGE_GENERAL, data);
}
GPUTexture *GPU_texture_create_2d_array(const char *name,
int w,
int h,
int d,
int mip_len,
eGPUTextureFormat format,
const float *data)
{
return GPU_texture_create_2d_array_ex(
name, w, h, d, mip_len, format, GPU_TEXTURE_USAGE_GENERAL, data);
}
GPUTexture *GPU_texture_create_3d(const char *name,
int w,
int h,
int d,
int mip_len,
eGPUTextureFormat texture_format,
eGPUDataFormat data_format,
const void *data)
{
return GPU_texture_create_3d_ex(
name, w, h, d, mip_len, texture_format, data_format, GPU_TEXTURE_USAGE_GENERAL, data);
}
GPUTexture *GPU_texture_create_cube(
const char *name, int w, int mip_len, eGPUTextureFormat format, const float *data)
{
return GPU_texture_create_cube_ex(name, w, mip_len, format, GPU_TEXTURE_USAGE_GENERAL, data);
}
GPUTexture *GPU_texture_create_cube_array(
const char *name, int w, int d, int mip_len, eGPUTextureFormat format, const float *data)
{
return GPU_texture_create_cube_array_ex(
name, w, d, mip_len, format, GPU_TEXTURE_USAGE_GENERAL, data);
}
GPUTexture *GPU_texture_create_compressed_2d(
const char *name, int w, int h, int miplen, eGPUTextureFormat format, const void *data)
{
return GPU_texture_create_compressed_2d_ex(
name, w, h, miplen, format, GPU_TEXTURE_USAGE_GENERAL, data);
}
GPUTexture *GPU_texture_create_from_vertbuf(const char *name, GPUVertBuf *vert)
{
#ifndef NDEBUG
@ -389,7 +499,16 @@ GPUTexture *GPU_texture_create_error(int dimension, bool is_array)
type = (dimension == 2) ? (is_array ? GPU_TEXTURE_2D_ARRAY : GPU_TEXTURE_2D) : type;
type = (dimension == 1) ? (is_array ? GPU_TEXTURE_1D_ARRAY : GPU_TEXTURE_1D) : type;
return gpu_texture_create("invalid_tex", w, h, d, type, 1, GPU_RGBA8, GPU_DATA_FLOAT, pixel);
return gpu_texture_create("invalid_tex",
w,
h,
d,
type,
1,
GPU_RGBA8,
GPU_DATA_FLOAT,
GPU_TEXTURE_USAGE_GENERAL,
pixel);
}
GPUTexture *GPU_texture_create_view(const char *name,
@ -427,6 +546,13 @@ GPUTexture *GPU_texture_create_single_layer_view(const char *name, const GPUText
return wrap(view);
}
/* ------ Usage ------ */
eGPUTextureUsage GPU_texture_usage(const GPUTexture *texture_)
{
const Texture *tex = reinterpret_cast<const Texture *>(texture_);
return tex->usage_get();
}
/* ------ Update ------ */
void GPU_texture_update_mipmap(GPUTexture *tex_,
@ -473,6 +599,10 @@ void GPU_texture_update_sub_from_pixel_buffer(GPUTexture *tex,
void *GPU_texture_read(GPUTexture *tex_, eGPUDataFormat data_format, int miplvl)
{
Texture *tex = reinterpret_cast<Texture *>(tex_);
BLI_assert_msg(
GPU_texture_usage(tex_) & GPU_TEXTURE_USAGE_HOST_READ,
"The host-read usage flag must be specified up-front. Only textures which require data "
"reads should be flagged, allowing the backend to make certain optimiastions.");
return tex->read(miplvl, data_format);
}

View File

@ -82,6 +82,8 @@ class Texture {
eGPUTextureFormatFlag format_flag_;
/** Texture type. */
eGPUTextureType type_;
/** Texutre usage flags */
eGPUTextureUsage gpu_image_usage_flags_;
/** Number of mipmaps this texture has (Max miplvl). */
/* TODO(fclem): Should become immutable and the need for mipmaps should be specified upfront. */
@ -127,6 +129,8 @@ class Texture {
void detach_from(FrameBuffer *fb);
void update(eGPUDataFormat format, const void *data);
void usage_set(eGPUTextureUsage usage_flags);
virtual void update_sub(
int mip, int offset[3], int extent[3], eGPUDataFormat format, const void *data) = 0;
virtual void update_sub(int offset[3],
@ -148,6 +152,10 @@ class Texture {
{
return d_;
}
eGPUTextureUsage usage_get() const
{
return gpu_image_usage_flags_;
}
void mip_size_get(int mip, int r_size[3]) const
{

View File

@ -120,12 +120,15 @@ static void gpu_viewport_textures_create(GPUViewport *viewport)
{
int *size = viewport->size;
float empty_pixel[4] = {0.0f, 0.0f, 0.0f, 0.0f};
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
if (viewport->color_render_tx[0] == NULL) {
viewport->color_render_tx[0] = GPU_texture_create_2d(
"dtxl_color", UNPACK2(size), 1, GPU_RGBA16F, NULL);
viewport->color_overlay_tx[0] = GPU_texture_create_2d(
"dtxl_color_overlay", UNPACK2(size), 1, GPU_SRGB8_A8, NULL);
viewport->color_render_tx[0] = GPU_texture_create_2d_ex(
"dtxl_color", UNPACK2(size), 1, GPU_RGBA16F, usage, NULL);
viewport->color_overlay_tx[0] = GPU_texture_create_2d_ex(
"dtxl_color_overlay", UNPACK2(size), 1, GPU_SRGB8_A8, usage, NULL);
if (GPU_clear_viewport_workaround()) {
GPU_texture_clear(viewport->color_render_tx[0], GPU_DATA_FLOAT, empty_pixel);
GPU_texture_clear(viewport->color_overlay_tx[0], GPU_DATA_FLOAT, empty_pixel);
@ -133,10 +136,11 @@ static void gpu_viewport_textures_create(GPUViewport *viewport)
}
if ((viewport->flag & GPU_VIEWPORT_STEREO) != 0 && viewport->color_render_tx[1] == NULL) {
viewport->color_render_tx[1] = GPU_texture_create_2d(
"dtxl_color_stereo", UNPACK2(size), 1, GPU_RGBA16F, NULL);
viewport->color_overlay_tx[1] = GPU_texture_create_2d(
"dtxl_color_overlay_stereo", UNPACK2(size), 1, GPU_SRGB8_A8, NULL);
viewport->color_render_tx[1] = GPU_texture_create_2d_ex(
"dtxl_color_stereo", UNPACK2(size), 1, GPU_RGBA16F, usage, NULL);
viewport->color_overlay_tx[1] = GPU_texture_create_2d_ex(
"dtxl_color_overlay_stereo", UNPACK2(size), 1, GPU_SRGB8_A8, usage, NULL);
if (GPU_clear_viewport_workaround()) {
GPU_texture_clear(viewport->color_render_tx[1], GPU_DATA_FLOAT, empty_pixel);
GPU_texture_clear(viewport->color_overlay_tx[1], GPU_DATA_FLOAT, empty_pixel);
@ -145,8 +149,8 @@ static void gpu_viewport_textures_create(GPUViewport *viewport)
/* Can be shared with GPUOffscreen. */
if (viewport->depth_tx == NULL) {
viewport->depth_tx = GPU_texture_create_2d(
"dtxl_depth", UNPACK2(size), 1, GPU_DEPTH24_STENCIL8, NULL);
viewport->depth_tx = GPU_texture_create_2d_ex(
"dtxl_depth", UNPACK2(size), 1, GPU_DEPTH24_STENCIL8, usage, NULL);
if (GPU_clear_viewport_workaround()) {
static int depth_clear = 0;
GPU_texture_clear(viewport->depth_tx, GPU_DATA_UINT_24_8, &depth_clear);

View File

@ -212,14 +212,12 @@ class MTLTexture : public Texture {
/* Max mip-maps for currently allocated texture resource. */
int mtl_max_mips_ = 1;
bool has_generated_mips_ = false;
/* VBO. */
MTLVertBuf *vert_buffer_;
id<MTLBuffer> vert_buffer_mtl_;
/* Core parameters and sub-resources. */
eGPUTextureUsage gpu_image_usage_flags_;
/* Whether the texture's properties or state has changed (e.g. mipmap range), and re-baking of
* GPU resource is required. */
bool is_dirty_;
@ -609,4 +607,46 @@ inline eGPUDataFormat to_mtl_internal_data_format(eGPUTextureFormat tex_format)
}
}
inline MTLTextureUsage mtl_usage_from_gpu(eGPUTextureUsage usage)
{
MTLTextureUsage mtl_usage = MTLTextureUsageUnknown;
if (usage == GPU_TEXTURE_USAGE_GENERAL) {
return MTLTextureUsageUnknown;
}
if (usage & GPU_TEXTURE_USAGE_SHADER_READ) {
mtl_usage = mtl_usage | MTLTextureUsageShaderRead;
}
if (usage & GPU_TEXTURE_USAGE_SHADER_WRITE) {
mtl_usage = mtl_usage | MTLTextureUsageShaderWrite;
}
if (usage & GPU_TEXTURE_USAGE_ATTACHMENT) {
mtl_usage = mtl_usage | MTLTextureUsageRenderTarget;
}
if (usage & GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW) {
mtl_usage = mtl_usage | MTLTextureUsagePixelFormatView;
}
return mtl_usage;
}
inline eGPUTextureUsage gpu_usage_from_mtl(MTLTextureUsage mtl_usage)
{
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ;
if (mtl_usage == MTLTextureUsageUnknown) {
return GPU_TEXTURE_USAGE_GENERAL;
}
if (mtl_usage & MTLTextureUsageShaderRead) {
usage = usage | GPU_TEXTURE_USAGE_SHADER_READ;
}
if (mtl_usage & MTLTextureUsageShaderWrite) {
usage = usage | GPU_TEXTURE_USAGE_SHADER_WRITE;
}
if (mtl_usage & MTLTextureUsageRenderTarget) {
usage = usage | GPU_TEXTURE_USAGE_ATTACHMENT;
}
if (mtl_usage & MTLTextureUsagePixelFormatView) {
usage = usage | GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW;
}
return usage;
}
} // namespace blender::gpu

View File

@ -60,9 +60,6 @@ void gpu::MTLTexture::mtl_texture_init()
tex_swizzle_mask_[3] = 'a';
mtl_swizzle_mask_ = MTLTextureSwizzleChannelsMake(
MTLTextureSwizzleRed, MTLTextureSwizzleGreen, MTLTextureSwizzleBlue, MTLTextureSwizzleAlpha);
/* TODO(Metal): Find a way of specifying texture usage externally. */
gpu_image_usage_flags_ = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
}
gpu::MTLTexture::MTLTexture(const char *name) : Texture(name)
@ -89,6 +86,7 @@ gpu::MTLTexture::MTLTexture(const char *name,
/* Assign MTLTexture. */
texture_ = metal_texture;
[texture_ retain];
gpu_image_usage_flags_ = gpu_usage_from_mtl(metal_texture.usage);
/* Flag as Baked. */
is_baked_ = true;
@ -116,6 +114,23 @@ gpu::MTLTexture::~MTLTexture()
void gpu::MTLTexture::bake_mip_swizzle_view()
{
if (texture_view_dirty_flags_) {
/* Optimization: only generate texture view for mipmapped textures if base level > 0
* and max level does not match the existing number of mips.
* Only apply this if mipmap is the only change, and we have not previously generated
* a texture view. For textures which are created as views, this should also be skipped. */
if (resource_mode_ != MTL_TEXTURE_MODE_TEXTURE_VIEW &&
texture_view_dirty_flags_ == TEXTURE_VIEW_MIP_DIRTY && mip_swizzle_view_ == nil) {
if (mip_texture_base_level_ == 0 && mip_texture_max_level_ == mtl_max_mips_) {
texture_view_dirty_flags_ = TEXTURE_VIEW_NOT_DIRTY;
return;
}
}
/* Ensure we have texture view usage flagged. */
BLI_assert(gpu_image_usage_flags_ & GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW);
/* if a texture view was previously created we release it. */
if (mip_swizzle_view_ != nil) {
[mip_swizzle_view_ release];
@ -207,7 +222,13 @@ id<MTLTexture> gpu::MTLTexture::get_metal_handle()
if (mip_swizzle_view_ != nil || texture_view_dirty_flags_) {
bake_mip_swizzle_view();
return mip_swizzle_view_;
/* Optimisation: If texture view does not change mip parameters, no texture view will be
* baked. This is because texture views remove the ability to perform lossless compression.
*/
if (mip_swizzle_view_ != nil) {
return mip_swizzle_view_;
}
}
return texture_;
}
@ -226,6 +247,7 @@ id<MTLTexture> gpu::MTLTexture::get_metal_handle_base()
if (mip_swizzle_view_ != nil || texture_view_dirty_flags_) {
bake_mip_swizzle_view();
}
BLI_assert(mip_swizzle_view_ != nil);
return mip_swizzle_view_;
}
@ -583,21 +605,71 @@ void gpu::MTLTexture::update_sub(
*((int *)&compatible_write_format));
return;
}
id<MTLTexture> texture_handle = ((compatible_write_format == destination_format)) ?
texture_ :
[texture_
newTextureViewWithPixelFormat:compatible_write_format];
/* Prepare command encoders. */
id<MTLBlitCommandEncoder> blit_encoder = nil;
id<MTLComputeCommandEncoder> compute_encoder = nil;
id<MTLTexture> staging_texture = nil;
id<MTLTexture> texture_handle = nil;
/* Use staging texture. */
bool use_staging_texture = false;
if (can_use_direct_blit) {
blit_encoder = ctx->main_command_buffer.ensure_begin_blit_encoder();
BLI_assert(blit_encoder != nil);
/* If we need to use a texture view to write texture data as the source
* format is unwritable, if our texture has not been initialised with
* texture view support, use a staging texture. */
if ((compatible_write_format != destination_format) &&
!(gpu_image_usage_flags_ & GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW)) {
use_staging_texture = true;
}
}
else {
compute_encoder = ctx->main_command_buffer.ensure_begin_compute_encoder();
BLI_assert(compute_encoder != nil);
/* For compute, we should use a stating texture to avoid texture write usage,
* if it has not been specified for the texture. Using shader-write disables
* lossless texture compression, so this is best to avoid where possible. */
if (!(gpu_image_usage_flags_ & GPU_TEXTURE_USAGE_SHADER_WRITE)) {
use_staging_texture = true;
}
if (compatible_write_format != destination_format) {
if (!(gpu_image_usage_flags_ & GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW)) {
use_staging_texture = true;
}
}
}
/* Allocate stating texture if needed. */
if (use_staging_texture) {
/* Create staging texture to avoid shader-write limiting optimisation. */
BLI_assert(texture_descriptor_ != nullptr);
MTLTextureUsage original_usage = texture_descriptor_.usage;
texture_descriptor_.usage = original_usage | MTLTextureUsageShaderWrite |
MTLTextureUsagePixelFormatView;
staging_texture = [ctx->device newTextureWithDescriptor:texture_descriptor_];
staging_texture.label = @"Staging texture";
texture_descriptor_.usage = original_usage;
/* Create texture view if needed. */
texture_handle = ((compatible_write_format == destination_format)) ?
[staging_texture retain] :
[staging_texture newTextureViewWithPixelFormat:compatible_write_format];
}
else {
/* Use texture view. */
if (compatible_write_format != destination_format) {
BLI_assert(gpu_image_usage_flags_ & GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW);
texture_handle = [texture_ newTextureViewWithPixelFormat:compatible_write_format];
}
else {
texture_handle = texture_;
[texture_handle retain];
}
}
switch (type_) {
@ -865,13 +937,21 @@ void gpu::MTLTexture::update_sub(
return;
}
/* If staging texture was used, copy contents to original texture. */
if (use_staging_texture) {
/* When using staging texture, copy results into existing texture. */
BLI_assert(staging_texture != nil);
blit_encoder = ctx->main_command_buffer.ensure_begin_blit_encoder();
[blit_encoder copyFromTexture:staging_texture toTexture:texture_];
[staging_texture release];
}
/* Finalize Blit Encoder. */
if (can_use_direct_blit) {
/* Textures which use MTLStorageModeManaged need to have updated contents
* synced back to CPU to avoid an automatic flush overwriting contents. */
if (texture_.storageMode == MTLStorageModeManaged) {
[blit_encoder synchronizeResource:texture_buffer_];
[blit_encoder synchronizeResource:texture_];
}
}
else {
@ -879,9 +959,12 @@ void gpu::MTLTexture::update_sub(
* synced back to CPU to avoid an automatic flush overwriting contents. */
if (texture_.storageMode == MTLStorageModeManaged) {
blit_encoder = ctx->main_command_buffer.ensure_begin_blit_encoder();
[blit_encoder synchronizeResource:texture_buffer_];
[blit_encoder synchronizeResource:texture_];
}
}
/* Decrement texture reference counts. This ensures temporary texture views are released. */
[texture_handle release];
}
}
@ -959,6 +1042,9 @@ void gpu::MTLTexture::ensure_mipmaps(int miplvl)
/* Check if baked. */
if (is_baked_ && mipmaps_ > mtl_max_mips_) {
BLI_assert_msg(false,
"Texture requires a higher mipmap level count. Please specify the required "
"amount upfront.");
is_dirty_ = true;
MTL_LOG_WARNING("Texture requires regenerating due to increase in mip-count\n");
}
@ -1006,6 +1092,7 @@ void gpu::MTLTexture::generate_mipmap()
[enc insertDebugSignpost:@"Generate MipMaps"];
}
[enc generateMipmapsForTexture:texture_];
has_generated_mips_ = true;
}
return;
}
@ -1121,6 +1208,8 @@ void gpu::MTLTexture::swizzle_set(const char swizzle_mask[4])
swizzle_to_mtl(swizzle_mask[2]),
swizzle_to_mtl(swizzle_mask[3]));
BLI_assert_msg(gpu_image_usage_flags_ & GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW,
"Texture view support is required to change swizzle parameters.");
mtl_swizzle_mask_ = new_swizzle_mask;
texture_view_dirty_flags_ |= TEXTURE_VIEW_SWIZZLE_DIRTY;
}
@ -1318,6 +1407,7 @@ void gpu::MTLTexture::read_internal(int mip,
/* Texture View for SRGB special case. */
id<MTLTexture> read_texture = texture_;
if (format_ == GPU_SRGB8_A8) {
BLI_assert(gpu_image_usage_flags_ & GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW);
read_texture = [texture_ newTextureViewWithPixelFormat:MTLPixelFormatRGBA8Unorm];
}
@ -1598,6 +1688,9 @@ bool gpu::MTLTexture::init_internal(const GPUTexture *src, int mip_offset, int l
mip_texture_base_level_ = mip_offset;
mip_texture_base_layer_ = layer_offset;
/* Assign usage. */
gpu_image_usage_flags_ = GPU_texture_usage(src);
/* Assign texture as view. */
const gpu::MTLTexture *mtltex = static_cast<const gpu::MTLTexture *>(unwrap(src));
texture_ = mtltex->texture_;
@ -1638,11 +1731,8 @@ void gpu::MTLTexture::prepare_internal()
mtl_max_mips_ = 1;
}
else {
int effective_h = (type_ == GPU_TEXTURE_1D_ARRAY) ? 0 : h_;
int effective_d = (type_ != GPU_TEXTURE_3D) ? 0 : d_;
int max_dimension = max_iii(w_, effective_h, effective_d);
int max_miplvl = max_ii(floor(log2(max_dimension)) + 1, 1);
mtl_max_mips_ = max_miplvl;
/* Require correct explicit mipmap level counts. */
mtl_max_mips_ = mipmaps_;
}
}
@ -1672,6 +1762,13 @@ void gpu::MTLTexture::ensure_baked()
/* Format and mip levels (TODO(Metal): Optimize mipmaps counts, specify up-front). */
MTLPixelFormat mtl_format = gpu_texture_format_to_metal(format_);
/* SRGB textures require a texture view for reading data and when rendering with SRGB
* disabled. Enabling the texture_view or texture_read usage flags disables lossless
* compression, so the situations in which it is used should be limited. */
if (format_ == GPU_SRGB8_A8) {
gpu_image_usage_flags_ = gpu_image_usage_flags_ | GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW;
}
/* Create texture descriptor. */
switch (type_) {
@ -1688,9 +1785,7 @@ void gpu::MTLTexture::ensure_baked()
texture_descriptor_.depth = 1;
texture_descriptor_.arrayLength = (type_ == GPU_TEXTURE_1D_ARRAY) ? h_ : 1;
texture_descriptor_.mipmapLevelCount = (mtl_max_mips_ > 0) ? mtl_max_mips_ : 1;
texture_descriptor_.usage =
MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite |
MTLTextureUsagePixelFormatView; /* TODO(Metal): Optimize usage flags. */
texture_descriptor_.usage = mtl_usage_from_gpu(gpu_image_usage_flags_);
texture_descriptor_.storageMode = MTLStorageModePrivate;
texture_descriptor_.sampleCount = 1;
texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
@ -1710,9 +1805,7 @@ void gpu::MTLTexture::ensure_baked()
texture_descriptor_.depth = 1;
texture_descriptor_.arrayLength = (type_ == GPU_TEXTURE_2D_ARRAY) ? d_ : 1;
texture_descriptor_.mipmapLevelCount = (mtl_max_mips_ > 0) ? mtl_max_mips_ : 1;
texture_descriptor_.usage =
MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite |
MTLTextureUsagePixelFormatView; /* TODO(Metal): Optimize usage flags. */
texture_descriptor_.usage = mtl_usage_from_gpu(gpu_image_usage_flags_);
texture_descriptor_.storageMode = MTLStorageModePrivate;
texture_descriptor_.sampleCount = 1;
texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
@ -1730,9 +1823,7 @@ void gpu::MTLTexture::ensure_baked()
texture_descriptor_.depth = d_;
texture_descriptor_.arrayLength = 1;
texture_descriptor_.mipmapLevelCount = (mtl_max_mips_ > 0) ? mtl_max_mips_ : 1;
texture_descriptor_.usage =
MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite |
MTLTextureUsagePixelFormatView; /* TODO(Metal): Optimize usage flags. */
texture_descriptor_.usage = mtl_usage_from_gpu(gpu_image_usage_flags_);
texture_descriptor_.storageMode = MTLStorageModePrivate;
texture_descriptor_.sampleCount = 1;
texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
@ -1755,9 +1846,7 @@ void gpu::MTLTexture::ensure_baked()
texture_descriptor_.depth = 1;
texture_descriptor_.arrayLength = (type_ == GPU_TEXTURE_CUBE_ARRAY) ? d_ / 6 : 1;
texture_descriptor_.mipmapLevelCount = (mtl_max_mips_ > 0) ? mtl_max_mips_ : 1;
texture_descriptor_.usage =
MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite |
MTLTextureUsagePixelFormatView; /* TODO(Metal): Optimize usage flags. */
texture_descriptor_.usage = mtl_usage_from_gpu(gpu_image_usage_flags_);
texture_descriptor_.storageMode = MTLStorageModePrivate;
texture_descriptor_.sampleCount = 1;
texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
@ -1774,9 +1863,7 @@ void gpu::MTLTexture::ensure_baked()
texture_descriptor_.depth = 1;
texture_descriptor_.arrayLength = 1;
texture_descriptor_.mipmapLevelCount = (mtl_max_mips_ > 0) ? mtl_max_mips_ : 1;
texture_descriptor_.usage =
MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite |
MTLTextureUsagePixelFormatView; /* TODO(Metal): Optimize usage flags. */
texture_descriptor_.usage = mtl_usage_from_gpu(gpu_image_usage_flags_);
texture_descriptor_.storageMode = MTLStorageModePrivate;
texture_descriptor_.sampleCount = 1;
texture_descriptor_.cpuCacheMode = MTLCPUCacheModeDefaultCache;
@ -1837,6 +1924,15 @@ void gpu::MTLTexture::reset()
blit_fb_ = nullptr;
}
/* Descriptor. */
if (texture_descriptor_ != nullptr) {
[texture_descriptor_ release];
texture_descriptor_ = nullptr;
}
/* Reset mipmap state. */
has_generated_mips_ = false;
BLI_assert(texture_ == nil);
BLI_assert(mip_swizzle_view_ == nil);
}

View File

@ -102,7 +102,7 @@ MTLPixelFormat gpu_texture_format_to_metal(eGPUTextureFormat tex_format)
case GPU_DEPTH32F_STENCIL8:
return MTLPixelFormatDepth32Float_Stencil8;
case GPU_DEPTH24_STENCIL8: {
BLI_assert(false && "GPU_DEPTH24_STENCIL8 not supported by Apple Silicon.");
BLI_assert_msg(false, "GPU_DEPTH24_STENCIL8 not supported by Apple Silicon.");
return MTLPixelFormatDepth24Unorm_Stencil8;
}
case GPU_SRGB8_A8:
@ -118,7 +118,7 @@ MTLPixelFormat gpu_texture_format_to_metal(eGPUTextureFormat tex_format)
return MTLPixelFormatDepth16Unorm;
default:
BLI_assert(!"Unrecognized GPU pixel format!\n");
BLI_assert_msg(false, "Unrecognised GPU pixel format!\n");
return MTLPixelFormatRGBA8Unorm;
}
}
@ -177,7 +177,7 @@ int get_mtl_format_bytesize(MTLPixelFormat tex_format)
return 2;
default:
BLI_assert(!"Unrecognized GPU pixel format!\n");
BLI_assert_msg(false, "Unrecognised GPU pixel format!\n");
return 1;
}
}
@ -232,7 +232,7 @@ int get_mtl_format_num_components(MTLPixelFormat tex_format)
return 1;
default:
BLI_assert(!"Unrecognized GPU pixel format!\n");
BLI_assert_msg(false, "Unrecognised GPU pixel format!\n");
return 1;
}
}
@ -508,13 +508,19 @@ void gpu::MTLTexture::update_sub_depth_2d(
break;
default:
BLI_assert(false && "Unsupported eGPUDataFormat being passed to depth texture update\n");
BLI_assert_msg(false, "Unsupported eGPUDataFormat being passed to depth texture update\n");
return;
}
/* Push contents into an r32_tex and render contents to depth using a shader. */
GPUTexture *r32_tex_tmp = GPU_texture_create_2d(
"depth_intermediate_copy_tex", w_, h_, 1, format, nullptr);
GPUTexture *r32_tex_tmp = GPU_texture_create_2d_ex("depth_intermediate_copy_tex",
w_,
h_,
1,
format,
GPU_TEXTURE_USAGE_SHADER_READ |
GPU_TEXTURE_USAGE_ATTACHMENT,
nullptr);
GPU_texture_filter_mode(r32_tex_tmp, false);
GPU_texture_wrap_mode(r32_tex_tmp, false, true);
gpu::MTLTexture *mtl_tex = static_cast<gpu::MTLTexture *>(unwrap(r32_tex_tmp));

View File

@ -251,10 +251,12 @@ GPUTexture *IMB_touch_gpu_texture(const char *name,
GPUTexture *tex;
if (layers > 0) {
tex = GPU_texture_create_2d_array(name, w, h, layers, 9999, tex_format, NULL);
tex = GPU_texture_create_2d_array_ex(
name, w, h, layers, 9999, tex_format, GPU_TEXTURE_USAGE_SHADER_READ, NULL);
}
else {
tex = GPU_texture_create_2d(name, w, h, 9999, tex_format, NULL);
tex = GPU_texture_create_2d_ex(
name, w, h, 9999, tex_format, GPU_TEXTURE_USAGE_SHADER_READ, NULL);
}
GPU_texture_swizzle_set(tex, imb_gpu_get_swizzle(ibuf));
@ -349,11 +351,13 @@ GPUTexture *IMB_create_gpu_texture(const char *name,
bool freebuf = false;
/* Create Texture. */
tex = GPU_texture_create_2d(name, UNPACK2(size), 9999, tex_format, NULL);
tex = GPU_texture_create_2d_ex(
name, UNPACK2(size), 9999, tex_format, GPU_TEXTURE_USAGE_SHADER_READ, NULL);
if (tex == NULL) {
size[0] = max_ii(1, size[0] / 2);
size[1] = max_ii(1, size[1] / 2);
tex = GPU_texture_create_2d(name, UNPACK2(size), 9999, tex_format, NULL);
tex = GPU_texture_create_2d_ex(
name, UNPACK2(size), 9999, tex_format, GPU_TEXTURE_USAGE_SHADER_READ, NULL);
do_rescale = true;
}
BLI_assert(tex != NULL);

View File

@ -2295,8 +2295,13 @@ static void radial_control_set_tex(RadialControl *rc)
rc->use_secondary_tex,
!ELEM(rc->subtype, PROP_NONE, PROP_PIXEL, PROP_DISTANCE)))) {
rc->texture = GPU_texture_create_2d(
"radial_control", ibuf->x, ibuf->y, 1, GPU_R8, ibuf->rect_float);
rc->texture = GPU_texture_create_2d_ex("radial_control",
ibuf->x,
ibuf->y,
1,
GPU_R8,
GPU_TEXTURE_USAGE_SHADER_READ,
ibuf->rect_float);
GPU_texture_filter_mode(rc->texture, true);
GPU_texture_swizzle_set(rc->texture, "111r");

View File

@ -477,7 +477,8 @@ static void draw_display_buffer(PlayState *ps, ImBuf *ibuf)
void *buffer_cache_handle = NULL;
display_buffer = ocio_transform_ibuf(ps, ibuf, &glsl_used, &format, &data, &buffer_cache_handle);
GPUTexture *texture = GPU_texture_create_2d("display_buf", ibuf->x, ibuf->y, 1, format, NULL);
GPUTexture *texture = GPU_texture_create_2d_ex(
"display_buf", ibuf->x, ibuf->y, 1, format, GPU_TEXTURE_USAGE_SHADER_READ, NULL);
GPU_texture_update(texture, data, display_buffer);
GPU_texture_filter_mode(texture, false);