1/**************************************************************************/
2/* texture_storage.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#include "texture_storage.h"
32
33#include "../effects/copy_effects.h"
34#include "../framebuffer_cache_rd.h"
35#include "material_storage.h"
36#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
37
38using namespace RendererRD;
39
40///////////////////////////////////////////////////////////////////////////
41// TextureStorage::CanvasTexture
42
43void TextureStorage::CanvasTexture::clear_sets() {
44 if (cleared_cache) {
45 return;
46 }
47 for (int i = 1; i < RS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) {
48 for (int j = 1; j < RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) {
49 for (int k = 0; k < 2; k++) {
50 if (RD::get_singleton()->uniform_set_is_valid(uniform_sets[i][j][k])) {
51 RD::get_singleton()->free(uniform_sets[i][j][k]);
52 uniform_sets[i][j][k] = RID();
53 }
54 }
55 }
56 }
57 cleared_cache = true;
58}
59
60TextureStorage::CanvasTexture::~CanvasTexture() {
61 clear_sets();
62}
63
64///////////////////////////////////////////////////////////////////////////
65// TextureStorage::Texture
66
67void TextureStorage::Texture::cleanup() {
68 if (RD::get_singleton()->texture_is_valid(rd_texture_srgb)) {
69 //erase this first, as it's a dependency of the one below
70 RD::get_singleton()->free(rd_texture_srgb);
71 }
72 if (RD::get_singleton()->texture_is_valid(rd_texture)) {
73 RD::get_singleton()->free(rd_texture);
74 }
75 if (canvas_texture) {
76 memdelete(canvas_texture);
77 }
78}
79
80///////////////////////////////////////////////////////////////////////////
81// TextureStorage
82
83TextureStorage *TextureStorage::singleton = nullptr;
84
85TextureStorage *TextureStorage::get_singleton() {
86 return singleton;
87}
88
89TextureStorage::TextureStorage() {
90 singleton = this;
91
92 { //create default textures
93
94 RD::TextureFormat tformat;
95 tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
96 tformat.width = 4;
97 tformat.height = 4;
98 tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
99 tformat.texture_type = RD::TEXTURE_TYPE_2D;
100
101 Vector<uint8_t> pv;
102 pv.resize(16 * 4);
103 for (int i = 0; i < 16; i++) {
104 // Opaque white.
105 pv.set(i * 4 + 0, 255);
106 pv.set(i * 4 + 1, 255);
107 pv.set(i * 4 + 2, 255);
108 pv.set(i * 4 + 3, 255);
109 }
110
111 {
112 Vector<Vector<uint8_t>> vpv;
113 vpv.push_back(pv);
114 default_rd_textures[DEFAULT_RD_TEXTURE_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
115 }
116
117 for (int i = 0; i < 16; i++) {
118 // Opaque black.
119 pv.set(i * 4 + 0, 0);
120 pv.set(i * 4 + 1, 0);
121 pv.set(i * 4 + 2, 0);
122 pv.set(i * 4 + 3, 255);
123 }
124
125 {
126 Vector<Vector<uint8_t>> vpv;
127 vpv.push_back(pv);
128 default_rd_textures[DEFAULT_RD_TEXTURE_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
129 }
130
131 for (int i = 0; i < 16; i++) {
132 // Transparent black.
133 pv.set(i * 4 + 0, 0);
134 pv.set(i * 4 + 1, 0);
135 pv.set(i * 4 + 2, 0);
136 pv.set(i * 4 + 3, 0);
137 }
138
139 {
140 Vector<Vector<uint8_t>> vpv;
141 vpv.push_back(pv);
142 default_rd_textures[DEFAULT_RD_TEXTURE_TRANSPARENT] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
143 }
144
145 for (int i = 0; i < 16; i++) {
146 // Opaque normal map "flat" color.
147 pv.set(i * 4 + 0, 128);
148 pv.set(i * 4 + 1, 128);
149 pv.set(i * 4 + 2, 255);
150 pv.set(i * 4 + 3, 255);
151 }
152
153 {
154 Vector<Vector<uint8_t>> vpv;
155 vpv.push_back(pv);
156 default_rd_textures[DEFAULT_RD_TEXTURE_NORMAL] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
157 }
158
159 for (int i = 0; i < 16; i++) {
160 // Opaque flowmap "flat" color.
161 pv.set(i * 4 + 0, 255);
162 pv.set(i * 4 + 1, 128);
163 pv.set(i * 4 + 2, 255);
164 pv.set(i * 4 + 3, 255);
165 }
166
167 {
168 Vector<Vector<uint8_t>> vpv;
169 vpv.push_back(pv);
170 default_rd_textures[DEFAULT_RD_TEXTURE_ANISO] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
171 }
172
173 {
174 RD::TextureFormat tf;
175 tf.format = RD::DATA_FORMAT_D16_UNORM;
176 tf.width = 4;
177 tf.height = 4;
178 tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
179 tf.texture_type = RD::TEXTURE_TYPE_2D;
180
181 Vector<uint8_t> sv;
182 sv.resize(16 * 2);
183 uint16_t *ptr = (uint16_t *)sv.ptrw();
184 for (int i = 0; i < 16; i++) {
185 ptr[i] = Math::make_half_float(1.0f);
186 }
187
188 Vector<Vector<uint8_t>> vpv;
189 vpv.push_back(sv);
190 default_rd_textures[DEFAULT_RD_TEXTURE_DEPTH] = RD::get_singleton()->texture_create(tf, RD::TextureView(), vpv);
191 }
192
193 for (int i = 0; i < 16; i++) {
194 pv.set(i * 4 + 0, 0);
195 pv.set(i * 4 + 1, 0);
196 pv.set(i * 4 + 2, 0);
197 pv.set(i * 4 + 3, 0);
198 }
199
200 default_rd_textures[DEFAULT_RD_TEXTURE_MULTIMESH_BUFFER] = RD::get_singleton()->texture_buffer_create(16, RD::DATA_FORMAT_R8G8B8A8_UNORM, pv);
201
202 for (int i = 0; i < 16; i++) {
203 pv.set(i * 4 + 0, 0);
204 pv.set(i * 4 + 1, 0);
205 pv.set(i * 4 + 2, 0);
206 pv.set(i * 4 + 3, 0);
207 }
208
209 {
210 tformat.format = RD::DATA_FORMAT_R8G8B8A8_UINT;
211 Vector<Vector<uint8_t>> vpv;
212 vpv.push_back(pv);
213 default_rd_textures[DEFAULT_RD_TEXTURE_2D_UINT] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
214 }
215 }
216
217 { //create default black cubemap array
218
219 RD::TextureFormat tformat;
220 tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
221 tformat.width = 4;
222 tformat.height = 4;
223 tformat.array_layers = 6;
224 tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
225 tformat.texture_type = RD::TEXTURE_TYPE_CUBE_ARRAY;
226
227 Vector<uint8_t> pv;
228 pv.resize(16 * 4);
229 for (int i = 0; i < 16; i++) {
230 pv.set(i * 4 + 0, 0);
231 pv.set(i * 4 + 1, 0);
232 pv.set(i * 4 + 2, 0);
233 pv.set(i * 4 + 3, 0);
234 }
235
236 {
237 Vector<Vector<uint8_t>> vpv;
238 for (int i = 0; i < 6; i++) {
239 vpv.push_back(pv);
240 }
241 default_rd_textures[DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
242 }
243 }
244
245 { //create default white cubemap array
246
247 RD::TextureFormat tformat;
248 tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
249 tformat.width = 4;
250 tformat.height = 4;
251 tformat.array_layers = 6;
252 tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
253 tformat.texture_type = RD::TEXTURE_TYPE_CUBE_ARRAY;
254
255 Vector<uint8_t> pv;
256 pv.resize(16 * 4);
257 for (int i = 0; i < 16; i++) {
258 pv.set(i * 4 + 0, 255);
259 pv.set(i * 4 + 1, 255);
260 pv.set(i * 4 + 2, 255);
261 pv.set(i * 4 + 3, 255);
262 }
263
264 {
265 Vector<Vector<uint8_t>> vpv;
266 for (int i = 0; i < 6; i++) {
267 vpv.push_back(pv);
268 }
269 default_rd_textures[DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
270 }
271 }
272
273 { //create default black cubemap
274
275 RD::TextureFormat tformat;
276 tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
277 tformat.width = 4;
278 tformat.height = 4;
279 tformat.array_layers = 6;
280 tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
281 tformat.texture_type = RD::TEXTURE_TYPE_CUBE;
282
283 Vector<uint8_t> pv;
284 pv.resize(16 * 4);
285 for (int i = 0; i < 16; i++) {
286 pv.set(i * 4 + 0, 0);
287 pv.set(i * 4 + 1, 0);
288 pv.set(i * 4 + 2, 0);
289 pv.set(i * 4 + 3, 0);
290 }
291
292 {
293 Vector<Vector<uint8_t>> vpv;
294 for (int i = 0; i < 6; i++) {
295 vpv.push_back(pv);
296 }
297 default_rd_textures[DEFAULT_RD_TEXTURE_CUBEMAP_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
298 }
299 }
300
301 { //create default white cubemap
302
303 RD::TextureFormat tformat;
304 tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
305 tformat.width = 4;
306 tformat.height = 4;
307 tformat.array_layers = 6;
308 tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
309 tformat.texture_type = RD::TEXTURE_TYPE_CUBE;
310
311 Vector<uint8_t> pv;
312 pv.resize(16 * 4);
313 for (int i = 0; i < 16; i++) {
314 pv.set(i * 4 + 0, 255);
315 pv.set(i * 4 + 1, 255);
316 pv.set(i * 4 + 2, 255);
317 pv.set(i * 4 + 3, 255);
318 }
319
320 {
321 Vector<Vector<uint8_t>> vpv;
322 for (int i = 0; i < 6; i++) {
323 vpv.push_back(pv);
324 }
325 default_rd_textures[DEFAULT_RD_TEXTURE_CUBEMAP_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
326 }
327 }
328
329 { //create default 3D
330
331 RD::TextureFormat tformat;
332 tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
333 tformat.width = 4;
334 tformat.height = 4;
335 tformat.depth = 4;
336 tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
337 tformat.texture_type = RD::TEXTURE_TYPE_3D;
338
339 Vector<uint8_t> pv;
340 pv.resize(64 * 4);
341 for (int i = 0; i < 64; i++) {
342 pv.set(i * 4 + 0, 0);
343 pv.set(i * 4 + 1, 0);
344 pv.set(i * 4 + 2, 0);
345 pv.set(i * 4 + 3, 0);
346 }
347
348 {
349 Vector<Vector<uint8_t>> vpv;
350 vpv.push_back(pv);
351 default_rd_textures[DEFAULT_RD_TEXTURE_3D_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
352 }
353 for (int i = 0; i < 64; i++) {
354 pv.set(i * 4 + 0, 255);
355 pv.set(i * 4 + 1, 255);
356 pv.set(i * 4 + 2, 255);
357 pv.set(i * 4 + 3, 255);
358 }
359
360 {
361 Vector<Vector<uint8_t>> vpv;
362 vpv.push_back(pv);
363 default_rd_textures[DEFAULT_RD_TEXTURE_3D_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
364 }
365 }
366
367 { //create default array white
368
369 RD::TextureFormat tformat;
370 tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
371 tformat.width = 4;
372 tformat.height = 4;
373 tformat.array_layers = 1;
374 tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
375 tformat.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
376
377 Vector<uint8_t> pv;
378 pv.resize(16 * 4);
379 for (int i = 0; i < 16; i++) {
380 pv.set(i * 4 + 0, 255);
381 pv.set(i * 4 + 1, 255);
382 pv.set(i * 4 + 2, 255);
383 pv.set(i * 4 + 3, 255);
384 }
385
386 {
387 Vector<Vector<uint8_t>> vpv;
388 vpv.push_back(pv);
389 default_rd_textures[DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
390 }
391 }
392
393 { //create default array black
394
395 RD::TextureFormat tformat;
396 tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
397 tformat.width = 4;
398 tformat.height = 4;
399 tformat.array_layers = 1;
400 tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
401 tformat.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
402
403 Vector<uint8_t> pv;
404 pv.resize(16 * 4);
405 for (int i = 0; i < 16; i++) {
406 pv.set(i * 4 + 0, 0);
407 pv.set(i * 4 + 1, 0);
408 pv.set(i * 4 + 2, 0);
409 pv.set(i * 4 + 3, 0);
410 }
411
412 {
413 Vector<Vector<uint8_t>> vpv;
414 vpv.push_back(pv);
415 default_rd_textures[DEFAULT_RD_TEXTURE_2D_ARRAY_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
416 }
417 }
418
419 { //create default array normal
420
421 RD::TextureFormat tformat;
422 tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
423 tformat.width = 4;
424 tformat.height = 4;
425 tformat.array_layers = 1;
426 tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
427 tformat.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
428
429 Vector<uint8_t> pv;
430 pv.resize(16 * 4);
431 for (int i = 0; i < 16; i++) {
432 pv.set(i * 4 + 0, 128);
433 pv.set(i * 4 + 1, 128);
434 pv.set(i * 4 + 2, 255);
435 pv.set(i * 4 + 3, 255);
436 }
437
438 {
439 Vector<Vector<uint8_t>> vpv;
440 vpv.push_back(pv);
441 default_rd_textures[DEFAULT_RD_TEXTURE_2D_ARRAY_NORMAL] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
442 }
443 }
444
445 { //create default array depth
446
447 RD::TextureFormat tformat;
448 tformat.format = RD::DATA_FORMAT_D16_UNORM;
449 tformat.width = 4;
450 tformat.height = 4;
451 tformat.array_layers = 1;
452 tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
453 tformat.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
454
455 Vector<uint8_t> sv;
456 sv.resize(16 * 2);
457 uint16_t *ptr = (uint16_t *)sv.ptrw();
458 for (int i = 0; i < 16; i++) {
459 ptr[i] = Math::make_half_float(1.0f);
460 }
461
462 {
463 Vector<Vector<uint8_t>> vsv;
464 vsv.push_back(sv);
465 default_rd_textures[DEFAULT_RD_TEXTURE_2D_ARRAY_DEPTH] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vsv);
466 }
467 }
468
469 { // default atlas texture
470 RD::TextureFormat tformat;
471 tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
472 tformat.width = 4;
473 tformat.height = 4;
474 tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
475 tformat.texture_type = RD::TEXTURE_TYPE_2D;
476
477 Vector<uint8_t> pv;
478 pv.resize(16 * 4);
479 for (int i = 0; i < 16; i++) {
480 pv.set(i * 4 + 0, 0);
481 pv.set(i * 4 + 1, 0);
482 pv.set(i * 4 + 2, 0);
483 pv.set(i * 4 + 3, 255);
484 }
485
486 {
487 Vector<Vector<uint8_t>> vpv;
488 vpv.push_back(pv);
489 decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
490 decal_atlas.texture_srgb = decal_atlas.texture;
491 }
492 }
493
494 { //create default VRS
495
496 RD::TextureFormat tformat;
497 tformat.format = RD::DATA_FORMAT_R8_UINT;
498 tformat.width = 4;
499 tformat.height = 4;
500 tformat.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_VRS_ATTACHMENT_BIT;
501 tformat.texture_type = RD::TEXTURE_TYPE_2D;
502 if (!RD::get_singleton()->has_feature(RD::SUPPORTS_ATTACHMENT_VRS)) {
503 tformat.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
504 }
505
506 Vector<uint8_t> pv;
507 pv.resize(4 * 4);
508 for (int i = 0; i < 4 * 4; i++) {
509 pv.set(i, 0);
510 }
511
512 {
513 Vector<Vector<uint8_t>> vpv;
514 vpv.push_back(pv);
515 default_rd_textures[DEFAULT_RD_TEXTURE_VRS] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
516 }
517 }
518
519 {
520 Vector<String> sdf_modes;
521 sdf_modes.push_back("\n#define MODE_LOAD\n");
522 sdf_modes.push_back("\n#define MODE_LOAD_SHRINK\n");
523 sdf_modes.push_back("\n#define MODE_PROCESS\n");
524 sdf_modes.push_back("\n#define MODE_PROCESS_OPTIMIZED\n");
525 sdf_modes.push_back("\n#define MODE_STORE\n");
526 sdf_modes.push_back("\n#define MODE_STORE_SHRINK\n");
527
528 rt_sdf.shader.initialize(sdf_modes);
529
530 rt_sdf.shader_version = rt_sdf.shader.version_create();
531
532 for (int i = 0; i < RenderTargetSDF::SHADER_MAX; i++) {
533 rt_sdf.pipelines[i] = RD::get_singleton()->compute_pipeline_create(rt_sdf.shader.version_get_shader(rt_sdf.shader_version, i));
534 }
535 }
536}
537
538TextureStorage::~TextureStorage() {
539 rt_sdf.shader.version_free(rt_sdf.shader_version);
540
541 free_decal_data();
542
543 if (decal_atlas.textures.size()) {
544 ERR_PRINT("Decal Atlas: " + itos(decal_atlas.textures.size()) + " textures were not removed from the atlas.");
545 }
546
547 if (decal_atlas.texture.is_valid()) {
548 RD::get_singleton()->free(decal_atlas.texture);
549 }
550
551 //def textures
552 for (int i = 0; i < DEFAULT_RD_TEXTURE_MAX; i++) {
553 if (default_rd_textures[i].is_valid()) {
554 RD::get_singleton()->free(default_rd_textures[i]);
555 }
556 }
557
558 singleton = nullptr;
559}
560
561bool TextureStorage::free(RID p_rid) {
562 if (owns_texture(p_rid)) {
563 texture_free(p_rid);
564 return true;
565 } else if (owns_canvas_texture(p_rid)) {
566 canvas_texture_free(p_rid);
567 return true;
568 } else if (owns_decal(p_rid)) {
569 decal_free(p_rid);
570 return true;
571 } else if (owns_decal_instance(p_rid)) {
572 decal_instance_free(p_rid);
573 return true;
574 } else if (owns_render_target(p_rid)) {
575 render_target_free(p_rid);
576 return true;
577 }
578
579 return false;
580}
581
582bool TextureStorage::can_create_resources_async() const {
583 return true;
584}
585
586/* Canvas Texture API */
587
588RID TextureStorage::canvas_texture_allocate() {
589 return canvas_texture_owner.allocate_rid();
590}
591
592void TextureStorage::canvas_texture_initialize(RID p_rid) {
593 canvas_texture_owner.initialize_rid(p_rid);
594}
595
596void TextureStorage::canvas_texture_free(RID p_rid) {
597 canvas_texture_owner.free(p_rid);
598}
599
600void TextureStorage::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
601 CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
602 ERR_FAIL_NULL(ct);
603
604 switch (p_channel) {
605 case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: {
606 ct->diffuse = p_texture;
607 } break;
608 case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: {
609 ct->normal_map = p_texture;
610 } break;
611 case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: {
612 ct->specular = p_texture;
613 } break;
614 }
615
616 ct->clear_sets();
617}
618
619void TextureStorage::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) {
620 CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
621 ERR_FAIL_NULL(ct);
622
623 ct->specular_color.r = p_specular_color.r;
624 ct->specular_color.g = p_specular_color.g;
625 ct->specular_color.b = p_specular_color.b;
626 ct->specular_color.a = p_shininess;
627 ct->clear_sets();
628}
629
630void TextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {
631 CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
632 ERR_FAIL_NULL(ct);
633
634 ct->texture_filter = p_filter;
635 ct->clear_sets();
636}
637
638void TextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
639 CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
640 ERR_FAIL_NULL(ct);
641
642 ct->texture_repeat = p_repeat;
643 ct->clear_sets();
644}
645
646bool TextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, bool p_use_srgb, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular, bool p_texture_is_data) {
647 MaterialStorage *material_storage = MaterialStorage::get_singleton();
648
649 CanvasTexture *ct = nullptr;
650 Texture *t = get_texture(p_texture);
651
652 // TODO once we have our texture storage split off we'll look into moving this code into canvas_texture
653
654 if (t) {
655 //regular texture
656 if (!t->canvas_texture) {
657 t->canvas_texture = memnew(CanvasTexture);
658 t->canvas_texture->diffuse = p_texture;
659 }
660
661 ct = t->canvas_texture;
662 if (t->render_target) {
663 t->render_target->was_used = true;
664 }
665 } else {
666 ct = canvas_texture_owner.get_or_null(p_texture);
667 }
668
669 if (!ct) {
670 return false; //invalid texture RID
671 }
672
673 RS::CanvasItemTextureFilter filter = ct->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT ? ct->texture_filter : p_base_filter;
674 ERR_FAIL_COND_V(filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, false);
675
676 RS::CanvasItemTextureRepeat repeat = ct->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT ? ct->texture_repeat : p_base_repeat;
677 ERR_FAIL_COND_V(repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, false);
678
679 RID uniform_set = ct->uniform_sets[filter][repeat][int(p_use_srgb)];
680 if (!RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
681 //create and update
682 Vector<RD::Uniform> uniforms;
683 { //diffuse
684 RD::Uniform u;
685 u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
686 u.binding = 0;
687
688 t = get_texture(ct->diffuse);
689 if (!t) {
690 u.append_id(texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE));
691 ct->size_cache = Size2i(1, 1);
692 } else {
693 u.append_id(t->rd_texture_srgb.is_valid() && p_use_srgb && !p_texture_is_data ? t->rd_texture_srgb : t->rd_texture);
694 ct->size_cache = Size2i(t->width_2d, t->height_2d);
695 if (t->render_target) {
696 t->render_target->was_used = true;
697 }
698 }
699 uniforms.push_back(u);
700 }
701 { //normal
702 RD::Uniform u;
703 u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
704 u.binding = 1;
705
706 t = get_texture(ct->normal_map);
707 if (!t) {
708 u.append_id(texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL));
709 ct->use_normal_cache = false;
710 } else {
711 u.append_id(t->rd_texture);
712 ct->use_normal_cache = true;
713 if (t->render_target) {
714 t->render_target->was_used = true;
715 }
716 }
717 uniforms.push_back(u);
718 }
719 { //specular
720 RD::Uniform u;
721 u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
722 u.binding = 2;
723
724 t = get_texture(ct->specular);
725 if (!t) {
726 u.append_id(texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE));
727 ct->use_specular_cache = false;
728 } else {
729 u.append_id(t->rd_texture);
730 ct->use_specular_cache = true;
731 if (t->render_target) {
732 t->render_target->was_used = true;
733 }
734 }
735 uniforms.push_back(u);
736 }
737 { //sampler
738 RD::Uniform u;
739 u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
740 u.binding = 3;
741 u.append_id(material_storage->sampler_rd_get_default(filter, repeat));
742 uniforms.push_back(u);
743 }
744
745 uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_base_shader, p_base_set);
746 ct->uniform_sets[filter][repeat][int(p_use_srgb)] = uniform_set;
747 ct->cleared_cache = false;
748 }
749
750 r_uniform_set = uniform_set;
751 r_size = ct->size_cache;
752 r_specular_shininess = ct->specular_color;
753 r_use_normal = ct->use_normal_cache;
754 r_use_specular = ct->use_specular_cache;
755
756 return true;
757}
758
759/* Texture API */
760
761RID TextureStorage::texture_allocate() {
762 return texture_owner.allocate_rid();
763}
764
765void TextureStorage::texture_free(RID p_texture) {
766 Texture *t = texture_owner.get_or_null(p_texture);
767 ERR_FAIL_COND(!t);
768 ERR_FAIL_COND(t->is_render_target);
769
770 t->cleanup();
771
772 if (t->is_proxy && t->proxy_to.is_valid()) {
773 Texture *proxy_to = texture_owner.get_or_null(t->proxy_to);
774 if (proxy_to) {
775 proxy_to->proxies.erase(p_texture);
776 }
777 }
778
779 decal_atlas_remove_texture(p_texture);
780
781 for (int i = 0; i < t->proxies.size(); i++) {
782 Texture *p = texture_owner.get_or_null(t->proxies[i]);
783 ERR_CONTINUE(!p);
784 p->proxy_to = RID();
785 p->rd_texture = RID();
786 p->rd_texture_srgb = RID();
787 }
788
789 texture_owner.free(p_texture);
790}
791
792void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) {
793 ERR_FAIL_COND(p_image.is_null());
794
795 TextureToRDFormat ret_format;
796 Ref<Image> image = _validate_texture_format(p_image, ret_format);
797
798 Texture texture;
799
800 texture.type = TextureStorage::TYPE_2D;
801
802 texture.width = p_image->get_width();
803 texture.height = p_image->get_height();
804 texture.layers = 1;
805 texture.mipmaps = p_image->get_mipmap_count() + 1;
806 texture.depth = 1;
807 texture.format = p_image->get_format();
808 texture.validated_format = image->get_format();
809
810 texture.rd_type = RD::TEXTURE_TYPE_2D;
811 texture.rd_format = ret_format.format;
812 texture.rd_format_srgb = ret_format.format_srgb;
813
814 RD::TextureFormat rd_format;
815 RD::TextureView rd_view;
816 { //attempt register
817 rd_format.format = texture.rd_format;
818 rd_format.width = texture.width;
819 rd_format.height = texture.height;
820 rd_format.depth = 1;
821 rd_format.array_layers = 1;
822 rd_format.mipmaps = texture.mipmaps;
823 rd_format.texture_type = texture.rd_type;
824 rd_format.samples = RD::TEXTURE_SAMPLES_1;
825 rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
826 if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
827 rd_format.shareable_formats.push_back(texture.rd_format);
828 rd_format.shareable_formats.push_back(texture.rd_format_srgb);
829 }
830 }
831 {
832 rd_view.swizzle_r = ret_format.swizzle_r;
833 rd_view.swizzle_g = ret_format.swizzle_g;
834 rd_view.swizzle_b = ret_format.swizzle_b;
835 rd_view.swizzle_a = ret_format.swizzle_a;
836 }
837 Vector<uint8_t> data = image->get_data(); //use image data
838 Vector<Vector<uint8_t>> data_slices;
839 data_slices.push_back(data);
840 texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices);
841 ERR_FAIL_COND(texture.rd_texture.is_null());
842 if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
843 rd_view.format_override = texture.rd_format_srgb;
844 texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture);
845 if (texture.rd_texture_srgb.is_null()) {
846 RD::get_singleton()->free(texture.rd_texture);
847 ERR_FAIL_COND(texture.rd_texture_srgb.is_null());
848 }
849 }
850
851 //used for 2D, overridable
852 texture.width_2d = texture.width;
853 texture.height_2d = texture.height;
854 texture.is_render_target = false;
855 texture.rd_view = rd_view;
856 texture.is_proxy = false;
857
858 texture_owner.initialize_rid(p_texture, texture);
859}
860
861void TextureStorage::texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) {
862 ERR_FAIL_COND(p_layers.size() == 0);
863
864 ERR_FAIL_COND(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6);
865 ERR_FAIL_COND(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY && (p_layers.size() < 6 || (p_layers.size() % 6) != 0));
866
867 TextureToRDFormat ret_format;
868 Vector<Ref<Image>> images;
869 {
870 int valid_width = 0;
871 int valid_height = 0;
872 bool valid_mipmaps = false;
873 Image::Format valid_format = Image::FORMAT_MAX;
874
875 for (int i = 0; i < p_layers.size(); i++) {
876 ERR_FAIL_COND(p_layers[i]->is_empty());
877
878 if (i == 0) {
879 valid_width = p_layers[i]->get_width();
880 valid_height = p_layers[i]->get_height();
881 valid_format = p_layers[i]->get_format();
882 valid_mipmaps = p_layers[i]->has_mipmaps();
883 } else {
884 ERR_FAIL_COND(p_layers[i]->get_width() != valid_width);
885 ERR_FAIL_COND(p_layers[i]->get_height() != valid_height);
886 ERR_FAIL_COND(p_layers[i]->get_format() != valid_format);
887 ERR_FAIL_COND(p_layers[i]->has_mipmaps() != valid_mipmaps);
888 }
889
890 images.push_back(_validate_texture_format(p_layers[i], ret_format));
891 }
892 }
893
894 Texture texture;
895
896 texture.type = TextureStorage::TYPE_LAYERED;
897 texture.layered_type = p_layered_type;
898
899 texture.width = p_layers[0]->get_width();
900 texture.height = p_layers[0]->get_height();
901 texture.layers = p_layers.size();
902 texture.mipmaps = p_layers[0]->get_mipmap_count() + 1;
903 texture.depth = 1;
904 texture.format = p_layers[0]->get_format();
905 texture.validated_format = images[0]->get_format();
906
907 switch (p_layered_type) {
908 case RS::TEXTURE_LAYERED_2D_ARRAY: {
909 texture.rd_type = RD::TEXTURE_TYPE_2D_ARRAY;
910 } break;
911 case RS::TEXTURE_LAYERED_CUBEMAP: {
912 texture.rd_type = RD::TEXTURE_TYPE_CUBE;
913 } break;
914 case RS::TEXTURE_LAYERED_CUBEMAP_ARRAY: {
915 texture.rd_type = RD::TEXTURE_TYPE_CUBE_ARRAY;
916 } break;
917 default:
918 ERR_FAIL(); // Shouldn't happen, silence warnings.
919 }
920
921 texture.rd_format = ret_format.format;
922 texture.rd_format_srgb = ret_format.format_srgb;
923
924 RD::TextureFormat rd_format;
925 RD::TextureView rd_view;
926 { //attempt register
927 rd_format.format = texture.rd_format;
928 rd_format.width = texture.width;
929 rd_format.height = texture.height;
930 rd_format.depth = 1;
931 rd_format.array_layers = texture.layers;
932 rd_format.mipmaps = texture.mipmaps;
933 rd_format.texture_type = texture.rd_type;
934 rd_format.samples = RD::TEXTURE_SAMPLES_1;
935 rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
936 if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
937 rd_format.shareable_formats.push_back(texture.rd_format);
938 rd_format.shareable_formats.push_back(texture.rd_format_srgb);
939 }
940 }
941 {
942 rd_view.swizzle_r = ret_format.swizzle_r;
943 rd_view.swizzle_g = ret_format.swizzle_g;
944 rd_view.swizzle_b = ret_format.swizzle_b;
945 rd_view.swizzle_a = ret_format.swizzle_a;
946 }
947 Vector<Vector<uint8_t>> data_slices;
948 for (int i = 0; i < images.size(); i++) {
949 Vector<uint8_t> data = images[i]->get_data(); //use image data
950 data_slices.push_back(data);
951 }
952 texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices);
953 ERR_FAIL_COND(texture.rd_texture.is_null());
954 if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
955 rd_view.format_override = texture.rd_format_srgb;
956 texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture);
957 if (texture.rd_texture_srgb.is_null()) {
958 RD::get_singleton()->free(texture.rd_texture);
959 ERR_FAIL_COND(texture.rd_texture_srgb.is_null());
960 }
961 }
962
963 //used for 2D, overridable
964 texture.width_2d = texture.width;
965 texture.height_2d = texture.height;
966 texture.is_render_target = false;
967 texture.rd_view = rd_view;
968 texture.is_proxy = false;
969
970 texture_owner.initialize_rid(p_texture, texture);
971}
972
973void TextureStorage::texture_3d_initialize(RID p_texture, Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) {
974 ERR_FAIL_COND(p_data.size() == 0);
975
976 Image::Image3DValidateError verr = Image::validate_3d_image(p_format, p_width, p_height, p_depth, p_mipmaps, p_data);
977 if (verr != Image::VALIDATE_3D_OK) {
978 ERR_FAIL_MSG(Image::get_3d_image_validation_error_text(verr));
979 }
980
981 TextureToRDFormat ret_format;
982 Image::Format validated_format = Image::FORMAT_MAX;
983 Vector<uint8_t> all_data;
984 uint32_t mipmap_count = 0;
985 Vector<Texture::BufferSlice3D> slices;
986 {
987 Vector<Ref<Image>> images;
988 uint32_t all_data_size = 0;
989 images.resize(p_data.size());
990 for (int i = 0; i < p_data.size(); i++) {
991 TextureToRDFormat f;
992 images.write[i] = _validate_texture_format(p_data[i], f);
993 if (i == 0) {
994 ret_format = f;
995 validated_format = images[0]->get_format();
996 }
997
998 all_data_size += images[i]->get_data().size();
999 }
1000
1001 all_data.resize(all_data_size); //consolidate all data here
1002 uint32_t offset = 0;
1003 Size2i prev_size;
1004 for (int i = 0; i < p_data.size(); i++) {
1005 uint32_t s = images[i]->get_data().size();
1006
1007 memcpy(&all_data.write[offset], images[i]->get_data().ptr(), s);
1008 {
1009 Texture::BufferSlice3D slice;
1010 slice.size.width = images[i]->get_width();
1011 slice.size.height = images[i]->get_height();
1012 slice.offset = offset;
1013 slice.buffer_size = s;
1014 slices.push_back(slice);
1015 }
1016 offset += s;
1017
1018 Size2i img_size(images[i]->get_width(), images[i]->get_height());
1019 if (img_size != prev_size) {
1020 mipmap_count++;
1021 }
1022 prev_size = img_size;
1023 }
1024 }
1025
1026 Texture texture;
1027
1028 texture.type = TextureStorage::TYPE_3D;
1029 texture.width = p_width;
1030 texture.height = p_height;
1031 texture.depth = p_depth;
1032 texture.mipmaps = mipmap_count;
1033 texture.format = p_data[0]->get_format();
1034 texture.validated_format = validated_format;
1035
1036 texture.buffer_size_3d = all_data.size();
1037 texture.buffer_slices_3d = slices;
1038
1039 texture.rd_type = RD::TEXTURE_TYPE_3D;
1040 texture.rd_format = ret_format.format;
1041 texture.rd_format_srgb = ret_format.format_srgb;
1042
1043 RD::TextureFormat rd_format;
1044 RD::TextureView rd_view;
1045 { //attempt register
1046 rd_format.format = texture.rd_format;
1047 rd_format.width = texture.width;
1048 rd_format.height = texture.height;
1049 rd_format.depth = texture.depth;
1050 rd_format.array_layers = 1;
1051 rd_format.mipmaps = texture.mipmaps;
1052 rd_format.texture_type = texture.rd_type;
1053 rd_format.samples = RD::TEXTURE_SAMPLES_1;
1054 rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
1055 if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
1056 rd_format.shareable_formats.push_back(texture.rd_format);
1057 rd_format.shareable_formats.push_back(texture.rd_format_srgb);
1058 }
1059 }
1060 {
1061 rd_view.swizzle_r = ret_format.swizzle_r;
1062 rd_view.swizzle_g = ret_format.swizzle_g;
1063 rd_view.swizzle_b = ret_format.swizzle_b;
1064 rd_view.swizzle_a = ret_format.swizzle_a;
1065 }
1066 Vector<Vector<uint8_t>> data_slices;
1067 data_slices.push_back(all_data); //one slice
1068
1069 texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices);
1070 ERR_FAIL_COND(texture.rd_texture.is_null());
1071 if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
1072 rd_view.format_override = texture.rd_format_srgb;
1073 texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture);
1074 if (texture.rd_texture_srgb.is_null()) {
1075 RD::get_singleton()->free(texture.rd_texture);
1076 ERR_FAIL_COND(texture.rd_texture_srgb.is_null());
1077 }
1078 }
1079
1080 //used for 2D, overridable
1081 texture.width_2d = texture.width;
1082 texture.height_2d = texture.height;
1083 texture.is_render_target = false;
1084 texture.rd_view = rd_view;
1085 texture.is_proxy = false;
1086
1087 texture_owner.initialize_rid(p_texture, texture);
1088}
1089
1090void TextureStorage::texture_proxy_initialize(RID p_texture, RID p_base) {
1091 Texture *tex = texture_owner.get_or_null(p_base);
1092 ERR_FAIL_COND(!tex);
1093 Texture proxy_tex = *tex;
1094
1095 proxy_tex.rd_view.format_override = tex->rd_format;
1096 proxy_tex.rd_texture = RD::get_singleton()->texture_create_shared(proxy_tex.rd_view, tex->rd_texture);
1097 if (proxy_tex.rd_texture_srgb.is_valid()) {
1098 proxy_tex.rd_view.format_override = tex->rd_format_srgb;
1099 proxy_tex.rd_texture_srgb = RD::get_singleton()->texture_create_shared(proxy_tex.rd_view, tex->rd_texture);
1100 }
1101 proxy_tex.proxy_to = p_base;
1102 proxy_tex.is_render_target = false;
1103 proxy_tex.is_proxy = true;
1104 proxy_tex.proxies.clear();
1105
1106 texture_owner.initialize_rid(p_texture, proxy_tex);
1107
1108 tex->proxies.push_back(p_texture);
1109}
1110
1111void TextureStorage::_texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate) {
1112 ERR_FAIL_COND(p_image.is_null() || p_image->is_empty());
1113
1114 Texture *tex = texture_owner.get_or_null(p_texture);
1115 ERR_FAIL_COND(!tex);
1116 ERR_FAIL_COND(tex->is_render_target);
1117 ERR_FAIL_COND(p_image->get_width() != tex->width || p_image->get_height() != tex->height);
1118 ERR_FAIL_COND(p_image->get_format() != tex->format);
1119
1120 if (tex->type == TextureStorage::TYPE_LAYERED) {
1121 ERR_FAIL_INDEX(p_layer, tex->layers);
1122 }
1123
1124#ifdef TOOLS_ENABLED
1125 tex->image_cache_2d.unref();
1126#endif
1127 TextureToRDFormat f;
1128 Ref<Image> validated = _validate_texture_format(p_image, f);
1129
1130 RD::get_singleton()->texture_update(tex->rd_texture, p_layer, validated->get_data());
1131}
1132
1133void TextureStorage::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) {
1134 _texture_2d_update(p_texture, p_image, p_layer, false);
1135}
1136
1137void TextureStorage::texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) {
1138 Texture *tex = texture_owner.get_or_null(p_texture);
1139 ERR_FAIL_COND(!tex);
1140 ERR_FAIL_COND(tex->type != TextureStorage::TYPE_3D);
1141
1142 Image::Image3DValidateError verr = Image::validate_3d_image(tex->format, tex->width, tex->height, tex->depth, tex->mipmaps > 1, p_data);
1143 if (verr != Image::VALIDATE_3D_OK) {
1144 ERR_FAIL_MSG(Image::get_3d_image_validation_error_text(verr));
1145 }
1146
1147 Vector<uint8_t> all_data;
1148 {
1149 Vector<Ref<Image>> images;
1150 uint32_t all_data_size = 0;
1151 images.resize(p_data.size());
1152 for (int i = 0; i < p_data.size(); i++) {
1153 Ref<Image> image = p_data[i];
1154 if (image->get_format() != tex->validated_format) {
1155 image = image->duplicate();
1156 image->convert(tex->validated_format);
1157 }
1158 all_data_size += image->get_data().size();
1159 images.write[i] = image;
1160 }
1161
1162 all_data.resize(all_data_size); //consolidate all data here
1163 uint32_t offset = 0;
1164
1165 for (int i = 0; i < p_data.size(); i++) {
1166 uint32_t s = images[i]->get_data().size();
1167 memcpy(&all_data.write[offset], images[i]->get_data().ptr(), s);
1168 offset += s;
1169 }
1170 }
1171
1172 RD::get_singleton()->texture_update(tex->rd_texture, 0, all_data);
1173}
1174
1175void TextureStorage::texture_proxy_update(RID p_texture, RID p_proxy_to) {
1176 Texture *tex = texture_owner.get_or_null(p_texture);
1177 ERR_FAIL_COND(!tex);
1178 ERR_FAIL_COND(!tex->is_proxy);
1179 Texture *proxy_to = texture_owner.get_or_null(p_proxy_to);
1180 ERR_FAIL_COND(!proxy_to);
1181 ERR_FAIL_COND(proxy_to->is_proxy);
1182
1183 if (tex->proxy_to.is_valid()) {
1184 //unlink proxy
1185 if (RD::get_singleton()->texture_is_valid(tex->rd_texture)) {
1186 RD::get_singleton()->free(tex->rd_texture);
1187 tex->rd_texture = RID();
1188 }
1189 if (RD::get_singleton()->texture_is_valid(tex->rd_texture_srgb)) {
1190 RD::get_singleton()->free(tex->rd_texture_srgb);
1191 tex->rd_texture_srgb = RID();
1192 }
1193 Texture *prev_tex = texture_owner.get_or_null(tex->proxy_to);
1194 ERR_FAIL_COND(!prev_tex);
1195 prev_tex->proxies.erase(p_texture);
1196 }
1197
1198 // Copy canvas_texture so it doesn't leak.
1199 CanvasTexture *canvas_texture = tex->canvas_texture;
1200
1201 *tex = *proxy_to;
1202
1203 tex->proxy_to = p_proxy_to;
1204 tex->is_render_target = false;
1205 tex->is_proxy = true;
1206 tex->proxies.clear();
1207 proxy_to->proxies.push_back(p_texture);
1208 tex->canvas_texture = canvas_texture;
1209
1210 tex->rd_view.format_override = tex->rd_format;
1211 tex->rd_texture = RD::get_singleton()->texture_create_shared(tex->rd_view, proxy_to->rd_texture);
1212 if (tex->rd_texture_srgb.is_valid()) {
1213 tex->rd_view.format_override = tex->rd_format_srgb;
1214 tex->rd_texture_srgb = RD::get_singleton()->texture_create_shared(tex->rd_view, proxy_to->rd_texture);
1215 }
1216}
1217
1218//these two APIs can be used together or in combination with the others.
1219void TextureStorage::texture_2d_placeholder_initialize(RID p_texture) {
1220 //this could be better optimized to reuse an existing image , done this way
1221 //for now to get it working
1222 Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8);
1223 image->fill(Color(1, 0, 1, 1));
1224
1225 texture_2d_initialize(p_texture, image);
1226}
1227
1228void TextureStorage::texture_2d_layered_placeholder_initialize(RID p_texture, RS::TextureLayeredType p_layered_type) {
1229 //this could be better optimized to reuse an existing image , done this way
1230 //for now to get it working
1231 Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8);
1232 image->fill(Color(1, 0, 1, 1));
1233
1234 Vector<Ref<Image>> images;
1235 if (p_layered_type == RS::TEXTURE_LAYERED_2D_ARRAY) {
1236 images.push_back(image);
1237 } else {
1238 //cube
1239 for (int i = 0; i < 6; i++) {
1240 images.push_back(image);
1241 }
1242 }
1243
1244 texture_2d_layered_initialize(p_texture, images, p_layered_type);
1245}
1246
1247void TextureStorage::texture_3d_placeholder_initialize(RID p_texture) {
1248 //this could be better optimized to reuse an existing image , done this way
1249 //for now to get it working
1250 Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8);
1251 image->fill(Color(1, 0, 1, 1));
1252
1253 Vector<Ref<Image>> images;
1254 //cube
1255 for (int i = 0; i < 4; i++) {
1256 images.push_back(image);
1257 }
1258
1259 texture_3d_initialize(p_texture, Image::FORMAT_RGBA8, 4, 4, 4, false, images);
1260}
1261
1262Ref<Image> TextureStorage::texture_2d_get(RID p_texture) const {
1263 Texture *tex = texture_owner.get_or_null(p_texture);
1264 ERR_FAIL_COND_V(!tex, Ref<Image>());
1265
1266#ifdef TOOLS_ENABLED
1267 if (tex->image_cache_2d.is_valid() && !tex->is_render_target) {
1268 return tex->image_cache_2d;
1269 }
1270#endif
1271 Vector<uint8_t> data = RD::get_singleton()->texture_get_data(tex->rd_texture, 0);
1272 ERR_FAIL_COND_V(data.size() == 0, Ref<Image>());
1273 Ref<Image> image;
1274
1275 // Expand RGB10_A2 into RGBAH. This is needed for capturing viewport data
1276 // when using the mobile renderer with HDR mode on.
1277 if (tex->rd_format == RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32) {
1278 Vector<uint8_t> new_data;
1279 new_data.resize(data.size() * 2);
1280 uint16_t *ndp = (uint16_t *)new_data.ptr();
1281
1282 uint32_t *ptr = (uint32_t *)data.ptr();
1283 uint32_t num_pixels = data.size() / 4;
1284
1285 for (uint32_t ofs = 0; ofs < num_pixels; ofs++) {
1286 uint32_t px = ptr[ofs];
1287 uint32_t r = (px & 0x3FF);
1288 uint32_t g = ((px >> 10) & 0x3FF);
1289 uint32_t b = ((px >> 20) & 0x3FF);
1290 uint32_t a = ((px >> 30) & 0x3);
1291
1292 ndp[ofs * 4 + 0] = Math::make_half_float(float(r) / 1023.0);
1293 ndp[ofs * 4 + 1] = Math::make_half_float(float(g) / 1023.0);
1294 ndp[ofs * 4 + 2] = Math::make_half_float(float(b) / 1023.0);
1295 ndp[ofs * 4 + 3] = Math::make_half_float(float(a) / 3.0);
1296 }
1297 image = Image::create_from_data(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, new_data);
1298 } else {
1299 image = Image::create_from_data(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data);
1300 }
1301
1302 ERR_FAIL_COND_V(image->is_empty(), Ref<Image>());
1303 if (tex->format != tex->validated_format) {
1304 image->convert(tex->format);
1305 }
1306
1307#ifdef TOOLS_ENABLED
1308 if (Engine::get_singleton()->is_editor_hint() && !tex->is_render_target) {
1309 tex->image_cache_2d = image;
1310 }
1311#endif
1312
1313 return image;
1314}
1315
1316Ref<Image> TextureStorage::texture_2d_layer_get(RID p_texture, int p_layer) const {
1317 Texture *tex = texture_owner.get_or_null(p_texture);
1318 ERR_FAIL_COND_V(!tex, Ref<Image>());
1319
1320 Vector<uint8_t> data = RD::get_singleton()->texture_get_data(tex->rd_texture, p_layer);
1321 ERR_FAIL_COND_V(data.size() == 0, Ref<Image>());
1322 Ref<Image> image = Image::create_from_data(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data);
1323 ERR_FAIL_COND_V(image->is_empty(), Ref<Image>());
1324 if (tex->format != tex->validated_format) {
1325 image->convert(tex->format);
1326 }
1327
1328 return image;
1329}
1330
1331Vector<Ref<Image>> TextureStorage::texture_3d_get(RID p_texture) const {
1332 Texture *tex = texture_owner.get_or_null(p_texture);
1333 ERR_FAIL_COND_V(!tex, Vector<Ref<Image>>());
1334 ERR_FAIL_COND_V(tex->type != TextureStorage::TYPE_3D, Vector<Ref<Image>>());
1335
1336 Vector<uint8_t> all_data = RD::get_singleton()->texture_get_data(tex->rd_texture, 0);
1337
1338 ERR_FAIL_COND_V(all_data.size() != (int)tex->buffer_size_3d, Vector<Ref<Image>>());
1339
1340 Vector<Ref<Image>> ret;
1341
1342 for (int i = 0; i < tex->buffer_slices_3d.size(); i++) {
1343 const Texture::BufferSlice3D &bs = tex->buffer_slices_3d[i];
1344 ERR_FAIL_COND_V(bs.offset >= (uint32_t)all_data.size(), Vector<Ref<Image>>());
1345 ERR_FAIL_COND_V(bs.offset + bs.buffer_size > (uint32_t)all_data.size(), Vector<Ref<Image>>());
1346 Vector<uint8_t> sub_region = all_data.slice(bs.offset, bs.offset + bs.buffer_size);
1347
1348 Ref<Image> img = Image::create_from_data(bs.size.width, bs.size.height, false, tex->validated_format, sub_region);
1349 ERR_FAIL_COND_V(img->is_empty(), Vector<Ref<Image>>());
1350 if (tex->format != tex->validated_format) {
1351 img->convert(tex->format);
1352 }
1353
1354 ret.push_back(img);
1355 }
1356
1357 return ret;
1358}
1359
1360void TextureStorage::texture_replace(RID p_texture, RID p_by_texture) {
1361 Texture *tex = texture_owner.get_or_null(p_texture);
1362 ERR_FAIL_COND(!tex);
1363 ERR_FAIL_COND(tex->proxy_to.is_valid()); //can't replace proxy
1364 Texture *by_tex = texture_owner.get_or_null(p_by_texture);
1365 ERR_FAIL_COND(!by_tex);
1366 ERR_FAIL_COND(by_tex->proxy_to.is_valid()); //can't replace proxy
1367
1368 if (tex == by_tex) {
1369 return;
1370 }
1371
1372 if (tex->rd_texture_srgb.is_valid()) {
1373 RD::get_singleton()->free(tex->rd_texture_srgb);
1374 }
1375 RD::get_singleton()->free(tex->rd_texture);
1376
1377 if (tex->canvas_texture) {
1378 memdelete(tex->canvas_texture);
1379 tex->canvas_texture = nullptr;
1380 }
1381
1382 Vector<RID> proxies_to_update = tex->proxies;
1383 Vector<RID> proxies_to_redirect = by_tex->proxies;
1384
1385 *tex = *by_tex;
1386
1387 tex->proxies = proxies_to_update; //restore proxies, so they can be updated
1388
1389 if (tex->canvas_texture) {
1390 tex->canvas_texture->diffuse = p_texture; //update
1391 }
1392
1393 for (int i = 0; i < proxies_to_update.size(); i++) {
1394 texture_proxy_update(proxies_to_update[i], p_texture);
1395 }
1396 for (int i = 0; i < proxies_to_redirect.size(); i++) {
1397 texture_proxy_update(proxies_to_redirect[i], p_texture);
1398 }
1399 //delete last, so proxies can be updated
1400 texture_owner.free(p_by_texture);
1401
1402 decal_atlas_mark_dirty_on_texture(p_texture);
1403}
1404
1405void TextureStorage::texture_set_size_override(RID p_texture, int p_width, int p_height) {
1406 Texture *tex = texture_owner.get_or_null(p_texture);
1407 ERR_FAIL_COND(!tex);
1408 ERR_FAIL_COND(tex->type != TextureStorage::TYPE_2D);
1409
1410 tex->width_2d = p_width;
1411 tex->height_2d = p_height;
1412}
1413
1414void TextureStorage::texture_set_path(RID p_texture, const String &p_path) {
1415 Texture *tex = texture_owner.get_or_null(p_texture);
1416 ERR_FAIL_COND(!tex);
1417
1418 tex->path = p_path;
1419}
1420
1421String TextureStorage::texture_get_path(RID p_texture) const {
1422 Texture *tex = texture_owner.get_or_null(p_texture);
1423 ERR_FAIL_COND_V(!tex, String());
1424
1425 return tex->path;
1426}
1427
1428Image::Format TextureStorage::texture_get_format(RID p_texture) const {
1429 Texture *tex = texture_owner.get_or_null(p_texture);
1430 ERR_FAIL_COND_V(!tex, Image::FORMAT_MAX);
1431
1432 return tex->format;
1433}
1434
1435void TextureStorage::texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {
1436 Texture *tex = texture_owner.get_or_null(p_texture);
1437 ERR_FAIL_COND(!tex);
1438
1439 tex->detect_3d_callback_ud = p_userdata;
1440 tex->detect_3d_callback = p_callback;
1441}
1442
1443void TextureStorage::texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {
1444 Texture *tex = texture_owner.get_or_null(p_texture);
1445 ERR_FAIL_COND(!tex);
1446
1447 tex->detect_normal_callback_ud = p_userdata;
1448 tex->detect_normal_callback = p_callback;
1449}
1450
1451void TextureStorage::texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) {
1452 Texture *tex = texture_owner.get_or_null(p_texture);
1453 ERR_FAIL_COND(!tex);
1454
1455 tex->detect_roughness_callback_ud = p_userdata;
1456 tex->detect_roughness_callback = p_callback;
1457}
1458
1459void TextureStorage::texture_debug_usage(List<RS::TextureInfo> *r_info) {
1460}
1461
1462void TextureStorage::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) {
1463}
1464
1465Size2 TextureStorage::texture_size_with_proxy(RID p_proxy) {
1466 return texture_2d_get_size(p_proxy);
1467}
1468
1469void TextureStorage::texture_rd_initialize(RID p_texture, const RID &p_rd_texture, const RS::TextureLayeredType p_layer_type) {
1470 ERR_FAIL_COND(!RD::get_singleton()->texture_is_valid(p_rd_texture));
1471
1472 // TODO : investigate if we can support this, will need to be able to obtain the order and obtain the slice info
1473 ERR_FAIL_COND_MSG(RD::get_singleton()->texture_is_shared(p_rd_texture), "Please create the texture object using the original texture");
1474
1475 RD::TextureFormat tf = RD::get_singleton()->texture_get_format(p_rd_texture);
1476 ERR_FAIL_COND(!(tf.usage_bits & RD::TEXTURE_USAGE_SAMPLING_BIT));
1477
1478 TextureFromRDFormat imfmt;
1479 _texture_format_from_rd(tf.format, imfmt);
1480 ERR_FAIL_COND(imfmt.image_format == Image::FORMAT_MAX);
1481
1482 Texture texture;
1483
1484 switch (tf.texture_type) {
1485 case RD::TEXTURE_TYPE_2D: {
1486 ERR_FAIL_COND(tf.array_layers != 1);
1487 texture.type = TextureStorage::TYPE_2D;
1488 } break;
1489 case RD::TEXTURE_TYPE_2D_ARRAY: {
1490 // RenderingDevice doesn't distinguish between Array textures and Cube textures
1491 // this condition covers TextureArrays, TextureCube, and TextureCubeArray.
1492 ERR_FAIL_COND(tf.array_layers == 1);
1493 texture.type = TextureStorage::TYPE_LAYERED;
1494 texture.layered_type = p_layer_type;
1495 } break;
1496 case RD::TEXTURE_TYPE_3D: {
1497 ERR_FAIL_COND(tf.array_layers != 1);
1498 texture.type = TextureStorage::TYPE_3D;
1499 } break;
1500 default: {
1501 ERR_FAIL_MSG("This RD texture can't be used as a render texture");
1502 } break;
1503 }
1504
1505 texture.width = tf.width;
1506 texture.height = tf.height;
1507 texture.depth = tf.depth;
1508 texture.layers = tf.array_layers;
1509 texture.mipmaps = tf.mipmaps;
1510 texture.format = imfmt.image_format;
1511 texture.validated_format = texture.format; // ??
1512
1513 RD::TextureView rd_view;
1514 rd_view.format_override = imfmt.rd_format == tf.format ? RD::DATA_FORMAT_MAX : imfmt.rd_format;
1515 rd_view.swizzle_r = imfmt.swizzle_r;
1516 rd_view.swizzle_g = imfmt.swizzle_g;
1517 rd_view.swizzle_b = imfmt.swizzle_b;
1518 rd_view.swizzle_a = imfmt.swizzle_a;
1519
1520 texture.rd_type = tf.texture_type;
1521 texture.rd_view = rd_view;
1522 texture.rd_format = imfmt.rd_format;
1523 // We create a shared texture here even if our view matches, so we don't obtain ownership.
1524 texture.rd_texture = RD::get_singleton()->texture_create_shared(rd_view, p_rd_texture);
1525 if (imfmt.rd_format_srgb != RD::DATA_FORMAT_MAX) {
1526 rd_view.format_override = imfmt.rd_format_srgb == tf.format ? RD::DATA_FORMAT_MAX : imfmt.rd_format;
1527 texture.rd_format_srgb = imfmt.rd_format_srgb;
1528 // We create a shared texture here even if our view matches, so we don't obtain ownership.
1529 texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, p_rd_texture);
1530 }
1531
1532 // TODO figure out what to do with slices
1533
1534 texture.width_2d = texture.width;
1535 texture.height_2d = texture.height;
1536 texture.is_render_target = false;
1537 texture.is_proxy = false;
1538
1539 texture_owner.initialize_rid(p_texture, texture);
1540}
1541
1542RID TextureStorage::texture_get_rd_texture(RID p_texture, bool p_srgb) const {
1543 if (p_texture.is_null()) {
1544 return RID();
1545 }
1546
1547 Texture *tex = texture_owner.get_or_null(p_texture);
1548 if (!tex) {
1549 return RID();
1550 }
1551
1552 return (p_srgb && tex->rd_texture_srgb.is_valid()) ? tex->rd_texture_srgb : tex->rd_texture;
1553}
1554
1555uint64_t TextureStorage::texture_get_native_handle(RID p_texture, bool p_srgb) const {
1556 Texture *tex = texture_owner.get_or_null(p_texture);
1557 ERR_FAIL_COND_V(!tex, 0);
1558
1559 if (p_srgb && tex->rd_texture_srgb.is_valid()) {
1560 return RD::get_singleton()->texture_get_native_handle(tex->rd_texture_srgb);
1561 } else {
1562 return RD::get_singleton()->texture_get_native_handle(tex->rd_texture);
1563 }
1564}
1565
1566Ref<Image> TextureStorage::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) {
1567 Ref<Image> image = p_image->duplicate();
1568
1569 switch (p_image->get_format()) {
1570 case Image::FORMAT_L8: {
1571 r_format.format = RD::DATA_FORMAT_R8_UNORM;
1572 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1573 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_R;
1574 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_R;
1575 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1576 } break; //luminance
1577 case Image::FORMAT_LA8: {
1578 r_format.format = RD::DATA_FORMAT_R8G8_UNORM;
1579 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1580 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_R;
1581 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_R;
1582 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_G;
1583 } break; //luminance-alpha
1584 case Image::FORMAT_R8: {
1585 r_format.format = RD::DATA_FORMAT_R8_UNORM;
1586 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1587 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO;
1588 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
1589 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1590 } break;
1591 case Image::FORMAT_RG8: {
1592 r_format.format = RD::DATA_FORMAT_R8G8_UNORM;
1593 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1594 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1595 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
1596 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1597 } break;
1598 case Image::FORMAT_RGB8: {
1599 //this format is not mandatory for specification, check if supported first
1600 if (false && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R8G8B8_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT) && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R8G8B8_SRGB, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1601 r_format.format = RD::DATA_FORMAT_R8G8B8_UNORM;
1602 r_format.format_srgb = RD::DATA_FORMAT_R8G8B8_SRGB;
1603 } else {
1604 //not supported, reconvert
1605 r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
1606 r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
1607 image->convert(Image::FORMAT_RGBA8);
1608 }
1609 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1610 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1611 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
1612 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1613
1614 } break;
1615 case Image::FORMAT_RGBA8: {
1616 r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
1617 r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
1618 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1619 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1620 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
1621 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
1622 } break;
1623 case Image::FORMAT_RGBA4444: {
1624 r_format.format = RD::DATA_FORMAT_B4G4R4A4_UNORM_PACK16;
1625 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_B; //needs swizzle
1626 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1627 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_R;
1628 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
1629 } break;
1630 case Image::FORMAT_RGB565: {
1631 r_format.format = RD::DATA_FORMAT_B5G6R5_UNORM_PACK16;
1632 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_B;
1633 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1634 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_R;
1635 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
1636 } break;
1637 case Image::FORMAT_RF: {
1638 r_format.format = RD::DATA_FORMAT_R32_SFLOAT;
1639 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1640 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO;
1641 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
1642 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1643 } break; //float
1644 case Image::FORMAT_RGF: {
1645 r_format.format = RD::DATA_FORMAT_R32G32_SFLOAT;
1646 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1647 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1648 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
1649 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1650 } break;
1651 case Image::FORMAT_RGBF: {
1652 //this format is not mandatory for specification, check if supported first
1653 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R32G32B32_SFLOAT, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1654 r_format.format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
1655 } else {
1656 //not supported, reconvert
1657 r_format.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
1658 image->convert(Image::FORMAT_RGBAF);
1659 }
1660
1661 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1662 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1663 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
1664 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1665 } break;
1666 case Image::FORMAT_RGBAF: {
1667 r_format.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
1668 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1669 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1670 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
1671 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
1672
1673 } break;
1674 case Image::FORMAT_RH: {
1675 r_format.format = RD::DATA_FORMAT_R16_SFLOAT;
1676 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1677 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO;
1678 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
1679 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1680
1681 } break; //half float
1682 case Image::FORMAT_RGH: {
1683 r_format.format = RD::DATA_FORMAT_R16G16_SFLOAT;
1684 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1685 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1686 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
1687 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1688
1689 } break;
1690 case Image::FORMAT_RGBH: {
1691 //this format is not mandatory for specification, check if supported first
1692 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R16G16B16_SFLOAT, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1693 r_format.format = RD::DATA_FORMAT_R16G16B16_SFLOAT;
1694 } else {
1695 //not supported, reconvert
1696 r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
1697 image->convert(Image::FORMAT_RGBAH);
1698 }
1699
1700 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1701 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1702 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
1703 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1704 } break;
1705 case Image::FORMAT_RGBAH: {
1706 r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
1707 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1708 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1709 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
1710 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
1711
1712 } break;
1713 case Image::FORMAT_RGBE9995: {
1714 r_format.format = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32;
1715 // TODO: Need to make a function in Image to swap bits for this.
1716 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_IDENTITY;
1717 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_IDENTITY;
1718 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_IDENTITY;
1719 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_IDENTITY;
1720 } break;
1721 case Image::FORMAT_DXT1: {
1722 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1723 r_format.format = RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK;
1724 r_format.format_srgb = RD::DATA_FORMAT_BC1_RGB_SRGB_BLOCK;
1725 } else {
1726 //not supported, reconvert
1727 r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
1728 r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
1729 image->decompress();
1730 image->convert(Image::FORMAT_RGBA8);
1731 }
1732 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1733 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1734 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
1735 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1736
1737 } break; //s3tc bc1
1738 case Image::FORMAT_DXT3: {
1739 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC2_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1740 r_format.format = RD::DATA_FORMAT_BC2_UNORM_BLOCK;
1741 r_format.format_srgb = RD::DATA_FORMAT_BC2_SRGB_BLOCK;
1742 } else {
1743 //not supported, reconvert
1744 r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
1745 r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
1746 image->decompress();
1747 image->convert(Image::FORMAT_RGBA8);
1748 }
1749 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1750 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1751 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
1752 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
1753
1754 } break; //bc2
1755 case Image::FORMAT_DXT5: {
1756 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC3_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1757 r_format.format = RD::DATA_FORMAT_BC3_UNORM_BLOCK;
1758 r_format.format_srgb = RD::DATA_FORMAT_BC3_SRGB_BLOCK;
1759 } else {
1760 //not supported, reconvert
1761 r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
1762 r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
1763 image->decompress();
1764 image->convert(Image::FORMAT_RGBA8);
1765 }
1766 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1767 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1768 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
1769 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
1770 } break; //bc3
1771 case Image::FORMAT_RGTC_R: {
1772 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC4_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1773 r_format.format = RD::DATA_FORMAT_BC4_UNORM_BLOCK;
1774 } else {
1775 //not supported, reconvert
1776 r_format.format = RD::DATA_FORMAT_R8_UNORM;
1777 image->decompress();
1778 image->convert(Image::FORMAT_R8);
1779 }
1780 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1781 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO;
1782 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
1783 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1784
1785 } break;
1786 case Image::FORMAT_RGTC_RG: {
1787 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC5_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1788 r_format.format = RD::DATA_FORMAT_BC5_UNORM_BLOCK;
1789 } else {
1790 //not supported, reconvert
1791 r_format.format = RD::DATA_FORMAT_R8G8_UNORM;
1792 image->decompress();
1793 image->convert(Image::FORMAT_RG8);
1794 }
1795 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1796 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1797 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
1798 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1799
1800 } break;
1801 case Image::FORMAT_BPTC_RGBA: {
1802 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC7_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1803 r_format.format = RD::DATA_FORMAT_BC7_UNORM_BLOCK;
1804 r_format.format_srgb = RD::DATA_FORMAT_BC7_SRGB_BLOCK;
1805 } else {
1806 //not supported, reconvert
1807 r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
1808 r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
1809 image->decompress();
1810 image->convert(Image::FORMAT_RGBA8);
1811 }
1812 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1813 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1814 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
1815 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
1816
1817 } break; //btpc bc7
1818 case Image::FORMAT_BPTC_RGBF: {
1819 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC6H_SFLOAT_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1820 r_format.format = RD::DATA_FORMAT_BC6H_SFLOAT_BLOCK;
1821 } else {
1822 //not supported, reconvert
1823 r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
1824 image->decompress();
1825 image->convert(Image::FORMAT_RGBAH);
1826 }
1827 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1828 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1829 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
1830 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1831 } break; //float bc6h
1832 case Image::FORMAT_BPTC_RGBFU: {
1833 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC6H_UFLOAT_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1834 r_format.format = RD::DATA_FORMAT_BC6H_UFLOAT_BLOCK;
1835 } else {
1836 //not supported, reconvert
1837 r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
1838 image->decompress();
1839 image->convert(Image::FORMAT_RGBAH);
1840 }
1841 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1842 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1843 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
1844 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1845 } break; //unsigned float bc6hu
1846 case Image::FORMAT_ETC2_R11: {
1847 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_EAC_R11_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1848 r_format.format = RD::DATA_FORMAT_EAC_R11_UNORM_BLOCK;
1849 } else {
1850 //not supported, reconvert
1851 r_format.format = RD::DATA_FORMAT_R8_UNORM;
1852 image->decompress();
1853 image->convert(Image::FORMAT_R8);
1854 }
1855 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1856 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO;
1857 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
1858 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1859
1860 } break; //etc2
1861 case Image::FORMAT_ETC2_R11S: {
1862 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_EAC_R11_SNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1863 r_format.format = RD::DATA_FORMAT_EAC_R11_SNORM_BLOCK;
1864 } else {
1865 //not supported, reconvert
1866 r_format.format = RD::DATA_FORMAT_R8_SNORM;
1867 image->decompress();
1868 image->convert(Image::FORMAT_R8);
1869 }
1870 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1871 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO;
1872 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
1873 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1874 } break; //signed: {} break; NOT srgb.
1875 case Image::FORMAT_ETC2_RG11: {
1876 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_EAC_R11G11_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1877 r_format.format = RD::DATA_FORMAT_EAC_R11G11_UNORM_BLOCK;
1878 } else {
1879 //not supported, reconvert
1880 r_format.format = RD::DATA_FORMAT_R8G8_UNORM;
1881 image->decompress();
1882 image->convert(Image::FORMAT_RG8);
1883 }
1884 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1885 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1886 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
1887 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1888 } break;
1889 case Image::FORMAT_ETC2_RG11S: {
1890 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_EAC_R11G11_SNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1891 r_format.format = RD::DATA_FORMAT_EAC_R11G11_SNORM_BLOCK;
1892 } else {
1893 //not supported, reconvert
1894 r_format.format = RD::DATA_FORMAT_R8G8_SNORM;
1895 image->decompress();
1896 image->convert(Image::FORMAT_RG8);
1897 }
1898 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1899 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1900 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
1901 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1902 } break;
1903 case Image::FORMAT_ETC:
1904 case Image::FORMAT_ETC2_RGB8: {
1905 //ETC2 is backwards compatible with ETC1, and all modern platforms support it
1906 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1907 r_format.format = RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
1908 r_format.format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK;
1909 } else {
1910 //not supported, reconvert
1911 r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
1912 r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
1913 image->decompress();
1914 image->convert(Image::FORMAT_RGBA8);
1915 }
1916 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1917 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1918 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
1919 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1920
1921 } break;
1922 case Image::FORMAT_ETC2_RGBA8: {
1923 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1924 r_format.format = RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
1925 r_format.format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK;
1926 } else {
1927 //not supported, reconvert
1928 r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
1929 r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
1930 image->decompress();
1931 image->convert(Image::FORMAT_RGBA8);
1932 }
1933 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1934 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1935 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
1936 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
1937 } break;
1938 case Image::FORMAT_ETC2_RGB8A1: {
1939 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1940 r_format.format = RD::DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
1941 r_format.format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK;
1942 } else {
1943 //not supported, reconvert
1944 r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
1945 r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
1946 image->decompress();
1947 image->convert(Image::FORMAT_RGBA8);
1948 }
1949 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1950 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
1951 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
1952 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
1953 } break;
1954 case Image::FORMAT_ETC2_RA_AS_RG: {
1955 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1956 r_format.format = RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
1957 r_format.format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK;
1958 } else {
1959 //not supported, reconvert
1960 r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
1961 r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
1962 image->decompress();
1963 image->convert(Image::FORMAT_RGBA8);
1964 }
1965 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1966 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_A;
1967 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
1968 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1969 } break;
1970 case Image::FORMAT_DXT5_RA_AS_RG: {
1971 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC3_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1972 r_format.format = RD::DATA_FORMAT_BC3_UNORM_BLOCK;
1973 r_format.format_srgb = RD::DATA_FORMAT_BC3_SRGB_BLOCK;
1974 } else {
1975 //not supported, reconvert
1976 r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
1977 r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
1978 image->decompress();
1979 image->convert(Image::FORMAT_RGBA8);
1980 }
1981 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
1982 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_A;
1983 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
1984 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
1985 } break;
1986 case Image::FORMAT_ASTC_4x4:
1987 case Image::FORMAT_ASTC_4x4_HDR: {
1988 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ASTC_4x4_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1989 r_format.format = RD::DATA_FORMAT_ASTC_4x4_UNORM_BLOCK;
1990 if (p_image->get_format() == Image::FORMAT_ASTC_4x4) {
1991 r_format.format_srgb = RD::DATA_FORMAT_ASTC_4x4_SRGB_BLOCK;
1992 }
1993 } else {
1994 //not supported, reconvert
1995 r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
1996 r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
1997 image->decompress();
1998 image->convert(Image::FORMAT_RGBA8);
1999 }
2000 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2001 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2002 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2003 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
2004
2005 } break; // astc 4x4
2006 case Image::FORMAT_ASTC_8x8:
2007 case Image::FORMAT_ASTC_8x8_HDR: {
2008 if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ASTC_8x8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
2009 r_format.format = RD::DATA_FORMAT_ASTC_8x8_UNORM_BLOCK;
2010 if (p_image->get_format() == Image::FORMAT_ASTC_8x8) {
2011 r_format.format_srgb = RD::DATA_FORMAT_ASTC_8x8_SRGB_BLOCK;
2012 }
2013 } else {
2014 //not supported, reconvert
2015 r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
2016 r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
2017 image->decompress();
2018 image->convert(Image::FORMAT_RGBA8);
2019 }
2020 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2021 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2022 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2023 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
2024
2025 } break; // astc 8x8
2026
2027 default: {
2028 }
2029 }
2030
2031 return image;
2032}
2033
2034void TextureStorage::_texture_format_from_rd(RD::DataFormat p_rd_format, TextureFromRDFormat &r_format) {
2035 switch (p_rd_format) {
2036 case RD::DATA_FORMAT_R8_UNORM: {
2037 r_format.image_format = Image::FORMAT_L8;
2038 r_format.rd_format = RD::DATA_FORMAT_R8_UNORM;
2039 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2040 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_R;
2041 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_R;
2042 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2043 } break; //luminance
2044 case RD::DATA_FORMAT_R8G8_UNORM: {
2045 r_format.image_format = Image::FORMAT_LA8;
2046 r_format.rd_format = RD::DATA_FORMAT_R8G8_UNORM;
2047 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2048 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_R;
2049 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_R;
2050 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_G;
2051 } break; //luminance-alpha
2052 /* already maps to L8/LA8
2053 case RD::DATA_FORMAT_R8_UNORM: {
2054 r_format.image_format = Image::FORMAT_R8;
2055 r_format.rd_format = RD::DATA_FORMAT_R8_UNORM;
2056 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2057 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO;
2058 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
2059 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2060 } break;
2061 case RD::DATA_FORMAT_R8G8_UNORM: {
2062 r_format.image_format = Image::FORMAT_RG8;
2063 r_format.rd_format = RD::DATA_FORMAT_R8G8_UNORM;
2064 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2065 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2066 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
2067 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2068 } break;
2069 */
2070 case RD::DATA_FORMAT_R8G8B8_UNORM:
2071 case RD::DATA_FORMAT_R8G8B8_SRGB: {
2072 r_format.image_format = Image::FORMAT_RGB8;
2073 r_format.rd_format = RD::DATA_FORMAT_R8G8B8_UNORM;
2074 r_format.rd_format_srgb = RD::DATA_FORMAT_R8G8B8_SRGB;
2075 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2076 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2077 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2078 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2079
2080 } break;
2081 case RD::DATA_FORMAT_R8G8B8A8_UNORM:
2082 case RD::DATA_FORMAT_R8G8B8A8_SRGB: {
2083 r_format.image_format = Image::FORMAT_RGBA8;
2084 r_format.rd_format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
2085 r_format.rd_format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
2086 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2087 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2088 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2089 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
2090 } break;
2091 case RD::DATA_FORMAT_B4G4R4A4_UNORM_PACK16: {
2092 r_format.image_format = Image::FORMAT_RGBA4444;
2093 r_format.rd_format = RD::DATA_FORMAT_B4G4R4A4_UNORM_PACK16;
2094 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_B; //needs swizzle
2095 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2096 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_R;
2097 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
2098 } break;
2099 case RD::DATA_FORMAT_B5G6R5_UNORM_PACK16: {
2100 r_format.image_format = Image::FORMAT_RGB565;
2101 r_format.rd_format = RD::DATA_FORMAT_B5G6R5_UNORM_PACK16;
2102 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_B;
2103 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2104 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_R;
2105 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
2106 } break;
2107 case RD::DATA_FORMAT_R32_SFLOAT: {
2108 r_format.image_format = Image::FORMAT_RF;
2109 r_format.rd_format = RD::DATA_FORMAT_R32_SFLOAT;
2110 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2111 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO;
2112 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
2113 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2114 } break; //float
2115 case RD::DATA_FORMAT_R32G32_SFLOAT: {
2116 r_format.image_format = Image::FORMAT_RGF;
2117 r_format.rd_format = RD::DATA_FORMAT_R32G32_SFLOAT;
2118 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2119 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2120 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
2121 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2122 } break;
2123 case RD::DATA_FORMAT_R32G32B32_SFLOAT: {
2124 r_format.image_format = Image::FORMAT_RGBF;
2125 r_format.rd_format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
2126 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2127 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2128 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2129 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2130 } break;
2131 case RD::DATA_FORMAT_R32G32B32A32_SFLOAT: {
2132 r_format.image_format = Image::FORMAT_RGBF;
2133 r_format.rd_format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
2134 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2135 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2136 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2137 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
2138
2139 } break;
2140 case RD::DATA_FORMAT_R16_SFLOAT: {
2141 r_format.image_format = Image::FORMAT_RH;
2142 r_format.rd_format = RD::DATA_FORMAT_R16_SFLOAT;
2143 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2144 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO;
2145 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
2146 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2147
2148 } break; //half float
2149 case RD::DATA_FORMAT_R16G16_SFLOAT: {
2150 r_format.image_format = Image::FORMAT_RGH;
2151 r_format.rd_format = RD::DATA_FORMAT_R16G16_SFLOAT;
2152 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2153 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2154 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
2155 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2156
2157 } break;
2158 case RD::DATA_FORMAT_R16G16B16_SFLOAT: {
2159 r_format.image_format = Image::FORMAT_RGBH;
2160 r_format.rd_format = RD::DATA_FORMAT_R16G16B16_SFLOAT;
2161 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2162 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2163 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2164 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2165 } break;
2166 case RD::DATA_FORMAT_R16G16B16A16_SFLOAT: {
2167 r_format.image_format = Image::FORMAT_RGBAH;
2168 r_format.rd_format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
2169 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2170 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2171 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2172 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
2173
2174 } break;
2175 case RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32: {
2176 r_format.image_format = Image::FORMAT_RGBE9995;
2177 r_format.rd_format = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32;
2178 // TODO: Need to make a function in Image to swap bits for this.
2179 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_IDENTITY;
2180 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_IDENTITY;
2181 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_IDENTITY;
2182 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_IDENTITY;
2183 } break;
2184 case RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK:
2185 case RD::DATA_FORMAT_BC1_RGB_SRGB_BLOCK: {
2186 r_format.image_format = Image::FORMAT_DXT1;
2187 r_format.rd_format = RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK;
2188 r_format.rd_format_srgb = RD::DATA_FORMAT_BC1_RGB_SRGB_BLOCK;
2189 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2190 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2191 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2192 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2193
2194 } break; //s3tc bc1
2195 case RD::DATA_FORMAT_BC2_UNORM_BLOCK:
2196 case RD::DATA_FORMAT_BC2_SRGB_BLOCK: {
2197 r_format.image_format = Image::FORMAT_DXT3;
2198 r_format.rd_format = RD::DATA_FORMAT_BC2_UNORM_BLOCK;
2199 r_format.rd_format_srgb = RD::DATA_FORMAT_BC2_SRGB_BLOCK;
2200 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2201 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2202 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2203 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
2204
2205 } break; //bc2
2206 case RD::DATA_FORMAT_BC3_UNORM_BLOCK:
2207 case RD::DATA_FORMAT_BC3_SRGB_BLOCK: {
2208 r_format.image_format = Image::FORMAT_DXT5;
2209 r_format.rd_format = RD::DATA_FORMAT_BC3_UNORM_BLOCK;
2210 r_format.rd_format_srgb = RD::DATA_FORMAT_BC3_SRGB_BLOCK;
2211 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2212 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2213 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2214 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
2215 } break; //bc3
2216 case RD::DATA_FORMAT_BC4_UNORM_BLOCK: {
2217 r_format.image_format = Image::FORMAT_RGTC_R;
2218 r_format.rd_format = RD::DATA_FORMAT_BC4_UNORM_BLOCK;
2219 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2220 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO;
2221 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
2222 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2223
2224 } break;
2225 case RD::DATA_FORMAT_BC5_UNORM_BLOCK: {
2226 r_format.image_format = Image::FORMAT_RGTC_RG;
2227 r_format.rd_format = RD::DATA_FORMAT_BC5_UNORM_BLOCK;
2228 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2229 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2230 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
2231 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2232
2233 } break;
2234 case RD::DATA_FORMAT_BC7_UNORM_BLOCK:
2235 case RD::DATA_FORMAT_BC7_SRGB_BLOCK: {
2236 r_format.image_format = Image::FORMAT_BPTC_RGBA;
2237 r_format.rd_format = RD::DATA_FORMAT_BC7_UNORM_BLOCK;
2238 r_format.rd_format_srgb = RD::DATA_FORMAT_BC7_SRGB_BLOCK;
2239 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2240 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2241 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2242 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
2243
2244 } break; //btpc bc7
2245 case RD::DATA_FORMAT_BC6H_SFLOAT_BLOCK: {
2246 r_format.image_format = Image::FORMAT_BPTC_RGBF;
2247 r_format.rd_format = RD::DATA_FORMAT_BC6H_SFLOAT_BLOCK;
2248 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2249 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2250 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2251 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2252 } break; //float bc6h
2253 case RD::DATA_FORMAT_BC6H_UFLOAT_BLOCK: {
2254 r_format.image_format = Image::FORMAT_BPTC_RGBFU;
2255 r_format.rd_format = RD::DATA_FORMAT_BC6H_UFLOAT_BLOCK;
2256 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2257 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2258 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2259 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2260 } break; //unsigned float bc6hu
2261 case RD::DATA_FORMAT_EAC_R11_UNORM_BLOCK: {
2262 r_format.image_format = Image::FORMAT_ETC2_R11;
2263 r_format.rd_format = RD::DATA_FORMAT_EAC_R11_UNORM_BLOCK;
2264 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2265 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO;
2266 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
2267 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2268
2269 } break; //etc2
2270 case RD::DATA_FORMAT_EAC_R11_SNORM_BLOCK: {
2271 r_format.image_format = Image::FORMAT_ETC2_R11S;
2272 r_format.rd_format = RD::DATA_FORMAT_EAC_R11_SNORM_BLOCK;
2273 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2274 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO;
2275 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
2276 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2277 } break; //signed: {} break; NOT srgb.
2278 case RD::DATA_FORMAT_EAC_R11G11_UNORM_BLOCK: {
2279 r_format.image_format = Image::FORMAT_ETC2_RG11;
2280 r_format.rd_format = RD::DATA_FORMAT_EAC_R11G11_UNORM_BLOCK;
2281 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2282 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2283 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
2284 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2285 } break;
2286 case RD::DATA_FORMAT_EAC_R11G11_SNORM_BLOCK: {
2287 r_format.image_format = Image::FORMAT_ETC2_RG11S;
2288 r_format.rd_format = RD::DATA_FORMAT_EAC_R11G11_SNORM_BLOCK;
2289 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2290 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2291 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
2292 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2293 } break;
2294 case RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
2295 case RD::DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: {
2296 r_format.image_format = Image::FORMAT_ETC2_RGB8;
2297 r_format.rd_format = RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
2298 r_format.rd_format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK;
2299 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2300 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2301 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2302 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2303
2304 } break;
2305 /* already maps to FORMAT_ETC2_RGBA8
2306 case RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
2307 case RD::DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: {
2308 r_format.image_format = Image::FORMAT_ETC2_RGBA8;
2309 r_format.rd_format = RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
2310 r_format.rd_format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK;
2311 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2312 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2313 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2314 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
2315 } break;
2316 */
2317 case RD::DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
2318 case RD::DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: {
2319 r_format.image_format = Image::FORMAT_ETC2_RGB8A1;
2320 r_format.rd_format = RD::DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
2321 r_format.rd_format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK;
2322 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2323 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2324 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2325 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
2326 } break;
2327 case RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
2328 case RD::DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: {
2329 r_format.image_format = Image::FORMAT_ETC2_RA_AS_RG;
2330 r_format.rd_format = RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
2331 r_format.rd_format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK;
2332 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2333 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_A;
2334 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
2335 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2336 } break;
2337 /* already maps to FORMAT_DXT5
2338 case RD::DATA_FORMAT_BC3_UNORM_BLOCK:
2339 case RD::DATA_FORMAT_BC3_SRGB_BLOCK: {
2340 r_format.image_format = Image::FORMAT_DXT5_RA_AS_RG;
2341 r_format.rd_format = RD::DATA_FORMAT_BC3_UNORM_BLOCK;
2342 r_format.rd_format_srgb = RD::DATA_FORMAT_BC3_SRGB_BLOCK;
2343 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2344 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_A;
2345 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
2346 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
2347 } break;
2348 */
2349 case RD::DATA_FORMAT_ASTC_4x4_UNORM_BLOCK: {
2350 // Q: Do we do as we do below, just create the sRGB variant?
2351 r_format.image_format = Image::FORMAT_ASTC_4x4;
2352 r_format.rd_format = RD::DATA_FORMAT_ASTC_4x4_UNORM_BLOCK;
2353 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2354 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2355 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2356 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
2357 } break;
2358 case RD::DATA_FORMAT_ASTC_4x4_SRGB_BLOCK: {
2359 r_format.image_format = Image::FORMAT_ASTC_4x4_HDR;
2360 r_format.rd_format = RD::DATA_FORMAT_ASTC_4x4_UNORM_BLOCK;
2361 r_format.rd_format_srgb = RD::DATA_FORMAT_ASTC_4x4_SRGB_BLOCK;
2362 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2363 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2364 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2365 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
2366
2367 } break; // astc 4x4
2368 case RD::DATA_FORMAT_ASTC_8x8_UNORM_BLOCK: {
2369 // Q: Do we do as we do below, just create the sRGB variant?
2370 r_format.image_format = Image::FORMAT_ASTC_8x8;
2371 r_format.rd_format = RD::DATA_FORMAT_ASTC_8x8_UNORM_BLOCK;
2372 } break;
2373 case RD::DATA_FORMAT_ASTC_8x8_SRGB_BLOCK: {
2374 r_format.image_format = Image::FORMAT_ASTC_8x8_HDR;
2375 r_format.rd_format = RD::DATA_FORMAT_ASTC_8x8_UNORM_BLOCK;
2376 r_format.rd_format_srgb = RD::DATA_FORMAT_ASTC_8x8_SRGB_BLOCK;
2377 r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
2378 r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
2379 r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
2380 r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
2381
2382 } break; // astc 8x8
2383
2384 default: {
2385 ERR_FAIL_MSG("Unsupported image format");
2386 }
2387 }
2388}
2389
2390/* DECAL API */
2391
2392RID TextureStorage::decal_atlas_get_texture() const {
2393 return decal_atlas.texture;
2394}
2395
2396RID TextureStorage::decal_atlas_get_texture_srgb() const {
2397 return decal_atlas.texture_srgb;
2398}
2399
2400RID TextureStorage::decal_allocate() {
2401 return decal_owner.allocate_rid();
2402}
2403
2404void TextureStorage::decal_initialize(RID p_decal) {
2405 decal_owner.initialize_rid(p_decal, Decal());
2406}
2407
2408void TextureStorage::decal_free(RID p_rid) {
2409 Decal *decal = decal_owner.get_or_null(p_rid);
2410 for (int i = 0; i < RS::DECAL_TEXTURE_MAX; i++) {
2411 if (decal->textures[i].is_valid() && owns_texture(decal->textures[i])) {
2412 texture_remove_from_decal_atlas(decal->textures[i]);
2413 }
2414 }
2415 decal->dependency.deleted_notify(p_rid);
2416 decal_owner.free(p_rid);
2417}
2418
2419void TextureStorage::decal_set_size(RID p_decal, const Vector3 &p_size) {
2420 Decal *decal = decal_owner.get_or_null(p_decal);
2421 ERR_FAIL_COND(!decal);
2422 decal->size = p_size;
2423 decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
2424}
2425
2426void TextureStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
2427 Decal *decal = decal_owner.get_or_null(p_decal);
2428 ERR_FAIL_COND(!decal);
2429 ERR_FAIL_INDEX(p_type, RS::DECAL_TEXTURE_MAX);
2430
2431 if (decal->textures[p_type] == p_texture) {
2432 return;
2433 }
2434
2435 ERR_FAIL_COND(p_texture.is_valid() && !owns_texture(p_texture));
2436
2437 if (decal->textures[p_type].is_valid() && owns_texture(decal->textures[p_type])) {
2438 texture_remove_from_decal_atlas(decal->textures[p_type]);
2439 }
2440
2441 decal->textures[p_type] = p_texture;
2442
2443 if (decal->textures[p_type].is_valid()) {
2444 texture_add_to_decal_atlas(decal->textures[p_type]);
2445 }
2446
2447 decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_DECAL);
2448}
2449
2450void TextureStorage::decal_set_emission_energy(RID p_decal, float p_energy) {
2451 Decal *decal = decal_owner.get_or_null(p_decal);
2452 ERR_FAIL_COND(!decal);
2453 decal->emission_energy = p_energy;
2454}
2455
2456void TextureStorage::decal_set_albedo_mix(RID p_decal, float p_mix) {
2457 Decal *decal = decal_owner.get_or_null(p_decal);
2458 ERR_FAIL_COND(!decal);
2459 decal->albedo_mix = p_mix;
2460}
2461
2462void TextureStorage::decal_set_modulate(RID p_decal, const Color &p_modulate) {
2463 Decal *decal = decal_owner.get_or_null(p_decal);
2464 ERR_FAIL_COND(!decal);
2465 decal->modulate = p_modulate;
2466}
2467
2468void TextureStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
2469 Decal *decal = decal_owner.get_or_null(p_decal);
2470 ERR_FAIL_COND(!decal);
2471 decal->cull_mask = p_layers;
2472 decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_DECAL);
2473}
2474
2475void TextureStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
2476 Decal *decal = decal_owner.get_or_null(p_decal);
2477 ERR_FAIL_COND(!decal);
2478 decal->distance_fade = p_enabled;
2479 decal->distance_fade_begin = p_begin;
2480 decal->distance_fade_length = p_length;
2481}
2482
2483void TextureStorage::decal_set_fade(RID p_decal, float p_above, float p_below) {
2484 Decal *decal = decal_owner.get_or_null(p_decal);
2485 ERR_FAIL_COND(!decal);
2486 decal->upper_fade = p_above;
2487 decal->lower_fade = p_below;
2488}
2489
2490void TextureStorage::decal_set_normal_fade(RID p_decal, float p_fade) {
2491 Decal *decal = decal_owner.get_or_null(p_decal);
2492 ERR_FAIL_COND(!decal);
2493 decal->normal_fade = p_fade;
2494}
2495
2496void TextureStorage::decal_atlas_mark_dirty_on_texture(RID p_texture) {
2497 if (decal_atlas.textures.has(p_texture)) {
2498 //belongs to decal atlas..
2499
2500 decal_atlas.dirty = true; //mark it dirty since it was most likely modified
2501 }
2502}
2503
2504void TextureStorage::decal_atlas_remove_texture(RID p_texture) {
2505 if (decal_atlas.textures.has(p_texture)) {
2506 decal_atlas.textures.erase(p_texture);
2507 //there is not much a point of making it dirty, just let it be.
2508 }
2509}
2510
2511AABB TextureStorage::decal_get_aabb(RID p_decal) const {
2512 Decal *decal = decal_owner.get_or_null(p_decal);
2513 ERR_FAIL_COND_V(!decal, AABB());
2514
2515 return AABB(-decal->size / 2, decal->size);
2516}
2517
2518uint32_t TextureStorage::decal_get_cull_mask(RID p_decal) const {
2519 Decal *decal = decal_owner.get_or_null(p_decal);
2520 ERR_FAIL_COND_V(!decal, 0);
2521
2522 return decal->cull_mask;
2523}
2524
2525Dependency *TextureStorage::decal_get_dependency(RID p_decal) {
2526 Decal *decal = decal_owner.get_or_null(p_decal);
2527 ERR_FAIL_COND_V(!decal, nullptr);
2528
2529 return &decal->dependency;
2530}
2531
2532void TextureStorage::update_decal_atlas() {
2533 CopyEffects *copy_effects = CopyEffects::get_singleton();
2534 ERR_FAIL_NULL(copy_effects);
2535
2536 if (!decal_atlas.dirty) {
2537 return; //nothing to do
2538 }
2539
2540 decal_atlas.dirty = false;
2541
2542 if (decal_atlas.texture.is_valid()) {
2543 RD::get_singleton()->free(decal_atlas.texture);
2544 decal_atlas.texture = RID();
2545 decal_atlas.texture_srgb = RID();
2546 decal_atlas.texture_mipmaps.clear();
2547 }
2548
2549 int border = 1 << decal_atlas.mipmaps;
2550
2551 if (decal_atlas.textures.size()) {
2552 //generate atlas
2553 Vector<DecalAtlas::SortItem> itemsv;
2554 itemsv.resize(decal_atlas.textures.size());
2555 int base_size = 8;
2556
2557 int idx = 0;
2558
2559 for (const KeyValue<RID, DecalAtlas::Texture> &E : decal_atlas.textures) {
2560 DecalAtlas::SortItem &si = itemsv.write[idx];
2561
2562 Texture *src_tex = get_texture(E.key);
2563
2564 si.size.width = (src_tex->width / border) + 1;
2565 si.size.height = (src_tex->height / border) + 1;
2566 si.pixel_size = Size2i(src_tex->width, src_tex->height);
2567
2568 if (base_size < si.size.width) {
2569 base_size = nearest_power_of_2_templated(si.size.width);
2570 }
2571
2572 si.texture = E.key;
2573 idx++;
2574 }
2575
2576 //sort items by size
2577 itemsv.sort();
2578
2579 //attempt to create atlas
2580 int item_count = itemsv.size();
2581 DecalAtlas::SortItem *items = itemsv.ptrw();
2582
2583 int atlas_height = 0;
2584
2585 while (true) {
2586 Vector<int> v_offsetsv;
2587 v_offsetsv.resize(base_size);
2588
2589 int *v_offsets = v_offsetsv.ptrw();
2590 memset(v_offsets, 0, sizeof(int) * base_size);
2591
2592 int max_height = 0;
2593
2594 for (int i = 0; i < item_count; i++) {
2595 //best fit
2596 DecalAtlas::SortItem &si = items[i];
2597 int best_idx = -1;
2598 int best_height = 0x7FFFFFFF;
2599 for (int j = 0; j <= base_size - si.size.width; j++) {
2600 int height = 0;
2601 for (int k = 0; k < si.size.width; k++) {
2602 int h = v_offsets[k + j];
2603 if (h > height) {
2604 height = h;
2605 if (height > best_height) {
2606 break; //already bad
2607 }
2608 }
2609 }
2610
2611 if (height < best_height) {
2612 best_height = height;
2613 best_idx = j;
2614 }
2615 }
2616
2617 //update
2618 for (int k = 0; k < si.size.width; k++) {
2619 v_offsets[k + best_idx] = best_height + si.size.height;
2620 }
2621
2622 si.pos.x = best_idx;
2623 si.pos.y = best_height;
2624
2625 if (si.pos.y + si.size.height > max_height) {
2626 max_height = si.pos.y + si.size.height;
2627 }
2628 }
2629
2630 if (max_height <= base_size * 2) {
2631 atlas_height = max_height;
2632 break; //good ratio, break;
2633 }
2634
2635 base_size *= 2;
2636 }
2637
2638 decal_atlas.size.width = base_size * border;
2639 decal_atlas.size.height = nearest_power_of_2_templated(atlas_height * border);
2640
2641 for (int i = 0; i < item_count; i++) {
2642 DecalAtlas::Texture *t = decal_atlas.textures.getptr(items[i].texture);
2643 t->uv_rect.position = items[i].pos * border + Vector2i(border / 2, border / 2);
2644 t->uv_rect.size = items[i].pixel_size;
2645
2646 t->uv_rect.position /= Size2(decal_atlas.size);
2647 t->uv_rect.size /= Size2(decal_atlas.size);
2648 }
2649 } else {
2650 //use border as size, so it at least has enough mipmaps
2651 decal_atlas.size.width = border;
2652 decal_atlas.size.height = border;
2653 }
2654
2655 //blit textures
2656
2657 RD::TextureFormat tformat;
2658 tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
2659 tformat.width = decal_atlas.size.width;
2660 tformat.height = decal_atlas.size.height;
2661 tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
2662 tformat.texture_type = RD::TEXTURE_TYPE_2D;
2663 tformat.mipmaps = decal_atlas.mipmaps;
2664 tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_UNORM);
2665 tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB);
2666
2667 decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView());
2668 RD::get_singleton()->texture_clear(decal_atlas.texture, Color(0, 0, 0, 0), 0, decal_atlas.mipmaps, 0, 1);
2669
2670 {
2671 //create the framebuffer
2672
2673 Size2i s = decal_atlas.size;
2674
2675 for (int i = 0; i < decal_atlas.mipmaps; i++) {
2676 DecalAtlas::MipMap mm;
2677 mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), decal_atlas.texture, 0, i);
2678 Vector<RID> fb;
2679 fb.push_back(mm.texture);
2680 mm.fb = RD::get_singleton()->framebuffer_create(fb);
2681 mm.size = s;
2682 decal_atlas.texture_mipmaps.push_back(mm);
2683
2684 s.width = MAX(1, s.width >> 1);
2685 s.height = MAX(1, s.height >> 1);
2686 }
2687 {
2688 //create the SRGB variant
2689 RD::TextureView rd_view;
2690 rd_view.format_override = RD::DATA_FORMAT_R8G8B8A8_SRGB;
2691 decal_atlas.texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, decal_atlas.texture);
2692 }
2693 }
2694
2695 RID prev_texture;
2696 for (int i = 0; i < decal_atlas.texture_mipmaps.size(); i++) {
2697 const DecalAtlas::MipMap &mm = decal_atlas.texture_mipmaps[i];
2698
2699 Color clear_color(0, 0, 0, 0);
2700
2701 if (decal_atlas.textures.size()) {
2702 if (i == 0) {
2703 Vector<Color> cc;
2704 cc.push_back(clear_color);
2705
2706 RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(mm.fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, cc);
2707
2708 for (const KeyValue<RID, DecalAtlas::Texture> &E : decal_atlas.textures) {
2709 DecalAtlas::Texture *t = decal_atlas.textures.getptr(E.key);
2710 Texture *src_tex = get_texture(E.key);
2711 copy_effects->copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0);
2712 }
2713
2714 RD::get_singleton()->draw_list_end();
2715
2716 prev_texture = mm.texture;
2717 } else {
2718 copy_effects->copy_to_fb_rect(prev_texture, mm.fb, Rect2i(Point2i(), mm.size));
2719 prev_texture = mm.texture;
2720 }
2721 } else {
2722 RD::get_singleton()->texture_clear(mm.texture, clear_color, 0, 1, 0, 1);
2723 }
2724 }
2725}
2726
2727void TextureStorage::texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp) {
2728 if (!decal_atlas.textures.has(p_texture)) {
2729 DecalAtlas::Texture t;
2730 t.users = 1;
2731 t.panorama_to_dp_users = p_panorama_to_dp ? 1 : 0;
2732 decal_atlas.textures[p_texture] = t;
2733 decal_atlas.dirty = true;
2734 } else {
2735 DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
2736 t->users++;
2737 if (p_panorama_to_dp) {
2738 t->panorama_to_dp_users++;
2739 }
2740 }
2741}
2742
2743void TextureStorage::texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp) {
2744 DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
2745 ERR_FAIL_COND(!t);
2746 t->users--;
2747 if (p_panorama_to_dp) {
2748 ERR_FAIL_COND(t->panorama_to_dp_users == 0);
2749 t->panorama_to_dp_users--;
2750 }
2751 if (t->users == 0) {
2752 decal_atlas.textures.erase(p_texture);
2753 //do not mark it dirty, there is no need to since it remains working
2754 }
2755}
2756
2757/* DECAL INSTANCE API */
2758
2759RID TextureStorage::decal_instance_create(RID p_decal) {
2760 DecalInstance di;
2761 di.decal = p_decal;
2762 di.forward_id = ForwardIDStorage::get_singleton()->allocate_forward_id(FORWARD_ID_TYPE_DECAL);
2763 return decal_instance_owner.make_rid(di);
2764}
2765
2766void TextureStorage::decal_instance_free(RID p_decal_instance) {
2767 DecalInstance *di = decal_instance_owner.get_or_null(p_decal_instance);
2768 ForwardIDStorage::get_singleton()->free_forward_id(FORWARD_ID_TYPE_DECAL, di->forward_id);
2769 decal_instance_owner.free(p_decal_instance);
2770}
2771
2772void TextureStorage::decal_instance_set_transform(RID p_decal_instance, const Transform3D &p_transform) {
2773 DecalInstance *di = decal_instance_owner.get_or_null(p_decal_instance);
2774 ERR_FAIL_COND(!di);
2775 di->transform = p_transform;
2776}
2777
2778void TextureStorage::decal_instance_set_sorting_offset(RID p_decal_instance, float p_sorting_offset) {
2779 DecalInstance *di = decal_instance_owner.get_or_null(p_decal_instance);
2780 ERR_FAIL_COND(!di);
2781 di->sorting_offset = p_sorting_offset;
2782}
2783
2784/* DECAL DATA API */
2785
2786void TextureStorage::free_decal_data() {
2787 if (decal_buffer.is_valid()) {
2788 RD::get_singleton()->free(decal_buffer);
2789 decal_buffer = RID();
2790 }
2791
2792 if (decals != nullptr) {
2793 memdelete_arr(decals);
2794 decals = nullptr;
2795 }
2796
2797 if (decal_sort != nullptr) {
2798 memdelete_arr(decal_sort);
2799 decal_sort = nullptr;
2800 }
2801}
2802
2803void TextureStorage::set_max_decals(const uint32_t p_max_decals) {
2804 max_decals = p_max_decals;
2805 uint32_t decal_buffer_size = max_decals * sizeof(DecalData);
2806 decals = memnew_arr(DecalData, max_decals);
2807 decal_sort = memnew_arr(DecalInstanceSort, max_decals);
2808 decal_buffer = RD::get_singleton()->storage_buffer_create(decal_buffer_size);
2809}
2810
2811void TextureStorage::update_decal_buffer(const PagedArray<RID> &p_decals, const Transform3D &p_camera_xform) {
2812 ForwardIDStorage *forward_id_storage = ForwardIDStorage::get_singleton();
2813
2814 Transform3D uv_xform;
2815 uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0));
2816 uv_xform.origin = Vector3(-1.0, 0.0, -1.0);
2817
2818 uint32_t decals_size = p_decals.size();
2819
2820 decal_count = 0;
2821
2822 for (uint32_t i = 0; i < decals_size; i++) {
2823 if (decal_count == max_decals) {
2824 break;
2825 }
2826
2827 DecalInstance *decal_instance = decal_instance_owner.get_or_null(p_decals[i]);
2828 if (!decal_instance) {
2829 continue;
2830 }
2831 Decal *decal = decal_owner.get_or_null(decal_instance->decal);
2832
2833 Transform3D xform = decal_instance->transform;
2834
2835 real_t distance = p_camera_xform.origin.distance_to(xform.origin);
2836
2837 if (decal->distance_fade) {
2838 float fade_begin = decal->distance_fade_begin;
2839 float fade_length = decal->distance_fade_length;
2840
2841 if (distance > fade_begin) {
2842 if (distance > fade_begin + fade_length) {
2843 continue; // do not use this decal, its invisible
2844 }
2845 }
2846 }
2847
2848 decal_sort[decal_count].decal_instance = decal_instance;
2849 decal_sort[decal_count].decal = decal;
2850 decal_sort[decal_count].depth = distance - decal_instance->sorting_offset;
2851 decal_count++;
2852 }
2853
2854 if (decal_count > 0) {
2855 SortArray<DecalInstanceSort> sort_array;
2856 sort_array.sort(decal_sort, decal_count);
2857 }
2858
2859 bool using_forward_ids = forward_id_storage->uses_forward_ids();
2860 for (uint32_t i = 0; i < decal_count; i++) {
2861 DecalInstance *decal_instance = decal_sort[i].decal_instance;
2862 Decal *decal = decal_sort[i].decal;
2863
2864 if (using_forward_ids) {
2865 forward_id_storage->map_forward_id(FORWARD_ID_TYPE_DECAL, decal_instance->forward_id, i);
2866 }
2867
2868 decal_instance->cull_mask = decal->cull_mask;
2869
2870 float fade = 1.0;
2871
2872 if (decal->distance_fade) {
2873 const real_t distance = decal_sort[i].depth + decal_instance->sorting_offset;
2874 const float fade_begin = decal->distance_fade_begin;
2875 const float fade_length = decal->distance_fade_length;
2876
2877 if (distance > fade_begin) {
2878 // Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player.
2879 fade = Math::smoothstep(0.0f, 1.0f, 1.0f - float(distance - fade_begin) / fade_length);
2880 }
2881 }
2882
2883 DecalData &dd = decals[i];
2884
2885 Vector3 decal_extents = decal->size / 2;
2886
2887 Transform3D scale_xform;
2888 scale_xform.basis.scale(decal_extents);
2889
2890 Transform3D xform = decal_instance->transform;
2891
2892 Transform3D camera_inverse_xform = p_camera_xform.affine_inverse();
2893
2894 Transform3D to_decal_xform = (camera_inverse_xform * xform * scale_xform * uv_xform).affine_inverse();
2895 MaterialStorage::store_transform(to_decal_xform, dd.xform);
2896
2897 Vector3 normal = xform.basis.get_column(Vector3::AXIS_Y).normalized();
2898 normal = camera_inverse_xform.basis.xform(normal); //camera is normalized, so fine
2899
2900 dd.normal[0] = normal.x;
2901 dd.normal[1] = normal.y;
2902 dd.normal[2] = normal.z;
2903 dd.normal_fade = decal->normal_fade;
2904
2905 RID albedo_tex = decal->textures[RS::DECAL_TEXTURE_ALBEDO];
2906 RID emission_tex = decal->textures[RS::DECAL_TEXTURE_EMISSION];
2907 if (albedo_tex.is_valid()) {
2908 Rect2 rect = decal_atlas_get_texture_rect(albedo_tex);
2909 dd.albedo_rect[0] = rect.position.x;
2910 dd.albedo_rect[1] = rect.position.y;
2911 dd.albedo_rect[2] = rect.size.x;
2912 dd.albedo_rect[3] = rect.size.y;
2913 } else {
2914 if (!emission_tex.is_valid()) {
2915 continue; //no albedo, no emission, no decal.
2916 }
2917 dd.albedo_rect[0] = 0;
2918 dd.albedo_rect[1] = 0;
2919 dd.albedo_rect[2] = 0;
2920 dd.albedo_rect[3] = 0;
2921 }
2922
2923 RID normal_tex = decal->textures[RS::DECAL_TEXTURE_NORMAL];
2924
2925 if (normal_tex.is_valid()) {
2926 Rect2 rect = decal_atlas_get_texture_rect(normal_tex);
2927 dd.normal_rect[0] = rect.position.x;
2928 dd.normal_rect[1] = rect.position.y;
2929 dd.normal_rect[2] = rect.size.x;
2930 dd.normal_rect[3] = rect.size.y;
2931
2932 Basis normal_xform = camera_inverse_xform.basis * xform.basis.orthonormalized();
2933 MaterialStorage::store_basis_3x4(normal_xform, dd.normal_xform);
2934 } else {
2935 dd.normal_rect[0] = 0;
2936 dd.normal_rect[1] = 0;
2937 dd.normal_rect[2] = 0;
2938 dd.normal_rect[3] = 0;
2939 }
2940
2941 RID orm_tex = decal->textures[RS::DECAL_TEXTURE_ORM];
2942 if (orm_tex.is_valid()) {
2943 Rect2 rect = decal_atlas_get_texture_rect(orm_tex);
2944 dd.orm_rect[0] = rect.position.x;
2945 dd.orm_rect[1] = rect.position.y;
2946 dd.orm_rect[2] = rect.size.x;
2947 dd.orm_rect[3] = rect.size.y;
2948 } else {
2949 dd.orm_rect[0] = 0;
2950 dd.orm_rect[1] = 0;
2951 dd.orm_rect[2] = 0;
2952 dd.orm_rect[3] = 0;
2953 }
2954
2955 if (emission_tex.is_valid()) {
2956 Rect2 rect = decal_atlas_get_texture_rect(emission_tex);
2957 dd.emission_rect[0] = rect.position.x;
2958 dd.emission_rect[1] = rect.position.y;
2959 dd.emission_rect[2] = rect.size.x;
2960 dd.emission_rect[3] = rect.size.y;
2961 } else {
2962 dd.emission_rect[0] = 0;
2963 dd.emission_rect[1] = 0;
2964 dd.emission_rect[2] = 0;
2965 dd.emission_rect[3] = 0;
2966 }
2967
2968 Color modulate = decal->modulate;
2969 dd.modulate[0] = modulate.r;
2970 dd.modulate[1] = modulate.g;
2971 dd.modulate[2] = modulate.b;
2972 dd.modulate[3] = modulate.a * fade;
2973 dd.emission_energy = decal->emission_energy * fade;
2974 dd.albedo_mix = decal->albedo_mix;
2975 dd.mask = decal->cull_mask;
2976 dd.upper_fade = decal->upper_fade;
2977 dd.lower_fade = decal->lower_fade;
2978
2979 // hook for subclass to do further processing.
2980 RendererSceneRenderRD::get_singleton()->setup_added_decal(xform, decal_extents);
2981 }
2982
2983 if (decal_count > 0) {
2984 RD::get_singleton()->buffer_update(decal_buffer, 0, sizeof(DecalData) * decal_count, decals, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
2985 }
2986}
2987
2988/* RENDER TARGET API */
2989
2990RID TextureStorage::RenderTarget::get_framebuffer() {
2991 // Note that if we're using an overridden color buffer, we're likely cycling through a texture chain.
2992 // this is where our framebuffer cache comes in clutch..
2993
2994 if (msaa != RS::VIEWPORT_MSAA_DISABLED) {
2995 return FramebufferCacheRD::get_singleton()->get_cache_multiview(view_count, color_multisample, overridden.color.is_valid() ? overridden.color : color);
2996 } else {
2997 return FramebufferCacheRD::get_singleton()->get_cache_multiview(view_count, overridden.color.is_valid() ? overridden.color : color);
2998 }
2999}
3000
3001void TextureStorage::_clear_render_target(RenderTarget *rt) {
3002 // clear overrides, we assume these are freed by the object that created them
3003 rt->overridden.color = RID();
3004 rt->overridden.depth = RID();
3005 rt->overridden.velocity = RID();
3006 rt->overridden.cached_slices.clear(); // these are automatically freed when their parent textures are freed so just clear
3007
3008 // free in reverse dependency order
3009 if (rt->framebuffer_uniform_set.is_valid()) {
3010 rt->framebuffer_uniform_set = RID(); //chain deleted
3011 }
3012
3013 if (rt->color.is_valid()) {
3014 RD::get_singleton()->free(rt->color);
3015 }
3016 rt->color_slices.clear(); // these are automatically freed.
3017
3018 if (rt->color_multisample.is_valid()) {
3019 RD::get_singleton()->free(rt->color_multisample);
3020 }
3021
3022 if (rt->backbuffer.is_valid()) {
3023 RD::get_singleton()->free(rt->backbuffer);
3024 rt->backbuffer = RID();
3025 rt->backbuffer_mipmaps.clear();
3026 rt->backbuffer_uniform_set = RID(); //chain deleted
3027 }
3028
3029 _render_target_clear_sdf(rt);
3030
3031 rt->color = RID();
3032 rt->color_multisample = RID();
3033 if (rt->texture.is_valid()) {
3034 Texture *tex = get_texture(rt->texture);
3035 tex->render_target = nullptr;
3036 }
3037}
3038
3039void TextureStorage::_update_render_target(RenderTarget *rt) {
3040 if (rt->texture.is_null()) {
3041 //create a placeholder until updated
3042 rt->texture = texture_allocate();
3043 texture_2d_placeholder_initialize(rt->texture);
3044 Texture *tex = get_texture(rt->texture);
3045 tex->is_render_target = true;
3046 }
3047
3048 _clear_render_target(rt);
3049
3050 if (rt->size.width == 0 || rt->size.height == 0) {
3051 return;
3052 }
3053 if (rt->use_hdr) {
3054 rt->color_format = RendererSceneRenderRD::get_singleton()->_render_buffers_get_color_format();
3055 rt->color_format_srgb = rt->color_format;
3056 rt->image_format = rt->is_transparent ? Image::FORMAT_RGBAH : Image::FORMAT_RGBH;
3057 } else {
3058 rt->color_format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
3059 rt->color_format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
3060 rt->image_format = rt->is_transparent ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8;
3061 }
3062
3063 RD::TextureFormat rd_color_attachment_format;
3064 RD::TextureView rd_view;
3065 { //attempt register
3066 rd_color_attachment_format.format = rt->color_format;
3067 rd_color_attachment_format.width = rt->size.width;
3068 rd_color_attachment_format.height = rt->size.height;
3069 rd_color_attachment_format.depth = 1;
3070 rd_color_attachment_format.array_layers = rt->view_count; // for stereo we create two (or more) layers, need to see if we can make fallback work like this too if we don't have multiview
3071 rd_color_attachment_format.mipmaps = 1;
3072 if (rd_color_attachment_format.array_layers > 1) { // why are we not using rt->texture_type ??
3073 rd_color_attachment_format.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
3074 } else {
3075 rd_color_attachment_format.texture_type = RD::TEXTURE_TYPE_2D;
3076 }
3077 rd_color_attachment_format.samples = RD::TEXTURE_SAMPLES_1;
3078 rd_color_attachment_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
3079 rd_color_attachment_format.usage_bits |= RD::TEXTURE_USAGE_STORAGE_BIT; // FIXME we need this only when FSR is enabled
3080 rd_color_attachment_format.shareable_formats.push_back(rt->color_format);
3081 rd_color_attachment_format.shareable_formats.push_back(rt->color_format_srgb);
3082 if (rt->msaa != RS::VIEWPORT_MSAA_DISABLED) {
3083 rd_color_attachment_format.is_resolve_buffer = true;
3084 }
3085 }
3086
3087 // TODO see if we can lazy create this once we actually use it as we may not need to create this if we have an overridden color buffer...
3088 rt->color = RD::get_singleton()->texture_create(rd_color_attachment_format, rd_view);
3089 ERR_FAIL_COND(rt->color.is_null());
3090
3091 if (rt->msaa != RS::VIEWPORT_MSAA_DISABLED) {
3092 // Use the texture format of the color attachment for the multisample color attachment.
3093 RD::TextureFormat rd_color_multisample_format = rd_color_attachment_format;
3094 const RD::TextureSamples texture_samples[RS::VIEWPORT_MSAA_MAX] = {
3095 RD::TEXTURE_SAMPLES_1,
3096 RD::TEXTURE_SAMPLES_2,
3097 RD::TEXTURE_SAMPLES_4,
3098 RD::TEXTURE_SAMPLES_8,
3099 };
3100 rd_color_multisample_format.samples = texture_samples[rt->msaa];
3101 rd_color_multisample_format.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
3102 RD::TextureView rd_view_multisample;
3103 rd_color_multisample_format.is_resolve_buffer = false;
3104 rt->color_multisample = RD::get_singleton()->texture_create(rd_color_multisample_format, rd_view_multisample);
3105 ERR_FAIL_COND(rt->color_multisample.is_null());
3106 }
3107
3108 { //update texture
3109
3110 Texture *tex = get_texture(rt->texture);
3111
3112 //free existing textures
3113 if (RD::get_singleton()->texture_is_valid(tex->rd_texture)) {
3114 RD::get_singleton()->free(tex->rd_texture);
3115 }
3116 if (RD::get_singleton()->texture_is_valid(tex->rd_texture_srgb)) {
3117 RD::get_singleton()->free(tex->rd_texture_srgb);
3118 }
3119
3120 tex->rd_texture = RID();
3121 tex->rd_texture_srgb = RID();
3122 tex->render_target = rt;
3123
3124 //create shared textures to the color buffer,
3125 //so transparent can be supported
3126 RD::TextureView view;
3127 view.format_override = rt->color_format;
3128 if (!rt->is_transparent) {
3129 view.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
3130 }
3131 tex->rd_texture = RD::get_singleton()->texture_create_shared(view, rt->color);
3132 if (rt->color_format_srgb != RD::DATA_FORMAT_MAX) {
3133 view.format_override = rt->color_format_srgb;
3134 tex->rd_texture_srgb = RD::get_singleton()->texture_create_shared(view, rt->color);
3135 }
3136 tex->rd_view = view;
3137 tex->width = rt->size.width;
3138 tex->height = rt->size.height;
3139 tex->width_2d = rt->size.width;
3140 tex->height_2d = rt->size.height;
3141 tex->rd_format = rt->color_format;
3142 tex->rd_format_srgb = rt->color_format_srgb;
3143 tex->format = rt->image_format;
3144 tex->validated_format = rt->use_hdr ? Image::FORMAT_RGBAH : Image::FORMAT_RGBA8;
3145
3146 Vector<RID> proxies = tex->proxies; //make a copy, since update may change it
3147 for (int i = 0; i < proxies.size(); i++) {
3148 texture_proxy_update(proxies[i], rt->texture);
3149 }
3150 }
3151}
3152
3153void TextureStorage::_create_render_target_backbuffer(RenderTarget *rt) {
3154 ERR_FAIL_COND(rt->backbuffer.is_valid());
3155
3156 uint32_t mipmaps_required = Image::get_image_required_mipmaps(rt->size.width, rt->size.height, Image::FORMAT_RGBA8);
3157 RD::TextureFormat tf;
3158 tf.format = rt->color_format;
3159 tf.width = rt->size.width;
3160 tf.height = rt->size.height;
3161 tf.texture_type = RD::TEXTURE_TYPE_2D;
3162 tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
3163 tf.mipmaps = mipmaps_required;
3164
3165 rt->backbuffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
3166 RD::get_singleton()->set_resource_name(rt->backbuffer, "Render Target Back Buffer");
3167 rt->backbuffer_mipmap0 = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, 0);
3168 RD::get_singleton()->set_resource_name(rt->backbuffer_mipmap0, "Back Buffer slice mipmap 0");
3169
3170 {
3171 Vector<RID> fb_tex;
3172 fb_tex.push_back(rt->backbuffer_mipmap0);
3173 rt->backbuffer_fb = RD::get_singleton()->framebuffer_create(fb_tex);
3174 }
3175
3176 if (rt->framebuffer_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rt->framebuffer_uniform_set)) {
3177 //the new one will require the backbuffer.
3178 RD::get_singleton()->free(rt->framebuffer_uniform_set);
3179 rt->framebuffer_uniform_set = RID();
3180 }
3181 //create mipmaps
3182 for (uint32_t i = 1; i < mipmaps_required; i++) {
3183 RID mipmap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, i);
3184 RD::get_singleton()->set_resource_name(mipmap, "Back Buffer slice mip: " + itos(i));
3185
3186 rt->backbuffer_mipmaps.push_back(mipmap);
3187 }
3188}
3189
3190RID TextureStorage::render_target_create() {
3191 RenderTarget render_target;
3192
3193 render_target.was_used = false;
3194 render_target.clear_requested = false;
3195
3196 _update_render_target(&render_target);
3197 return render_target_owner.make_rid(render_target);
3198}
3199
3200void TextureStorage::render_target_free(RID p_rid) {
3201 RenderTarget *rt = render_target_owner.get_or_null(p_rid);
3202
3203 _clear_render_target(rt);
3204
3205 if (rt->texture.is_valid()) {
3206 Texture *tex = get_texture(rt->texture);
3207 tex->is_render_target = false;
3208 texture_free(rt->texture);
3209 }
3210
3211 render_target_owner.free(p_rid);
3212}
3213
3214void TextureStorage::render_target_set_position(RID p_render_target, int p_x, int p_y) {
3215 //unused for this render target
3216}
3217
3218Point2i TextureStorage::render_target_get_position(RID p_render_target) const {
3219 //unused for this render target
3220 return Point2i();
3221}
3222
3223void TextureStorage::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) {
3224 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3225 ERR_FAIL_COND(!rt);
3226 if (rt->size.x != p_width || rt->size.y != p_height || rt->view_count != p_view_count) {
3227 rt->size.x = p_width;
3228 rt->size.y = p_height;
3229 rt->view_count = p_view_count;
3230 _update_render_target(rt);
3231 }
3232}
3233
3234Size2i TextureStorage::render_target_get_size(RID p_render_target) const {
3235 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3236 ERR_FAIL_COND_V(!rt, Size2i());
3237
3238 return rt->size;
3239}
3240
3241RID TextureStorage::render_target_get_texture(RID p_render_target) {
3242 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3243 ERR_FAIL_COND_V(!rt, RID());
3244
3245 return rt->texture;
3246}
3247
3248void TextureStorage::render_target_set_override(RID p_render_target, RID p_color_texture, RID p_depth_texture, RID p_velocity_texture) {
3249 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3250 ERR_FAIL_COND(!rt);
3251
3252 rt->overridden.color = p_color_texture;
3253 rt->overridden.depth = p_depth_texture;
3254 rt->overridden.velocity = p_velocity_texture;
3255}
3256
3257RID TextureStorage::render_target_get_override_color(RID p_render_target) const {
3258 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3259 ERR_FAIL_COND_V(!rt, RID());
3260
3261 return rt->overridden.color;
3262}
3263
3264RID TextureStorage::render_target_get_override_depth(RID p_render_target) const {
3265 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3266 ERR_FAIL_COND_V(!rt, RID());
3267
3268 return rt->overridden.depth;
3269}
3270
3271RID TextureStorage::render_target_get_override_depth_slice(RID p_render_target, const uint32_t p_layer) const {
3272 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3273 ERR_FAIL_COND_V(!rt, RID());
3274
3275 if (rt->overridden.depth.is_null()) {
3276 return RID();
3277 } else if (rt->view_count == 1) {
3278 return rt->overridden.depth;
3279 } else {
3280 RenderTarget::RTOverridden::SliceKey key(rt->overridden.depth, p_layer);
3281
3282 if (!rt->overridden.cached_slices.has(key)) {
3283 rt->overridden.cached_slices[key] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->overridden.depth, p_layer, 0);
3284 }
3285
3286 return rt->overridden.cached_slices[key];
3287 }
3288}
3289
3290RID TextureStorage::render_target_get_override_velocity(RID p_render_target) const {
3291 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3292 ERR_FAIL_COND_V(!rt, RID());
3293
3294 return rt->overridden.velocity;
3295}
3296
3297RID TextureStorage::render_target_get_override_velocity_slice(RID p_render_target, const uint32_t p_layer) const {
3298 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3299 ERR_FAIL_COND_V(!rt, RID());
3300
3301 if (rt->overridden.velocity.is_null()) {
3302 return RID();
3303 } else if (rt->view_count == 1) {
3304 return rt->overridden.velocity;
3305 } else {
3306 RenderTarget::RTOverridden::SliceKey key(rt->overridden.velocity, p_layer);
3307
3308 if (!rt->overridden.cached_slices.has(key)) {
3309 rt->overridden.cached_slices[key] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->overridden.velocity, p_layer, 0);
3310 }
3311
3312 return rt->overridden.cached_slices[key];
3313 }
3314}
3315
3316void TextureStorage::render_target_set_transparent(RID p_render_target, bool p_is_transparent) {
3317 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3318 ERR_FAIL_COND(!rt);
3319 rt->is_transparent = p_is_transparent;
3320 _update_render_target(rt);
3321}
3322
3323bool TextureStorage::render_target_get_transparent(RID p_render_target) const {
3324 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3325 ERR_FAIL_COND_V(!rt, false);
3326
3327 return rt->is_transparent;
3328}
3329
3330void TextureStorage::render_target_set_direct_to_screen(RID p_render_target, bool p_value) {
3331}
3332
3333bool TextureStorage::render_target_get_direct_to_screen(RID p_render_target) const {
3334 return false;
3335}
3336
3337bool TextureStorage::render_target_was_used(RID p_render_target) const {
3338 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3339 ERR_FAIL_COND_V(!rt, false);
3340 return rt->was_used;
3341}
3342
3343void TextureStorage::render_target_set_as_unused(RID p_render_target) {
3344 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3345 ERR_FAIL_COND(!rt);
3346 rt->was_used = false;
3347}
3348
3349void TextureStorage::render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) {
3350 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3351 ERR_FAIL_COND(!rt);
3352 if (p_msaa == rt->msaa) {
3353 return;
3354 }
3355
3356 rt->msaa = p_msaa;
3357 _update_render_target(rt);
3358}
3359
3360RS::ViewportMSAA TextureStorage::render_target_get_msaa(RID p_render_target) const {
3361 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3362 ERR_FAIL_COND_V(!rt, RS::VIEWPORT_MSAA_DISABLED);
3363
3364 return rt->msaa;
3365}
3366
3367void TextureStorage::render_target_set_use_hdr(RID p_render_target, bool p_use_hdr) {
3368 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3369 ERR_FAIL_COND(!rt);
3370
3371 if (p_use_hdr == rt->use_hdr) {
3372 return;
3373 }
3374
3375 rt->use_hdr = p_use_hdr;
3376 _update_render_target(rt);
3377}
3378
3379bool TextureStorage::render_target_is_using_hdr(RID p_render_target) const {
3380 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3381 ERR_FAIL_COND_V(!rt, false);
3382
3383 return rt->use_hdr;
3384}
3385
3386RID TextureStorage::render_target_get_rd_framebuffer(RID p_render_target) {
3387 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3388 ERR_FAIL_COND_V(!rt, RID());
3389
3390 return rt->get_framebuffer();
3391}
3392
3393RID TextureStorage::render_target_get_rd_texture(RID p_render_target) {
3394 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3395 ERR_FAIL_COND_V(!rt, RID());
3396
3397 if (rt->overridden.color.is_valid()) {
3398 return rt->overridden.color;
3399 } else {
3400 return rt->color;
3401 }
3402}
3403
3404RID TextureStorage::render_target_get_rd_texture_slice(RID p_render_target, uint32_t p_layer) {
3405 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3406 ERR_FAIL_COND_V(!rt, RID());
3407
3408 if (rt->view_count == 1) {
3409 return rt->color;
3410 } else {
3411 ERR_FAIL_UNSIGNED_INDEX_V(p_layer, rt->view_count, RID());
3412 if (rt->color_slices.size() == 0) {
3413 for (uint32_t v = 0; v < rt->view_count; v++) {
3414 RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->color, v, 0);
3415 rt->color_slices.push_back(slice);
3416 }
3417 }
3418 return rt->color_slices[p_layer];
3419 }
3420}
3421
3422RID TextureStorage::render_target_get_rd_texture_msaa(RID p_render_target) {
3423 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3424 ERR_FAIL_COND_V(!rt, RID());
3425
3426 return rt->color_multisample;
3427}
3428
3429RID TextureStorage::render_target_get_rd_backbuffer(RID p_render_target) {
3430 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3431 ERR_FAIL_COND_V(!rt, RID());
3432 return rt->backbuffer;
3433}
3434
3435RID TextureStorage::render_target_get_rd_backbuffer_framebuffer(RID p_render_target) {
3436 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3437 ERR_FAIL_COND_V(!rt, RID());
3438
3439 if (!rt->backbuffer.is_valid()) {
3440 _create_render_target_backbuffer(rt);
3441 }
3442
3443 return rt->backbuffer_fb;
3444}
3445
3446void TextureStorage::render_target_request_clear(RID p_render_target, const Color &p_clear_color) {
3447 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3448 ERR_FAIL_COND(!rt);
3449 rt->clear_requested = true;
3450 rt->clear_color = p_clear_color;
3451}
3452
3453bool TextureStorage::render_target_is_clear_requested(RID p_render_target) {
3454 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3455 ERR_FAIL_COND_V(!rt, false);
3456 return rt->clear_requested;
3457}
3458
3459Color TextureStorage::render_target_get_clear_request_color(RID p_render_target) {
3460 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3461 ERR_FAIL_COND_V(!rt, Color());
3462 return rt->use_hdr ? rt->clear_color.srgb_to_linear() : rt->clear_color;
3463}
3464
3465void TextureStorage::render_target_disable_clear_request(RID p_render_target) {
3466 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3467 ERR_FAIL_COND(!rt);
3468 rt->clear_requested = false;
3469}
3470
3471void TextureStorage::render_target_do_clear_request(RID p_render_target) {
3472 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3473 ERR_FAIL_COND(!rt);
3474 if (!rt->clear_requested) {
3475 return;
3476 }
3477 Vector<Color> clear_colors;
3478 clear_colors.push_back(rt->use_hdr ? rt->clear_color.srgb_to_linear() : rt->clear_color);
3479 RD::get_singleton()->draw_list_begin(rt->get_framebuffer(), RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, clear_colors);
3480 RD::get_singleton()->draw_list_end();
3481 rt->clear_requested = false;
3482}
3483
3484void TextureStorage::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) {
3485 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3486 ERR_FAIL_COND(!rt);
3487 if (rt->sdf_oversize == p_size && rt->sdf_scale == p_scale) {
3488 return;
3489 }
3490
3491 rt->sdf_oversize = p_size;
3492 rt->sdf_scale = p_scale;
3493
3494 _render_target_clear_sdf(rt);
3495}
3496
3497Rect2i TextureStorage::_render_target_get_sdf_rect(const RenderTarget *rt) const {
3498 Size2i margin;
3499 int scale;
3500 switch (rt->sdf_oversize) {
3501 case RS::VIEWPORT_SDF_OVERSIZE_100_PERCENT: {
3502 scale = 100;
3503 } break;
3504 case RS::VIEWPORT_SDF_OVERSIZE_120_PERCENT: {
3505 scale = 120;
3506 } break;
3507 case RS::VIEWPORT_SDF_OVERSIZE_150_PERCENT: {
3508 scale = 150;
3509 } break;
3510 case RS::VIEWPORT_SDF_OVERSIZE_200_PERCENT: {
3511 scale = 200;
3512 } break;
3513 default: {
3514 }
3515 }
3516
3517 margin = (rt->size * scale / 100) - rt->size;
3518
3519 Rect2i r(Vector2i(), rt->size);
3520 r.position -= margin;
3521 r.size += margin * 2;
3522
3523 return r;
3524}
3525
3526Rect2i TextureStorage::render_target_get_sdf_rect(RID p_render_target) const {
3527 const RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3528 ERR_FAIL_COND_V(!rt, Rect2i());
3529
3530 return _render_target_get_sdf_rect(rt);
3531}
3532
3533void TextureStorage::render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) {
3534 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3535 ERR_FAIL_COND(!rt);
3536
3537 rt->sdf_enabled = p_enabled;
3538}
3539
3540bool TextureStorage::render_target_is_sdf_enabled(RID p_render_target) const {
3541 const RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3542 ERR_FAIL_COND_V(!rt, false);
3543
3544 return rt->sdf_enabled;
3545}
3546
3547RID TextureStorage::render_target_get_sdf_texture(RID p_render_target) {
3548 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3549 ERR_FAIL_COND_V(!rt, RID());
3550 if (rt->sdf_buffer_read.is_null()) {
3551 // no texture, create a dummy one for the 2D uniform set
3552 RD::TextureFormat tformat;
3553 tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
3554 tformat.width = 4;
3555 tformat.height = 4;
3556 tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT;
3557 tformat.texture_type = RD::TEXTURE_TYPE_2D;
3558
3559 Vector<uint8_t> pv;
3560 pv.resize(16 * 4);
3561 memset(pv.ptrw(), 0, 16 * 4);
3562 Vector<Vector<uint8_t>> vpv;
3563
3564 rt->sdf_buffer_read = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
3565 }
3566
3567 return rt->sdf_buffer_read;
3568}
3569
3570void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) {
3571 ERR_FAIL_COND(rt->sdf_buffer_write_fb.is_valid());
3572 if (rt->sdf_buffer_read.is_valid()) {
3573 RD::get_singleton()->free(rt->sdf_buffer_read);
3574 rt->sdf_buffer_read = RID();
3575 }
3576
3577 Size2i size = _render_target_get_sdf_rect(rt).size;
3578
3579 RD::TextureFormat tformat;
3580 tformat.format = RD::DATA_FORMAT_R8_UNORM;
3581 tformat.width = size.width;
3582 tformat.height = size.height;
3583 tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
3584 tformat.texture_type = RD::TEXTURE_TYPE_2D;
3585
3586 rt->sdf_buffer_write = RD::get_singleton()->texture_create(tformat, RD::TextureView());
3587
3588 {
3589 Vector<RID> write_fb;
3590 write_fb.push_back(rt->sdf_buffer_write);
3591 rt->sdf_buffer_write_fb = RD::get_singleton()->framebuffer_create(write_fb);
3592 }
3593
3594 int scale;
3595 switch (rt->sdf_scale) {
3596 case RS::VIEWPORT_SDF_SCALE_100_PERCENT: {
3597 scale = 100;
3598 } break;
3599 case RS::VIEWPORT_SDF_SCALE_50_PERCENT: {
3600 scale = 50;
3601 } break;
3602 case RS::VIEWPORT_SDF_SCALE_25_PERCENT: {
3603 scale = 25;
3604 } break;
3605 default: {
3606 scale = 100;
3607 } break;
3608 }
3609
3610 rt->process_size = size * scale / 100;
3611 rt->process_size.x = MAX(rt->process_size.x, 1);
3612 rt->process_size.y = MAX(rt->process_size.y, 1);
3613
3614 tformat.format = RD::DATA_FORMAT_R16G16_SINT;
3615 tformat.width = rt->process_size.width;
3616 tformat.height = rt->process_size.height;
3617 tformat.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;
3618
3619 rt->sdf_buffer_process[0] = RD::get_singleton()->texture_create(tformat, RD::TextureView());
3620 rt->sdf_buffer_process[1] = RD::get_singleton()->texture_create(tformat, RD::TextureView());
3621
3622 tformat.format = RD::DATA_FORMAT_R16_SNORM;
3623 tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
3624
3625 rt->sdf_buffer_read = RD::get_singleton()->texture_create(tformat, RD::TextureView());
3626
3627 {
3628 Vector<RD::Uniform> uniforms;
3629 {
3630 RD::Uniform u;
3631 u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
3632 u.binding = 1;
3633 u.append_id(rt->sdf_buffer_write);
3634 uniforms.push_back(u);
3635 }
3636 {
3637 RD::Uniform u;
3638 u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
3639 u.binding = 2;
3640 u.append_id(rt->sdf_buffer_read);
3641 uniforms.push_back(u);
3642 }
3643 {
3644 RD::Uniform u;
3645 u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
3646 u.binding = 3;
3647 u.append_id(rt->sdf_buffer_process[0]);
3648 uniforms.push_back(u);
3649 }
3650 {
3651 RD::Uniform u;
3652 u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
3653 u.binding = 4;
3654 u.append_id(rt->sdf_buffer_process[1]);
3655 uniforms.push_back(u);
3656 }
3657
3658 rt->sdf_buffer_process_uniform_sets[0] = RD::get_singleton()->uniform_set_create(uniforms, rt_sdf.shader.version_get_shader(rt_sdf.shader_version, 0), 0);
3659 RID aux2 = uniforms.write[2].get_id(0);
3660 RID aux3 = uniforms.write[3].get_id(0);
3661 uniforms.write[2].set_id(0, aux3);
3662 uniforms.write[3].set_id(0, aux2);
3663 rt->sdf_buffer_process_uniform_sets[1] = RD::get_singleton()->uniform_set_create(uniforms, rt_sdf.shader.version_get_shader(rt_sdf.shader_version, 0), 0);
3664 }
3665}
3666
3667void TextureStorage::_render_target_clear_sdf(RenderTarget *rt) {
3668 if (rt->sdf_buffer_read.is_valid()) {
3669 RD::get_singleton()->free(rt->sdf_buffer_read);
3670 rt->sdf_buffer_read = RID();
3671 }
3672 if (rt->sdf_buffer_write_fb.is_valid()) {
3673 RD::get_singleton()->free(rt->sdf_buffer_write);
3674 RD::get_singleton()->free(rt->sdf_buffer_process[0]);
3675 RD::get_singleton()->free(rt->sdf_buffer_process[1]);
3676 rt->sdf_buffer_write = RID();
3677 rt->sdf_buffer_write_fb = RID();
3678 rt->sdf_buffer_process[0] = RID();
3679 rt->sdf_buffer_process[1] = RID();
3680 rt->sdf_buffer_process_uniform_sets[0] = RID();
3681 rt->sdf_buffer_process_uniform_sets[1] = RID();
3682 }
3683}
3684
3685RID TextureStorage::render_target_get_sdf_framebuffer(RID p_render_target) {
3686 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3687 ERR_FAIL_COND_V(!rt, RID());
3688
3689 if (rt->sdf_buffer_write_fb.is_null()) {
3690 _render_target_allocate_sdf(rt);
3691 }
3692
3693 return rt->sdf_buffer_write_fb;
3694}
3695void TextureStorage::render_target_sdf_process(RID p_render_target) {
3696 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3697 ERR_FAIL_COND(!rt);
3698 ERR_FAIL_COND(rt->sdf_buffer_write_fb.is_null());
3699
3700 RenderTargetSDF::PushConstant push_constant;
3701
3702 Rect2i r = _render_target_get_sdf_rect(rt);
3703
3704 push_constant.size[0] = r.size.width;
3705 push_constant.size[1] = r.size.height;
3706 push_constant.stride = 0;
3707 push_constant.shift = 0;
3708 push_constant.base_size[0] = r.size.width;
3709 push_constant.base_size[1] = r.size.height;
3710
3711 bool shrink = false;
3712
3713 switch (rt->sdf_scale) {
3714 case RS::VIEWPORT_SDF_SCALE_50_PERCENT: {
3715 push_constant.size[0] >>= 1;
3716 push_constant.size[1] >>= 1;
3717 push_constant.shift = 1;
3718 shrink = true;
3719 } break;
3720 case RS::VIEWPORT_SDF_SCALE_25_PERCENT: {
3721 push_constant.size[0] >>= 2;
3722 push_constant.size[1] >>= 2;
3723 push_constant.shift = 2;
3724 shrink = true;
3725 } break;
3726 default: {
3727 };
3728 }
3729
3730 RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
3731
3732 /* Load */
3733
3734 RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, rt_sdf.pipelines[shrink ? RenderTargetSDF::SHADER_LOAD_SHRINK : RenderTargetSDF::SHADER_LOAD]);
3735 RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[1], 0); //fill [0]
3736 RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant));
3737
3738 RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1);
3739
3740 /* Process */
3741
3742 int stride = nearest_power_of_2_templated(MAX(push_constant.size[0], push_constant.size[1]) / 2);
3743
3744 RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, rt_sdf.pipelines[RenderTargetSDF::SHADER_PROCESS]);
3745
3746 RD::get_singleton()->compute_list_add_barrier(compute_list);
3747 bool swap = false;
3748
3749 //jumpflood
3750 while (stride > 0) {
3751 RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[swap ? 1 : 0], 0);
3752 push_constant.stride = stride;
3753 RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant));
3754 RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1);
3755 stride /= 2;
3756 swap = !swap;
3757 RD::get_singleton()->compute_list_add_barrier(compute_list);
3758 }
3759
3760 /* Store */
3761
3762 RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, rt_sdf.pipelines[shrink ? RenderTargetSDF::SHADER_STORE_SHRINK : RenderTargetSDF::SHADER_STORE]);
3763 RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[swap ? 1 : 0], 0);
3764 RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant));
3765 RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1);
3766
3767 RD::get_singleton()->compute_list_end();
3768}
3769
3770void TextureStorage::render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps) {
3771 CopyEffects *copy_effects = CopyEffects::get_singleton();
3772 ERR_FAIL_NULL(copy_effects);
3773
3774 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3775 ERR_FAIL_COND(!rt);
3776 if (!rt->backbuffer.is_valid()) {
3777 _create_render_target_backbuffer(rt);
3778 }
3779
3780 Rect2i region;
3781 if (p_region == Rect2i()) {
3782 region.size = rt->size;
3783 } else {
3784 region = Rect2i(Size2i(), rt->size).intersection(p_region);
3785 if (region.size == Size2i()) {
3786 return; //nothing to do
3787 }
3788 }
3789
3790 // TODO figure out stereo support here
3791
3792 if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) {
3793 copy_effects->copy_to_rect(rt->color, rt->backbuffer_mipmap0, region, false, false, false, !rt->use_hdr, true);
3794 } else {
3795 copy_effects->copy_to_fb_rect(rt->color, rt->backbuffer_fb, region, false, false, false, false, RID(), false, true);
3796 }
3797
3798 if (!p_gen_mipmaps) {
3799 return;
3800 }
3801 RD::get_singleton()->draw_command_begin_label("Gaussian Blur Mipmaps");
3802 //then mipmap blur
3803 RID prev_texture = rt->color; //use color, not backbuffer, as bb has mipmaps.
3804
3805 Size2i texture_size = rt->size;
3806
3807 for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
3808 region.position.x >>= 1;
3809 region.position.y >>= 1;
3810 region.size.x = MAX(1, region.size.x >> 1);
3811 region.size.y = MAX(1, region.size.y >> 1);
3812 texture_size.x = MAX(1, texture_size.x >> 1);
3813 texture_size.y = MAX(1, texture_size.y >> 1);
3814
3815 RID mipmap = rt->backbuffer_mipmaps[i];
3816 if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) {
3817 copy_effects->gaussian_blur(prev_texture, mipmap, region, texture_size, !rt->use_hdr);
3818 } else {
3819 copy_effects->gaussian_blur_raster(prev_texture, mipmap, region, texture_size);
3820 }
3821 prev_texture = mipmap;
3822 }
3823 RD::get_singleton()->draw_command_end_label();
3824}
3825
3826void TextureStorage::render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color) {
3827 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3828 ERR_FAIL_COND(!rt);
3829
3830 CopyEffects *copy_effects = CopyEffects::get_singleton();
3831 ERR_FAIL_NULL(copy_effects);
3832
3833 if (!rt->backbuffer.is_valid()) {
3834 _create_render_target_backbuffer(rt);
3835 }
3836
3837 Rect2i region;
3838 if (p_region == Rect2i()) {
3839 region.size = rt->size;
3840 } else {
3841 region = Rect2i(Size2i(), rt->size).intersection(p_region);
3842 if (region.size == Size2i()) {
3843 return; //nothing to do
3844 }
3845 }
3846
3847 // Single texture copy for backbuffer.
3848 if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) {
3849 copy_effects->set_color(rt->backbuffer_mipmap0, p_color, region, !rt->use_hdr);
3850 } else {
3851 copy_effects->set_color_raster(rt->backbuffer_mipmap0, p_color, region);
3852 }
3853}
3854
3855void TextureStorage::render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region) {
3856 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3857 ERR_FAIL_COND(!rt);
3858
3859 CopyEffects *copy_effects = CopyEffects::get_singleton();
3860 ERR_FAIL_NULL(copy_effects);
3861
3862 if (!rt->backbuffer.is_valid()) {
3863 _create_render_target_backbuffer(rt);
3864 }
3865
3866 Rect2i region;
3867 if (p_region == Rect2i()) {
3868 region.size = rt->size;
3869 } else {
3870 region = Rect2i(Size2i(), rt->size).intersection(p_region);
3871 if (region.size == Size2i()) {
3872 return; //nothing to do
3873 }
3874 }
3875 RD::get_singleton()->draw_command_begin_label("Gaussian Blur Mipmaps2");
3876 //then mipmap blur
3877 RID prev_texture = rt->backbuffer_mipmap0;
3878 Size2i texture_size = rt->size;
3879
3880 for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
3881 region.position.x >>= 1;
3882 region.position.y >>= 1;
3883 region.size.x = MAX(1, region.size.x >> 1);
3884 region.size.y = MAX(1, region.size.y >> 1);
3885 texture_size.x = MAX(1, texture_size.x >> 1);
3886 texture_size.y = MAX(1, texture_size.y >> 1);
3887
3888 RID mipmap = rt->backbuffer_mipmaps[i];
3889
3890 if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) {
3891 copy_effects->gaussian_blur(prev_texture, mipmap, region, texture_size, !rt->use_hdr);
3892 } else {
3893 copy_effects->gaussian_blur_raster(prev_texture, mipmap, region, texture_size);
3894 }
3895 prev_texture = mipmap;
3896 }
3897 RD::get_singleton()->draw_command_end_label();
3898}
3899
3900RID TextureStorage::render_target_get_framebuffer_uniform_set(RID p_render_target) {
3901 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3902 ERR_FAIL_COND_V(!rt, RID());
3903 return rt->framebuffer_uniform_set;
3904}
3905RID TextureStorage::render_target_get_backbuffer_uniform_set(RID p_render_target) {
3906 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3907 ERR_FAIL_COND_V(!rt, RID());
3908 return rt->backbuffer_uniform_set;
3909}
3910
3911void TextureStorage::render_target_set_framebuffer_uniform_set(RID p_render_target, RID p_uniform_set) {
3912 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3913 ERR_FAIL_COND(!rt);
3914 rt->framebuffer_uniform_set = p_uniform_set;
3915}
3916
3917void TextureStorage::render_target_set_backbuffer_uniform_set(RID p_render_target, RID p_uniform_set) {
3918 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3919 ERR_FAIL_COND(!rt);
3920 rt->backbuffer_uniform_set = p_uniform_set;
3921}
3922
3923void TextureStorage::render_target_set_vrs_mode(RID p_render_target, RS::ViewportVRSMode p_mode) {
3924 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3925 ERR_FAIL_COND(!rt);
3926
3927 rt->vrs_mode = p_mode;
3928}
3929
3930RS::ViewportVRSMode TextureStorage::render_target_get_vrs_mode(RID p_render_target) const {
3931 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3932 ERR_FAIL_COND_V(!rt, RS::VIEWPORT_VRS_DISABLED);
3933
3934 return rt->vrs_mode;
3935}
3936
3937void TextureStorage::render_target_set_vrs_texture(RID p_render_target, RID p_texture) {
3938 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3939 ERR_FAIL_COND(!rt);
3940
3941 rt->vrs_texture = p_texture;
3942}
3943
3944RID TextureStorage::render_target_get_vrs_texture(RID p_render_target) const {
3945 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3946 ERR_FAIL_COND_V(!rt, RID());
3947
3948 return rt->vrs_texture;
3949}
3950