render_scene_buffers_gles3.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. /**************************************************************************/
  2. /* render_scene_buffers_gles3.cpp */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. #ifdef GLES3_ENABLED
  31. #include "render_scene_buffers_gles3.h"
  32. #include "config.h"
  33. #include "texture_storage.h"
  34. #include "utilities.h"
  35. #ifdef ANDROID_ENABLED
  36. #define glFramebufferTextureMultiviewOVR GLES3::Config::get_singleton()->eglFramebufferTextureMultiviewOVR
  37. #define glTexStorage3DMultisample GLES3::Config::get_singleton()->eglTexStorage3DMultisample
  38. #define glFramebufferTexture2DMultisampleEXT GLES3::Config::get_singleton()->eglFramebufferTexture2DMultisampleEXT
  39. #define glFramebufferTextureMultisampleMultiviewOVR GLES3::Config::get_singleton()->eglFramebufferTextureMultisampleMultiviewOVR
  40. #endif // ANDROID_ENABLED
  41. // Will only be defined if GLES 3.2 headers are included
  42. #ifndef GL_TEXTURE_2D_MULTISAMPLE_ARRAY
  43. #define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
  44. #endif
  45. RenderSceneBuffersGLES3::RenderSceneBuffersGLES3() {
  46. for (int i = 0; i < 4; i++) {
  47. glow.levels[i].color = 0;
  48. glow.levels[i].fbo = 0;
  49. }
  50. }
  51. RenderSceneBuffersGLES3::~RenderSceneBuffersGLES3() {
  52. free_render_buffer_data();
  53. }
  54. void RenderSceneBuffersGLES3::_rt_attach_textures(GLuint p_color, GLuint p_depth, GLsizei p_samples, uint32_t p_view_count, bool p_depth_has_stencil) {
  55. if (p_view_count > 1) {
  56. if (p_samples > 1) {
  57. #if defined(ANDROID_ENABLED) || defined(WEB_ENABLED)
  58. glFramebufferTextureMultisampleMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, p_color, 0, p_samples, 0, p_view_count);
  59. glFramebufferTextureMultisampleMultiviewOVR(GL_FRAMEBUFFER, p_depth_has_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT, p_depth, 0, p_samples, 0, p_view_count);
  60. #else
  61. ERR_PRINT_ONCE("Multiview MSAA isn't supported on this platform.");
  62. #endif
  63. } else {
  64. #ifndef IOS_ENABLED
  65. glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, p_color, 0, 0, p_view_count);
  66. glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, p_depth_has_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT, p_depth, 0, 0, p_view_count);
  67. #else
  68. ERR_PRINT_ONCE("Multiview isn't supported on this platform.");
  69. #endif
  70. }
  71. } else {
  72. if (p_samples > 1) {
  73. #ifdef ANDROID_ENABLED
  74. glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_color, 0, p_samples);
  75. glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, p_depth_has_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, p_depth, 0, p_samples);
  76. #else
  77. ERR_PRINT_ONCE("MSAA via EXT_multisampled_render_to_texture isn't supported on this platform.");
  78. #endif
  79. } else {
  80. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_color, 0);
  81. glFramebufferTexture2D(GL_FRAMEBUFFER, p_depth_has_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, p_depth, 0);
  82. }
  83. }
  84. }
  85. GLuint RenderSceneBuffersGLES3::_rt_get_cached_fbo(GLuint p_color, GLuint p_depth, GLsizei p_samples, uint32_t p_view_count) {
  86. FBDEF new_fbo;
  87. #if defined(ANDROID_ENABLED) || defined(WEB_ENABLED)
  88. // There shouldn't be more then 3 entries in this...
  89. for (const FBDEF &cached_fbo : msaa3d.cached_fbos) {
  90. if (cached_fbo.color == p_color && cached_fbo.depth == p_depth) {
  91. return cached_fbo.fbo;
  92. }
  93. }
  94. new_fbo.color = p_color;
  95. new_fbo.depth = p_depth;
  96. glGenFramebuffers(1, &new_fbo.fbo);
  97. glBindFramebuffer(GL_FRAMEBUFFER, new_fbo.fbo);
  98. _rt_attach_textures(p_color, p_depth, p_samples, p_view_count, true);
  99. GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  100. if (status != GL_FRAMEBUFFER_COMPLETE) {
  101. WARN_PRINT("Could not create 3D MSAA framebuffer, status: " + GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status));
  102. glDeleteFramebuffers(1, &new_fbo.fbo);
  103. new_fbo.fbo = 0;
  104. } else {
  105. // cache it!
  106. msaa3d.cached_fbos.push_back(new_fbo);
  107. }
  108. glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
  109. #endif
  110. return new_fbo.fbo;
  111. }
  112. void RenderSceneBuffersGLES3::configure(const RenderSceneBuffersConfiguration *p_config) {
  113. GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
  114. GLES3::Config *config = GLES3::Config::get_singleton();
  115. free_render_buffer_data();
  116. internal_size = p_config->get_internal_size();
  117. target_size = p_config->get_target_size();
  118. scaling_3d_mode = p_config->get_scaling_3d_mode();
  119. //fsr_sharpness = p_config->get_fsr_sharpness();
  120. //texture_mipmap_bias = p_config->get_texture_mipmap_bias();
  121. //anisotropic_filtering_level = p_config->get_anisotropic_filtering_level();
  122. render_target = p_config->get_render_target();
  123. msaa3d.mode = p_config->get_msaa_3d();
  124. //screen_space_aa = p_config->get_screen_space_aa();
  125. //use_debanding = p_config->get_use_debanding();
  126. view_count = config->multiview_supported ? p_config->get_view_count() : 1;
  127. bool use_multiview = view_count > 1;
  128. // Get color format data from our render target so we match those
  129. if (render_target.is_valid()) {
  130. color_internal_format = texture_storage->render_target_get_color_internal_format(render_target);
  131. color_format = texture_storage->render_target_get_color_format(render_target);
  132. color_type = texture_storage->render_target_get_color_type(render_target);
  133. color_format_size = texture_storage->render_target_get_color_format_size(render_target);
  134. } else {
  135. // reflection probe? or error?
  136. color_internal_format = GL_RGBA8;
  137. color_format = GL_RGBA;
  138. color_type = GL_UNSIGNED_BYTE;
  139. color_format_size = 4;
  140. }
  141. // Check our scaling mode
  142. if (scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF && internal_size.x == 0 && internal_size.y == 0) {
  143. // Disable, no size set.
  144. scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;
  145. } else if (scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF && internal_size == target_size) {
  146. // If size matches, we won't use scaling.
  147. scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;
  148. } else if (scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF && scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_BILINEAR) {
  149. // We only support bilinear scaling atm.
  150. WARN_PRINT_ONCE("GLES only supports bilinear scaling.");
  151. scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_BILINEAR;
  152. }
  153. // Check if we support MSAA.
  154. if (msaa3d.mode != RS::VIEWPORT_MSAA_DISABLED && internal_size.x == 0 && internal_size.y == 0) {
  155. // Disable, no size set.
  156. msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;
  157. } else if (!use_multiview && msaa3d.mode != RS::VIEWPORT_MSAA_DISABLED && !config->msaa_supported && !config->rt_msaa_supported) {
  158. WARN_PRINT_ONCE("MSAA is not supported on this device.");
  159. msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;
  160. } else if (use_multiview && msaa3d.mode != RS::VIEWPORT_MSAA_DISABLED && !config->msaa_multiview_supported && !config->rt_msaa_multiview_supported) {
  161. WARN_PRINT_ONCE("Multiview MSAA is not supported on this device.");
  162. msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;
  163. }
  164. // We don't create our buffers right away because post effects can be made active at any time and change our buffer configuration.
  165. }
  166. void RenderSceneBuffersGLES3::_check_render_buffers() {
  167. GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
  168. GLES3::Config *config = GLES3::Config::get_singleton();
  169. ERR_FAIL_COND(view_count == 0);
  170. bool use_internal_buffer = scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF || apply_color_adjustments_in_post;
  171. GLenum depth_format = GL_DEPTH24_STENCIL8;
  172. uint32_t depth_format_size = 4;
  173. bool use_multiview = view_count > 1;
  174. if ((!use_internal_buffer || internal3d.color != 0) && (msaa3d.mode == RS::VIEWPORT_MSAA_DISABLED || msaa3d.color != 0)) {
  175. // already setup!
  176. return;
  177. }
  178. if (use_internal_buffer && internal3d.color == 0) {
  179. // Setup our internal buffer.
  180. GLenum texture_target = use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
  181. // Create our color buffer.
  182. glGenTextures(1, &internal3d.color);
  183. glBindTexture(texture_target, internal3d.color);
  184. if (use_multiview) {
  185. glTexImage3D(texture_target, 0, color_internal_format, internal_size.x, internal_size.y, view_count, 0, color_format, color_type, nullptr);
  186. } else {
  187. glTexImage2D(texture_target, 0, color_internal_format, internal_size.x, internal_size.y, 0, color_format, color_type, nullptr);
  188. }
  189. glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  190. glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  191. glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  192. glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  193. GLES3::Utilities::get_singleton()->texture_allocated_data(internal3d.color, internal_size.x * internal_size.y * view_count * color_format_size, "3D color texture");
  194. // Create our depth buffer.
  195. glGenTextures(1, &internal3d.depth);
  196. glBindTexture(texture_target, internal3d.depth);
  197. if (use_multiview) {
  198. glTexImage3D(texture_target, 0, depth_format, internal_size.x, internal_size.y, view_count, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
  199. } else {
  200. glTexImage2D(texture_target, 0, depth_format, internal_size.x, internal_size.y, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
  201. }
  202. glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  203. glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  204. glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  205. glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  206. GLES3::Utilities::get_singleton()->texture_allocated_data(internal3d.depth, internal_size.x * internal_size.y * view_count * depth_format_size, "3D depth texture");
  207. // Create our internal 3D FBO.
  208. // Note that if MSAA is used and our rt_msaa_* extensions are available, this is only used for blitting and effects.
  209. glGenFramebuffers(1, &internal3d.fbo);
  210. glBindFramebuffer(GL_FRAMEBUFFER, internal3d.fbo);
  211. #ifndef IOS_ENABLED
  212. if (use_multiview) {
  213. glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, internal3d.color, 0, 0, view_count);
  214. glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, internal3d.depth, 0, 0, view_count);
  215. } else {
  216. #else
  217. {
  218. #endif
  219. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, internal3d.color, 0);
  220. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, texture_target, internal3d.depth, 0);
  221. }
  222. GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  223. if (status != GL_FRAMEBUFFER_COMPLETE) {
  224. _clear_intermediate_buffers();
  225. WARN_PRINT("Could not create 3D internal buffers, status: " + texture_storage->get_framebuffer_error(status));
  226. }
  227. glBindTexture(texture_target, 0);
  228. glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
  229. }
  230. if (msaa3d.mode != RS::VIEWPORT_MSAA_DISABLED && msaa3d.color == 0) {
  231. // Setup MSAA.
  232. const GLsizei samples[] = { 1, 2, 4, 8 };
  233. msaa3d.samples = samples[msaa3d.mode];
  234. // Constrain by limits of OpenGL driver.
  235. if (msaa3d.samples > config->msaa_max_samples) {
  236. msaa3d.samples = config->msaa_max_samples;
  237. }
  238. if (!use_multiview && !config->rt_msaa_supported) {
  239. // Render to texture extensions not supported? fall back to MSAA framebuffer through GL_EXT_framebuffer_multisample.
  240. // Note, if 2D MSAA matches 3D MSAA and we're not scaling, it would be ideal if we reuse our 2D MSAA buffer here.
  241. // We can't however because we don't trigger a change in configuration if 2D MSAA changes.
  242. // We'll accept the overhead in this situation.
  243. msaa3d.needs_resolve = true;
  244. msaa3d.check_fbo_cache = false;
  245. // Create our color buffer.
  246. glGenRenderbuffers(1, &msaa3d.color);
  247. glBindRenderbuffer(GL_RENDERBUFFER, msaa3d.color);
  248. glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa3d.samples, color_internal_format, internal_size.x, internal_size.y);
  249. GLES3::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");
  250. // Create our depth buffer.
  251. glGenRenderbuffers(1, &msaa3d.depth);
  252. glBindRenderbuffer(GL_RENDERBUFFER, msaa3d.depth);
  253. glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa3d.samples, depth_format, internal_size.x, internal_size.y);
  254. GLES3::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");
  255. // Create our MSAA 3D FBO.
  256. glGenFramebuffers(1, &msaa3d.fbo);
  257. glBindFramebuffer(GL_FRAMEBUFFER, msaa3d.fbo);
  258. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, msaa3d.color);
  259. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, msaa3d.depth);
  260. GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  261. if (status != GL_FRAMEBUFFER_COMPLETE) {
  262. _clear_msaa3d_buffers();
  263. msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;
  264. WARN_PRINT("Could not create 3D MSAA buffers, status: " + texture_storage->get_framebuffer_error(status));
  265. }
  266. glBindRenderbuffer(GL_RENDERBUFFER, 0);
  267. glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
  268. #if !defined(IOS_ENABLED) && !defined(WEB_ENABLED)
  269. } else if (use_multiview && !config->rt_msaa_multiview_supported) {
  270. // Render to texture extensions not supported? fall back to MSAA textures through GL_EXT_multiview_texture_multisample.
  271. msaa3d.needs_resolve = true;
  272. msaa3d.check_fbo_cache = false;
  273. // Create our color buffer.
  274. glGenTextures(1, &msaa3d.color);
  275. glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.color);
  276. #ifdef ANDROID_ENABLED
  277. glTexStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.samples, color_internal_format, internal_size.x, internal_size.y, view_count, GL_TRUE);
  278. #else
  279. glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.samples, color_internal_format, internal_size.x, internal_size.y, view_count, GL_TRUE);
  280. #endif
  281. GLES3::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");
  282. // Create our depth buffer.
  283. glGenTextures(1, &msaa3d.depth);
  284. glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.depth);
  285. #ifdef ANDROID_ENABLED
  286. glTexStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.samples, depth_format, internal_size.x, internal_size.y, view_count, GL_TRUE);
  287. #else
  288. glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.samples, depth_format, internal_size.x, internal_size.y, view_count, GL_TRUE);
  289. #endif
  290. GLES3::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");
  291. // Create our MSAA 3D FBO.
  292. glGenFramebuffers(1, &msaa3d.fbo);
  293. glBindFramebuffer(GL_FRAMEBUFFER, msaa3d.fbo);
  294. glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, msaa3d.color, 0, 0, view_count);
  295. glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, msaa3d.depth, 0, 0, view_count);
  296. GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  297. if (status != GL_FRAMEBUFFER_COMPLETE) {
  298. _clear_msaa3d_buffers();
  299. msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;
  300. WARN_PRINT("Could not create 3D MSAA buffers, status: " + texture_storage->get_framebuffer_error(status));
  301. }
  302. glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0);
  303. glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
  304. #endif
  305. #if defined(ANDROID_ENABLED) || defined(WEB_ENABLED) // Only supported on OpenGLES!
  306. } else if (!use_internal_buffer) {
  307. // We are going to render directly into our render target textures,
  308. // these can change from frame to frame as we cycle through swapchains,
  309. // hence we'll use our FBO cache here.
  310. msaa3d.needs_resolve = false;
  311. msaa3d.check_fbo_cache = true;
  312. } else if (use_internal_buffer) {
  313. // We can combine MSAA and scaling/effects.
  314. msaa3d.needs_resolve = false;
  315. msaa3d.check_fbo_cache = false;
  316. // We render to our internal textures, MSAA is only done in tile memory only.
  317. // On mobile this means MSAA never leaves tile memory = efficiency!
  318. glGenFramebuffers(1, &msaa3d.fbo);
  319. glBindFramebuffer(GL_FRAMEBUFFER, msaa3d.fbo);
  320. _rt_attach_textures(internal3d.color, internal3d.depth, msaa3d.samples, view_count, true);
  321. GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  322. if (status != GL_FRAMEBUFFER_COMPLETE) {
  323. _clear_msaa3d_buffers();
  324. msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;
  325. WARN_PRINT("Could not create 3D MSAA framebuffer, status: " + texture_storage->get_framebuffer_error(status));
  326. }
  327. glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
  328. #endif
  329. } else {
  330. // HUH? how did we get here?
  331. WARN_PRINT_ONCE("MSAA is not supported on this device.");
  332. msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;
  333. msaa3d.samples = 1;
  334. msaa3d.check_fbo_cache = false;
  335. }
  336. } else {
  337. msaa3d.samples = 1;
  338. msaa3d.check_fbo_cache = false;
  339. }
  340. }
  341. void RenderSceneBuffersGLES3::configure_for_probe(Size2i p_size) {
  342. internal_size = p_size;
  343. target_size = p_size;
  344. scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;
  345. view_count = 1;
  346. }
  347. void RenderSceneBuffersGLES3::_clear_msaa3d_buffers() {
  348. for (const FBDEF &cached_fbo : msaa3d.cached_fbos) {
  349. GLuint fbo = cached_fbo.fbo;
  350. glDeleteFramebuffers(1, &fbo);
  351. }
  352. msaa3d.cached_fbos.clear();
  353. if (msaa3d.fbo) {
  354. glDeleteFramebuffers(1, &msaa3d.fbo);
  355. msaa3d.fbo = 0;
  356. }
  357. if (msaa3d.color != 0) {
  358. if (view_count == 1) {
  359. GLES3::Utilities::get_singleton()->render_buffer_free_data(msaa3d.color);
  360. } else {
  361. GLES3::Utilities::get_singleton()->texture_free_data(msaa3d.color);
  362. }
  363. msaa3d.color = 0;
  364. }
  365. if (msaa3d.depth != 0) {
  366. if (view_count == 1) {
  367. GLES3::Utilities::get_singleton()->render_buffer_free_data(msaa3d.depth);
  368. } else {
  369. GLES3::Utilities::get_singleton()->texture_free_data(msaa3d.depth);
  370. }
  371. msaa3d.depth = 0;
  372. }
  373. }
  374. void RenderSceneBuffersGLES3::_clear_intermediate_buffers() {
  375. if (internal3d.fbo) {
  376. glDeleteFramebuffers(1, &internal3d.fbo);
  377. internal3d.fbo = 0;
  378. }
  379. if (internal3d.color != 0) {
  380. GLES3::Utilities::get_singleton()->texture_free_data(internal3d.color);
  381. internal3d.color = 0;
  382. }
  383. if (internal3d.depth != 0) {
  384. GLES3::Utilities::get_singleton()->texture_free_data(internal3d.depth);
  385. internal3d.depth = 0;
  386. }
  387. }
  388. void RenderSceneBuffersGLES3::check_backbuffer(bool p_need_color, bool p_need_depth) {
  389. GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
  390. // Setup our back buffer
  391. if (backbuffer3d.fbo == 0) {
  392. glGenFramebuffers(1, &backbuffer3d.fbo);
  393. }
  394. glBindFramebuffer(GL_FRAMEBUFFER, backbuffer3d.fbo);
  395. bool use_multiview = view_count > 1 && GLES3::Config::get_singleton()->multiview_supported;
  396. GLenum texture_target = use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
  397. GLenum depth_format = GL_DEPTH24_STENCIL8;
  398. uint32_t depth_format_size = 4;
  399. if (backbuffer3d.color == 0 && p_need_color) {
  400. glGenTextures(1, &backbuffer3d.color);
  401. glBindTexture(texture_target, backbuffer3d.color);
  402. if (use_multiview) {
  403. glTexImage3D(texture_target, 0, color_internal_format, internal_size.x, internal_size.y, view_count, 0, color_format, color_type, nullptr);
  404. } else {
  405. glTexImage2D(texture_target, 0, color_internal_format, internal_size.x, internal_size.y, 0, color_format, color_type, nullptr);
  406. }
  407. glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  408. glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  409. glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  410. glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  411. GLES3::Utilities::get_singleton()->texture_allocated_data(backbuffer3d.color, internal_size.x * internal_size.y * view_count * color_format_size, "3D Back buffer color texture");
  412. #ifndef IOS_ENABLED
  413. if (use_multiview) {
  414. glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, backbuffer3d.color, 0, 0, view_count);
  415. } else {
  416. #else
  417. {
  418. #endif
  419. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, backbuffer3d.color, 0);
  420. }
  421. }
  422. if (backbuffer3d.depth == 0 && p_need_depth) {
  423. glGenTextures(1, &backbuffer3d.depth);
  424. glBindTexture(texture_target, backbuffer3d.depth);
  425. if (use_multiview) {
  426. glTexImage3D(texture_target, 0, depth_format, internal_size.x, internal_size.y, view_count, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT, nullptr);
  427. } else {
  428. glTexImage2D(texture_target, 0, depth_format, internal_size.x, internal_size.y, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT, nullptr);
  429. }
  430. glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  431. glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  432. glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  433. glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  434. GLES3::Utilities::get_singleton()->texture_allocated_data(backbuffer3d.depth, internal_size.x * internal_size.y * view_count * depth_format_size, "3D back buffer depth texture");
  435. #ifndef IOS_ENABLED
  436. if (use_multiview) {
  437. glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, backbuffer3d.depth, 0, 0, view_count);
  438. } else {
  439. #else
  440. {
  441. #endif
  442. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, texture_target, backbuffer3d.depth, 0);
  443. }
  444. }
  445. GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  446. if (status != GL_FRAMEBUFFER_COMPLETE) {
  447. _clear_back_buffers();
  448. WARN_PRINT("Could not create 3D back buffers, status: " + texture_storage->get_framebuffer_error(status));
  449. }
  450. glBindTexture(texture_target, 0);
  451. glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
  452. }
  453. void RenderSceneBuffersGLES3::_clear_back_buffers() {
  454. if (backbuffer3d.fbo) {
  455. glDeleteFramebuffers(1, &backbuffer3d.fbo);
  456. backbuffer3d.fbo = 0;
  457. }
  458. if (backbuffer3d.color != 0) {
  459. GLES3::Utilities::get_singleton()->texture_free_data(backbuffer3d.color);
  460. backbuffer3d.color = 0;
  461. }
  462. if (backbuffer3d.depth != 0) {
  463. GLES3::Utilities::get_singleton()->texture_free_data(backbuffer3d.depth);
  464. backbuffer3d.depth = 0;
  465. }
  466. }
  467. void RenderSceneBuffersGLES3::set_apply_color_adjustments_in_post(bool p_apply_in_post) {
  468. apply_color_adjustments_in_post = p_apply_in_post;
  469. }
  470. void RenderSceneBuffersGLES3::check_glow_buffers() {
  471. if (glow.levels[0].color != 0) {
  472. // already have these setup..
  473. return;
  474. }
  475. GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
  476. Size2i level_size = internal_size;
  477. for (int i = 0; i < 4; i++) {
  478. level_size = Size2i(level_size.x >> 1, level_size.y >> 1).maxi(4);
  479. glow.levels[i].size = level_size;
  480. // Create our texture
  481. glGenTextures(1, &glow.levels[i].color);
  482. glActiveTexture(GL_TEXTURE0);
  483. glBindTexture(GL_TEXTURE_2D, glow.levels[i].color);
  484. glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, level_size.x, level_size.y, 0, color_format, color_type, nullptr);
  485. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  486. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  487. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  488. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  489. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
  490. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
  491. GLES3::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));
  492. // Create our FBO
  493. glGenFramebuffers(1, &glow.levels[i].fbo);
  494. glBindFramebuffer(GL_FRAMEBUFFER, glow.levels[i].fbo);
  495. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glow.levels[i].color, 0);
  496. GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  497. if (status != GL_FRAMEBUFFER_COMPLETE) {
  498. WARN_PRINT("Could not create glow buffers, status: " + texture_storage->get_framebuffer_error(status));
  499. _clear_glow_buffers();
  500. break;
  501. }
  502. }
  503. glBindTexture(GL_TEXTURE_2D, 0);
  504. glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
  505. }
  506. void RenderSceneBuffersGLES3::_clear_glow_buffers() {
  507. for (int i = 0; i < 4; i++) {
  508. if (glow.levels[i].fbo != 0) {
  509. glDeleteFramebuffers(1, &glow.levels[i].fbo);
  510. glow.levels[i].fbo = 0;
  511. }
  512. if (glow.levels[i].color != 0) {
  513. GLES3::Utilities::get_singleton()->texture_free_data(glow.levels[i].color);
  514. glow.levels[i].color = 0;
  515. }
  516. }
  517. }
  518. void RenderSceneBuffersGLES3::free_render_buffer_data() {
  519. _clear_msaa3d_buffers();
  520. _clear_intermediate_buffers();
  521. _clear_back_buffers();
  522. _clear_glow_buffers();
  523. }
  524. GLuint RenderSceneBuffersGLES3::get_render_fbo() {
  525. GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
  526. GLuint rt_fbo = 0;
  527. _check_render_buffers();
  528. if (msaa3d.check_fbo_cache) {
  529. GLuint color = texture_storage->render_target_get_color(render_target);
  530. GLuint depth = texture_storage->render_target_get_depth(render_target);
  531. rt_fbo = _rt_get_cached_fbo(color, depth, msaa3d.samples, view_count);
  532. if (rt_fbo == 0) {
  533. // Somehow couldn't obtain this? Just render without MSAA.
  534. rt_fbo = texture_storage->render_target_get_fbo(render_target);
  535. }
  536. } else if (msaa3d.fbo != 0) {
  537. // We have an MSAA fbo, render to our MSAA buffer
  538. return msaa3d.fbo;
  539. } else if (internal3d.fbo != 0) {
  540. // We have an internal buffer, render to our internal buffer!
  541. return internal3d.fbo;
  542. } else {
  543. rt_fbo = texture_storage->render_target_get_fbo(render_target);
  544. }
  545. if (texture_storage->render_target_is_reattach_textures(render_target)) {
  546. GLuint color = texture_storage->render_target_get_color(render_target);
  547. GLuint depth = texture_storage->render_target_get_depth(render_target);
  548. bool depth_has_stencil = texture_storage->render_target_get_depth_has_stencil(render_target);
  549. glBindFramebuffer(GL_FRAMEBUFFER, rt_fbo);
  550. _rt_attach_textures(color, depth, msaa3d.samples, view_count, depth_has_stencil);
  551. glBindFramebuffer(GL_FRAMEBUFFER, texture_storage->system_fbo);
  552. }
  553. return rt_fbo;
  554. }
  555. #endif // GLES3_ENABLED