Path: blob/master/drivers/gles3/storage/texture_storage.cpp
10000 views
/**************************************************************************/1/* texture_storage.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#ifdef GLES3_ENABLED3132#include "texture_storage.h"3334#include "../effects/copy_effects.h"35#include "../rasterizer_gles3.h"36#include "config.h"37#include "utilities.h"3839#ifdef ANDROID_ENABLED40#define glFramebufferTextureMultiviewOVR GLES3::Config::get_singleton()->eglFramebufferTextureMultiviewOVR41#endif4243using namespace GLES3;4445TextureStorage *TextureStorage::singleton = nullptr;4647TextureStorage *TextureStorage::get_singleton() {48return singleton;49}5051static const GLenum _cube_side_enum[6] = {52GL_TEXTURE_CUBE_MAP_NEGATIVE_X,53GL_TEXTURE_CUBE_MAP_POSITIVE_X,54GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,55GL_TEXTURE_CUBE_MAP_POSITIVE_Y,56GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,57GL_TEXTURE_CUBE_MAP_POSITIVE_Z,58};5960TextureStorage::TextureStorage() {61singleton = this;6263{ //create default textures64{ // White Textures6566Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);67image->fill(Color(1, 1, 1, 1));68image->generate_mipmaps();6970default_gl_textures[DEFAULT_GL_TEXTURE_WHITE] = texture_allocate();71texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_WHITE], image);7273Vector<Ref<Image>> images;74images.push_back(image);7576default_gl_textures[DEFAULT_GL_TEXTURE_2D_ARRAY_WHITE] = texture_allocate();77texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_2D_ARRAY_WHITE], images, RS::TEXTURE_LAYERED_2D_ARRAY);7879for (int i = 0; i < 5; i++) {80images.push_back(image);81}8283default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_WHITE] = texture_allocate();84texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_WHITE], images, RS::TEXTURE_LAYERED_CUBEMAP);85}8687{88Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8);89image->fill(Color(1, 1, 1, 1));9091Vector<Ref<Image>> images;92for (int i = 0; i < 4; i++) {93images.push_back(image);94}95default_gl_textures[DEFAULT_GL_TEXTURE_3D_WHITE] = texture_allocate();96texture_3d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_3D_WHITE], image->get_format(), 4, 4, 4, false, images);97}9899{ // black100Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);101image->fill(Color(0, 0, 0, 1));102image->generate_mipmaps();103104default_gl_textures[DEFAULT_GL_TEXTURE_BLACK] = texture_allocate();105texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_BLACK], image);106107Vector<Ref<Image>> images;108for (int i = 0; i < 6; i++) {109images.push_back(image);110}111default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_BLACK] = texture_allocate();112texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_BLACK], images, RS::TEXTURE_LAYERED_CUBEMAP);113}114115{116Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8);117image->fill(Color());118119Vector<Ref<Image>> images;120for (int i = 0; i < 4; i++) {121images.push_back(image);122}123default_gl_textures[DEFAULT_GL_TEXTURE_3D_BLACK] = texture_allocate();124texture_3d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_3D_BLACK], image->get_format(), 4, 4, 4, false, images);125}126127{ // transparent black128Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);129image->fill(Color(0, 0, 0, 0));130image->generate_mipmaps();131132default_gl_textures[DEFAULT_GL_TEXTURE_TRANSPARENT] = texture_allocate();133texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_TRANSPARENT], image);134}135136{137Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);138image->fill(Color(0.5, 0.5, 1, 1));139image->generate_mipmaps();140141default_gl_textures[DEFAULT_GL_TEXTURE_NORMAL] = texture_allocate();142texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_NORMAL], image);143}144145{146Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);147image->fill(Color(1.0, 0.5, 1, 1));148image->generate_mipmaps();149150default_gl_textures[DEFAULT_GL_TEXTURE_ANISO] = texture_allocate();151texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_ANISO], image);152}153154{155default_gl_textures[DEFAULT_GL_TEXTURE_EXT] = texture_allocate();156texture_external_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_EXT], 1, 1, 0);157}158159{160unsigned char pixel_data[4 * 4 * 4];161for (int i = 0; i < 16; i++) {162pixel_data[i * 4 + 0] = 0;163pixel_data[i * 4 + 1] = 0;164pixel_data[i * 4 + 2] = 0;165pixel_data[i * 4 + 3] = 0;166}167168default_gl_textures[DEFAULT_GL_TEXTURE_2D_UINT] = texture_allocate();169Texture texture;170texture.width = 4;171texture.height = 4;172texture.format = Image::FORMAT_RGBA8;173texture.type = Texture::TYPE_2D;174texture.target = GL_TEXTURE_2D;175texture.active = true;176glGenTextures(1, &texture.tex_id);177texture_owner.initialize_rid(default_gl_textures[DEFAULT_GL_TEXTURE_2D_UINT], texture);178179glBindTexture(GL_TEXTURE_2D, texture.tex_id);180glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 4, 4, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixel_data);181GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, 4 * 4 * 4, "Default uint texture");182texture.gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);183}184{185uint16_t pixel_data[4 * 4];186for (int i = 0; i < 16; i++) {187pixel_data[i] = Math::make_half_float(1.0f);188}189190default_gl_textures[DEFAULT_GL_TEXTURE_DEPTH] = texture_allocate();191Texture texture;192texture.width = 4;193texture.height = 4;194texture.format = Image::FORMAT_RGBA8;195texture.type = Texture::TYPE_2D;196texture.target = GL_TEXTURE_2D;197texture.active = true;198glGenTextures(1, &texture.tex_id);199texture_owner.initialize_rid(default_gl_textures[DEFAULT_GL_TEXTURE_DEPTH], texture);200201glBindTexture(GL_TEXTURE_2D, texture.tex_id);202glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 4, 4, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, pixel_data);203GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, 4 * 4 * 2, "Default depth texture");204texture.gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);205}206}207208glBindTexture(GL_TEXTURE_2D, 0);209210{ // Atlas Texture initialize.211uint8_t pixel_data[4 * 4 * 4];212for (int i = 0; i < 16; i++) {213pixel_data[i * 4 + 0] = 0;214pixel_data[i * 4 + 1] = 0;215pixel_data[i * 4 + 2] = 0;216pixel_data[i * 4 + 3] = 255;217}218219glGenTextures(1, &texture_atlas.texture);220glBindTexture(GL_TEXTURE_2D, texture_atlas.texture);221glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel_data);222GLES3::Utilities::get_singleton()->texture_allocated_data(texture_atlas.texture, 4 * 4 * 4, "Texture atlas (Default)");223}224225glBindTexture(GL_TEXTURE_2D, 0);226227{228sdf_shader.shader.initialize();229sdf_shader.shader_version = sdf_shader.shader.version_create();230}231232// Initialize texture placeholder data for the `texture_*_placeholder_initialize()` methods.233234constexpr int placeholder_size = 4;235texture_2d_placeholder = Image::create_empty(placeholder_size, placeholder_size, false, Image::FORMAT_RGBA8);236// Draw a magenta/black checkerboard pattern.237for (int i = 0; i < placeholder_size * placeholder_size; i++) {238const int x = i % placeholder_size;239const int y = i / placeholder_size;240texture_2d_placeholder->set_pixel(x, y, (x + y) % 2 == 0 ? Color(1, 0, 1) : Color(0, 0, 0));241}242243texture_2d_array_placeholder.push_back(texture_2d_placeholder);244245for (int i = 0; i < 6; i++) {246cubemap_placeholder.push_back(texture_2d_placeholder);247}248249Ref<Image> texture_2d_placeholder_rotated;250texture_2d_placeholder_rotated.instantiate();251texture_2d_placeholder_rotated->copy_from(texture_2d_placeholder);252texture_2d_placeholder_rotated->rotate_90(CLOCKWISE);253for (int i = 0; i < 4; i++) {254// Alternate checkerboard pattern on odd layers (by using a copy that is rotated 90 degrees).255texture_3d_placeholder.push_back(i % 2 == 0 ? texture_2d_placeholder : texture_2d_placeholder_rotated);256}257258#ifdef GL_API_ENABLED259if (RasterizerGLES3::is_gles_over_gl()) {260glEnable(GL_PROGRAM_POINT_SIZE);261}262#endif // GL_API_ENABLED263}264265TextureStorage::~TextureStorage() {266singleton = nullptr;267for (int i = 0; i < DEFAULT_GL_TEXTURE_MAX; i++) {268texture_free(default_gl_textures[i]);269}270if (texture_atlas.texture != 0) {271GLES3::Utilities::get_singleton()->texture_free_data(texture_atlas.texture);272}273texture_atlas.texture = 0;274glDeleteFramebuffers(1, &texture_atlas.framebuffer);275texture_atlas.framebuffer = 0;276sdf_shader.shader.version_free(sdf_shader.shader_version);277}278279/* Canvas Texture API */280281RID TextureStorage::canvas_texture_allocate() {282return canvas_texture_owner.allocate_rid();283}284285void TextureStorage::canvas_texture_initialize(RID p_rid) {286canvas_texture_owner.initialize_rid(p_rid);287}288289void TextureStorage::canvas_texture_free(RID p_rid) {290canvas_texture_owner.free(p_rid);291}292293void TextureStorage::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {294CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);295ERR_FAIL_NULL(ct);296297switch (p_channel) {298case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: {299ct->diffuse = p_texture;300} break;301case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: {302ct->normal_map = p_texture;303} break;304case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: {305ct->specular = p_texture;306} break;307}308}309310void TextureStorage::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) {311CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);312ERR_FAIL_NULL(ct);313314ct->specular_color.r = p_specular_color.r;315ct->specular_color.g = p_specular_color.g;316ct->specular_color.b = p_specular_color.b;317ct->specular_color.a = p_shininess;318}319320void TextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {321CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);322ERR_FAIL_NULL(ct);323324ct->texture_filter = p_filter;325}326327void TextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {328CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);329ERR_FAIL_NULL(ct);330331ct->texture_repeat = p_repeat;332}333334/* Texture API */335336static inline Error _get_gl_uncompressed_format(const Ref<Image> &p_image, Image::Format p_format, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type) {337Config *config = Config::get_singleton();338339switch (p_format) {340case Image::FORMAT_L8: {341if (RasterizerGLES3::is_gles_over_gl()) {342r_gl_internal_format = GL_R8;343r_gl_format = GL_RED;344r_gl_type = GL_UNSIGNED_BYTE;345} else {346r_gl_internal_format = GL_LUMINANCE;347r_gl_format = GL_LUMINANCE;348r_gl_type = GL_UNSIGNED_BYTE;349}350} break;351case Image::FORMAT_LA8: {352if (RasterizerGLES3::is_gles_over_gl()) {353r_gl_internal_format = GL_RG8;354r_gl_format = GL_RG;355r_gl_type = GL_UNSIGNED_BYTE;356} else {357r_gl_internal_format = GL_LUMINANCE_ALPHA;358r_gl_format = GL_LUMINANCE_ALPHA;359r_gl_type = GL_UNSIGNED_BYTE;360}361} break;362case Image::FORMAT_R8: {363r_gl_internal_format = GL_R8;364r_gl_format = GL_RED;365r_gl_type = GL_UNSIGNED_BYTE;366} break;367case Image::FORMAT_RG8: {368r_gl_internal_format = GL_RG8;369r_gl_format = GL_RG;370r_gl_type = GL_UNSIGNED_BYTE;371} break;372case Image::FORMAT_RGB8: {373r_gl_internal_format = GL_RGB8;374r_gl_format = GL_RGB;375r_gl_type = GL_UNSIGNED_BYTE;376} break;377case Image::FORMAT_RGBA8: {378r_gl_internal_format = GL_RGBA8;379r_gl_format = GL_RGBA;380r_gl_type = GL_UNSIGNED_BYTE;381} break;382case Image::FORMAT_RGBA4444: {383r_gl_internal_format = GL_RGBA4;384r_gl_format = GL_RGBA;385r_gl_type = GL_UNSIGNED_SHORT_4_4_4_4;386} break;387case Image::FORMAT_RGB565: {388r_gl_internal_format = GL_RGB565;389r_gl_format = GL_RGB;390r_gl_type = GL_UNSIGNED_SHORT_5_6_5;391} break;392case Image::FORMAT_RF: {393if (config->float_texture_linear_supported) {394r_gl_internal_format = GL_R32F;395r_gl_format = GL_RED;396r_gl_type = GL_FLOAT;397} else {398if (p_image.is_valid()) {399p_image->convert(Image::FORMAT_RH);400}401r_real_format = Image::FORMAT_RH;402r_gl_internal_format = GL_R16F;403r_gl_format = GL_RED;404r_gl_type = GL_HALF_FLOAT;405}406} break;407case Image::FORMAT_RGF: {408if (config->float_texture_linear_supported) {409r_gl_internal_format = GL_RG32F;410r_gl_format = GL_RG;411r_gl_type = GL_FLOAT;412} else {413if (p_image.is_valid()) {414p_image->convert(Image::FORMAT_RGH);415}416r_real_format = Image::FORMAT_RGH;417r_gl_internal_format = GL_RG16F;418r_gl_format = GL_RG;419r_gl_type = GL_HALF_FLOAT;420}421} break;422case Image::FORMAT_RGBF: {423if (config->float_texture_linear_supported) {424r_gl_internal_format = GL_RGB32F;425r_gl_format = GL_RGB;426r_gl_type = GL_FLOAT;427} else {428if (p_image.is_valid()) {429p_image->convert(Image::FORMAT_RGBH);430}431r_real_format = Image::FORMAT_RGBH;432r_gl_internal_format = GL_RGB16F;433r_gl_format = GL_RGB;434r_gl_type = GL_HALF_FLOAT;435}436} break;437case Image::FORMAT_RGBAF: {438if (config->float_texture_linear_supported) {439r_gl_internal_format = GL_RGBA32F;440r_gl_format = GL_RGBA;441r_gl_type = GL_FLOAT;442} else {443if (p_image.is_valid()) {444p_image->convert(Image::FORMAT_RGBAH);445}446r_real_format = Image::FORMAT_RGBAH;447r_gl_internal_format = GL_RGBA16F;448r_gl_format = GL_RGBA;449r_gl_type = GL_HALF_FLOAT;450}451} break;452case Image::FORMAT_RH: {453r_gl_internal_format = GL_R16F;454r_gl_format = GL_RED;455r_gl_type = GL_HALF_FLOAT;456} break;457case Image::FORMAT_RGH: {458r_gl_internal_format = GL_RG16F;459r_gl_format = GL_RG;460r_gl_type = GL_HALF_FLOAT;461} break;462case Image::FORMAT_RGBH: {463r_gl_internal_format = GL_RGB16F;464r_gl_format = GL_RGB;465r_gl_type = GL_HALF_FLOAT;466} break;467case Image::FORMAT_RGBAH: {468r_gl_internal_format = GL_RGBA16F;469r_gl_format = GL_RGBA;470r_gl_type = GL_HALF_FLOAT;471} break;472case Image::FORMAT_RGBE9995: {473r_gl_internal_format = GL_RGB9_E5;474r_gl_format = GL_RGB;475r_gl_type = GL_UNSIGNED_INT_5_9_9_9_REV;476} break;477default: {478return ERR_UNAVAILABLE;479}480}481482return OK;483}484485Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_force_decompress) const {486Config *config = Config::get_singleton();487r_gl_format = 0;488Ref<Image> image = p_image;489r_compressed = false;490r_real_format = p_format;491492if (!Image::is_format_compressed(p_format)) {493Error err = _get_gl_uncompressed_format(p_image, p_format, r_real_format, r_gl_format, r_gl_internal_format, r_gl_type);494ERR_FAIL_COND_V_MSG(err != OK, Ref<Image>(), vformat("The image format %d is not supported by the Compatibility renderer.", p_format));495496if (p_format != r_real_format) {497WARN_PRINT(vformat("Image format %s not supported by hardware, converting to %s.", Image::get_format_name(p_format), Image::get_format_name(r_real_format)));498}499500return p_image;501}502503// For compressed images, some formats may not be supported by the current device and will require decompression.504bool need_decompress = false;505bool decompress_ra_to_rg = false;506507switch (p_format) {508case Image::FORMAT_DXT1: {509if (config->s3tc_supported) {510r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT;511r_gl_format = GL_RGBA;512r_gl_type = GL_UNSIGNED_BYTE;513r_compressed = true;514} else {515need_decompress = true;516}517} break;518case Image::FORMAT_DXT3: {519if (config->s3tc_supported) {520r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT;521r_gl_format = GL_RGBA;522r_gl_type = GL_UNSIGNED_BYTE;523r_compressed = true;524} else {525need_decompress = true;526}527} break;528case Image::FORMAT_DXT5: {529if (config->s3tc_supported) {530r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;531r_gl_format = GL_RGBA;532r_gl_type = GL_UNSIGNED_BYTE;533r_compressed = true;534} else {535need_decompress = true;536}537} break;538case Image::FORMAT_RGTC_R: {539if (config->rgtc_supported) {540r_gl_internal_format = _EXT_COMPRESSED_RED_RGTC1_EXT;541r_gl_format = GL_RGBA;542r_gl_type = GL_UNSIGNED_BYTE;543r_compressed = true;544} else {545need_decompress = true;546}547} break;548case Image::FORMAT_RGTC_RG: {549if (config->rgtc_supported) {550r_gl_internal_format = _EXT_COMPRESSED_RED_GREEN_RGTC2_EXT;551r_gl_format = GL_RGBA;552r_gl_type = GL_UNSIGNED_BYTE;553r_compressed = true;554} else {555need_decompress = true;556}557} break;558case Image::FORMAT_BPTC_RGBA: {559if (config->bptc_supported) {560r_gl_internal_format = _EXT_COMPRESSED_RGBA_BPTC_UNORM;561r_gl_format = GL_RGBA;562r_gl_type = GL_UNSIGNED_BYTE;563r_compressed = true;564} else {565need_decompress = true;566}567} break;568case Image::FORMAT_BPTC_RGBF: {569if (config->bptc_supported) {570r_gl_internal_format = _EXT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT;571r_gl_format = GL_RGB;572r_gl_type = GL_FLOAT;573r_compressed = true;574} else {575need_decompress = true;576}577} break;578case Image::FORMAT_BPTC_RGBFU: {579if (config->bptc_supported) {580r_gl_internal_format = _EXT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT;581r_gl_format = GL_RGB;582r_gl_type = GL_FLOAT;583r_compressed = true;584} else {585need_decompress = true;586}587} break;588case Image::FORMAT_ETC2_R11: {589if (config->etc2_supported) {590r_gl_internal_format = _EXT_COMPRESSED_R11_EAC;591r_gl_format = GL_RED;592r_gl_type = GL_UNSIGNED_BYTE;593r_compressed = true;594} else {595need_decompress = true;596}597} break;598case Image::FORMAT_ETC2_R11S: {599if (config->etc2_supported) {600r_gl_internal_format = _EXT_COMPRESSED_SIGNED_R11_EAC;601r_gl_format = GL_RED;602r_gl_type = GL_UNSIGNED_BYTE;603r_compressed = true;604} else {605need_decompress = true;606}607} break;608case Image::FORMAT_ETC2_RG11: {609if (config->etc2_supported) {610r_gl_internal_format = _EXT_COMPRESSED_RG11_EAC;611r_gl_format = GL_RG;612r_gl_type = GL_UNSIGNED_BYTE;613r_compressed = true;614} else {615need_decompress = true;616}617} break;618case Image::FORMAT_ETC2_RG11S: {619if (config->etc2_supported) {620r_gl_internal_format = _EXT_COMPRESSED_SIGNED_RG11_EAC;621r_gl_format = GL_RG;622r_gl_type = GL_UNSIGNED_BYTE;623r_compressed = true;624} else {625need_decompress = true;626}627} break;628case Image::FORMAT_ETC:629case Image::FORMAT_ETC2_RGB8: {630if (config->etc2_supported) {631r_gl_internal_format = _EXT_COMPRESSED_RGB8_ETC2;632r_gl_format = GL_RGB;633r_gl_type = GL_UNSIGNED_BYTE;634r_compressed = true;635} else {636need_decompress = true;637}638} break;639case Image::FORMAT_ETC2_RGBA8: {640if (config->etc2_supported) {641r_gl_internal_format = _EXT_COMPRESSED_RGBA8_ETC2_EAC;642r_gl_format = GL_RGBA;643r_gl_type = GL_UNSIGNED_BYTE;644r_compressed = true;645} else {646need_decompress = true;647}648} break;649case Image::FORMAT_ETC2_RGB8A1: {650if (config->etc2_supported) {651r_gl_internal_format = _EXT_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;652r_gl_format = GL_RGBA;653r_gl_type = GL_UNSIGNED_BYTE;654r_compressed = true;655} else {656need_decompress = true;657}658} break;659case Image::FORMAT_ETC2_RA_AS_RG: {660#ifndef WEB_ENABLED661if (config->etc2_supported) {662r_gl_internal_format = _EXT_COMPRESSED_RGBA8_ETC2_EAC;663r_gl_format = GL_RGBA;664r_gl_type = GL_UNSIGNED_BYTE;665r_compressed = true;666} else667#endif668{669need_decompress = true;670}671decompress_ra_to_rg = true;672} break;673case Image::FORMAT_DXT5_RA_AS_RG: {674#ifndef WEB_ENABLED675if (config->s3tc_supported) {676r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;677r_gl_format = GL_RGBA;678r_gl_type = GL_UNSIGNED_BYTE;679r_compressed = true;680} else681#endif682{683need_decompress = true;684}685decompress_ra_to_rg = true;686} break;687case Image::FORMAT_ASTC_4x4: {688if (config->astc_supported) {689r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_4x4_KHR;690r_gl_format = GL_RGBA;691r_gl_type = GL_UNSIGNED_BYTE;692r_compressed = true;693} else {694need_decompress = true;695}696} break;697case Image::FORMAT_ASTC_4x4_HDR: {698if (config->astc_hdr_supported) {699r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_4x4_KHR;700r_gl_format = GL_RGBA;701r_gl_type = GL_UNSIGNED_BYTE;702r_compressed = true;703} else {704need_decompress = true;705}706} break;707case Image::FORMAT_ASTC_8x8: {708if (config->astc_supported) {709r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_8x8_KHR;710r_gl_format = GL_RGBA;711r_gl_type = GL_UNSIGNED_BYTE;712r_compressed = true;713} else {714need_decompress = true;715}716} break;717case Image::FORMAT_ASTC_8x8_HDR: {718if (config->astc_hdr_supported) {719r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_8x8_KHR;720r_gl_format = GL_RGBA;721r_gl_type = GL_UNSIGNED_BYTE;722r_compressed = true;723} else {724need_decompress = true;725}726} break;727default: {728ERR_FAIL_V_MSG(Ref<Image>(), vformat("The image format %d is not supported by the Compatibility renderer.", p_format));729}730}731732if (need_decompress || p_force_decompress) {733if (image.is_valid()) {734image = image->duplicate();735image->decompress();736ERR_FAIL_COND_V(image->is_compressed(), image);737738if (decompress_ra_to_rg) {739image->convert_ra_rgba8_to_rg();740image->convert(Image::FORMAT_RG8);741}742743Error err = _get_gl_uncompressed_format(image, image->get_format(), r_real_format, r_gl_format, r_gl_internal_format, r_gl_type);744ERR_FAIL_COND_V_MSG(err != OK, Ref<Image>(), vformat("The image format %d is not supported by the Compatibility renderer.", image->get_format()));745746r_real_format = image->get_format();747r_compressed = false;748749if (p_format != image->get_format()) {750WARN_PRINT(vformat("Image format %s not supported by hardware, converting to %s.", Image::get_format_name(p_format), Image::get_format_name(image->get_format())));751}752}753754return image;755}756757return p_image;758}759760RID TextureStorage::texture_allocate() {761return texture_owner.allocate_rid();762}763764void TextureStorage::texture_free(RID p_texture) {765Texture *t = texture_owner.get_or_null(p_texture);766ERR_FAIL_NULL(t);767ERR_FAIL_COND(t->is_render_target);768769if (t->canvas_texture) {770memdelete(t->canvas_texture);771}772773bool must_free_data = false;774if (t->is_proxy) {775if (t->proxy_to.is_valid()) {776Texture *proxy_to = texture_owner.get_or_null(t->proxy_to);777if (proxy_to) {778proxy_to->proxies.erase(p_texture);779}780}781} else {782must_free_data = t->tex_id != 0 && !t->is_from_native_handle;783}784if (must_free_data) {785GLES3::Utilities::get_singleton()->texture_free_data(t->tex_id);786t->tex_id = 0;787}788789texture_atlas_remove_texture(p_texture);790791for (int i = 0; i < t->proxies.size(); i++) {792Texture *p = texture_owner.get_or_null(t->proxies[i]);793ERR_CONTINUE(!p);794p->proxy_to = RID();795p->tex_id = 0;796}797798texture_owner.free(p_texture);799}800801void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) {802ERR_FAIL_COND(p_image.is_null());803804Texture texture;805texture.width = p_image->get_width();806texture.height = p_image->get_height();807texture.alloc_width = texture.width;808texture.alloc_height = texture.height;809texture.mipmaps = p_image->get_mipmap_count() + 1;810texture.format = p_image->get_format();811texture.type = Texture::TYPE_2D;812texture.target = GL_TEXTURE_2D;813_get_gl_image_and_format(Ref<Image>(), texture.format, texture.real_format, texture.gl_format_cache, texture.gl_internal_format_cache, texture.gl_type_cache, texture.compressed, false);814texture.total_data_size = p_image->get_image_data_size(texture.width, texture.height, texture.format, texture.mipmaps);815texture.active = true;816glGenTextures(1, &texture.tex_id);817GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture 2D");818texture_owner.initialize_rid(p_texture, texture);819texture_set_data(p_texture, p_image);820}821822void TextureStorage::texture_external_initialize(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) {823Texture texture;824texture.active = true;825texture.alloc_width = texture.width = p_width;826texture.alloc_height = texture.height = p_height;827texture.real_format = texture.format = Image::FORMAT_RGB8;828texture.type = Texture::TYPE_2D;829830if (GLES3::Config::get_singleton()->external_texture_supported) {831texture.target = _GL_TEXTURE_EXTERNAL_OES;832} else {833texture.target = GL_TEXTURE_2D;834}835836glGenTextures(1, &texture.tex_id);837glBindTexture(texture.target, texture.tex_id);838839#ifdef ANDROID_ENABLED840if (texture.target == _GL_TEXTURE_EXTERNAL_OES) {841if (p_external_buffer) {842GLES3::Config::get_singleton()->eglEGLImageTargetTexture2DOES(_GL_TEXTURE_EXTERNAL_OES, reinterpret_cast<void *>(p_external_buffer));843}844texture.total_data_size = 0;845} else846#endif847{848// If external textures aren't supported, allocate an empty 1x1 texture.849glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);850texture.total_data_size = 3;851}852853glTexParameteri(texture.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);854glTexParameteri(texture.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);855glTexParameteri(texture.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);856glTexParameteri(texture.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);857858GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture External");859texture_owner.initialize_rid(p_texture, texture);860861glBindTexture(texture.target, 0);862}863864void TextureStorage::texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) {865ERR_FAIL_COND(p_layers.is_empty());866867ERR_FAIL_COND(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6);868ERR_FAIL_COND_MSG(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY, "Cubemap Arrays are not supported in the Compatibility renderer.");869870const Ref<Image> &image = p_layers[0];871{872int valid_width = 0;873int valid_height = 0;874bool valid_mipmaps = false;875Image::Format valid_format = Image::FORMAT_MAX;876877for (int i = 0; i < p_layers.size(); i++) {878ERR_FAIL_COND(p_layers[i]->is_empty());879880if (i == 0) {881valid_width = p_layers[i]->get_width();882valid_height = p_layers[i]->get_height();883valid_format = p_layers[i]->get_format();884valid_mipmaps = p_layers[i]->has_mipmaps();885} else {886ERR_FAIL_COND(p_layers[i]->get_width() != valid_width);887ERR_FAIL_COND(p_layers[i]->get_height() != valid_height);888ERR_FAIL_COND(p_layers[i]->get_format() != valid_format);889ERR_FAIL_COND(p_layers[i]->has_mipmaps() != valid_mipmaps);890}891}892}893894Texture texture;895texture.width = image->get_width();896texture.height = image->get_height();897texture.alloc_width = texture.width;898texture.alloc_height = texture.height;899texture.mipmaps = image->get_mipmap_count() + 1;900texture.format = image->get_format();901texture.type = Texture::TYPE_LAYERED;902texture.layered_type = p_layered_type;903texture.target = p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D_ARRAY;904texture.layers = p_layers.size();905_get_gl_image_and_format(Ref<Image>(), texture.format, texture.real_format, texture.gl_format_cache, texture.gl_internal_format_cache, texture.gl_type_cache, texture.compressed, false);906texture.total_data_size = p_layers[0]->get_image_data_size(texture.width, texture.height, texture.format, texture.mipmaps) * texture.layers;907texture.active = true;908glGenTextures(1, &texture.tex_id);909GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture Layered");910texture_owner.initialize_rid(p_texture, texture);911for (int i = 0; i < p_layers.size(); i++) {912_texture_set_data(p_texture, p_layers[i], i, i == 0);913}914}915916void TextureStorage::texture_3d_initialize(RID p_texture, Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) {917ERR_FAIL_COND(p_data.is_empty());918919Image::Image3DValidateError verr = Image::validate_3d_image(p_format, p_width, p_height, p_depth, p_mipmaps, p_data);920ERR_FAIL_COND_MSG(verr != Image::VALIDATE_3D_OK, Image::get_3d_image_validation_error_text(verr));921922Ref<Image> image = p_data[0];923int mipmap_count = 0;924{925Size2i prev_size;926for (int i = 0; i < p_data.size(); i++) {927Size2i img_size(p_data[i]->get_width(), p_data[i]->get_height());928if (img_size != prev_size) {929mipmap_count++;930}931prev_size = img_size;932}933}934935Texture texture;936texture.width = p_width;937texture.height = p_height;938texture.depth = p_depth;939texture.alloc_width = texture.width;940texture.alloc_height = texture.height;941texture.mipmaps = mipmap_count;942texture.format = image->get_format();943texture.type = Texture::TYPE_3D;944texture.target = GL_TEXTURE_3D;945_get_gl_image_and_format(Ref<Image>(), texture.format, texture.real_format, texture.gl_format_cache, texture.gl_internal_format_cache, texture.gl_type_cache, texture.compressed, false);946texture.total_data_size = p_data[0]->get_image_data_size(texture.width, texture.height, texture.format, texture.mipmaps) * texture.depth;947texture.active = true;948glGenTextures(1, &texture.tex_id);949GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture 3D");950texture_owner.initialize_rid(p_texture, texture);951_texture_set_3d_data(p_texture, p_data, true);952}953954// Called internally when texture_proxy_create(p_base) is called.955// Note: p_base is the root and p_texture is the proxy.956void TextureStorage::texture_proxy_initialize(RID p_texture, RID p_base) {957Texture *texture = texture_owner.get_or_null(p_base);958ERR_FAIL_NULL(texture);959Texture proxy_tex;960proxy_tex.copy_from(*texture);961proxy_tex.proxy_to = p_base;962proxy_tex.is_render_target = false;963proxy_tex.is_proxy = true;964proxy_tex.proxies.clear();965texture->proxies.push_back(p_texture);966texture_owner.initialize_rid(p_texture, proxy_tex);967}968969RID TextureStorage::texture_create_from_native_handle(RS::TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers, RS::TextureLayeredType p_layered_type) {970Texture texture;971texture.active = true;972texture.is_from_native_handle = true;973974switch (p_type) {975case RS::TEXTURE_TYPE_2D: {976texture.type = Texture::TYPE_2D;977texture.target = GL_TEXTURE_2D;978} break;979case RS::TEXTURE_TYPE_3D: {980texture.type = Texture::TYPE_3D;981texture.target = GL_TEXTURE_3D;982} break;983case RS::TEXTURE_TYPE_LAYERED: {984texture.type = Texture::TYPE_LAYERED;985texture.target = GL_TEXTURE_2D_ARRAY;986} break;987}988989texture.real_format = texture.format = p_format;990texture.tex_id = p_native_handle;991texture.alloc_width = texture.width = p_width;992texture.alloc_height = texture.height = p_height;993texture.depth = p_depth;994texture.layers = p_layers;995texture.layered_type = p_layered_type;996997return texture_owner.make_rid(texture);998}9991000void TextureStorage::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) {1001texture_set_data(p_texture, p_image, p_layer);10021003Texture *tex = texture_owner.get_or_null(p_texture);1004ERR_FAIL_NULL(tex);1005GLES3::Utilities::get_singleton()->texture_resize_data(tex->tex_id, tex->total_data_size);10061007#ifdef TOOLS_ENABLED1008tex->image_cache_2d.unref();1009#endif1010}10111012void TextureStorage::texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) {1013Texture *tex = texture_owner.get_or_null(p_texture);1014ERR_FAIL_NULL(tex);1015ERR_FAIL_COND(tex->type != Texture::TYPE_3D);10161017Image::Image3DValidateError verr = Image::validate_3d_image(tex->format, tex->width, tex->height, tex->depth, tex->mipmaps > 1, p_data);1018ERR_FAIL_COND_MSG(verr != Image::VALIDATE_3D_OK, Image::get_3d_image_validation_error_text(verr));10191020_texture_set_3d_data(p_texture, p_data, false);10211022GLES3::Utilities::get_singleton()->texture_resize_data(tex->tex_id, tex->total_data_size);1023}10241025void TextureStorage::texture_external_update(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) {1026Texture *tex = texture_owner.get_or_null(p_texture);1027ERR_FAIL_NULL(tex);10281029tex->alloc_width = tex->width = p_width;1030tex->alloc_height = tex->height = p_height;10311032#ifdef ANDROID_ENABLED1033if (tex->target == _GL_TEXTURE_EXTERNAL_OES && p_external_buffer) {1034glBindTexture(_GL_TEXTURE_EXTERNAL_OES, tex->tex_id);1035GLES3::Config::get_singleton()->eglEGLImageTargetTexture2DOES(_GL_TEXTURE_EXTERNAL_OES, reinterpret_cast<void *>(p_external_buffer));1036glBindTexture(_GL_TEXTURE_EXTERNAL_OES, 0);1037}1038#endif1039}10401041void TextureStorage::texture_proxy_update(RID p_texture, RID p_proxy_to) {1042Texture *tex = texture_owner.get_or_null(p_texture);1043ERR_FAIL_NULL(tex);1044ERR_FAIL_COND(!tex->is_proxy);1045Texture *proxy_to = texture_owner.get_or_null(p_proxy_to);1046ERR_FAIL_NULL(proxy_to);1047ERR_FAIL_COND(proxy_to->is_proxy);10481049if (tex->proxy_to.is_valid()) {1050Texture *prev_tex = texture_owner.get_or_null(tex->proxy_to);1051ERR_FAIL_NULL(prev_tex);1052prev_tex->proxies.erase(p_texture);1053}10541055*tex = *proxy_to;10561057tex->proxy_to = p_proxy_to;1058tex->is_render_target = false;1059tex->is_proxy = true;1060tex->proxies.clear();1061tex->canvas_texture = nullptr;1062tex->tex_id = 0;1063proxy_to->proxies.push_back(p_texture);1064}10651066void TextureStorage::texture_2d_placeholder_initialize(RID p_texture) {1067texture_2d_initialize(p_texture, texture_2d_placeholder);1068}10691070void TextureStorage::texture_2d_layered_placeholder_initialize(RID p_texture, RS::TextureLayeredType p_layered_type) {1071if (p_layered_type == RS::TEXTURE_LAYERED_2D_ARRAY) {1072texture_2d_layered_initialize(p_texture, texture_2d_array_placeholder, p_layered_type);1073} else {1074texture_2d_layered_initialize(p_texture, cubemap_placeholder, p_layered_type);1075}1076}10771078void TextureStorage::texture_3d_placeholder_initialize(RID p_texture) {1079texture_3d_initialize(p_texture, Image::FORMAT_RGBA8, 4, 4, 4, false, texture_3d_placeholder);1080}10811082Ref<Image> TextureStorage::texture_2d_get(RID p_texture) const {1083Texture *texture = texture_owner.get_or_null(p_texture);1084ERR_FAIL_NULL_V(texture, Ref<Image>());10851086#ifdef TOOLS_ENABLED1087if (texture->image_cache_2d.is_valid() && !texture->is_render_target) {1088return texture->image_cache_2d;1089}1090#endif10911092Ref<Image> image;1093#ifdef GL_API_ENABLED1094if (RasterizerGLES3::is_gles_over_gl()) {1095// OpenGL 3.3 supports glGetTexImage which is faster and simpler than glReadPixels.1096// It also allows for reading compressed textures, mipmaps, and more formats.1097Vector<uint8_t> data;10981099int64_t data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, texture->real_format, texture->mipmaps > 1);11001101data.resize(data_size * 2); // Add some memory at the end, just in case for buggy drivers.1102uint8_t *w = data.ptrw();11031104glActiveTexture(GL_TEXTURE0);11051106glBindTexture(texture->target, texture->tex_id);11071108glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);11091110for (int i = 0; i < texture->mipmaps; i++) {1111int64_t ofs = Image::get_image_mipmap_offset(texture->alloc_width, texture->alloc_height, texture->real_format, i);11121113if (texture->compressed) {1114glPixelStorei(GL_PACK_ALIGNMENT, 4);1115glGetCompressedTexImage(texture->target, i, &w[ofs]);1116} else {1117glPixelStorei(GL_PACK_ALIGNMENT, 1);1118glGetTexImage(texture->target, i, texture->gl_format_cache, texture->gl_type_cache, &w[ofs]);1119}1120}11211122data.resize(data_size);11231124ERR_FAIL_COND_V(data.is_empty(), Ref<Image>());1125image = Image::create_from_data(texture->alloc_width, texture->alloc_height, texture->mipmaps > 1, texture->real_format, data);1126if (image->is_empty()) {1127const String &path_str = texture->path.is_empty() ? "with no path" : vformat("with path '%s'", texture->path);1128ERR_FAIL_V_MSG(Ref<Image>(), vformat("Texture %s has no data.", path_str));1129}11301131if (texture->format != texture->real_format && !Image::is_format_compressed(texture->real_format)) {1132image->convert(texture->format);1133}1134}1135#endif // GL_API_ENABLED1136#ifdef GLES_API_ENABLED1137if (!RasterizerGLES3::is_gles_over_gl()) {1138Vector<uint8_t> data;11391140// On web and mobile we always read an RGBA8 image with no mipmaps.1141int64_t data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, Image::FORMAT_RGBA8, false);11421143data.resize(data_size * 2); // Add some memory at the end, just in case for buggy drivers.1144uint8_t *w = data.ptrw();11451146GLuint temp_framebuffer;1147glGenFramebuffers(1, &temp_framebuffer);11481149GLuint temp_color_texture;1150glGenTextures(1, &temp_color_texture);11511152glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer);11531154glBindTexture(GL_TEXTURE_2D, temp_color_texture);1155glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);11561157glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);1158glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);1159glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temp_color_texture, 0);11601161glDepthMask(GL_FALSE);1162glDisable(GL_DEPTH_TEST);1163glDisable(GL_CULL_FACE);1164glDisable(GL_BLEND);1165glDepthFunc(GL_GEQUAL);1166glColorMask(1, 1, 1, 1);1167glActiveTexture(GL_TEXTURE0);1168glBindTexture(GL_TEXTURE_2D, texture->tex_id);11691170glViewport(0, 0, texture->alloc_width, texture->alloc_height);1171glClearColor(0.0, 0.0, 0.0, 0.0);1172glClear(GL_COLOR_BUFFER_BIT);11731174CopyEffects::get_singleton()->copy_to_rect(Rect2i(0, 0, 1.0, 1.0));11751176glReadPixels(0, 0, texture->alloc_width, texture->alloc_height, GL_RGBA, GL_UNSIGNED_BYTE, &w[0]);11771178glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);1179glDeleteTextures(1, &temp_color_texture);1180glDeleteFramebuffers(1, &temp_framebuffer);11811182data.resize(data_size);11831184ERR_FAIL_COND_V(data.is_empty(), Ref<Image>());1185image = Image::create_from_data(texture->alloc_width, texture->alloc_height, false, Image::FORMAT_RGBA8, data);1186if (image->is_empty()) {1187const String &path_str = texture->path.is_empty() ? "with no path" : vformat("with path '%s'", texture->path);1188ERR_FAIL_V_MSG(Ref<Image>(), vformat("Texture %s has no data.", path_str));1189}11901191if (texture->format != Image::FORMAT_RGBA8 && !Image::is_format_compressed(texture->format)) {1192image->convert(texture->format);1193}11941195if (texture->mipmaps > 1) {1196image->generate_mipmaps();1197}1198}1199#endif // GLES_API_ENABLED12001201#ifdef TOOLS_ENABLED1202if (Engine::get_singleton()->is_editor_hint() && !texture->is_render_target) {1203texture->image_cache_2d = image;1204}1205#endif12061207return image;1208}12091210Ref<Image> TextureStorage::texture_2d_layer_get(RID p_texture, int p_layer) const {1211Texture *texture = texture_owner.get_or_null(p_texture);1212ERR_FAIL_NULL_V(texture, Ref<Image>());12131214Vector<uint8_t> data;12151216int64_t data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, Image::FORMAT_RGBA8, false);12171218data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers1219uint8_t *w = data.ptrw();12201221GLuint temp_framebuffer;1222glGenFramebuffers(1, &temp_framebuffer);12231224GLuint temp_color_texture;1225glGenTextures(1, &temp_color_texture);12261227glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer);12281229glBindTexture(GL_TEXTURE_2D, temp_color_texture);1230glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);12311232glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);1233glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);1234glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temp_color_texture, 0);12351236glDepthMask(GL_FALSE);1237glDisable(GL_DEPTH_TEST);1238glDisable(GL_CULL_FACE);1239glDisable(GL_BLEND);1240glDepthFunc(GL_LEQUAL);1241glColorMask(1, 1, 1, 1);1242glActiveTexture(GL_TEXTURE0);1243glBindTexture(GL_TEXTURE_2D_ARRAY, texture->tex_id);12441245glViewport(0, 0, texture->alloc_width, texture->alloc_height);1246glClearColor(0.0, 0.0, 0.0, 0.0);1247glClear(GL_COLOR_BUFFER_BIT);12481249CopyEffects::get_singleton()->copy_to_rect_3d(Rect2i(0, 0, 1, 1), p_layer, Texture::TYPE_LAYERED);12501251glReadPixels(0, 0, texture->alloc_width, texture->alloc_height, GL_RGBA, GL_UNSIGNED_BYTE, &w[0]);12521253glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);1254glDeleteTextures(1, &temp_color_texture);1255glDeleteFramebuffers(1, &temp_framebuffer);12561257data.resize(data_size);12581259ERR_FAIL_COND_V(data.is_empty(), Ref<Image>());1260Ref<Image> image = Image::create_from_data(texture->width, texture->height, false, Image::FORMAT_RGBA8, data);1261if (image->is_empty()) {1262const String &path_str = texture->path.is_empty() ? "with no path" : vformat("with path '%s'", texture->path);1263ERR_FAIL_V_MSG(Ref<Image>(), vformat("Texture %s has no data.", path_str));1264}12651266if (texture->format != Image::FORMAT_RGBA8 && !Image::is_format_compressed(texture->format)) {1267image->convert(texture->format);1268}12691270if (texture->mipmaps > 1) {1271image->generate_mipmaps();1272}12731274return image;1275}12761277Vector<Ref<Image>> TextureStorage::_texture_3d_read_framebuffer(GLES3::Texture *p_texture) const {1278ERR_FAIL_NULL_V(p_texture, Vector<Ref<Image>>());12791280Vector<Ref<Image>> ret;1281Vector<uint8_t> data;12821283int width = p_texture->width;1284int height = p_texture->height;1285int depth = p_texture->depth;12861287for (int mipmap_level = 0; mipmap_level < p_texture->mipmaps; mipmap_level++) {1288int64_t data_size = Image::get_image_data_size(width, height, Image::FORMAT_RGBA8, false);1289glViewport(0, 0, width, height);1290glClearColor(0.0, 0.0, 0.0, 0.0);1291glClear(GL_COLOR_BUFFER_BIT);12921293for (int layer = 0; layer < depth; layer++) {1294data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers1295uint8_t *w = data.ptrw();12961297float layer_f = layer / float(depth);1298CopyEffects::get_singleton()->copy_to_rect_3d(Rect2i(0, 0, 1, 1), layer_f, Texture::TYPE_3D, mipmap_level);1299glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &w[0]);13001301data.resize(data_size);1302ERR_FAIL_COND_V(data.is_empty(), Vector<Ref<Image>>());13031304Ref<Image> img = Image::create_from_data(width, height, false, Image::FORMAT_RGBA8, data);1305ERR_FAIL_COND_V(img->is_empty(), Vector<Ref<Image>>());13061307if (p_texture->format != Image::FORMAT_RGBA8 && !Image::is_format_compressed(p_texture->format)) {1308img->convert(p_texture->format);1309}13101311ret.push_back(img);1312}13131314width = MAX(1, width >> 1);1315height = MAX(1, height >> 1);1316depth = MAX(1, depth >> 1);1317}13181319return ret;1320}13211322Vector<Ref<Image>> TextureStorage::texture_3d_get(RID p_texture) const {1323Texture *texture = texture_owner.get_or_null(p_texture);1324ERR_FAIL_NULL_V(texture, Vector<Ref<Image>>());1325ERR_FAIL_COND_V(texture->type != Texture::TYPE_3D, Vector<Ref<Image>>());13261327#ifdef TOOLS_ENABLED1328if (!texture->image_cache_3d.is_empty() && !texture->is_render_target) {1329return texture->image_cache_3d;1330}1331#endif13321333GLuint temp_framebuffer;1334glGenFramebuffers(1, &temp_framebuffer);13351336GLuint temp_color_texture;1337glGenTextures(1, &temp_color_texture);13381339glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer);13401341glBindTexture(GL_TEXTURE_2D, temp_color_texture);1342glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);13431344glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);1345glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);1346glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temp_color_texture, 0);13471348glDepthMask(GL_FALSE);1349glDisable(GL_DEPTH_TEST);1350glDisable(GL_CULL_FACE);1351glDisable(GL_BLEND);1352glDepthFunc(GL_LEQUAL);1353glColorMask(1, 1, 1, 1);1354glActiveTexture(GL_TEXTURE0);1355glBindTexture(GL_TEXTURE_3D, texture->tex_id);13561357Vector<Ref<Image>> ret = _texture_3d_read_framebuffer(texture);13581359glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);1360glDeleteTextures(1, &temp_color_texture);1361glDeleteFramebuffers(1, &temp_framebuffer);13621363#ifdef TOOLS_ENABLED1364if (Engine::get_singleton()->is_editor_hint() && !texture->is_render_target) {1365texture->image_cache_3d = ret;1366}1367#endif13681369return ret;1370}13711372void TextureStorage::texture_replace(RID p_texture, RID p_by_texture) {1373Texture *tex_to = texture_owner.get_or_null(p_texture);1374ERR_FAIL_NULL(tex_to);1375ERR_FAIL_COND(tex_to->is_proxy); //can't replace proxy1376Texture *tex_from = texture_owner.get_or_null(p_by_texture);1377ERR_FAIL_NULL(tex_from);1378ERR_FAIL_COND(tex_from->is_proxy); //can't replace proxy13791380if (tex_to == tex_from) {1381return;1382}13831384if (tex_to->canvas_texture) {1385memdelete(tex_to->canvas_texture);1386tex_to->canvas_texture = nullptr;1387}13881389if (tex_to->tex_id) {1390GLES3::Utilities::get_singleton()->texture_free_data(tex_to->tex_id);1391tex_to->tex_id = 0;1392}13931394Vector<RID> proxies_to_update = tex_to->proxies;1395Vector<RID> proxies_to_redirect = tex_from->proxies;13961397*tex_to = *tex_from;13981399tex_to->proxies = proxies_to_update; //restore proxies, so they can be updated14001401if (tex_to->canvas_texture) {1402tex_to->canvas_texture->diffuse = p_texture; //update1403}14041405for (int i = 0; i < proxies_to_update.size(); i++) {1406texture_proxy_update(proxies_to_update[i], p_texture);1407}1408for (int i = 0; i < proxies_to_redirect.size(); i++) {1409texture_proxy_update(proxies_to_redirect[i], p_texture);1410}1411//delete last, so proxies can be updated1412texture_owner.free(p_by_texture);14131414texture_atlas_mark_dirty_on_texture(p_texture);1415}14161417void TextureStorage::texture_set_size_override(RID p_texture, int p_width, int p_height) {1418Texture *texture = texture_owner.get_or_null(p_texture);14191420ERR_FAIL_NULL(texture);1421ERR_FAIL_COND(texture->is_render_target);14221423ERR_FAIL_COND(p_width <= 0 || p_width > 16384);1424ERR_FAIL_COND(p_height <= 0 || p_height > 16384);1425//real texture size is in alloc width and height1426texture->width = p_width;1427texture->height = p_height;1428}14291430void TextureStorage::texture_set_path(RID p_texture, const String &p_path) {1431Texture *texture = texture_owner.get_or_null(p_texture);1432ERR_FAIL_NULL(texture);14331434texture->path = p_path;1435}14361437String TextureStorage::texture_get_path(RID p_texture) const {1438Texture *texture = texture_owner.get_or_null(p_texture);1439ERR_FAIL_NULL_V(texture, "");14401441return texture->path;1442}14431444void TextureStorage::texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {1445Texture *texture = texture_owner.get_or_null(p_texture);1446ERR_FAIL_NULL(texture);14471448texture->detect_3d_callback = p_callback;1449texture->detect_3d_callback_ud = p_userdata;1450}14511452void TextureStorage::texture_set_detect_srgb_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {1453}14541455void TextureStorage::texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {1456Texture *texture = texture_owner.get_or_null(p_texture);1457ERR_FAIL_NULL(texture);14581459texture->detect_normal_callback = p_callback;1460texture->detect_normal_callback_ud = p_userdata;1461}14621463void TextureStorage::texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) {1464Texture *texture = texture_owner.get_or_null(p_texture);1465ERR_FAIL_NULL(texture);14661467texture->detect_roughness_callback = p_callback;1468texture->detect_roughness_callback_ud = p_userdata;1469}14701471void TextureStorage::texture_debug_usage(List<RS::TextureInfo> *r_info) {1472for (const RID &rid : texture_owner.get_owned_list()) {1473Texture *t = texture_owner.get_or_null(rid);1474if (!t) {1475continue;1476}1477RS::TextureInfo tinfo;1478tinfo.path = t->path;1479tinfo.format = t->format;1480tinfo.width = t->alloc_width;1481tinfo.height = t->alloc_height;1482tinfo.bytes = t->total_data_size;1483tinfo.type = static_cast<RenderingServer::TextureType>(t->type);14841485switch (t->type) {1486case Texture::TYPE_3D:1487tinfo.depth = t->depth;1488break;14891490case Texture::TYPE_LAYERED:1491tinfo.depth = t->layers;1492break;14931494default:1495tinfo.depth = 0;1496break;1497}14981499r_info->push_back(tinfo);1500}1501}15021503void TextureStorage::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) {1504Texture *texture = texture_owner.get_or_null(p_texture);1505ERR_FAIL_NULL(texture);15061507texture->redraw_if_visible = p_enable;1508}15091510Size2 TextureStorage::texture_size_with_proxy(RID p_texture) {1511const Texture *texture = texture_owner.get_or_null(p_texture);1512ERR_FAIL_NULL_V(texture, Size2());1513if (texture->is_proxy) {1514const Texture *proxy = texture_owner.get_or_null(texture->proxy_to);1515return Size2(proxy->width, proxy->height);1516} else {1517return Size2(texture->width, texture->height);1518}1519}15201521void TextureStorage::texture_rd_initialize(RID p_texture, const RID &p_rd_texture, const RS::TextureLayeredType p_layer_type) {1522}15231524RID TextureStorage::texture_get_rd_texture(RID p_texture, bool p_srgb) const {1525return RID();1526}15271528uint64_t TextureStorage::texture_get_native_handle(RID p_texture, bool p_srgb) const {1529const Texture *texture = texture_owner.get_or_null(p_texture);1530ERR_FAIL_NULL_V(texture, 0);15311532return texture->tex_id;1533}15341535void TextureStorage::texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer) {1536_texture_set_data(p_texture, p_image, p_layer, false);1537}15381539void TextureStorage::_texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_initialize) {1540Texture *texture = texture_owner.get_or_null(p_texture);15411542ERR_FAIL_NULL(texture);1543if (texture->target == GL_TEXTURE_3D) {1544// Target is set to a 3D texture or array texture, exit early to avoid spamming errors1545return;1546}1547ERR_FAIL_COND(!texture->active);1548ERR_FAIL_COND(texture->is_render_target);1549ERR_FAIL_COND(p_image.is_null());1550ERR_FAIL_COND(texture->format != p_image->get_format());15511552ERR_FAIL_COND(!p_image->get_width());1553ERR_FAIL_COND(!p_image->get_height());15541555GLenum type;1556GLenum format;1557GLenum internal_format;1558bool compressed = false;15591560bool needs_decompress = texture->resize_to_po2;15611562// Support for RGTC-compressed Texture Arrays isn't mandated by GLES3/WebGL.1563if (!RasterizerGLES3::is_gles_over_gl() && texture->target == GL_TEXTURE_2D_ARRAY) {1564if (p_image->get_format() == Image::FORMAT_RGTC_R || p_image->get_format() == Image::FORMAT_RGTC_RG) {1565needs_decompress = true;1566}1567}15681569Image::Format real_format;1570Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), real_format, format, internal_format, type, compressed, needs_decompress);1571ERR_FAIL_COND(img.is_null());1572if (texture->resize_to_po2) {1573if (p_image->is_compressed()) {1574ERR_PRINT("Texture '" + texture->path + "' is required to be a power of 2 because it uses either mipmaps or repeat, so it was decompressed. This will hurt performance and memory usage.");1575}15761577if (img == p_image) {1578img = img->duplicate();1579}1580img->resize_to_po2(false);1581}15821583GLenum blit_target = (texture->target == GL_TEXTURE_CUBE_MAP) ? _cube_side_enum[p_layer] : texture->target;15841585Vector<uint8_t> read = img->get_data();15861587glActiveTexture(GL_TEXTURE0);1588glBindTexture(texture->target, texture->tex_id);1589_texture_set_swizzle(texture, real_format);15901591int mipmaps = img->has_mipmaps() ? img->get_mipmap_count() + 1 : 1;15921593// Set filtering and repeat state to default.1594if (mipmaps > 1) {1595texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS);1596} else {1597texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);1598}15991600texture->gl_set_repeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);16011602int w = img->get_width();1603int h = img->get_height();16041605int tsize = 0;16061607for (int i = 0; i < mipmaps; i++) {1608int64_t size, ofs;1609img->get_mipmap_offset_and_size(i, ofs, size);1610if (compressed) {1611glPixelStorei(GL_UNPACK_ALIGNMENT, 4);1612if (texture->target == GL_TEXTURE_2D_ARRAY) {1613if (p_initialize) {1614glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, i, internal_format, w, h, texture->layers, 0, size * texture->layers, nullptr);1615}1616glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, i, 0, 0, p_layer, w, h, 1, internal_format, size, &read[ofs]);1617} else {1618glCompressedTexImage2D(blit_target, i, internal_format, w, h, 0, size, &read[ofs]);1619}1620} else {1621glPixelStorei(GL_UNPACK_ALIGNMENT, 1);1622if (texture->target == GL_TEXTURE_2D_ARRAY) {1623if (p_initialize) {1624glTexImage3D(GL_TEXTURE_2D_ARRAY, i, internal_format, w, h, texture->layers, 0, format, type, nullptr);1625}1626glTexSubImage3D(GL_TEXTURE_2D_ARRAY, i, 0, 0, p_layer, w, h, 1, format, type, &read[ofs]);1627} else {1628glTexImage2D(blit_target, i, internal_format, w, h, 0, format, type, &read[ofs]);1629}1630}16311632tsize += size;16331634w = MAX(1, w >> 1);1635h = MAX(1, h >> 1);1636}16371638if (texture->target == GL_TEXTURE_CUBE_MAP || texture->target == GL_TEXTURE_2D_ARRAY) {1639texture->total_data_size = tsize * texture->layers;1640} else {1641texture->total_data_size = tsize;1642}16431644texture->stored_cube_sides |= (1 << p_layer);16451646texture->mipmaps = mipmaps;1647}16481649void TextureStorage::_texture_set_3d_data(RID p_texture, const Vector<Ref<Image>> &p_data, bool p_initialize) {1650Texture *texture = texture_owner.get_or_null(p_texture);16511652ERR_FAIL_NULL(texture);1653ERR_FAIL_COND(!texture->active);1654ERR_FAIL_COND(texture->is_render_target);1655ERR_FAIL_COND(texture->target != GL_TEXTURE_3D);1656ERR_FAIL_COND(p_data.is_empty());16571658GLenum type;1659GLenum format;1660GLenum internal_format;1661bool compressed = false;16621663Image::Format real_format;1664Ref<Image> img = _get_gl_image_and_format(p_data[0], p_data[0]->get_format(), real_format, format, internal_format, type, compressed, texture->resize_to_po2);1665ERR_FAIL_COND(img.is_null());16661667ERR_FAIL_COND_MSG(compressed, "Compressed 3D textures are not supported in the Compatibility renderer.");16681669glActiveTexture(GL_TEXTURE0);1670glBindTexture(texture->target, texture->tex_id);1671_texture_set_swizzle(texture, texture->real_format);16721673// Set filtering and repeat state to default.1674if (texture->mipmaps > 1) {1675texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS);1676} else {1677texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);1678}16791680texture->gl_set_repeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);16811682Vector<Ref<Image>> images;1683images.resize(p_data.size());1684for (int i = 0; i < p_data.size(); i++) {1685Ref<Image> image = p_data[i];1686if (image->get_format() != texture->format) {1687image = image->duplicate();1688image->convert(texture->format);1689}1690images.write[i] = image;1691}16921693glPixelStorei(GL_UNPACK_ALIGNMENT, 1);16941695int all_data_size = 0;1696int mipmap_level = 0;1697int layer = 0;1698int depth = texture->depth;1699Size2i prev_size(images[0]->get_width(), images[0]->get_height());1700for (int i = 0; i < images.size(); i++) {1701Ref<Image> image = images[i];1702Size2i img_size(image->get_width(), image->get_height());17031704if (img_size != prev_size) {1705mipmap_level++;1706depth = MAX(1, depth >> 1);1707layer = 0;1708}1709prev_size = img_size;1710all_data_size += image->get_data().size();17111712if (layer == 0 && p_initialize) {1713glTexImage3D(GL_TEXTURE_3D, mipmap_level, internal_format, img_size.width, img_size.height, depth, 0, format, type, nullptr);1714}17151716glTexSubImage3D(GL_TEXTURE_3D, mipmap_level, 0, 0, layer, img_size.width, img_size.height, 1, format, type, image->get_data().ptr());17171718layer++;1719}17201721texture->total_data_size = all_data_size;1722texture->mipmaps = mipmap_level + 1;17231724#ifdef TOOLS_ENABLED1725if (Engine::get_singleton()->is_editor_hint() && !texture->is_render_target) {1726texture->image_cache_3d = images;1727}1728#endif1729}17301731void TextureStorage::_texture_set_swizzle(GLES3::Texture *p_texture, Image::Format p_real_format) {1732#ifndef WEB_ENABLED1733switch (p_texture->format) {1734case Image::FORMAT_L8: {1735if (RasterizerGLES3::is_gles_over_gl()) {1736glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);1737glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_RED);1738glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_B, GL_RED);1739glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_A, GL_ONE);1740} else {1741glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);1742glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);1743glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_B, GL_BLUE);1744glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);1745}1746} break;1747case Image::FORMAT_LA8: {1748if (RasterizerGLES3::is_gles_over_gl()) {1749glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);1750glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_RED);1751glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_B, GL_RED);1752glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_A, GL_GREEN);1753} else {1754glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);1755glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);1756glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_B, GL_BLUE);1757glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);1758}1759} break;1760case Image::FORMAT_ETC2_RA_AS_RG:1761case Image::FORMAT_DXT5_RA_AS_RG: {1762glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);1763if (p_texture->format == p_real_format) {1764// Swizzle RA from compressed texture into RG.1765glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_ALPHA);1766} else {1767// Converted textures are already in RG, leave as-is.1768glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);1769}1770glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_B, GL_ZERO);1771glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_A, GL_ONE);1772} break;1773default: {1774glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);1775glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);1776glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_B, GL_BLUE);1777glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);1778} break;1779}1780#endif // WEB_ENABLED1781}17821783Image::Format TextureStorage::texture_get_format(RID p_texture) const {1784Texture *texture = texture_owner.get_or_null(p_texture);17851786ERR_FAIL_NULL_V(texture, Image::FORMAT_L8);17871788return texture->format;1789}17901791uint32_t TextureStorage::texture_get_texid(RID p_texture) const {1792Texture *texture = texture_owner.get_or_null(p_texture);17931794ERR_FAIL_NULL_V(texture, 0);17951796return texture->tex_id;1797}17981799Vector3i TextureStorage::texture_get_size(RID p_texture) const {1800Texture *texture = texture_owner.get_or_null(p_texture);18011802ERR_FAIL_NULL_V(texture, Vector3i(0, 0, 0));18031804return Vector3i(texture->width, texture->height, texture->depth);1805}18061807uint32_t TextureStorage::texture_get_width(RID p_texture) const {1808Texture *texture = texture_owner.get_or_null(p_texture);18091810ERR_FAIL_NULL_V(texture, 0);18111812return texture->width;1813}18141815uint32_t TextureStorage::texture_get_height(RID p_texture) const {1816Texture *texture = texture_owner.get_or_null(p_texture);18171818ERR_FAIL_NULL_V(texture, 0);18191820return texture->height;1821}18221823uint32_t TextureStorage::texture_get_depth(RID p_texture) const {1824Texture *texture = texture_owner.get_or_null(p_texture);18251826ERR_FAIL_NULL_V(texture, 0);18271828return texture->depth;1829}18301831void TextureStorage::texture_bind(RID p_texture, uint32_t p_texture_no) {1832Texture *texture = texture_owner.get_or_null(p_texture);18331834ERR_FAIL_NULL(texture);18351836glActiveTexture(GL_TEXTURE0 + p_texture_no);1837glBindTexture(texture->target, texture->tex_id);1838}18391840/* TEXTURE ATLAS API */18411842void TextureStorage::texture_add_to_texture_atlas(RID p_texture) {1843if (!texture_atlas.textures.has(p_texture)) {1844TextureAtlas::Texture t;1845t.users = 1;1846texture_atlas.textures[p_texture] = t;1847texture_atlas.dirty = true;1848} else {1849TextureAtlas::Texture *t = texture_atlas.textures.getptr(p_texture);1850t->users++;1851}1852}18531854void TextureStorage::texture_remove_from_texture_atlas(RID p_texture) {1855TextureAtlas::Texture *t = texture_atlas.textures.getptr(p_texture);1856ERR_FAIL_NULL(t);1857t->users--;1858if (t->users == 0) {1859texture_atlas.textures.erase(p_texture);1860// Do not mark it dirty, there is no need to since it remains working.1861}1862}18631864void TextureStorage::texture_atlas_mark_dirty_on_texture(RID p_texture) {1865if (texture_atlas.textures.has(p_texture)) {1866texture_atlas.dirty = true; // Mark it dirty since it was most likely modified.1867}1868}18691870void TextureStorage::texture_atlas_remove_texture(RID p_texture) {1871if (texture_atlas.textures.has(p_texture)) {1872texture_atlas.textures.erase(p_texture);1873// There is not much a point of making it dirty, texture can be removed next time the atlas is updated.1874}1875}18761877GLuint TextureStorage::texture_atlas_get_texture() const {1878return texture_atlas.texture;1879}18801881void TextureStorage::update_texture_atlas() {1882CopyEffects *copy_effects = CopyEffects::get_singleton();1883ERR_FAIL_NULL(copy_effects);18841885if (!texture_atlas.dirty) {1886return; //nothing to do1887}18881889texture_atlas.dirty = false;18901891if (texture_atlas.texture != 0) {1892GLES3::Utilities::get_singleton()->texture_free_data(texture_atlas.texture);1893texture_atlas.texture = 0;1894glDeleteFramebuffers(1, &texture_atlas.framebuffer);1895texture_atlas.framebuffer = 0;1896}18971898const int border = 2;18991900if (texture_atlas.textures.size()) {1901//generate atlas1902Vector<TextureAtlas::SortItem> itemsv;1903itemsv.resize(texture_atlas.textures.size());1904uint32_t base_size = 8;19051906int idx = 0;19071908for (const KeyValue<RID, TextureAtlas::Texture> &E : texture_atlas.textures) {1909TextureAtlas::SortItem &si = itemsv.write[idx];19101911Texture *src_tex = get_texture(E.key);19121913si.size.width = (src_tex->width / border) + 1;1914si.size.height = (src_tex->height / border) + 1;1915si.pixel_size = Size2i(src_tex->width, src_tex->height);19161917if (base_size < (uint32_t)si.size.width) {1918base_size = nearest_power_of_2_templated(si.size.width);1919}19201921si.texture = E.key;1922idx++;1923}19241925//sort items by size1926itemsv.sort();19271928//attempt to create atlas1929int item_count = itemsv.size();1930TextureAtlas::SortItem *items = itemsv.ptrw();19311932int atlas_height = 0;19331934while (true) {1935Vector<int> v_offsetsv;1936v_offsetsv.resize(base_size);19371938int *v_offsets = v_offsetsv.ptrw();1939memset(v_offsets, 0, sizeof(int) * base_size);19401941int max_height = 0;19421943for (int i = 0; i < item_count; i++) {1944//best fit1945TextureAtlas::SortItem &si = items[i];1946int best_idx = -1;1947int best_height = 0x7FFFFFFF;1948for (uint32_t j = 0; j <= base_size - si.size.width; j++) {1949int height = 0;1950for (int k = 0; k < si.size.width; k++) {1951int h = v_offsets[k + j];1952if (h > height) {1953height = h;1954if (height > best_height) {1955break; //already bad1956}1957}1958}19591960if (height < best_height) {1961best_height = height;1962best_idx = j;1963}1964}19651966//update1967for (int k = 0; k < si.size.width; k++) {1968v_offsets[k + best_idx] = best_height + si.size.height;1969}19701971si.pos.x = best_idx;1972si.pos.y = best_height;19731974if (si.pos.y + si.size.height > max_height) {1975max_height = si.pos.y + si.size.height;1976}1977}19781979if ((uint32_t)max_height <= base_size * 2) {1980atlas_height = max_height;1981break; //good ratio, break;1982}19831984base_size *= 2;1985}19861987texture_atlas.size.width = base_size * border;1988texture_atlas.size.height = nearest_power_of_2_templated(atlas_height * border);19891990for (int i = 0; i < item_count; i++) {1991TextureAtlas::Texture *t = texture_atlas.textures.getptr(items[i].texture);1992t->uv_rect.position = items[i].pos * border + Vector2i(border / 2, border / 2);1993t->uv_rect.size = items[i].pixel_size;19941995t->uv_rect.position /= Size2(texture_atlas.size);1996t->uv_rect.size /= Size2(texture_atlas.size);1997}1998} else {1999texture_atlas.size.width = 4;2000texture_atlas.size.height = 4;2001}20022003{ // Atlas Texture initialize.2004// TODO validate texture atlas size with maximum texture size2005glGenTextures(1, &texture_atlas.texture);2006glActiveTexture(GL_TEXTURE0);2007glBindTexture(GL_TEXTURE_2D, texture_atlas.texture);2008glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texture_atlas.size.width, texture_atlas.size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);2009GLES3::Utilities::get_singleton()->texture_allocated_data(texture_atlas.texture, texture_atlas.size.width * texture_atlas.size.height * 4, "Texture atlas");20102011glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);2012glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);2013glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);2014glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);2015glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);2016glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);20172018glGenFramebuffers(1, &texture_atlas.framebuffer);2019glBindFramebuffer(GL_FRAMEBUFFER, texture_atlas.framebuffer);2020glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_atlas.texture, 0);20212022GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);20232024if (status != GL_FRAMEBUFFER_COMPLETE) {2025glDeleteFramebuffers(1, &texture_atlas.framebuffer);2026texture_atlas.framebuffer = 0;2027GLES3::Utilities::get_singleton()->texture_free_data(texture_atlas.texture);2028texture_atlas.texture = 0;2029WARN_PRINT("Could not create texture atlas, status: " + get_framebuffer_error(status));2030return;2031}2032glViewport(0, 0, texture_atlas.size.width, texture_atlas.size.height);2033glClearColor(0.0, 0.0, 0.0, 0.0);2034glClear(GL_COLOR_BUFFER_BIT);2035glBindTexture(GL_TEXTURE_2D, 0);2036}20372038glDisable(GL_BLEND);20392040if (texture_atlas.textures.size()) {2041for (const KeyValue<RID, TextureAtlas::Texture> &E : texture_atlas.textures) {2042TextureAtlas::Texture *t = texture_atlas.textures.getptr(E.key);2043Texture *src_tex = get_texture(E.key);2044glActiveTexture(GL_TEXTURE0);2045glBindTexture(GL_TEXTURE_2D, src_tex->tex_id);2046copy_effects->copy_to_rect(t->uv_rect);2047}2048}2049glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);2050}20512052/* DECAL API */20532054RID TextureStorage::decal_allocate() {2055return RID();2056}20572058void TextureStorage::decal_initialize(RID p_rid) {2059}20602061void TextureStorage::decal_set_size(RID p_decal, const Vector3 &p_size) {2062}20632064void TextureStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {2065}20662067void TextureStorage::decal_set_emission_energy(RID p_decal, float p_energy) {2068}20692070void TextureStorage::decal_set_albedo_mix(RID p_decal, float p_mix) {2071}20722073void TextureStorage::decal_set_modulate(RID p_decal, const Color &p_modulate) {2074}20752076void TextureStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {2077}20782079void TextureStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {2080}20812082void TextureStorage::decal_set_fade(RID p_decal, float p_above, float p_below) {2083}20842085void TextureStorage::decal_set_normal_fade(RID p_decal, float p_fade) {2086}20872088AABB TextureStorage::decal_get_aabb(RID p_decal) const {2089return AABB();2090}20912092/* RENDER TARGET API */20932094GLuint TextureStorage::system_fbo = 0;20952096void TextureStorage::_update_render_target(RenderTarget *rt) {2097// do not allocate a render target with no size2098if (rt->size.x <= 0 || rt->size.y <= 0) {2099return;2100}21012102// do not allocate a render target that is attached to the screen2103if (rt->direct_to_screen) {2104rt->fbo = system_fbo;2105return;2106}21072108Config *config = Config::get_singleton();21092110if (rt->hdr) {2111rt->color_internal_format = GL_RGBA16F;2112rt->color_format = GL_RGBA;2113rt->color_type = GL_FLOAT;2114rt->color_format_size = 8;2115rt->image_format = Image::FORMAT_RGBAF;2116} else if (rt->is_transparent) {2117rt->color_internal_format = GL_RGBA8;2118rt->color_format = GL_RGBA;2119rt->color_type = GL_UNSIGNED_BYTE;2120rt->color_format_size = 4;2121rt->image_format = Image::FORMAT_RGBA8;2122} else {2123rt->color_internal_format = GL_RGB10_A2;2124rt->color_format = GL_RGBA;2125rt->color_type = GL_UNSIGNED_INT_2_10_10_10_REV;2126rt->color_format_size = 4;2127rt->image_format = Image::FORMAT_RGBA8;2128}21292130glDisable(GL_SCISSOR_TEST);2131glColorMask(1, 1, 1, 1);2132glDepthMask(GL_FALSE);21332134{2135Texture *texture;2136bool use_multiview = rt->view_count > 1 && config->multiview_supported;2137GLenum texture_target = use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;21382139/* Front FBO */21402141glGenFramebuffers(1, &rt->fbo);2142glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);21432144// color2145if (rt->overridden.color.is_valid()) {2146texture = get_texture(rt->overridden.color);2147ERR_FAIL_NULL(texture);21482149rt->color = texture->tex_id;2150rt->size = Size2i(texture->width, texture->height);2151} else {2152texture = get_texture(rt->texture);2153ERR_FAIL_NULL(texture);21542155glGenTextures(1, &rt->color);2156glBindTexture(texture_target, rt->color);21572158if (use_multiview) {2159glTexImage3D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, rt->view_count, 0, rt->color_format, rt->color_type, nullptr);2160} else {2161glTexImage2D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, 0, rt->color_format, rt->color_type, nullptr);2162}21632164texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);2165texture->gl_set_repeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);21662167GLES3::Utilities::get_singleton()->texture_allocated_data(rt->color, rt->size.x * rt->size.y * rt->view_count * rt->color_format_size, "Render target color texture");2168}2169#ifndef IOS_ENABLED2170if (use_multiview) {2171glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, rt->color, 0, 0, rt->view_count);2172} else {2173#else2174{2175#endif2176glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, rt->color, 0);2177}21782179// depth2180if (rt->overridden.depth.is_valid()) {2181texture = get_texture(rt->overridden.depth);2182ERR_FAIL_NULL(texture);21832184rt->depth = texture->tex_id;2185rt->depth_has_stencil = rt->overridden.depth_has_stencil;2186} else {2187glGenTextures(1, &rt->depth);2188glBindTexture(texture_target, rt->depth);21892190if (use_multiview) {2191glTexImage3D(texture_target, 0, GL_DEPTH24_STENCIL8, rt->size.x, rt->size.y, rt->view_count, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);2192} else {2193glTexImage2D(texture_target, 0, GL_DEPTH24_STENCIL8, rt->size.x, rt->size.y, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);2194}21952196glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);2197glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);2198glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);2199glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);22002201rt->depth_has_stencil = true;22022203GLES3::Utilities::get_singleton()->texture_allocated_data(rt->depth, rt->size.x * rt->size.y * rt->view_count * 4, "Render target depth texture");2204}22052206#ifndef IOS_ENABLED2207if (use_multiview) {2208glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, rt->depth_has_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT, rt->depth, 0, 0, rt->view_count);2209} else {2210#else2211{2212#endif2213glFramebufferTexture2D(GL_FRAMEBUFFER, rt->depth_has_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT, texture_target, rt->depth, 0);2214}22152216GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);2217if (status != GL_FRAMEBUFFER_COMPLETE) {2218glDeleteFramebuffers(1, &rt->fbo);2219if (rt->overridden.color.is_null()) {2220GLES3::Utilities::get_singleton()->texture_free_data(rt->color);2221}2222if (rt->overridden.depth.is_null()) {2223GLES3::Utilities::get_singleton()->texture_free_data(rt->depth);2224}2225rt->fbo = 0;2226rt->size.x = 0;2227rt->size.y = 0;2228rt->color = 0;2229rt->depth = 0;2230if (rt->overridden.color.is_null()) {2231texture->tex_id = 0;2232texture->active = false;2233}2234WARN_PRINT("Could not create render target, status: " + get_framebuffer_error(status));2235return;2236}22372238texture->is_render_target = true;2239texture->render_target = rt;2240if (rt->overridden.color.is_null()) {2241texture->format = rt->image_format;2242texture->real_format = rt->image_format;2243texture->target = texture_target;2244if (rt->view_count > 1 && config->multiview_supported) {2245texture->type = Texture::TYPE_LAYERED;2246texture->layers = rt->view_count;2247} else {2248texture->type = Texture::TYPE_2D;2249texture->layers = 1;2250}2251texture->gl_format_cache = rt->color_format;2252texture->gl_type_cache = !rt->hdr ? GL_UNSIGNED_BYTE : GL_FLOAT; // to set HDR format size to 8 and keep 4 for LDR format2253texture->gl_internal_format_cache = rt->color_internal_format;2254texture->tex_id = rt->color;2255texture->width = rt->size.x;2256texture->alloc_width = rt->size.x;2257texture->height = rt->size.y;2258texture->alloc_height = rt->size.y;2259texture->active = true;2260}2261}22622263glClearColor(0, 0, 0, 0);2264glClear(GL_COLOR_BUFFER_BIT);2265glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);2266}22672268void TextureStorage::_create_render_target_backbuffer(RenderTarget *rt) {2269ERR_FAIL_COND_MSG(rt->backbuffer_fbo != 0, "Cannot allocate RenderTarget backbuffer: already initialized.");2270ERR_FAIL_COND(rt->direct_to_screen);2271// Allocate mipmap chains for full screen blur2272// Limit mipmaps so smallest is 32x32 to avoid unnecessary framebuffer switches2273int count = MAX(1, Image::get_image_required_mipmaps(rt->size.x, rt->size.y, Image::FORMAT_RGBA8) - 4);2274if (rt->size.x > 40 && rt->size.y > 40) {2275GLsizei width = rt->size.x;2276GLsizei height = rt->size.y;22772278rt->mipmap_count = count;22792280glGenTextures(1, &rt->backbuffer);2281glBindTexture(GL_TEXTURE_2D, rt->backbuffer);2282uint32_t texture_size_bytes = 0;22832284for (int l = 0; l < count; l++) {2285texture_size_bytes += width * height * 4;2286glTexImage2D(GL_TEXTURE_2D, l, rt->color_internal_format, width, height, 0, rt->color_format, rt->color_type, nullptr);2287width = MAX(1, (width / 2));2288height = MAX(1, (height / 2));2289}22902291glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);2292glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, count - 1);22932294glGenFramebuffers(1, &rt->backbuffer_fbo);2295glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);22962297glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->backbuffer, 0);22982299GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);2300if (status != GL_FRAMEBUFFER_COMPLETE) {2301WARN_PRINT_ONCE("Cannot allocate mipmaps for canvas screen blur. Status: " + get_framebuffer_error(status));2302glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);2303return;2304}2305GLES3::Utilities::get_singleton()->texture_allocated_data(rt->backbuffer, texture_size_bytes, "Render target backbuffer color texture");23062307// Initialize all levels to clear black.2308for (int j = 0; j < count; j++) {2309glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->backbuffer, j);2310glClearColor(0.0, 0.0, 0.0, 0.0);2311glClear(GL_COLOR_BUFFER_BIT);2312}23132314glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->backbuffer, 0);23152316glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);2317glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);2318glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);2319glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);2320}2321}2322void GLES3::TextureStorage::check_backbuffer(RenderTarget *rt, const bool uses_screen_texture, const bool uses_depth_texture) {2323if (rt->backbuffer != 0 && rt->backbuffer_depth != 0) {2324return;2325}23262327Config *config = Config::get_singleton();2328bool use_multiview = rt->view_count > 1 && config->multiview_supported;2329GLenum texture_target = use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;2330if (rt->backbuffer_fbo == 0) {2331glGenFramebuffers(1, &rt->backbuffer_fbo);2332}2333glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);2334if (rt->backbuffer == 0 && uses_screen_texture) {2335glGenTextures(1, &rt->backbuffer);2336glBindTexture(texture_target, rt->backbuffer);2337if (use_multiview) {2338glTexImage3D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, rt->view_count, 0, rt->color_format, rt->color_type, nullptr);2339} else {2340glTexImage2D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, 0, rt->color_format, rt->color_type, nullptr);2341}2342GLES3::Utilities::get_singleton()->texture_allocated_data(rt->backbuffer, rt->size.x * rt->size.y * rt->view_count * rt->color_format_size, "Render target backbuffer color texture (3D)");2343glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);2344glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);2345glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);2346glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);2347#ifndef IOS_ENABLED2348if (use_multiview) {2349glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, rt->backbuffer, 0, 0, rt->view_count);2350} else {2351#else2352{2353#endif2354glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->backbuffer, 0);2355}2356}2357if (rt->backbuffer_depth == 0 && uses_depth_texture) {2358glGenTextures(1, &rt->backbuffer_depth);2359glBindTexture(texture_target, rt->backbuffer_depth);23602361GLint internal_format;2362GLenum format;2363GLenum type;2364GLenum attachment;2365int element_size;23662367if (rt->depth_has_stencil) {2368internal_format = GL_DEPTH24_STENCIL8;2369format = GL_DEPTH_STENCIL;2370type = GL_UNSIGNED_INT_24_8;2371attachment = GL_DEPTH_STENCIL_ATTACHMENT;2372element_size = 4;2373} else {2374internal_format = GL_DEPTH_COMPONENT24;2375format = GL_DEPTH_COMPONENT;2376type = GL_UNSIGNED_INT;2377attachment = GL_DEPTH_ATTACHMENT;2378element_size = 3;2379}23802381if (use_multiview) {2382glTexImage3D(texture_target, 0, internal_format, rt->size.x, rt->size.y, rt->view_count, 0, format, type, nullptr);2383} else {2384glTexImage2D(texture_target, 0, internal_format, rt->size.x, rt->size.y, 0, format, type, nullptr);2385}2386GLES3::Utilities::get_singleton()->texture_allocated_data(rt->backbuffer_depth, rt->size.x * rt->size.y * rt->view_count * element_size, "Render target backbuffer depth texture");23872388glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);2389glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);2390glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);2391glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);2392#ifndef IOS_ENABLED2393if (use_multiview) {2394glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, attachment, rt->backbuffer_depth, 0, 0, rt->view_count);2395} else {2396#else2397{2398#endif2399glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, rt->backbuffer_depth, 0);2400}2401}2402}2403void TextureStorage::_clear_render_target(RenderTarget *rt) {2404// there is nothing else to clear when DIRECT_TO_SCREEN is used2405if (rt->direct_to_screen) {2406return;2407}24082409// Dispose of the cached fbo's and the allocated textures2410for (KeyValue<uint32_t, RenderTarget::RTOverridden::FBOCacheEntry> &E : rt->overridden.fbo_cache) {2411glDeleteTextures(E.value.allocated_textures.size(), E.value.allocated_textures.ptr());2412// Don't delete the current FBO, we'll do that a couple lines down.2413if (E.value.fbo != rt->fbo) {2414glDeleteFramebuffers(1, &E.value.fbo);2415}2416}2417rt->overridden.fbo_cache.clear();24182419if (rt->fbo) {2420glDeleteFramebuffers(1, &rt->fbo);2421rt->fbo = 0;2422}24232424if (rt->overridden.color.is_null()) {2425if (rt->texture.is_valid()) {2426Texture *tex = get_texture(rt->texture);2427tex->alloc_height = 0;2428tex->alloc_width = 0;2429tex->width = 0;2430tex->height = 0;2431tex->active = false;2432tex->render_target = nullptr;2433tex->is_render_target = false;2434tex->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_MAX);2435tex->gl_set_repeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX);2436}2437} else {2438Texture *tex = get_texture(rt->overridden.color);2439tex->render_target = nullptr;2440tex->is_render_target = false;2441}24422443if (rt->overridden.color.is_valid()) {2444rt->overridden.color = RID();2445} else if (rt->color) {2446GLES3::Utilities::get_singleton()->texture_free_data(rt->color);2447if (rt->texture.is_valid()) {2448Texture *tex = get_texture(rt->texture);2449tex->tex_id = 0;2450}2451}2452rt->color = 0;24532454if (rt->overridden.depth.is_valid()) {2455rt->overridden.depth = RID();2456} else if (rt->depth) {2457GLES3::Utilities::get_singleton()->texture_free_data(rt->depth);2458}2459rt->depth = 0;24602461rt->overridden.velocity = RID();2462rt->overridden.is_overridden = false;24632464if (rt->backbuffer_fbo != 0) {2465glDeleteFramebuffers(1, &rt->backbuffer_fbo);2466rt->backbuffer_fbo = 0;2467}2468if (rt->backbuffer != 0) {2469GLES3::Utilities::get_singleton()->texture_free_data(rt->backbuffer);2470rt->backbuffer = 0;2471}2472if (rt->backbuffer_depth != 0) {2473GLES3::Utilities::get_singleton()->texture_free_data(rt->backbuffer_depth);2474rt->backbuffer_depth = 0;2475}2476_render_target_clear_sdf(rt);2477}24782479RID TextureStorage::render_target_create() {2480RenderTarget render_target;2481render_target.used_in_frame = false;2482render_target.clear_requested = false;24832484Texture t;2485t.active = true;2486t.render_target = &render_target;2487t.is_render_target = true;24882489render_target.texture = texture_owner.make_rid(t);2490_update_render_target(&render_target);2491return render_target_owner.make_rid(render_target);2492}24932494void TextureStorage::render_target_free(RID p_rid) {2495RenderTarget *rt = render_target_owner.get_or_null(p_rid);2496_clear_render_target(rt);24972498Texture *t = get_texture(rt->texture);2499if (t) {2500t->is_render_target = false;2501if (rt->overridden.color.is_null()) {2502texture_free(rt->texture);2503}2504//memdelete(t);2505}2506render_target_owner.free(p_rid);2507}25082509void TextureStorage::render_target_set_position(RID p_render_target, int p_x, int p_y) {2510RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2511ERR_FAIL_NULL(rt);25122513rt->position = Point2i(p_x, p_y);2514}25152516Point2i TextureStorage::render_target_get_position(RID p_render_target) const {2517RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2518ERR_FAIL_NULL_V(rt, Point2i());25192520return rt->position;2521}25222523void TextureStorage::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) {2524RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2525ERR_FAIL_NULL(rt);25262527if (p_width == rt->size.x && p_height == rt->size.y && p_view_count == rt->view_count) {2528return;2529}2530if (rt->overridden.color.is_valid()) {2531return;2532}25332534_clear_render_target(rt);25352536rt->size = Size2i(p_width, p_height);2537rt->view_count = p_view_count;25382539_update_render_target(rt);2540}25412542// TODO: convert to Size2i internally2543Size2i TextureStorage::render_target_get_size(RID p_render_target) const {2544RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2545ERR_FAIL_NULL_V(rt, Size2i());25462547return rt->size;2548}25492550void TextureStorage::render_target_set_override(RID p_render_target, RID p_color_texture, RID p_depth_texture, RID p_velocity_texture, RID p_velocity_depth_texture) {2551RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2552ERR_FAIL_NULL(rt);2553ERR_FAIL_COND(rt->direct_to_screen);25542555rt->overridden.velocity = p_velocity_texture;25562557if (rt->overridden.color == p_color_texture && rt->overridden.depth == p_depth_texture) {2558return;2559}25602561if (p_color_texture.is_null() && p_depth_texture.is_null()) {2562_clear_render_target(rt);2563_update_render_target(rt);2564return;2565}25662567if (!rt->overridden.is_overridden) {2568_clear_render_target(rt);2569}25702571rt->overridden.color = p_color_texture;2572rt->overridden.depth = p_depth_texture;2573rt->overridden.depth_has_stencil = p_depth_texture.is_null();2574rt->overridden.is_overridden = true;25752576uint32_t hash_key = hash_murmur3_one_64(p_color_texture.get_id());2577hash_key = hash_murmur3_one_64(p_depth_texture.get_id(), hash_key);2578hash_key = hash_fmix32(hash_key);25792580RBMap<uint32_t, RenderTarget::RTOverridden::FBOCacheEntry>::Element *cache;2581if ((cache = rt->overridden.fbo_cache.find(hash_key)) != nullptr) {2582rt->fbo = cache->get().fbo;2583rt->color = cache->get().color;2584rt->depth = cache->get().depth;2585rt->depth_has_stencil = cache->get().depth_has_stencil;2586rt->size = cache->get().size;2587rt->texture = p_color_texture;2588return;2589}25902591_update_render_target(rt);25922593RenderTarget::RTOverridden::FBOCacheEntry new_entry;2594new_entry.fbo = rt->fbo;2595new_entry.color = rt->color;2596new_entry.depth = rt->depth;2597new_entry.depth_has_stencil = rt->depth_has_stencil;2598new_entry.size = rt->size;2599// Keep track of any textures we had to allocate because they weren't overridden.2600if (p_color_texture.is_null()) {2601new_entry.allocated_textures.push_back(rt->color);2602}2603if (p_depth_texture.is_null()) {2604new_entry.allocated_textures.push_back(rt->depth);2605}2606rt->overridden.fbo_cache.insert(hash_key, new_entry);2607}26082609RID TextureStorage::render_target_get_override_color(RID p_render_target) const {2610RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2611ERR_FAIL_NULL_V(rt, RID());26122613return rt->overridden.color;2614}26152616RID TextureStorage::render_target_get_override_depth(RID p_render_target) const {2617RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2618ERR_FAIL_NULL_V(rt, RID());26192620return rt->overridden.depth;2621}26222623RID TextureStorage::render_target_get_override_velocity(RID p_render_target) const {2624RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2625ERR_FAIL_NULL_V(rt, RID());26262627return rt->overridden.velocity;2628}26292630void TextureStorage::render_target_set_render_region(RID p_render_target, const Rect2i &p_render_region) {2631RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2632ERR_FAIL_NULL(rt);26332634rt->render_region = p_render_region;2635}26362637Rect2i TextureStorage::render_target_get_render_region(RID p_render_target) const {2638RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2639ERR_FAIL_NULL_V(rt, Rect2i());26402641return rt->render_region;2642}26432644RID TextureStorage::render_target_get_texture(RID p_render_target) {2645RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2646ERR_FAIL_NULL_V(rt, RID());26472648if (rt->overridden.color.is_valid()) {2649return rt->overridden.color;2650}26512652return rt->texture;2653}26542655void TextureStorage::render_target_set_transparent(RID p_render_target, bool p_transparent) {2656RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2657ERR_FAIL_NULL(rt);26582659rt->is_transparent = p_transparent;26602661if (rt->overridden.color.is_null()) {2662_clear_render_target(rt);2663_update_render_target(rt);2664}2665}26662667bool TextureStorage::render_target_get_transparent(RID p_render_target) const {2668RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2669ERR_FAIL_NULL_V(rt, false);26702671return rt->is_transparent;2672}26732674void TextureStorage::render_target_set_direct_to_screen(RID p_render_target, bool p_direct_to_screen) {2675RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2676ERR_FAIL_NULL(rt);26772678if (p_direct_to_screen == rt->direct_to_screen) {2679return;2680}2681// When setting DIRECT_TO_SCREEN, you need to clear before the value is set, but allocate after as2682// those functions change how they operate depending on the value of DIRECT_TO_SCREEN2683_clear_render_target(rt);2684rt->direct_to_screen = p_direct_to_screen;2685if (rt->direct_to_screen) {2686rt->overridden.color = RID();2687rt->overridden.depth = RID();2688rt->overridden.velocity = RID();2689}2690_update_render_target(rt);2691}26922693bool TextureStorage::render_target_get_direct_to_screen(RID p_render_target) const {2694RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2695ERR_FAIL_NULL_V(rt, false);26962697return rt->direct_to_screen;2698}26992700bool TextureStorage::render_target_was_used(RID p_render_target) const {2701RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2702ERR_FAIL_NULL_V(rt, false);27032704return rt->used_in_frame;2705}27062707void TextureStorage::render_target_clear_used(RID p_render_target) {2708RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2709ERR_FAIL_NULL(rt);27102711rt->used_in_frame = false;2712}27132714void TextureStorage::render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) {2715RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2716ERR_FAIL_NULL(rt);2717ERR_FAIL_COND(rt->direct_to_screen);2718if (p_msaa == rt->msaa) {2719return;2720}27212722WARN_PRINT("2D MSAA is not yet supported for GLES3.");27232724_clear_render_target(rt);2725rt->msaa = p_msaa;2726_update_render_target(rt);2727}27282729RS::ViewportMSAA TextureStorage::render_target_get_msaa(RID p_render_target) const {2730RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2731ERR_FAIL_NULL_V(rt, RS::VIEWPORT_MSAA_DISABLED);27322733return rt->msaa;2734}27352736void TextureStorage::render_target_set_use_hdr(RID p_render_target, bool p_use_hdr_2d) {2737RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2738ERR_FAIL_NULL(rt);2739ERR_FAIL_COND(rt->direct_to_screen);2740if (p_use_hdr_2d == rt->hdr) {2741return;2742}27432744_clear_render_target(rt);2745rt->hdr = p_use_hdr_2d;2746_update_render_target(rt);2747}27482749bool TextureStorage::render_target_is_using_hdr(RID p_render_target) const {2750RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2751ERR_FAIL_NULL_V(rt, false);27522753return rt->hdr;2754}27552756GLuint TextureStorage::render_target_get_color_internal_format(RID p_render_target) const {2757RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2758ERR_FAIL_NULL_V(rt, GL_RGBA8);27592760return rt->color_internal_format;2761}27622763GLuint TextureStorage::render_target_get_color_format(RID p_render_target) const {2764RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2765ERR_FAIL_NULL_V(rt, GL_RGBA);27662767return rt->color_format;2768}27692770GLuint TextureStorage::render_target_get_color_type(RID p_render_target) const {2771RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2772ERR_FAIL_NULL_V(rt, GL_UNSIGNED_BYTE);27732774return rt->color_type;2775}27762777uint32_t TextureStorage::render_target_get_color_format_size(RID p_render_target) const {2778RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2779ERR_FAIL_NULL_V(rt, 4);27802781return rt->color_format_size;2782}27832784void TextureStorage::render_target_request_clear(RID p_render_target, const Color &p_clear_color) {2785RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2786ERR_FAIL_NULL(rt);2787rt->clear_requested = true;2788rt->clear_color = p_clear_color;2789}27902791bool TextureStorage::render_target_is_clear_requested(RID p_render_target) {2792RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2793ERR_FAIL_NULL_V(rt, false);2794return rt->clear_requested;2795}2796Color TextureStorage::render_target_get_clear_request_color(RID p_render_target) {2797RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2798ERR_FAIL_NULL_V(rt, Color());2799return rt->clear_color;2800}28012802void TextureStorage::render_target_disable_clear_request(RID p_render_target) {2803RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2804ERR_FAIL_NULL(rt);2805rt->clear_requested = false;2806}28072808void TextureStorage::render_target_do_clear_request(RID p_render_target) {2809RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2810ERR_FAIL_NULL(rt);2811if (!rt->clear_requested) {2812return;2813}2814glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);28152816glClearBufferfv(GL_COLOR, 0, rt->clear_color.components);2817rt->clear_requested = false;2818glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);2819}28202821GLuint TextureStorage::render_target_get_fbo(RID p_render_target) const {2822RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2823ERR_FAIL_NULL_V(rt, 0);28242825return rt->fbo;2826}28272828GLuint TextureStorage::render_target_get_color(RID p_render_target) const {2829RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2830ERR_FAIL_NULL_V(rt, 0);28312832if (rt->overridden.color.is_valid()) {2833Texture *texture = get_texture(rt->overridden.color);2834ERR_FAIL_NULL_V(texture, 0);28352836return texture->tex_id;2837} else {2838return rt->color;2839}2840}28412842GLuint TextureStorage::render_target_get_depth(RID p_render_target) const {2843RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2844ERR_FAIL_NULL_V(rt, 0);28452846if (rt->overridden.depth.is_valid()) {2847Texture *texture = get_texture(rt->overridden.depth);2848ERR_FAIL_NULL_V(texture, 0);28492850return texture->tex_id;2851} else {2852return rt->depth;2853}2854}28552856bool TextureStorage::render_target_get_depth_has_stencil(RID p_render_target) const {2857RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2858ERR_FAIL_NULL_V(rt, 0);28592860return rt->depth_has_stencil;2861}28622863void TextureStorage::render_target_set_reattach_textures(RID p_render_target, bool p_reattach_textures) const {2864RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2865ERR_FAIL_NULL(rt);28662867rt->reattach_textures = p_reattach_textures;2868}28692870bool TextureStorage::render_target_is_reattach_textures(RID p_render_target) const {2871RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2872ERR_FAIL_NULL_V(rt, false);28732874return rt->reattach_textures;2875}28762877void TextureStorage::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) {2878RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2879ERR_FAIL_NULL(rt);2880if (rt->sdf_oversize == p_size && rt->sdf_scale == p_scale) {2881return;2882}28832884rt->sdf_oversize = p_size;2885rt->sdf_scale = p_scale;28862887_render_target_clear_sdf(rt);2888}28892890Rect2i TextureStorage::_render_target_get_sdf_rect(const RenderTarget *rt) const {2891Size2i margin;2892int scale;2893switch (rt->sdf_oversize) {2894case RS::VIEWPORT_SDF_OVERSIZE_100_PERCENT: {2895scale = 100;2896} break;2897case RS::VIEWPORT_SDF_OVERSIZE_120_PERCENT: {2898scale = 120;2899} break;2900case RS::VIEWPORT_SDF_OVERSIZE_150_PERCENT: {2901scale = 150;2902} break;2903case RS::VIEWPORT_SDF_OVERSIZE_200_PERCENT: {2904scale = 200;2905} break;2906default: {2907ERR_PRINT("Invalid viewport SDF oversize, defaulting to 100%.");2908scale = 100;2909} break;2910}29112912margin = (rt->size * scale / 100) - rt->size;29132914Rect2i r(Vector2i(), rt->size);2915r.position -= margin;2916r.size += margin * 2;29172918return r;2919}29202921Rect2i TextureStorage::render_target_get_sdf_rect(RID p_render_target) const {2922const RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2923ERR_FAIL_NULL_V(rt, Rect2i());29242925return _render_target_get_sdf_rect(rt);2926}29272928void TextureStorage::render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) {2929RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2930ERR_FAIL_NULL(rt);29312932rt->sdf_enabled = p_enabled;2933}29342935bool TextureStorage::render_target_is_sdf_enabled(RID p_render_target) const {2936const RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2937ERR_FAIL_NULL_V(rt, false);29382939return rt->sdf_enabled;2940}29412942GLuint TextureStorage::render_target_get_sdf_texture(RID p_render_target) {2943RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2944ERR_FAIL_NULL_V(rt, 0);2945if (rt->sdf_texture_read == 0) {2946Texture *texture = texture_owner.get_or_null(default_gl_textures[DEFAULT_GL_TEXTURE_BLACK]);2947return texture->tex_id;2948}29492950return rt->sdf_texture_read;2951}29522953void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) {2954ERR_FAIL_COND(rt->sdf_texture_write_fb != 0);29552956Size2i size = _render_target_get_sdf_rect(rt).size;29572958glGenTextures(1, &rt->sdf_texture_write);2959glActiveTexture(GL_TEXTURE0);2960glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_write);2961glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, size.width, size.height, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr);2962GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_write, size.width * size.height, "SDF texture");2963glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);2964glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);2965glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);2966glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);2967glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);2968glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);29692970glGenFramebuffers(1, &rt->sdf_texture_write_fb);2971glBindFramebuffer(GL_FRAMEBUFFER, rt->sdf_texture_write_fb);2972glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->sdf_texture_write, 0);29732974int scale;2975switch (rt->sdf_scale) {2976case RS::VIEWPORT_SDF_SCALE_100_PERCENT: {2977scale = 100;2978} break;2979case RS::VIEWPORT_SDF_SCALE_50_PERCENT: {2980scale = 50;2981} break;2982case RS::VIEWPORT_SDF_SCALE_25_PERCENT: {2983scale = 25;2984} break;2985default: {2986ERR_PRINT("Invalid viewport SDF scale, defaulting to 100%.");2987scale = 100;2988} break;2989}29902991rt->process_size = size * scale / 100;2992rt->process_size = rt->process_size.maxi(1);29932994glGenTextures(2, rt->sdf_texture_process);2995glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[0]);2996glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16I, rt->process_size.width, rt->process_size.height, 0, GL_RG_INTEGER, GL_SHORT, nullptr);2997glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);2998glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);2999glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);3000glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);3001glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);3002glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);3003GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_process[0], rt->process_size.width * rt->process_size.height * 4, "SDF process texture[0]");30043005glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[1]);3006glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16I, rt->process_size.width, rt->process_size.height, 0, GL_RG_INTEGER, GL_SHORT, nullptr);3007glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);3008glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);3009glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);3010glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);3011glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);3012glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);3013GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_process[1], rt->process_size.width * rt->process_size.height * 4, "SDF process texture[1]");30143015glGenTextures(1, &rt->sdf_texture_read);3016glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_read);3017glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rt->process_size.width, rt->process_size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);3018glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);3019glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);3020glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);3021glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);3022glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);3023glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);3024GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_read, rt->process_size.width * rt->process_size.height * 4, "SDF texture (read)");3025}30263027void TextureStorage::_render_target_clear_sdf(RenderTarget *rt) {3028if (rt->sdf_texture_write_fb != 0) {3029GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_read);3030GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_write);3031GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_process[0]);3032GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_process[1]);30333034glDeleteFramebuffers(1, &rt->sdf_texture_write_fb);3035rt->sdf_texture_read = 0;3036rt->sdf_texture_write = 0;3037rt->sdf_texture_process[0] = 0;3038rt->sdf_texture_process[1] = 0;3039rt->sdf_texture_write_fb = 0;3040}3041}30423043GLuint TextureStorage::render_target_get_sdf_framebuffer(RID p_render_target) {3044RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3045ERR_FAIL_NULL_V(rt, 0);30463047if (rt->sdf_texture_write_fb == 0) {3048_render_target_allocate_sdf(rt);3049}30503051return rt->sdf_texture_write_fb;3052}3053void TextureStorage::render_target_sdf_process(RID p_render_target) {3054CopyEffects *copy_effects = CopyEffects::get_singleton();30553056RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3057ERR_FAIL_NULL(rt);3058ERR_FAIL_COND(rt->sdf_texture_write_fb == 0);30593060Rect2i r = _render_target_get_sdf_rect(rt);30613062Size2i size = r.size;3063int32_t shift = 0;30643065bool shrink = false;30663067switch (rt->sdf_scale) {3068case RS::VIEWPORT_SDF_SCALE_50_PERCENT: {3069size[0] >>= 1;3070size[1] >>= 1;3071shift = 1;3072shrink = true;3073} break;3074case RS::VIEWPORT_SDF_SCALE_25_PERCENT: {3075size[0] >>= 2;3076size[1] >>= 2;3077shift = 2;3078shrink = true;3079} break;3080default: {3081};3082}30833084GLuint temp_fb;3085glGenFramebuffers(1, &temp_fb);3086glBindFramebuffer(GL_FRAMEBUFFER, temp_fb);30873088// Load3089CanvasSdfShaderGLES3::ShaderVariant variant = shrink ? CanvasSdfShaderGLES3::MODE_LOAD_SHRINK : CanvasSdfShaderGLES3::MODE_LOAD;3090bool success = sdf_shader.shader.version_bind_shader(sdf_shader.shader_version, variant);3091if (!success) {3092return;3093}30943095sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::BASE_SIZE, r.size, sdf_shader.shader_version, variant);3096sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SIZE, size, sdf_shader.shader_version, variant);3097sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::STRIDE, 0, sdf_shader.shader_version, variant);3098sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SHIFT, shift, sdf_shader.shader_version, variant);30993100glActiveTexture(GL_TEXTURE0);3101glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_write);31023103glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->sdf_texture_process[0], 0);3104glViewport(0, 0, size.width, size.height);3105glEnable(GL_SCISSOR_TEST);3106glScissor(0, 0, size.width, size.height);31073108copy_effects->draw_screen_triangle();31093110// Process31113112int stride = nearest_power_of_2_templated(MAX(size.width, size.height) / 2);31133114variant = CanvasSdfShaderGLES3::MODE_PROCESS;3115success = sdf_shader.shader.version_bind_shader(sdf_shader.shader_version, variant);3116if (!success) {3117return;3118}31193120sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::BASE_SIZE, r.size, sdf_shader.shader_version, variant);3121sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SIZE, size, sdf_shader.shader_version, variant);3122sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::STRIDE, stride, sdf_shader.shader_version, variant);3123sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SHIFT, shift, sdf_shader.shader_version, variant);31243125bool swap = false;31263127//jumpflood3128while (stride > 0) {3129glBindTexture(GL_TEXTURE_2D, 0);3130glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->sdf_texture_process[swap ? 0 : 1], 0);3131glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[swap ? 1 : 0]);31323133sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::STRIDE, stride, sdf_shader.shader_version, variant);31343135copy_effects->draw_screen_triangle();31363137stride /= 2;3138swap = !swap;3139}31403141// Store3142variant = shrink ? CanvasSdfShaderGLES3::MODE_STORE_SHRINK : CanvasSdfShaderGLES3::MODE_STORE;3143success = sdf_shader.shader.version_bind_shader(sdf_shader.shader_version, variant);3144if (!success) {3145return;3146}31473148sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::BASE_SIZE, r.size, sdf_shader.shader_version, variant);3149sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SIZE, size, sdf_shader.shader_version, variant);3150sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::STRIDE, stride, sdf_shader.shader_version, variant);3151sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SHIFT, shift, sdf_shader.shader_version, variant);31523153glBindTexture(GL_TEXTURE_2D, 0);3154glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->sdf_texture_read, 0);3155glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[swap ? 1 : 0]);31563157copy_effects->draw_screen_triangle();31583159glBindTexture(GL_TEXTURE_2D, 0);3160glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);3161glDeleteFramebuffers(1, &temp_fb);3162glDisable(GL_SCISSOR_TEST);3163}31643165void TextureStorage::render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps) {3166RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3167ERR_FAIL_NULL(rt);3168ERR_FAIL_COND(rt->direct_to_screen);31693170if (rt->backbuffer_fbo == 0) {3171_create_render_target_backbuffer(rt);3172}31733174Rect2i region;3175if (p_region == Rect2i()) {3176region.size = rt->size;3177} else {3178region = Rect2i(Size2i(), rt->size).intersection(p_region);3179if (region.size == Size2i()) {3180return; //nothing to do3181}3182}31833184glDisable(GL_BLEND);3185// Single texture copy for backbuffer.3186glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);3187glActiveTexture(GL_TEXTURE0);3188glBindTexture(GL_TEXTURE_2D, rt->color);3189Rect2 normalized_region = region;3190normalized_region.position = normalized_region.position / Size2(rt->size);3191normalized_region.size = normalized_region.size / Size2(rt->size);3192GLES3::CopyEffects::get_singleton()->copy_to_and_from_rect(normalized_region);31933194if (p_gen_mipmaps) {3195GLES3::CopyEffects::get_singleton()->gaussian_blur(rt->backbuffer, rt->mipmap_count, region, rt->size);3196glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);3197}31983199glEnable(GL_BLEND); // 2D starts with blend enabled.3200}32013202void TextureStorage::render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color) {3203RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3204ERR_FAIL_NULL(rt);3205ERR_FAIL_COND(rt->direct_to_screen);32063207if (rt->backbuffer_fbo == 0) {3208_create_render_target_backbuffer(rt);3209}32103211Rect2i region;3212if (p_region == Rect2i()) {3213// Just do a full screen clear;3214glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);3215glClearColor(p_color.r, p_color.g, p_color.b, p_color.a);3216glClear(GL_COLOR_BUFFER_BIT);3217} else {3218region = Rect2i(Size2i(), rt->size).intersection(p_region);3219if (region.size == Size2i()) {3220return; //nothing to do3221}3222glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);3223GLES3::CopyEffects::get_singleton()->set_color(p_color, region);3224}3225}32263227void TextureStorage::render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region) {3228RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3229ERR_FAIL_NULL(rt);32303231if (rt->backbuffer_fbo == 0) {3232_create_render_target_backbuffer(rt);3233}32343235Rect2i region;3236if (p_region == Rect2i()) {3237region.size = rt->size;3238} else {3239region = Rect2i(Size2i(), rt->size).intersection(p_region);3240if (region.size == Size2i()) {3241return; //nothing to do3242}3243}3244glDisable(GL_BLEND);3245GLES3::CopyEffects::get_singleton()->gaussian_blur(rt->backbuffer, rt->mipmap_count, region, rt->size);3246glEnable(GL_BLEND); // 2D starts with blend enabled.32473248glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);3249}32503251#endif // GLES3_ENABLED325232533254