Path: blob/master/drivers/gles3/storage/render_scene_buffers_gles3.cpp
21520 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// Will only be defined if GLES 3.2 headers are included38#ifndef GL_TEXTURE_2D_MULTISAMPLE_ARRAY39#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x910240#endif4142RenderSceneBuffersGLES3::RenderSceneBuffersGLES3() {43for (int i = 0; i < 4; i++) {44glow.levels[i].color = 0;45glow.levels[i].fbo = 0;46}47}4849RenderSceneBuffersGLES3::~RenderSceneBuffersGLES3() {50free_render_buffer_data();51}5253void RenderSceneBuffersGLES3::_rt_attach_textures(GLuint p_color, GLuint p_depth, GLsizei p_samples, uint32_t p_view_count, bool p_depth_has_stencil) {54if (p_view_count > 1) {55if (p_samples > 1) {56#if defined(ANDROID_ENABLED) || defined(WEB_ENABLED)57glFramebufferTextureMultisampleMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, p_color, 0, p_samples, 0, p_view_count);58glFramebufferTextureMultisampleMultiviewOVR(GL_FRAMEBUFFER, p_depth_has_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT, p_depth, 0, p_samples, 0, p_view_count);59#else60ERR_PRINT_ONCE("Multiview MSAA isn't supported on this platform.");61#endif62} else {63#ifndef IOS_ENABLED64glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, p_color, 0, 0, p_view_count);65glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, p_depth_has_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT, p_depth, 0, 0, p_view_count);66#else67ERR_PRINT_ONCE("Multiview isn't supported on this platform.");68#endif69}70} else {71if (p_samples > 1) {72#ifdef ANDROID_ENABLED73glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_color, 0, p_samples);74glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, p_depth_has_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, p_depth, 0, p_samples);75#else76ERR_PRINT_ONCE("MSAA via EXT_multisampled_render_to_texture isn't supported on this platform.");77#endif78} else {79glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_color, 0);80glFramebufferTexture2D(GL_FRAMEBUFFER, p_depth_has_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, p_depth, 0);81}82}83}8485GLuint RenderSceneBuffersGLES3::_rt_get_cached_fbo(GLuint p_color, GLuint p_depth, GLsizei p_samples, uint32_t p_view_count) {86FBDEF new_fbo;8788#if defined(ANDROID_ENABLED) || defined(WEB_ENABLED)89// There shouldn't be more then 3 entries in this...90for (const FBDEF &cached_fbo : msaa3d.cached_fbos) {91if (cached_fbo.color == p_color && cached_fbo.depth == p_depth) {92return cached_fbo.fbo;93}94}9596new_fbo.color = p_color;97new_fbo.depth = p_depth;9899glGenFramebuffers(1, &new_fbo.fbo);100glBindFramebuffer(GL_FRAMEBUFFER, new_fbo.fbo);101102_rt_attach_textures(p_color, p_depth, p_samples, p_view_count, true);103104GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);105if (status != GL_FRAMEBUFFER_COMPLETE) {106WARN_PRINT("Could not create 3D MSAA framebuffer, status: " + GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status));107108glDeleteFramebuffers(1, &new_fbo.fbo);109110new_fbo.fbo = 0;111} else {112// cache it!113msaa3d.cached_fbos.push_back(new_fbo);114}115116glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);117#endif118119return new_fbo.fbo;120}121122void RenderSceneBuffersGLES3::configure(const RenderSceneBuffersConfiguration *p_config) {123GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();124GLES3::Config *config = GLES3::Config::get_singleton();125126free_render_buffer_data();127128internal_size = p_config->get_internal_size();129target_size = p_config->get_target_size();130scaling_3d_mode = p_config->get_scaling_3d_mode();131//fsr_sharpness = p_config->get_fsr_sharpness();132//texture_mipmap_bias = p_config->get_texture_mipmap_bias();133//anisotropic_filtering_level = p_config->get_anisotropic_filtering_level();134render_target = p_config->get_render_target();135msaa3d.mode = p_config->get_msaa_3d();136//screen_space_aa = p_config->get_screen_space_aa();137//use_debanding = p_config->get_use_debanding();138view_count = config->multiview_supported ? p_config->get_view_count() : 1;139140bool use_multiview = view_count > 1;141142// Get color format data from our render target so we match those143if (render_target.is_valid()) {144color_internal_format = texture_storage->render_target_get_color_internal_format(render_target);145color_format = texture_storage->render_target_get_color_format(render_target);146color_type = texture_storage->render_target_get_color_type(render_target);147color_format_size = texture_storage->render_target_get_color_format_size(render_target);148} else {149// reflection probe? or error?150color_internal_format = GL_RGBA8;151color_format = GL_RGBA;152color_type = GL_UNSIGNED_BYTE;153color_format_size = 4;154}155156// Check our scaling mode157if (scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF && internal_size.x == 0 && internal_size.y == 0) {158// Disable, no size set.159scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;160} else if (scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF && internal_size == target_size) {161// If size matches, we won't use scaling.162scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;163} else if (scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF && scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_BILINEAR) {164// We only support bilinear scaling atm.165WARN_PRINT_ONCE("GLES only supports bilinear scaling.");166scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_BILINEAR;167}168169// Check if we support MSAA.170if (msaa3d.mode != RS::VIEWPORT_MSAA_DISABLED && internal_size.x == 0 && internal_size.y == 0) {171// Disable, no size set.172msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;173} else if (!use_multiview && msaa3d.mode != RS::VIEWPORT_MSAA_DISABLED && !config->msaa_supported && !config->rt_msaa_supported) {174WARN_PRINT_ONCE("MSAA is not supported on this device.");175msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;176} else if (use_multiview && msaa3d.mode != RS::VIEWPORT_MSAA_DISABLED && !config->msaa_multiview_supported && !config->rt_msaa_multiview_supported) {177WARN_PRINT_ONCE("Multiview MSAA is not supported on this device.");178msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;179}180181// We don't create our buffers right away because post effects can be made active at any time and change our buffer configuration.182}183184void RenderSceneBuffersGLES3::_check_render_buffers() {185GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();186GLES3::Config *config = GLES3::Config::get_singleton();187188ERR_FAIL_COND(view_count == 0);189190bool use_internal_buffer = scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF || apply_color_adjustments_in_post;191GLenum depth_format = GL_DEPTH24_STENCIL8;192uint32_t depth_format_size = 4;193bool use_multiview = view_count > 1;194195if (!use_internal_buffer && internal3d.color != 0) {196_clear_intermediate_buffers();197}198199if ((!use_internal_buffer || internal3d.color != 0) && (msaa3d.mode == RS::VIEWPORT_MSAA_DISABLED || msaa3d.color != 0)) {200// already setup!201return;202}203204if (use_internal_buffer && internal3d.color == 0) {205// Setup our internal buffer.206GLenum texture_target = use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;207208// Create our color buffer.209glGenTextures(1, &internal3d.color);210glBindTexture(texture_target, internal3d.color);211212if (use_multiview) {213glTexImage3D(texture_target, 0, color_internal_format, internal_size.x, internal_size.y, view_count, 0, color_format, color_type, nullptr);214} else {215glTexImage2D(texture_target, 0, color_internal_format, internal_size.x, internal_size.y, 0, color_format, color_type, nullptr);216}217218glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);219glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);220glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);221glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);222223GLES3::Utilities::get_singleton()->texture_allocated_data(internal3d.color, internal_size.x * internal_size.y * view_count * color_format_size, "3D color texture");224225// Create our depth buffer.226glGenTextures(1, &internal3d.depth);227glBindTexture(texture_target, internal3d.depth);228229if (use_multiview) {230glTexImage3D(texture_target, 0, depth_format, internal_size.x, internal_size.y, view_count, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);231} else {232glTexImage2D(texture_target, 0, depth_format, internal_size.x, internal_size.y, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);233}234235glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);236glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);237glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);238glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);239240GLES3::Utilities::get_singleton()->texture_allocated_data(internal3d.depth, internal_size.x * internal_size.y * view_count * depth_format_size, "3D depth texture");241242// Create our internal 3D FBO.243// Note that if MSAA is used and our rt_msaa_* extensions are available, this is only used for blitting and effects.244glGenFramebuffers(1, &internal3d.fbo);245glBindFramebuffer(GL_FRAMEBUFFER, internal3d.fbo);246247#ifndef IOS_ENABLED248if (use_multiview) {249glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, internal3d.color, 0, 0, view_count);250glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, internal3d.depth, 0, 0, view_count);251} else {252#else253{254#endif255glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, internal3d.color, 0);256glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, texture_target, internal3d.depth, 0);257}258259GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);260if (status != GL_FRAMEBUFFER_COMPLETE) {261_clear_intermediate_buffers();262WARN_PRINT("Could not create 3D internal buffers, status: " + texture_storage->get_framebuffer_error(status));263}264265glBindTexture(texture_target, 0);266glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);267}268269if (msaa3d.mode != RS::VIEWPORT_MSAA_DISABLED && msaa3d.color == 0) {270// Setup MSAA.271const GLsizei samples[] = { 1, 2, 4, 8 };272msaa3d.samples = samples[msaa3d.mode];273274// Constrain by limits of OpenGL driver.275if (msaa3d.samples > config->msaa_max_samples) {276msaa3d.samples = config->msaa_max_samples;277}278279if (!use_multiview && !config->rt_msaa_supported) {280// Render to texture extensions not supported? fall back to MSAA framebuffer through GL_EXT_framebuffer_multisample.281// Note, if 2D MSAA matches 3D MSAA and we're not scaling, it would be ideal if we reuse our 2D MSAA buffer here.282// We can't however because we don't trigger a change in configuration if 2D MSAA changes.283// We'll accept the overhead in this situation.284285msaa3d.needs_resolve = true;286msaa3d.check_fbo_cache = false;287288// Create our color buffer.289glGenRenderbuffers(1, &msaa3d.color);290glBindRenderbuffer(GL_RENDERBUFFER, msaa3d.color);291292glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa3d.samples, color_internal_format, internal_size.x, internal_size.y);293GLES3::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");294295// Create our depth buffer.296glGenRenderbuffers(1, &msaa3d.depth);297glBindRenderbuffer(GL_RENDERBUFFER, msaa3d.depth);298299glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa3d.samples, depth_format, internal_size.x, internal_size.y);300GLES3::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");301302// Create our MSAA 3D FBO.303glGenFramebuffers(1, &msaa3d.fbo);304glBindFramebuffer(GL_FRAMEBUFFER, msaa3d.fbo);305306glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, msaa3d.color);307glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, msaa3d.depth);308309GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);310if (status != GL_FRAMEBUFFER_COMPLETE) {311_clear_msaa3d_buffers();312msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;313WARN_PRINT("Could not create 3D MSAA buffers, status: " + texture_storage->get_framebuffer_error(status));314}315316glBindRenderbuffer(GL_RENDERBUFFER, 0);317glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);318#if !defined(IOS_ENABLED) && !defined(WEB_ENABLED)319} else if (use_multiview && !config->rt_msaa_multiview_supported) {320// Render to texture extensions not supported? fall back to MSAA textures through GL_EXT_multiview_texture_multisample.321msaa3d.needs_resolve = true;322msaa3d.check_fbo_cache = false;323324// Create our color buffer.325glGenTextures(1, &msaa3d.color);326glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.color);327328#ifdef ANDROID_ENABLED329glTexStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.samples, color_internal_format, internal_size.x, internal_size.y, view_count, GL_TRUE);330#else331glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.samples, color_internal_format, internal_size.x, internal_size.y, view_count, GL_TRUE);332#endif333334GLES3::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");335336// Create our depth buffer.337glGenTextures(1, &msaa3d.depth);338glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.depth);339340#ifdef ANDROID_ENABLED341glTexStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.samples, depth_format, internal_size.x, internal_size.y, view_count, GL_TRUE);342#else343glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.samples, depth_format, internal_size.x, internal_size.y, view_count, GL_TRUE);344#endif345346GLES3::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");347348// Create our MSAA 3D FBO.349glGenFramebuffers(1, &msaa3d.fbo);350glBindFramebuffer(GL_FRAMEBUFFER, msaa3d.fbo);351352glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, msaa3d.color, 0, 0, view_count);353glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, msaa3d.depth, 0, 0, view_count);354355GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);356if (status != GL_FRAMEBUFFER_COMPLETE) {357_clear_msaa3d_buffers();358msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;359WARN_PRINT("Could not create 3D MSAA buffers, status: " + texture_storage->get_framebuffer_error(status));360}361362glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0);363glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);364#endif365#if defined(ANDROID_ENABLED) || defined(WEB_ENABLED) // Only supported on OpenGLES!366} else if (!use_internal_buffer) {367// We are going to render directly into our render target textures,368// these can change from frame to frame as we cycle through swapchains,369// hence we'll use our FBO cache here.370msaa3d.needs_resolve = false;371msaa3d.check_fbo_cache = true;372} else if (use_internal_buffer) {373// We can combine MSAA and scaling/effects.374msaa3d.needs_resolve = false;375msaa3d.check_fbo_cache = false;376377// We render to our internal textures, MSAA is only done in tile memory only.378// On mobile this means MSAA never leaves tile memory = efficiency!379glGenFramebuffers(1, &msaa3d.fbo);380glBindFramebuffer(GL_FRAMEBUFFER, msaa3d.fbo);381382_rt_attach_textures(internal3d.color, internal3d.depth, msaa3d.samples, view_count, true);383384GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);385if (status != GL_FRAMEBUFFER_COMPLETE) {386_clear_msaa3d_buffers();387msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;388WARN_PRINT("Could not create 3D MSAA framebuffer, status: " + texture_storage->get_framebuffer_error(status));389}390391glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);392#endif393} else {394// HUH? how did we get here?395WARN_PRINT_ONCE("MSAA is not supported on this device.");396msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;397msaa3d.samples = 1;398msaa3d.check_fbo_cache = false;399}400} else {401msaa3d.samples = 1;402msaa3d.check_fbo_cache = false;403}404}405406void RenderSceneBuffersGLES3::configure_for_probe(Size2i p_size) {407internal_size = p_size;408target_size = p_size;409scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;410view_count = 1;411}412413void RenderSceneBuffersGLES3::_clear_msaa3d_buffers() {414for (const FBDEF &cached_fbo : msaa3d.cached_fbos) {415GLuint fbo = cached_fbo.fbo;416glDeleteFramebuffers(1, &fbo);417}418msaa3d.cached_fbos.clear();419420if (msaa3d.fbo) {421glDeleteFramebuffers(1, &msaa3d.fbo);422msaa3d.fbo = 0;423}424425if (msaa3d.color != 0) {426if (view_count == 1) {427GLES3::Utilities::get_singleton()->render_buffer_free_data(msaa3d.color);428} else {429GLES3::Utilities::get_singleton()->texture_free_data(msaa3d.color);430}431msaa3d.color = 0;432}433434if (msaa3d.depth != 0) {435if (view_count == 1) {436GLES3::Utilities::get_singleton()->render_buffer_free_data(msaa3d.depth);437} else {438GLES3::Utilities::get_singleton()->texture_free_data(msaa3d.depth);439}440msaa3d.depth = 0;441}442}443444void RenderSceneBuffersGLES3::_clear_intermediate_buffers() {445if (internal3d.fbo) {446glDeleteFramebuffers(1, &internal3d.fbo);447internal3d.fbo = 0;448}449450if (internal3d.color != 0) {451GLES3::Utilities::get_singleton()->texture_free_data(internal3d.color);452internal3d.color = 0;453}454455if (internal3d.depth != 0) {456GLES3::Utilities::get_singleton()->texture_free_data(internal3d.depth);457internal3d.depth = 0;458}459}460461void RenderSceneBuffersGLES3::check_backbuffer(bool p_need_color, bool p_need_depth) {462GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();463464// Setup our back buffer465466if (backbuffer3d.fbo == 0) {467glGenFramebuffers(1, &backbuffer3d.fbo);468}469470glBindFramebuffer(GL_FRAMEBUFFER, backbuffer3d.fbo);471472bool use_multiview = view_count > 1 && GLES3::Config::get_singleton()->multiview_supported;473GLenum texture_target = use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;474GLenum depth_format = GL_DEPTH24_STENCIL8;475uint32_t depth_format_size = 4;476477if (backbuffer3d.color == 0 && p_need_color) {478glGenTextures(1, &backbuffer3d.color);479glBindTexture(texture_target, backbuffer3d.color);480481if (use_multiview) {482glTexImage3D(texture_target, 0, color_internal_format, internal_size.x, internal_size.y, view_count, 0, color_format, color_type, nullptr);483} else {484glTexImage2D(texture_target, 0, color_internal_format, internal_size.x, internal_size.y, 0, color_format, color_type, nullptr);485}486487glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);488glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);489glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);490glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);491492GLES3::Utilities::get_singleton()->texture_allocated_data(backbuffer3d.color, internal_size.x * internal_size.y * view_count * color_format_size, "3D Back buffer color texture");493494#ifndef IOS_ENABLED495if (use_multiview) {496glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, backbuffer3d.color, 0, 0, view_count);497} else {498#else499{500#endif501glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, backbuffer3d.color, 0);502}503}504505if (backbuffer3d.depth == 0 && p_need_depth) {506glGenTextures(1, &backbuffer3d.depth);507glBindTexture(texture_target, backbuffer3d.depth);508509if (use_multiview) {510glTexImage3D(texture_target, 0, depth_format, internal_size.x, internal_size.y, view_count, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);511} else {512glTexImage2D(texture_target, 0, depth_format, internal_size.x, internal_size.y, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);513}514515glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);516glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);517glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);518glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);519520GLES3::Utilities::get_singleton()->texture_allocated_data(backbuffer3d.depth, internal_size.x * internal_size.y * view_count * depth_format_size, "3D back buffer depth texture");521522#ifndef IOS_ENABLED523if (use_multiview) {524glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, backbuffer3d.depth, 0, 0, view_count);525} else {526#else527{528#endif529glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, texture_target, backbuffer3d.depth, 0);530}531}532533GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);534if (status != GL_FRAMEBUFFER_COMPLETE) {535_clear_back_buffers();536WARN_PRINT("Could not create 3D back buffers, status: " + texture_storage->get_framebuffer_error(status));537}538539glBindTexture(texture_target, 0);540glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);541}542543void RenderSceneBuffersGLES3::_clear_back_buffers() {544if (backbuffer3d.fbo) {545glDeleteFramebuffers(1, &backbuffer3d.fbo);546backbuffer3d.fbo = 0;547}548549if (backbuffer3d.color != 0) {550GLES3::Utilities::get_singleton()->texture_free_data(backbuffer3d.color);551backbuffer3d.color = 0;552}553554if (backbuffer3d.depth != 0) {555GLES3::Utilities::get_singleton()->texture_free_data(backbuffer3d.depth);556backbuffer3d.depth = 0;557}558}559560void RenderSceneBuffersGLES3::set_apply_color_adjustments_in_post(bool p_apply_in_post) {561apply_color_adjustments_in_post = p_apply_in_post;562}563564void RenderSceneBuffersGLES3::check_glow_buffers() {565if (glow.levels[0].color != 0) {566// already have these setup..567return;568}569570GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();571Size2i level_size = internal_size;572for (int i = 0; i < 4; i++) {573level_size = Size2i(level_size.x >> 1, level_size.y >> 1).maxi(4);574575glow.levels[i].size = level_size;576577// Create our texture578glGenTextures(1, &glow.levels[i].color);579glActiveTexture(GL_TEXTURE0);580glBindTexture(GL_TEXTURE_2D, glow.levels[i].color);581582glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, level_size.x, level_size.y, 0, color_format, color_type, nullptr);583584glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);585glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);586glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);587glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);588589glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);590glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);591592GLES3::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));593594// Create our FBO595glGenFramebuffers(1, &glow.levels[i].fbo);596glBindFramebuffer(GL_FRAMEBUFFER, glow.levels[i].fbo);597598glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glow.levels[i].color, 0);599600GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);601if (status != GL_FRAMEBUFFER_COMPLETE) {602WARN_PRINT("Could not create glow buffers, status: " + texture_storage->get_framebuffer_error(status));603_clear_glow_buffers();604break;605}606}607608glBindTexture(GL_TEXTURE_2D, 0);609glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);610}611612void RenderSceneBuffersGLES3::_clear_glow_buffers() {613for (int i = 0; i < 4; i++) {614if (glow.levels[i].fbo != 0) {615glDeleteFramebuffers(1, &glow.levels[i].fbo);616glow.levels[i].fbo = 0;617}618619if (glow.levels[i].color != 0) {620GLES3::Utilities::get_singleton()->texture_free_data(glow.levels[i].color);621glow.levels[i].color = 0;622}623}624}625626void RenderSceneBuffersGLES3::free_render_buffer_data() {627_clear_msaa3d_buffers();628_clear_intermediate_buffers();629_clear_back_buffers();630_clear_glow_buffers();631}632633GLuint RenderSceneBuffersGLES3::get_render_fbo() {634GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();635GLuint rt_fbo = 0;636637_check_render_buffers();638639if (msaa3d.check_fbo_cache) {640GLuint color = texture_storage->render_target_get_color(render_target);641GLuint depth = texture_storage->render_target_get_depth(render_target);642643rt_fbo = _rt_get_cached_fbo(color, depth, msaa3d.samples, view_count);644if (rt_fbo == 0) {645// Somehow couldn't obtain this? Just render without MSAA.646rt_fbo = texture_storage->render_target_get_fbo(render_target);647}648} else if (msaa3d.fbo != 0) {649// We have an MSAA fbo, render to our MSAA buffer650return msaa3d.fbo;651} else if (internal3d.fbo != 0) {652// We have an internal buffer, render to our internal buffer!653return internal3d.fbo;654} else {655rt_fbo = texture_storage->render_target_get_fbo(render_target);656}657658if (texture_storage->render_target_is_reattach_textures(render_target)) {659GLuint color = texture_storage->render_target_get_color(render_target);660GLuint depth = texture_storage->render_target_get_depth(render_target);661bool depth_has_stencil = texture_storage->render_target_get_depth_has_stencil(render_target);662663glBindFramebuffer(GL_FRAMEBUFFER, rt_fbo);664_rt_attach_textures(color, depth, msaa3d.samples, view_count, depth_has_stencil);665glBindFramebuffer(GL_FRAMEBUFFER, texture_storage->system_fbo);666}667668return rt_fbo;669}670671#endif // GLES3_ENABLED672673674