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:
parent
359d98423e
commit
2e61c446ac
Notes:
blender-bot
2023-02-14 02:27:56 +01:00
Referenced by issue #96261, Metal Viewport
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue