Path: blob/master/drivers/gles3/storage/render_scene_buffers_gles3.cpp
10005 views
/**************************************************************************/1/* render_scene_buffers_gles3.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 "render_scene_buffers_gles3.h"33#include "config.h"34#include "texture_storage.h"35#include "utilities.h"3637#ifdef ANDROID_ENABLED38#define glFramebufferTextureMultiviewOVR GLES3::Config::get_singleton()->eglFramebufferTextureMultiviewOVR39#define glTexStorage3DMultisample GLES3::Config::get_singleton()->eglTexStorage3DMultisample40#define glFramebufferTexture2DMultisampleEXT GLES3::Config::get_singleton()->eglFramebufferTexture2DMultisampleEXT41#define glFramebufferTextureMultisampleMultiviewOVR GLES3::Config::get_singleton()->eglFramebufferTextureMultisampleMultiviewOVR42#endif // ANDROID_ENABLED4344// Will only be defined if GLES 3.2 headers are included45#ifndef GL_TEXTURE_2D_MULTISAMPLE_ARRAY46#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x910247#endif4849RenderSceneBuffersGLES3::RenderSceneBuffersGLES3() {50for (int i = 0; i < 4; i++) {51glow.levels[i].color = 0;52glow.levels[i].fbo = 0;53}54}5556RenderSceneBuffersGLES3::~RenderSceneBuffersGLES3() {57free_render_buffer_data();58}5960void RenderSceneBuffersGLES3::_rt_attach_textures(GLuint p_color, GLuint p_depth, GLsizei p_samples, uint32_t p_view_count, bool p_depth_has_stencil) {61if (p_view_count > 1) {62if (p_samples > 1) {63#if defined(ANDROID_ENABLED) || defined(WEB_ENABLED)64glFramebufferTextureMultisampleMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, p_color, 0, p_samples, 0, p_view_count);65glFramebufferTextureMultisampleMultiviewOVR(GL_FRAMEBUFFER, p_depth_has_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT, p_depth, 0, p_samples, 0, p_view_count);66#else67ERR_PRINT_ONCE("Multiview MSAA isn't supported on this platform.");68#endif69} else {70#ifndef IOS_ENABLED71glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, p_color, 0, 0, p_view_count);72glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, p_depth_has_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT, p_depth, 0, 0, p_view_count);73#else74ERR_PRINT_ONCE("Multiview isn't supported on this platform.");75#endif76}77} else {78if (p_samples > 1) {79#ifdef ANDROID_ENABLED80glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_color, 0, p_samples);81glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, p_depth_has_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, p_depth, 0, p_samples);82#else83ERR_PRINT_ONCE("MSAA via EXT_multisampled_render_to_texture isn't supported on this platform.");84#endif85} else {86glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_color, 0);87glFramebufferTexture2D(GL_FRAMEBUFFER, p_depth_has_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, p_depth, 0);88}89}90}9192GLuint RenderSceneBuffersGLES3::_rt_get_cached_fbo(GLuint p_color, GLuint p_depth, GLsizei p_samples, uint32_t p_view_count) {93FBDEF new_fbo;9495#if defined(ANDROID_ENABLED) || defined(WEB_ENABLED)96// There shouldn't be more then 3 entries in this...97for (const FBDEF &cached_fbo : msaa3d.cached_fbos) {98if (cached_fbo.color == p_color && cached_fbo.depth == p_depth) {99return cached_fbo.fbo;100}101}102103new_fbo.color = p_color;104new_fbo.depth = p_depth;105106glGenFramebuffers(1, &new_fbo.fbo);107glBindFramebuffer(GL_FRAMEBUFFER, new_fbo.fbo);108109_rt_attach_textures(p_color, p_depth, p_samples, p_view_count, true);110111GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);112if (status != GL_FRAMEBUFFER_COMPLETE) {113WARN_PRINT("Could not create 3D MSAA framebuffer, status: " + GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status));114115glDeleteFramebuffers(1, &new_fbo.fbo);116117new_fbo.fbo = 0;118} else {119// cache it!120msaa3d.cached_fbos.push_back(new_fbo);121}122123glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);124#endif125126return new_fbo.fbo;127}128129void RenderSceneBuffersGLES3::configure(const RenderSceneBuffersConfiguration *p_config) {130GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();131GLES3::Config *config = GLES3::Config::get_singleton();132133free_render_buffer_data();134135internal_size = p_config->get_internal_size();136target_size = p_config->get_target_size();137scaling_3d_mode = p_config->get_scaling_3d_mode();138//fsr_sharpness = p_config->get_fsr_sharpness();139//texture_mipmap_bias = p_config->get_texture_mipmap_bias();140//anisotropic_filtering_level = p_config->get_anisotropic_filtering_level();141render_target = p_config->get_render_target();142msaa3d.mode = p_config->get_msaa_3d();143//screen_space_aa = p_config->get_screen_space_aa();144//use_debanding = p_config->get_use_debanding();145view_count = config->multiview_supported ? p_config->get_view_count() : 1;146147bool use_multiview = view_count > 1;148149// Get color format data from our render target so we match those150if (render_target.is_valid()) {151color_internal_format = texture_storage->render_target_get_color_internal_format(render_target);152color_format = texture_storage->render_target_get_color_format(render_target);153color_type = texture_storage->render_target_get_color_type(render_target);154color_format_size = texture_storage->render_target_get_color_format_size(render_target);155} else {156// reflection probe? or error?157color_internal_format = GL_RGBA8;158color_format = GL_RGBA;159color_type = GL_UNSIGNED_BYTE;160color_format_size = 4;161}162163// Check our scaling mode164if (scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF && internal_size.x == 0 && internal_size.y == 0) {165// Disable, no size set.166scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;167} else if (scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF && internal_size == target_size) {168// If size matches, we won't use scaling.169scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;170} else if (scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF && scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_BILINEAR) {171// We only support bilinear scaling atm.172WARN_PRINT_ONCE("GLES only supports bilinear scaling.");173scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_BILINEAR;174}175176// Check if we support MSAA.177if (msaa3d.mode != RS::VIEWPORT_MSAA_DISABLED && internal_size.x == 0 && internal_size.y == 0) {178// Disable, no size set.179msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;180} else if (!use_multiview && msaa3d.mode != RS::VIEWPORT_MSAA_DISABLED && !config->msaa_supported && !config->rt_msaa_supported) {181WARN_PRINT_ONCE("MSAA is not supported on this device.");182msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;183} else if (use_multiview && msaa3d.mode != RS::VIEWPORT_MSAA_DISABLED && !config->msaa_multiview_supported && !config->rt_msaa_multiview_supported) {184WARN_PRINT_ONCE("Multiview MSAA is not supported on this device.");185msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;186}187188// We don't create our buffers right away because post effects can be made active at any time and change our buffer configuration.189}190191void RenderSceneBuffersGLES3::_check_render_buffers() {192GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();193GLES3::Config *config = GLES3::Config::get_singleton();194195ERR_FAIL_COND(view_count == 0);196197bool use_internal_buffer = scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF || apply_color_adjustments_in_post;198GLenum depth_format = GL_DEPTH24_STENCIL8;199uint32_t depth_format_size = 4;200bool use_multiview = view_count > 1;201202if ((!use_internal_buffer || internal3d.color != 0) && (msaa3d.mode == RS::VIEWPORT_MSAA_DISABLED || msaa3d.color != 0)) {203// already setup!204return;205}206207if (use_internal_buffer && internal3d.color == 0) {208// Setup our internal buffer.209GLenum texture_target = use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;210211// Create our color buffer.212glGenTextures(1, &internal3d.color);213glBindTexture(texture_target, internal3d.color);214215if (use_multiview) {216glTexImage3D(texture_target, 0, color_internal_format, internal_size.x, internal_size.y, view_count, 0, color_format, color_type, nullptr);217} else {218glTexImage2D(texture_target, 0, color_internal_format, internal_size.x, internal_size.y, 0, color_format, color_type, nullptr);219}220221glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);222glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);223glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);224glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);225226GLES3::Utilities::get_singleton()->texture_allocated_data(internal3d.color, internal_size.x * internal_size.y * view_count * color_format_size, "3D color texture");227228// Create our depth buffer.229glGenTextures(1, &internal3d.depth);230glBindTexture(texture_target, internal3d.depth);231232if (use_multiview) {233glTexImage3D(texture_target, 0, depth_format, internal_size.x, internal_size.y, view_count, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);234} else {235glTexImage2D(texture_target, 0, depth_format, internal_size.x, internal_size.y, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);236}237238glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);239glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);240glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);241glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);242243GLES3::Utilities::get_singleton()->texture_allocated_data(internal3d.depth, internal_size.x * internal_size.y * view_count * depth_format_size, "3D depth texture");244245// Create our internal 3D FBO.246// Note that if MSAA is used and our rt_msaa_* extensions are available, this is only used for blitting and effects.247glGenFramebuffers(1, &internal3d.fbo);248glBindFramebuffer(GL_FRAMEBUFFER, internal3d.fbo);249250#ifndef IOS_ENABLED251if (use_multiview) {252glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, internal3d.color, 0, 0, view_count);253glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, internal3d.depth, 0, 0, view_count);254} else {255#else256{257#endif258glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, internal3d.color, 0);259glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, texture_target, internal3d.depth, 0);260}261262GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);263if (status != GL_FRAMEBUFFER_COMPLETE) {264_clear_intermediate_buffers();265WARN_PRINT("Could not create 3D internal buffers, status: " + texture_storage->get_framebuffer_error(status));266}267268glBindTexture(texture_target, 0);269glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);270}271272if (msaa3d.mode != RS::VIEWPORT_MSAA_DISABLED && msaa3d.color == 0) {273// Setup MSAA.274const GLsizei samples[] = { 1, 2, 4, 8 };275msaa3d.samples = samples[msaa3d.mode];276277// Constrain by limits of OpenGL driver.278if (msaa3d.samples > config->msaa_max_samples) {279msaa3d.samples = config->msaa_max_samples;280}281282if (!use_multiview && !config->rt_msaa_supported) {283// Render to texture extensions not supported? fall back to MSAA framebuffer through GL_EXT_framebuffer_multisample.284// Note, if 2D MSAA matches 3D MSAA and we're not scaling, it would be ideal if we reuse our 2D MSAA buffer here.285// We can't however because we don't trigger a change in configuration if 2D MSAA changes.286// We'll accept the overhead in this situation.287288msaa3d.needs_resolve = true;289msaa3d.check_fbo_cache = false;290291// Create our color buffer.292glGenRenderbuffers(1, &msaa3d.color);293glBindRenderbuffer(GL_RENDERBUFFER, msaa3d.color);294295glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa3d.samples, color_internal_format, internal_size.x, internal_size.y);296GLES3::Utilities::get_singleton()->render_buffer_allocated_data(msaa3d.color, internal_size.x * internal_size.y * view_count * 4 * msaa3d.samples, "MSAA 3D color render buffer");297298// Create our depth buffer.299glGenRenderbuffers(1, &msaa3d.depth);300glBindRenderbuffer(GL_RENDERBUFFER, msaa3d.depth);301302glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa3d.samples, depth_format, internal_size.x, internal_size.y);303GLES3::Utilities::get_singleton()->render_buffer_allocated_data(msaa3d.depth, internal_size.x * internal_size.y * view_count * depth_format_size * msaa3d.samples, "MSAA 3D depth render buffer");304305// Create our MSAA 3D FBO.306glGenFramebuffers(1, &msaa3d.fbo);307glBindFramebuffer(GL_FRAMEBUFFER, msaa3d.fbo);308309glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, msaa3d.color);310glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, msaa3d.depth);311312GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);313if (status != GL_FRAMEBUFFER_COMPLETE) {314_clear_msaa3d_buffers();315msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;316WARN_PRINT("Could not create 3D MSAA buffers, status: " + texture_storage->get_framebuffer_error(status));317}318319glBindRenderbuffer(GL_RENDERBUFFER, 0);320glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);321#if !defined(IOS_ENABLED) && !defined(WEB_ENABLED)322} else if (use_multiview && !config->rt_msaa_multiview_supported) {323// Render to texture extensions not supported? fall back to MSAA textures through GL_EXT_multiview_texture_multisample.324msaa3d.needs_resolve = true;325msaa3d.check_fbo_cache = false;326327// Create our color buffer.328glGenTextures(1, &msaa3d.color);329glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.color);330331#ifdef ANDROID_ENABLED332glTexStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.samples, color_internal_format, internal_size.x, internal_size.y, view_count, GL_TRUE);333#else334glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.samples, color_internal_format, internal_size.x, internal_size.y, view_count, GL_TRUE);335#endif336337GLES3::Utilities::get_singleton()->texture_allocated_data(msaa3d.color, internal_size.x * internal_size.y * view_count * color_format_size * msaa3d.samples, "MSAA 3D color texture");338339// Create our depth buffer.340glGenTextures(1, &msaa3d.depth);341glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.depth);342343#ifdef ANDROID_ENABLED344glTexStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.samples, depth_format, internal_size.x, internal_size.y, view_count, GL_TRUE);345#else346glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.samples, depth_format, internal_size.x, internal_size.y, view_count, GL_TRUE);347#endif348349GLES3::Utilities::get_singleton()->texture_allocated_data(msaa3d.depth, internal_size.x * internal_size.y * view_count * depth_format_size * msaa3d.samples, "MSAA 3D depth texture");350351// Create our MSAA 3D FBO.352glGenFramebuffers(1, &msaa3d.fbo);353glBindFramebuffer(GL_FRAMEBUFFER, msaa3d.fbo);354355glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, msaa3d.color, 0, 0, view_count);356glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, msaa3d.depth, 0, 0, view_count);357358GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);359if (status != GL_FRAMEBUFFER_COMPLETE) {360_clear_msaa3d_buffers();361msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;362WARN_PRINT("Could not create 3D MSAA buffers, status: " + texture_storage->get_framebuffer_error(status));363}364365glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0);366glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);367#endif368#if defined(ANDROID_ENABLED) || defined(WEB_ENABLED) // Only supported on OpenGLES!369} else if (!use_internal_buffer) {370// We are going to render directly into our render target textures,371// these can change from frame to frame as we cycle through swapchains,372// hence we'll use our FBO cache here.373msaa3d.needs_resolve = false;374msaa3d.check_fbo_cache = true;375} else if (use_internal_buffer) {376// We can combine MSAA and scaling/effects.377msaa3d.needs_resolve = false;378msaa3d.check_fbo_cache = false;379380// We render to our internal textures, MSAA is only done in tile memory only.381// On mobile this means MSAA never leaves tile memory = efficiency!382glGenFramebuffers(1, &msaa3d.fbo);383glBindFramebuffer(GL_FRAMEBUFFER, msaa3d.fbo);384385_rt_attach_textures(internal3d.color, internal3d.depth, msaa3d.samples, view_count, true);386387GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);388if (status != GL_FRAMEBUFFER_COMPLETE) {389_clear_msaa3d_buffers();390msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;391WARN_PRINT("Could not create 3D MSAA framebuffer, status: " + texture_storage->get_framebuffer_error(status));392}393394glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);395#endif396} else {397// HUH? how did we get here?398WARN_PRINT_ONCE("MSAA is not supported on this device.");399msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;400msaa3d.samples = 1;401msaa3d.check_fbo_cache = false;402}403} else {404msaa3d.samples = 1;405msaa3d.check_fbo_cache = false;406}407}408409void RenderSceneBuffersGLES3::configure_for_probe(Size2i p_size) {410internal_size = p_size;411target_size = p_size;412scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;413view_count = 1;414}415416void RenderSceneBuffersGLES3::_clear_msaa3d_buffers() {417for (const FBDEF &cached_fbo : msaa3d.cached_fbos) {418GLuint fbo = cached_fbo.fbo;419glDeleteFramebuffers(1, &fbo);420}421msaa3d.cached_fbos.clear();422423if (msaa3d.fbo) {424glDeleteFramebuffers(1, &msaa3d.fbo);425msaa3d.fbo = 0;426}427428if (msaa3d.color != 0) {429if (view_count == 1) {430GLES3::Utilities::get_singleton()->render_buffer_free_data(msaa3d.color);431} else {432GLES3::Utilities::get_singleton()->texture_free_data(msaa3d.color);433}434msaa3d.color = 0;435}436437if (msaa3d.depth != 0) {438if (view_count == 1) {439GLES3::Utilities::get_singleton()->render_buffer_free_data(msaa3d.depth);440} else {441GLES3::Utilities::get_singleton()->texture_free_data(msaa3d.depth);442}443msaa3d.depth = 0;444}445}446447void RenderSceneBuffersGLES3::_clear_intermediate_buffers() {448if (internal3d.fbo) {449glDeleteFramebuffers(1, &internal3d.fbo);450internal3d.fbo = 0;451}452453if (internal3d.color != 0) {454GLES3::Utilities::get_singleton()->texture_free_data(internal3d.color);455internal3d.color = 0;456}457458if (internal3d.depth != 0) {459GLES3::Utilities::get_singleton()->texture_free_data(internal3d.depth);460internal3d.depth = 0;461}462}463464void RenderSceneBuffersGLES3::check_backbuffer(bool p_need_color, bool p_need_depth) {465GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();466467// Setup our back buffer468469if (backbuffer3d.fbo == 0) {470glGenFramebuffers(1, &backbuffer3d.fbo);471}472473glBindFramebuffer(GL_FRAMEBUFFER, backbuffer3d.fbo);474475bool use_multiview = view_count > 1 && GLES3::Config::get_singleton()->multiview_supported;476GLenum texture_target = use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;477GLenum depth_format = GL_DEPTH24_STENCIL8;478uint32_t depth_format_size = 4;479480if (backbuffer3d.color == 0 && p_need_color) {481glGenTextures(1, &backbuffer3d.color);482glBindTexture(texture_target, backbuffer3d.color);483484if (use_multiview) {485glTexImage3D(texture_target, 0, color_internal_format, internal_size.x, internal_size.y, view_count, 0, color_format, color_type, nullptr);486} else {487glTexImage2D(texture_target, 0, color_internal_format, internal_size.x, internal_size.y, 0, color_format, color_type, nullptr);488}489490glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);491glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);492glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);493glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);494495GLES3::Utilities::get_singleton()->texture_allocated_data(backbuffer3d.color, internal_size.x * internal_size.y * view_count * color_format_size, "3D Back buffer color texture");496497#ifndef IOS_ENABLED498if (use_multiview) {499glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, backbuffer3d.color, 0, 0, view_count);500} else {501#else502{503#endif504glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, backbuffer3d.color, 0);505}506}507508if (backbuffer3d.depth == 0 && p_need_depth) {509glGenTextures(1, &backbuffer3d.depth);510glBindTexture(texture_target, backbuffer3d.depth);511512if (use_multiview) {513glTexImage3D(texture_target, 0, depth_format, internal_size.x, internal_size.y, view_count, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT, nullptr);514} else {515glTexImage2D(texture_target, 0, depth_format, internal_size.x, internal_size.y, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT, nullptr);516}517518glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);519glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);520glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);521glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);522523GLES3::Utilities::get_singleton()->texture_allocated_data(backbuffer3d.depth, internal_size.x * internal_size.y * view_count * depth_format_size, "3D back buffer depth texture");524525#ifndef IOS_ENABLED526if (use_multiview) {527glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, backbuffer3d.depth, 0, 0, view_count);528} else {529#else530{531#endif532glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, texture_target, backbuffer3d.depth, 0);533}534}535536GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);537if (status != GL_FRAMEBUFFER_COMPLETE) {538_clear_back_buffers();539WARN_PRINT("Could not create 3D back buffers, status: " + texture_storage->get_framebuffer_error(status));540}541542glBindTexture(texture_target, 0);543glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);544}545546void RenderSceneBuffersGLES3::_clear_back_buffers() {547if (backbuffer3d.fbo) {548glDeleteFramebuffers(1, &backbuffer3d.fbo);549backbuffer3d.fbo = 0;550}551552if (backbuffer3d.color != 0) {553GLES3::Utilities::get_singleton()->texture_free_data(backbuffer3d.color);554backbuffer3d.color = 0;555}556557if (backbuffer3d.depth != 0) {558GLES3::Utilities::get_singleton()->texture_free_data(backbuffer3d.depth);559backbuffer3d.depth = 0;560}561}562563void RenderSceneBuffersGLES3::set_apply_color_adjustments_in_post(bool p_apply_in_post) {564apply_color_adjustments_in_post = p_apply_in_post;565}566567void RenderSceneBuffersGLES3::check_glow_buffers() {568if (glow.levels[0].color != 0) {569// already have these setup..570return;571}572573GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();574Size2i level_size = internal_size;575for (int i = 0; i < 4; i++) {576level_size = Size2i(level_size.x >> 1, level_size.y >> 1).maxi(4);577578glow.levels[i].size = level_size;579580// Create our texture581glGenTextures(1, &glow.levels[i].color);582glActiveTexture(GL_TEXTURE0);583glBindTexture(GL_TEXTURE_2D, glow.levels[i].color);584585glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, level_size.x, level_size.y, 0, color_format, color_type, nullptr);586587glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);588glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);589glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);590glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);591592glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);593glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);594595GLES3::Utilities::get_singleton()->texture_allocated_data(glow.levels[i].color, level_size.x * level_size.y * color_format_size, String("Glow buffer ") + String::num_int64(i));596597// Create our FBO598glGenFramebuffers(1, &glow.levels[i].fbo);599glBindFramebuffer(GL_FRAMEBUFFER, glow.levels[i].fbo);600601glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glow.levels[i].color, 0);602603GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);604if (status != GL_FRAMEBUFFER_COMPLETE) {605WARN_PRINT("Could not create glow buffers, status: " + texture_storage->get_framebuffer_error(status));606_clear_glow_buffers();607break;608}609}610611glBindTexture(GL_TEXTURE_2D, 0);612glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);613}614615void RenderSceneBuffersGLES3::_clear_glow_buffers() {616for (int i = 0; i < 4; i++) {617if (glow.levels[i].fbo != 0) {618glDeleteFramebuffers(1, &glow.levels[i].fbo);619glow.levels[i].fbo = 0;620}621622if (glow.levels[i].color != 0) {623GLES3::Utilities::get_singleton()->texture_free_data(glow.levels[i].color);624glow.levels[i].color = 0;625}626}627}628629void RenderSceneBuffersGLES3::free_render_buffer_data() {630_clear_msaa3d_buffers();631_clear_intermediate_buffers();632_clear_back_buffers();633_clear_glow_buffers();634}635636GLuint RenderSceneBuffersGLES3::get_render_fbo() {637GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();638GLuint rt_fbo = 0;639640_check_render_buffers();641642if (msaa3d.check_fbo_cache) {643GLuint color = texture_storage->render_target_get_color(render_target);644GLuint depth = texture_storage->render_target_get_depth(render_target);645646rt_fbo = _rt_get_cached_fbo(color, depth, msaa3d.samples, view_count);647if (rt_fbo == 0) {648// Somehow couldn't obtain this? Just render without MSAA.649rt_fbo = texture_storage->render_target_get_fbo(render_target);650}651} else if (msaa3d.fbo != 0) {652// We have an MSAA fbo, render to our MSAA buffer653return msaa3d.fbo;654} else if (internal3d.fbo != 0) {655// We have an internal buffer, render to our internal buffer!656return internal3d.fbo;657} else {658rt_fbo = texture_storage->render_target_get_fbo(render_target);659}660661if (texture_storage->render_target_is_reattach_textures(render_target)) {662GLuint color = texture_storage->render_target_get_color(render_target);663GLuint depth = texture_storage->render_target_get_depth(render_target);664bool depth_has_stencil = texture_storage->render_target_get_depth_has_stencil(render_target);665666glBindFramebuffer(GL_FRAMEBUFFER, rt_fbo);667_rt_attach_textures(color, depth, msaa3d.samples, view_count, depth_has_stencil);668glBindFramebuffer(GL_FRAMEBUFFER, texture_storage->system_fbo);669}670671return rt_fbo;672}673674#endif // GLES3_ENABLED675676677