Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/drivers/gles3/storage/render_scene_buffers_gles3.cpp
21520 views
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
31
#ifdef GLES3_ENABLED
32
33
#include "render_scene_buffers_gles3.h"
34
#include "config.h"
35
#include "texture_storage.h"
36
#include "utilities.h"
37
38
// Will only be defined if GLES 3.2 headers are included
39
#ifndef GL_TEXTURE_2D_MULTISAMPLE_ARRAY
40
#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
41
#endif
42
43
RenderSceneBuffersGLES3::RenderSceneBuffersGLES3() {
44
for (int i = 0; i < 4; i++) {
45
glow.levels[i].color = 0;
46
glow.levels[i].fbo = 0;
47
}
48
}
49
50
RenderSceneBuffersGLES3::~RenderSceneBuffersGLES3() {
51
free_render_buffer_data();
52
}
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
86
GLuint RenderSceneBuffersGLES3::_rt_get_cached_fbo(GLuint p_color, GLuint p_depth, GLsizei p_samples, uint32_t p_view_count) {
87
FBDEF new_fbo;
88
89
#if defined(ANDROID_ENABLED) || defined(WEB_ENABLED)
90
// There shouldn't be more then 3 entries in this...
91
for (const FBDEF &cached_fbo : msaa3d.cached_fbos) {
92
if (cached_fbo.color == p_color && cached_fbo.depth == p_depth) {
93
return cached_fbo.fbo;
94
}
95
}
96
97
new_fbo.color = p_color;
98
new_fbo.depth = p_depth;
99
100
glGenFramebuffers(1, &new_fbo.fbo);
101
glBindFramebuffer(GL_FRAMEBUFFER, new_fbo.fbo);
102
103
_rt_attach_textures(p_color, p_depth, p_samples, p_view_count, true);
104
105
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
106
if (status != GL_FRAMEBUFFER_COMPLETE) {
107
WARN_PRINT("Could not create 3D MSAA framebuffer, status: " + GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status));
108
109
glDeleteFramebuffers(1, &new_fbo.fbo);
110
111
new_fbo.fbo = 0;
112
} else {
113
// cache it!
114
msaa3d.cached_fbos.push_back(new_fbo);
115
}
116
117
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
118
#endif
119
120
return new_fbo.fbo;
121
}
122
123
void RenderSceneBuffersGLES3::configure(const RenderSceneBuffersConfiguration *p_config) {
124
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
125
GLES3::Config *config = GLES3::Config::get_singleton();
126
127
free_render_buffer_data();
128
129
internal_size = p_config->get_internal_size();
130
target_size = p_config->get_target_size();
131
scaling_3d_mode = p_config->get_scaling_3d_mode();
132
//fsr_sharpness = p_config->get_fsr_sharpness();
133
//texture_mipmap_bias = p_config->get_texture_mipmap_bias();
134
//anisotropic_filtering_level = p_config->get_anisotropic_filtering_level();
135
render_target = p_config->get_render_target();
136
msaa3d.mode = p_config->get_msaa_3d();
137
//screen_space_aa = p_config->get_screen_space_aa();
138
//use_debanding = p_config->get_use_debanding();
139
view_count = config->multiview_supported ? p_config->get_view_count() : 1;
140
141
bool use_multiview = view_count > 1;
142
143
// Get color format data from our render target so we match those
144
if (render_target.is_valid()) {
145
color_internal_format = texture_storage->render_target_get_color_internal_format(render_target);
146
color_format = texture_storage->render_target_get_color_format(render_target);
147
color_type = texture_storage->render_target_get_color_type(render_target);
148
color_format_size = texture_storage->render_target_get_color_format_size(render_target);
149
} else {
150
// reflection probe? or error?
151
color_internal_format = GL_RGBA8;
152
color_format = GL_RGBA;
153
color_type = GL_UNSIGNED_BYTE;
154
color_format_size = 4;
155
}
156
157
// Check our scaling mode
158
if (scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF && internal_size.x == 0 && internal_size.y == 0) {
159
// Disable, no size set.
160
scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;
161
} else if (scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF && internal_size == target_size) {
162
// If size matches, we won't use scaling.
163
scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;
164
} else if (scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF && scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_BILINEAR) {
165
// We only support bilinear scaling atm.
166
WARN_PRINT_ONCE("GLES only supports bilinear scaling.");
167
scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_BILINEAR;
168
}
169
170
// Check if we support MSAA.
171
if (msaa3d.mode != RS::VIEWPORT_MSAA_DISABLED && internal_size.x == 0 && internal_size.y == 0) {
172
// Disable, no size set.
173
msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;
174
} else if (!use_multiview && msaa3d.mode != RS::VIEWPORT_MSAA_DISABLED && !config->msaa_supported && !config->rt_msaa_supported) {
175
WARN_PRINT_ONCE("MSAA is not supported on this device.");
176
msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;
177
} else if (use_multiview && msaa3d.mode != RS::VIEWPORT_MSAA_DISABLED && !config->msaa_multiview_supported && !config->rt_msaa_multiview_supported) {
178
WARN_PRINT_ONCE("Multiview MSAA is not supported on this device.");
179
msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;
180
}
181
182
// We don't create our buffers right away because post effects can be made active at any time and change our buffer configuration.
183
}
184
185
void RenderSceneBuffersGLES3::_check_render_buffers() {
186
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
187
GLES3::Config *config = GLES3::Config::get_singleton();
188
189
ERR_FAIL_COND(view_count == 0);
190
191
bool use_internal_buffer = scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF || apply_color_adjustments_in_post;
192
GLenum depth_format = GL_DEPTH24_STENCIL8;
193
uint32_t depth_format_size = 4;
194
bool use_multiview = view_count > 1;
195
196
if (!use_internal_buffer && internal3d.color != 0) {
197
_clear_intermediate_buffers();
198
}
199
200
if ((!use_internal_buffer || internal3d.color != 0) && (msaa3d.mode == RS::VIEWPORT_MSAA_DISABLED || msaa3d.color != 0)) {
201
// already setup!
202
return;
203
}
204
205
if (use_internal_buffer && internal3d.color == 0) {
206
// Setup our internal buffer.
207
GLenum texture_target = use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
208
209
// Create our color buffer.
210
glGenTextures(1, &internal3d.color);
211
glBindTexture(texture_target, internal3d.color);
212
213
if (use_multiview) {
214
glTexImage3D(texture_target, 0, color_internal_format, internal_size.x, internal_size.y, view_count, 0, color_format, color_type, nullptr);
215
} else {
216
glTexImage2D(texture_target, 0, color_internal_format, internal_size.x, internal_size.y, 0, color_format, color_type, nullptr);
217
}
218
219
glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
220
glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
221
glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
222
glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
223
224
GLES3::Utilities::get_singleton()->texture_allocated_data(internal3d.color, internal_size.x * internal_size.y * view_count * color_format_size, "3D color texture");
225
226
// Create our depth buffer.
227
glGenTextures(1, &internal3d.depth);
228
glBindTexture(texture_target, internal3d.depth);
229
230
if (use_multiview) {
231
glTexImage3D(texture_target, 0, depth_format, internal_size.x, internal_size.y, view_count, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
232
} else {
233
glTexImage2D(texture_target, 0, depth_format, internal_size.x, internal_size.y, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
234
}
235
236
glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
237
glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
238
glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
239
glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
240
241
GLES3::Utilities::get_singleton()->texture_allocated_data(internal3d.depth, internal_size.x * internal_size.y * view_count * depth_format_size, "3D depth texture");
242
243
// Create our internal 3D FBO.
244
// Note that if MSAA is used and our rt_msaa_* extensions are available, this is only used for blitting and effects.
245
glGenFramebuffers(1, &internal3d.fbo);
246
glBindFramebuffer(GL_FRAMEBUFFER, internal3d.fbo);
247
248
#ifndef IOS_ENABLED
249
if (use_multiview) {
250
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, internal3d.color, 0, 0, view_count);
251
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, internal3d.depth, 0, 0, view_count);
252
} else {
253
#else
254
{
255
#endif
256
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, internal3d.color, 0);
257
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, texture_target, internal3d.depth, 0);
258
}
259
260
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
261
if (status != GL_FRAMEBUFFER_COMPLETE) {
262
_clear_intermediate_buffers();
263
WARN_PRINT("Could not create 3D internal buffers, status: " + texture_storage->get_framebuffer_error(status));
264
}
265
266
glBindTexture(texture_target, 0);
267
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
268
}
269
270
if (msaa3d.mode != RS::VIEWPORT_MSAA_DISABLED && msaa3d.color == 0) {
271
// Setup MSAA.
272
const GLsizei samples[] = { 1, 2, 4, 8 };
273
msaa3d.samples = samples[msaa3d.mode];
274
275
// Constrain by limits of OpenGL driver.
276
if (msaa3d.samples > config->msaa_max_samples) {
277
msaa3d.samples = config->msaa_max_samples;
278
}
279
280
if (!use_multiview && !config->rt_msaa_supported) {
281
// Render to texture extensions not supported? fall back to MSAA framebuffer through GL_EXT_framebuffer_multisample.
282
// Note, if 2D MSAA matches 3D MSAA and we're not scaling, it would be ideal if we reuse our 2D MSAA buffer here.
283
// We can't however because we don't trigger a change in configuration if 2D MSAA changes.
284
// We'll accept the overhead in this situation.
285
286
msaa3d.needs_resolve = true;
287
msaa3d.check_fbo_cache = false;
288
289
// Create our color buffer.
290
glGenRenderbuffers(1, &msaa3d.color);
291
glBindRenderbuffer(GL_RENDERBUFFER, msaa3d.color);
292
293
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa3d.samples, color_internal_format, internal_size.x, internal_size.y);
294
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");
295
296
// Create our depth buffer.
297
glGenRenderbuffers(1, &msaa3d.depth);
298
glBindRenderbuffer(GL_RENDERBUFFER, msaa3d.depth);
299
300
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa3d.samples, depth_format, internal_size.x, internal_size.y);
301
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");
302
303
// Create our MSAA 3D FBO.
304
glGenFramebuffers(1, &msaa3d.fbo);
305
glBindFramebuffer(GL_FRAMEBUFFER, msaa3d.fbo);
306
307
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, msaa3d.color);
308
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, msaa3d.depth);
309
310
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
311
if (status != GL_FRAMEBUFFER_COMPLETE) {
312
_clear_msaa3d_buffers();
313
msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;
314
WARN_PRINT("Could not create 3D MSAA buffers, status: " + texture_storage->get_framebuffer_error(status));
315
}
316
317
glBindRenderbuffer(GL_RENDERBUFFER, 0);
318
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
319
#if !defined(IOS_ENABLED) && !defined(WEB_ENABLED)
320
} else if (use_multiview && !config->rt_msaa_multiview_supported) {
321
// Render to texture extensions not supported? fall back to MSAA textures through GL_EXT_multiview_texture_multisample.
322
msaa3d.needs_resolve = true;
323
msaa3d.check_fbo_cache = false;
324
325
// Create our color buffer.
326
glGenTextures(1, &msaa3d.color);
327
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.color);
328
329
#ifdef ANDROID_ENABLED
330
glTexStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.samples, color_internal_format, internal_size.x, internal_size.y, view_count, GL_TRUE);
331
#else
332
glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.samples, color_internal_format, internal_size.x, internal_size.y, view_count, GL_TRUE);
333
#endif
334
335
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");
336
337
// Create our depth buffer.
338
glGenTextures(1, &msaa3d.depth);
339
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.depth);
340
341
#ifdef ANDROID_ENABLED
342
glTexStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.samples, depth_format, internal_size.x, internal_size.y, view_count, GL_TRUE);
343
#else
344
glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, msaa3d.samples, depth_format, internal_size.x, internal_size.y, view_count, GL_TRUE);
345
#endif
346
347
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");
348
349
// Create our MSAA 3D FBO.
350
glGenFramebuffers(1, &msaa3d.fbo);
351
glBindFramebuffer(GL_FRAMEBUFFER, msaa3d.fbo);
352
353
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, msaa3d.color, 0, 0, view_count);
354
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, msaa3d.depth, 0, 0, view_count);
355
356
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
357
if (status != GL_FRAMEBUFFER_COMPLETE) {
358
_clear_msaa3d_buffers();
359
msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;
360
WARN_PRINT("Could not create 3D MSAA buffers, status: " + texture_storage->get_framebuffer_error(status));
361
}
362
363
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0);
364
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
365
#endif
366
#if defined(ANDROID_ENABLED) || defined(WEB_ENABLED) // Only supported on OpenGLES!
367
} else if (!use_internal_buffer) {
368
// We are going to render directly into our render target textures,
369
// these can change from frame to frame as we cycle through swapchains,
370
// hence we'll use our FBO cache here.
371
msaa3d.needs_resolve = false;
372
msaa3d.check_fbo_cache = true;
373
} else if (use_internal_buffer) {
374
// We can combine MSAA and scaling/effects.
375
msaa3d.needs_resolve = false;
376
msaa3d.check_fbo_cache = false;
377
378
// We render to our internal textures, MSAA is only done in tile memory only.
379
// On mobile this means MSAA never leaves tile memory = efficiency!
380
glGenFramebuffers(1, &msaa3d.fbo);
381
glBindFramebuffer(GL_FRAMEBUFFER, msaa3d.fbo);
382
383
_rt_attach_textures(internal3d.color, internal3d.depth, msaa3d.samples, view_count, true);
384
385
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
386
if (status != GL_FRAMEBUFFER_COMPLETE) {
387
_clear_msaa3d_buffers();
388
msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;
389
WARN_PRINT("Could not create 3D MSAA framebuffer, status: " + texture_storage->get_framebuffer_error(status));
390
}
391
392
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
393
#endif
394
} else {
395
// HUH? how did we get here?
396
WARN_PRINT_ONCE("MSAA is not supported on this device.");
397
msaa3d.mode = RS::VIEWPORT_MSAA_DISABLED;
398
msaa3d.samples = 1;
399
msaa3d.check_fbo_cache = false;
400
}
401
} else {
402
msaa3d.samples = 1;
403
msaa3d.check_fbo_cache = false;
404
}
405
}
406
407
void RenderSceneBuffersGLES3::configure_for_probe(Size2i p_size) {
408
internal_size = p_size;
409
target_size = p_size;
410
scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;
411
view_count = 1;
412
}
413
414
void RenderSceneBuffersGLES3::_clear_msaa3d_buffers() {
415
for (const FBDEF &cached_fbo : msaa3d.cached_fbos) {
416
GLuint fbo = cached_fbo.fbo;
417
glDeleteFramebuffers(1, &fbo);
418
}
419
msaa3d.cached_fbos.clear();
420
421
if (msaa3d.fbo) {
422
glDeleteFramebuffers(1, &msaa3d.fbo);
423
msaa3d.fbo = 0;
424
}
425
426
if (msaa3d.color != 0) {
427
if (view_count == 1) {
428
GLES3::Utilities::get_singleton()->render_buffer_free_data(msaa3d.color);
429
} else {
430
GLES3::Utilities::get_singleton()->texture_free_data(msaa3d.color);
431
}
432
msaa3d.color = 0;
433
}
434
435
if (msaa3d.depth != 0) {
436
if (view_count == 1) {
437
GLES3::Utilities::get_singleton()->render_buffer_free_data(msaa3d.depth);
438
} else {
439
GLES3::Utilities::get_singleton()->texture_free_data(msaa3d.depth);
440
}
441
msaa3d.depth = 0;
442
}
443
}
444
445
void RenderSceneBuffersGLES3::_clear_intermediate_buffers() {
446
if (internal3d.fbo) {
447
glDeleteFramebuffers(1, &internal3d.fbo);
448
internal3d.fbo = 0;
449
}
450
451
if (internal3d.color != 0) {
452
GLES3::Utilities::get_singleton()->texture_free_data(internal3d.color);
453
internal3d.color = 0;
454
}
455
456
if (internal3d.depth != 0) {
457
GLES3::Utilities::get_singleton()->texture_free_data(internal3d.depth);
458
internal3d.depth = 0;
459
}
460
}
461
462
void RenderSceneBuffersGLES3::check_backbuffer(bool p_need_color, bool p_need_depth) {
463
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
464
465
// Setup our back buffer
466
467
if (backbuffer3d.fbo == 0) {
468
glGenFramebuffers(1, &backbuffer3d.fbo);
469
}
470
471
glBindFramebuffer(GL_FRAMEBUFFER, backbuffer3d.fbo);
472
473
bool use_multiview = view_count > 1 && GLES3::Config::get_singleton()->multiview_supported;
474
GLenum texture_target = use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
475
GLenum depth_format = GL_DEPTH24_STENCIL8;
476
uint32_t depth_format_size = 4;
477
478
if (backbuffer3d.color == 0 && p_need_color) {
479
glGenTextures(1, &backbuffer3d.color);
480
glBindTexture(texture_target, backbuffer3d.color);
481
482
if (use_multiview) {
483
glTexImage3D(texture_target, 0, color_internal_format, internal_size.x, internal_size.y, view_count, 0, color_format, color_type, nullptr);
484
} else {
485
glTexImage2D(texture_target, 0, color_internal_format, internal_size.x, internal_size.y, 0, color_format, color_type, nullptr);
486
}
487
488
glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
489
glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
490
glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
491
glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
492
493
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");
494
495
#ifndef IOS_ENABLED
496
if (use_multiview) {
497
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, backbuffer3d.color, 0, 0, view_count);
498
} else {
499
#else
500
{
501
#endif
502
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, backbuffer3d.color, 0);
503
}
504
}
505
506
if (backbuffer3d.depth == 0 && p_need_depth) {
507
glGenTextures(1, &backbuffer3d.depth);
508
glBindTexture(texture_target, backbuffer3d.depth);
509
510
if (use_multiview) {
511
glTexImage3D(texture_target, 0, depth_format, internal_size.x, internal_size.y, view_count, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
512
} else {
513
glTexImage2D(texture_target, 0, depth_format, internal_size.x, internal_size.y, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
514
}
515
516
glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
517
glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
518
glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
519
glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
520
521
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");
522
523
#ifndef IOS_ENABLED
524
if (use_multiview) {
525
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, backbuffer3d.depth, 0, 0, view_count);
526
} else {
527
#else
528
{
529
#endif
530
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, texture_target, backbuffer3d.depth, 0);
531
}
532
}
533
534
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
535
if (status != GL_FRAMEBUFFER_COMPLETE) {
536
_clear_back_buffers();
537
WARN_PRINT("Could not create 3D back buffers, status: " + texture_storage->get_framebuffer_error(status));
538
}
539
540
glBindTexture(texture_target, 0);
541
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
542
}
543
544
void RenderSceneBuffersGLES3::_clear_back_buffers() {
545
if (backbuffer3d.fbo) {
546
glDeleteFramebuffers(1, &backbuffer3d.fbo);
547
backbuffer3d.fbo = 0;
548
}
549
550
if (backbuffer3d.color != 0) {
551
GLES3::Utilities::get_singleton()->texture_free_data(backbuffer3d.color);
552
backbuffer3d.color = 0;
553
}
554
555
if (backbuffer3d.depth != 0) {
556
GLES3::Utilities::get_singleton()->texture_free_data(backbuffer3d.depth);
557
backbuffer3d.depth = 0;
558
}
559
}
560
561
void RenderSceneBuffersGLES3::set_apply_color_adjustments_in_post(bool p_apply_in_post) {
562
apply_color_adjustments_in_post = p_apply_in_post;
563
}
564
565
void RenderSceneBuffersGLES3::check_glow_buffers() {
566
if (glow.levels[0].color != 0) {
567
// already have these setup..
568
return;
569
}
570
571
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
572
Size2i level_size = internal_size;
573
for (int i = 0; i < 4; i++) {
574
level_size = Size2i(level_size.x >> 1, level_size.y >> 1).maxi(4);
575
576
glow.levels[i].size = level_size;
577
578
// Create our texture
579
glGenTextures(1, &glow.levels[i].color);
580
glActiveTexture(GL_TEXTURE0);
581
glBindTexture(GL_TEXTURE_2D, glow.levels[i].color);
582
583
glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, level_size.x, level_size.y, 0, color_format, color_type, nullptr);
584
585
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
586
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
587
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
588
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
589
590
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
591
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
592
593
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));
594
595
// Create our FBO
596
glGenFramebuffers(1, &glow.levels[i].fbo);
597
glBindFramebuffer(GL_FRAMEBUFFER, glow.levels[i].fbo);
598
599
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glow.levels[i].color, 0);
600
601
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
602
if (status != GL_FRAMEBUFFER_COMPLETE) {
603
WARN_PRINT("Could not create glow buffers, status: " + texture_storage->get_framebuffer_error(status));
604
_clear_glow_buffers();
605
break;
606
}
607
}
608
609
glBindTexture(GL_TEXTURE_2D, 0);
610
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
611
}
612
613
void RenderSceneBuffersGLES3::_clear_glow_buffers() {
614
for (int i = 0; i < 4; i++) {
615
if (glow.levels[i].fbo != 0) {
616
glDeleteFramebuffers(1, &glow.levels[i].fbo);
617
glow.levels[i].fbo = 0;
618
}
619
620
if (glow.levels[i].color != 0) {
621
GLES3::Utilities::get_singleton()->texture_free_data(glow.levels[i].color);
622
glow.levels[i].color = 0;
623
}
624
}
625
}
626
627
void RenderSceneBuffersGLES3::free_render_buffer_data() {
628
_clear_msaa3d_buffers();
629
_clear_intermediate_buffers();
630
_clear_back_buffers();
631
_clear_glow_buffers();
632
}
633
634
GLuint RenderSceneBuffersGLES3::get_render_fbo() {
635
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
636
GLuint rt_fbo = 0;
637
638
_check_render_buffers();
639
640
if (msaa3d.check_fbo_cache) {
641
GLuint color = texture_storage->render_target_get_color(render_target);
642
GLuint depth = texture_storage->render_target_get_depth(render_target);
643
644
rt_fbo = _rt_get_cached_fbo(color, depth, msaa3d.samples, view_count);
645
if (rt_fbo == 0) {
646
// Somehow couldn't obtain this? Just render without MSAA.
647
rt_fbo = texture_storage->render_target_get_fbo(render_target);
648
}
649
} else if (msaa3d.fbo != 0) {
650
// We have an MSAA fbo, render to our MSAA buffer
651
return msaa3d.fbo;
652
} else if (internal3d.fbo != 0) {
653
// We have an internal buffer, render to our internal buffer!
654
return internal3d.fbo;
655
} else {
656
rt_fbo = texture_storage->render_target_get_fbo(render_target);
657
}
658
659
if (texture_storage->render_target_is_reattach_textures(render_target)) {
660
GLuint color = texture_storage->render_target_get_color(render_target);
661
GLuint depth = texture_storage->render_target_get_depth(render_target);
662
bool depth_has_stencil = texture_storage->render_target_get_depth_has_stencil(render_target);
663
664
glBindFramebuffer(GL_FRAMEBUFFER, rt_fbo);
665
_rt_attach_textures(color, depth, msaa3d.samples, view_count, depth_has_stencil);
666
glBindFramebuffer(GL_FRAMEBUFFER, texture_storage->system_fbo);
667
}
668
669
return rt_fbo;
670
}
671
672
#endif // GLES3_ENABLED
673
674