Răsfoiți Sursa

Merge canvas and decal into TextureStorage and add render target

Bastiaan Olij 3 ani în urmă
părinte
comite
6b28d94e77
49 a modificat fișierele cu 3143 adăugiri și 3696 ștergeri
  1. 26 20
      drivers/gles3/rasterizer_canvas_gles3.cpp
  2. 0 1
      drivers/gles3/rasterizer_canvas_gles3.h
  3. 13 8
      drivers/gles3/rasterizer_gles3.cpp
  4. 0 7
      drivers/gles3/rasterizer_gles3.h
  5. 7 844
      drivers/gles3/rasterizer_storage_gles3.cpp
  6. 0 84
      drivers/gles3/rasterizer_storage_gles3.h
  7. 0 96
      drivers/gles3/storage/canvas_texture_storage.cpp
  8. 0 87
      drivers/gles3/storage/canvas_texture_storage.h
  9. 4 0
      drivers/gles3/storage/config.cpp
  10. 0 75
      drivers/gles3/storage/decal_atlas_storage.cpp
  11. 0 67
      drivers/gles3/storage/decal_atlas_storage.h
  12. 0 132
      drivers/gles3/storage/render_target_storage.h
  13. 932 0
      drivers/gles3/storage/texture_storage.cpp
  14. 226 2
      drivers/gles3/storage/texture_storage.h
  15. 2 1
      modules/openxr/extensions/openxr_vulkan_extension.cpp
  16. 0 6
      servers/rendering/dummy/rasterizer_dummy.h
  17. 1 20
      servers/rendering/dummy/rasterizer_storage_dummy.h
  18. 0 53
      servers/rendering/dummy/storage/canvas_texture_storage.h
  19. 0 62
      servers/rendering/dummy/storage/decal_atlas_storage.h
  20. 56 0
      servers/rendering/dummy/storage/texture_storage.h
  21. 7 7
      servers/rendering/renderer_canvas_cull.cpp
  22. 0 4
      servers/rendering/renderer_compositor.h
  23. 3 3
      servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
  24. 3 3
      servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
  25. 43 37
      servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
  26. 1 5
      servers/rendering/renderer_rd/renderer_compositor_rd.cpp
  27. 0 6
      servers/rendering/renderer_rd/renderer_compositor_rd.h
  28. 3 2
      servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
  29. 0 1
      servers/rendering/renderer_rd/renderer_scene_gi_rd.h
  30. 55 51
      servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
  31. 13 736
      servers/rendering/renderer_rd/renderer_storage_rd.cpp
  32. 0 120
      servers/rendering/renderer_rd/renderer_storage_rd.h
  33. 0 235
      servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.cpp
  34. 0 90
      servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h
  35. 0 437
      servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.cpp
  36. 0 211
      servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h
  37. 1315 3
      servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
  38. 336 1
      servers/rendering/renderer_rd/storage_rd/texture_storage.h
  39. 1 1
      servers/rendering/renderer_scene_cull.cpp
  40. 0 27
      servers/rendering/renderer_storage.h
  41. 28 27
      servers/rendering/renderer_viewport.cpp
  42. 0 2
      servers/rendering/rendering_server_default.cpp
  43. 2 2
      servers/rendering/rendering_server_default.h
  44. 0 2
      servers/rendering/rendering_server_globals.cpp
  45. 0 4
      servers/rendering/rendering_server_globals.h
  46. 0 51
      servers/rendering/storage/canvas_texture_storage.h
  47. 0 60
      servers/rendering/storage/decal_atlas_storage.h
  48. 62 0
      servers/rendering/storage/texture_storage.h
  49. 4 3
      servers/xr/xr_interface_extension.cpp

+ 26 - 20
drivers/gles3/rasterizer_canvas_gles3.cpp

@@ -38,9 +38,9 @@
 
 #include "core/config/project_settings.h"
 #include "servers/rendering/rendering_server_default.h"
-#include "storage/canvas_texture_storage.h"
 #include "storage/config.h"
 #include "storage/material_storage.h"
+#include "storage/texture_storage.h"
 
 #ifndef GLES_OVER_GL
 #define glClearDepth glClearDepthf
@@ -116,9 +116,11 @@ void RasterizerCanvasGLES3::_update_transform_to_mat4(const Transform3D &p_trans
 }
 
 void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) {
-	storage->frame.current_rt = nullptr;
+	GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
+
+	texture_storage->frame.current_rt = nullptr;
 
-	storage->_set_current_render_target(p_to_render_target);
+	texture_storage->_set_current_render_target(p_to_render_target);
 
 	Transform2D canvas_transform_inverse = p_canvas_transform.affine_inverse();
 
@@ -130,7 +132,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
 		//update canvas state uniform buffer
 		StateBuffer state_buffer;
 
-		Size2i ssize = storage->render_target_get_size(p_to_render_target);
+		Size2i ssize = texture_storage->render_target_get_size(p_to_render_target);
 
 		Transform3D screen_transform;
 		screen_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f);
@@ -149,11 +151,11 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
 		state_buffer.canvas_modulate[2] = p_modulate.b;
 		state_buffer.canvas_modulate[3] = p_modulate.a;
 
-		Size2 render_target_size = storage->render_target_get_size(p_to_render_target);
+		Size2 render_target_size = texture_storage->render_target_get_size(p_to_render_target);
 		state_buffer.screen_pixel_size[0] = 1.0 / render_target_size.x;
 		state_buffer.screen_pixel_size[1] = 1.0 / render_target_size.y;
 
-		state_buffer.time = storage->frame.time;
+		state_buffer.time = texture_storage->frame.time;
 		state_buffer.use_pixel_snap = p_snap_2d_vertices_to_pixel;
 
 		state_buffer.directional_light_count = 0; //directional_light_count;
@@ -166,7 +168,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
 		state_buffer.screen_to_sdf[0] = 1.0 / state_buffer.sdf_to_screen[0];
 		state_buffer.screen_to_sdf[1] = 1.0 / state_buffer.sdf_to_screen[1];
 
-		Rect2 sdf_rect = storage->render_target_get_sdf_rect(p_to_render_target);
+		Rect2 sdf_rect = texture_storage->render_target_get_sdf_rect(p_to_render_target);
 		Rect2 sdf_tex_rect(sdf_rect.position / canvas_scale, sdf_rect.size / canvas_scale);
 
 		state_buffer.sdf_to_tex[0] = 1.0 / sdf_tex_rect.size.width;
@@ -881,19 +883,21 @@ void RasterizerCanvasGLES3::update() {
 }
 
 void RasterizerCanvasGLES3::canvas_begin() {
+	GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
+
 	state.using_transparent_rt = false;
 
-	if (storage->frame.current_rt) {
-		storage->bind_framebuffer(storage->frame.current_rt->fbo);
-		state.using_transparent_rt = storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT];
+	if (texture_storage->frame.current_rt) {
+		glBindFramebuffer(GL_FRAMEBUFFER, texture_storage->frame.current_rt->fbo);
+		state.using_transparent_rt = texture_storage->frame.current_rt->flags[GLES3::TextureStorage::RENDER_TARGET_TRANSPARENT];
 	}
 
-	if (storage->frame.current_rt && storage->frame.current_rt->clear_requested) {
-		const Color &col = storage->frame.current_rt->clear_color;
+	if (texture_storage->frame.current_rt && texture_storage->frame.current_rt->clear_requested) {
+		const Color &col = texture_storage->frame.current_rt->clear_color;
 		glClearColor(col.r, col.g, col.b, col.a);
 
 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
-		storage->frame.current_rt->clear_requested = false;
+		texture_storage->frame.current_rt->clear_requested = false;
 	}
 
 	reset_canvas();
@@ -934,7 +938,7 @@ void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTe
 
 		ct = t->canvas_texture;
 	} else {
-		ct = GLES3::CanvasTextureStorage::get_singleton()->get_canvas_texture(p_texture);
+		ct = GLES3::TextureStorage::get_singleton()->get_canvas_texture(p_texture);
 	}
 
 	if (!ct) {
@@ -1041,6 +1045,8 @@ void RasterizerCanvasGLES3::_set_uniforms() {
 }
 
 void RasterizerCanvasGLES3::reset_canvas() {
+	GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
+
 	glDisable(GL_CULL_FACE);
 	glDisable(GL_DEPTH_TEST);
 	glDisable(GL_SCISSOR_TEST);
@@ -1049,7 +1055,7 @@ void RasterizerCanvasGLES3::reset_canvas() {
 
 	// Default to Mix.
 	glBlendEquation(GL_FUNC_ADD);
-	if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) {
+	if (texture_storage->frame.current_rt && texture_storage->frame.current_rt->flags[GLES3::TextureStorage::RENDER_TARGET_TRANSPARENT]) {
 		glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
 	} else {
 		glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
@@ -1255,7 +1261,7 @@ void RasterizerCanvasGLES3::_allocate_instance_data_buffer() {
 }
 
 void RasterizerCanvasGLES3::initialize() {
-	GLES3::CanvasTextureStorage *canvas_texture_storage = GLES3::CanvasTextureStorage::get_singleton();
+	GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
 	GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
 
 	// quad buffer
@@ -1450,8 +1456,8 @@ void fragment() {
 		material_storage->material_set_shader(default_canvas_group_material, default_canvas_group_shader);
 	}
 
-	default_canvas_texture = canvas_texture_storage->canvas_texture_allocate();
-	canvas_texture_storage->canvas_texture_initialize(default_canvas_texture);
+	default_canvas_texture = texture_storage->canvas_texture_allocate();
+	texture_storage->canvas_texture_initialize(default_canvas_texture);
 
 	state.using_light = nullptr;
 	state.using_transparent_rt = false;
@@ -1470,13 +1476,13 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
 }
 
 RasterizerCanvasGLES3::~RasterizerCanvasGLES3() {
-	GLES3::CanvasTextureStorage *canvas_texture_storage = GLES3::CanvasTextureStorage::get_singleton();
+	GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
 	GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
 
 	state.canvas_shader.version_free(state.canvas_shader_default_version);
 	material_storage->material_free(default_canvas_group_material);
 	material_storage->shader_free(default_canvas_group_shader);
-	canvas_texture_storage->canvas_texture_free(default_canvas_texture);
+	texture_storage->canvas_texture_free(default_canvas_texture);
 	singleton = nullptr;
 }
 

+ 0 - 1
drivers/gles3/rasterizer_canvas_gles3.h

@@ -37,7 +37,6 @@
 #include "rasterizer_storage_gles3.h"
 #include "servers/rendering/renderer_canvas_render.h"
 #include "servers/rendering/renderer_compositor.h"
-#include "storage/canvas_texture_storage.h"
 #include "storage/material_storage.h"
 #include "storage/texture_storage.h"
 

+ 13 - 8
drivers/gles3/rasterizer_gles3.cpp

@@ -34,6 +34,7 @@
 
 #include "core/config/project_settings.h"
 #include "core/os/os.h"
+#include "storage/texture_storage.h"
 
 #define _EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242
 #define _EXT_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243
@@ -87,6 +88,8 @@
 #endif
 
 void RasterizerGLES3::begin_frame(double frame_step) {
+	GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
+
 	frame++;
 	delta = frame_step;
 
@@ -95,9 +98,9 @@ void RasterizerGLES3::begin_frame(double frame_step) {
 	double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs");
 	time_total = Math::fmod(time_total, time_roll_over);
 
-	storage.frame.time = time_total;
-	storage.frame.count++;
-	storage.frame.delta = frame_step;
+	texture_storage->frame.time = time_total;
+	texture_storage->frame.count++;
+	texture_storage->frame.delta = frame_step;
 
 	storage.update_dirty_resources();
 
@@ -269,9 +272,10 @@ void RasterizerGLES3::prepare_for_blitting_render_targets() {
 }
 
 void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, DisplayServer::WindowID p_screen, const Rect2 &p_screen_rect) {
-	ERR_FAIL_COND(storage.frame.current_rt);
+	GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
+	ERR_FAIL_COND(texture_storage->frame.current_rt);
 
-	GLES3::RenderTarget *rt = storage.render_target_owner.get_or_null(p_render_target);
+	GLES3::RenderTarget *rt = texture_storage->get_render_target(p_render_target);
 	ERR_FAIL_COND(!rt);
 
 	// TODO: do we need a keep 3d linear option?
@@ -282,16 +286,17 @@ void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, Display
 		glBindFramebuffer(GL_READ_FRAMEBUFFER, rt->fbo);
 	}
 	glReadBuffer(GL_COLOR_ATTACHMENT0);
-	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
+	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
 	glBlitFramebuffer(0, 0, rt->width, rt->height, 0, p_screen_rect.size.y, p_screen_rect.size.x, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
 }
 
 // is this p_screen useless in a multi window environment?
 void RasterizerGLES3::blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) {
 	// do this once off for all blits
-	storage.bind_framebuffer_system();
+	GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
+	glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
 
-	storage.frame.current_rt = nullptr;
+	texture_storage->frame.current_rt = nullptr;
 
 	for (int i = 0; i < p_amount; i++) {
 		const BlitToScreen &blit = p_render_targets[i];

+ 0 - 7
drivers/gles3/rasterizer_gles3.h

@@ -37,12 +37,9 @@
 #include "rasterizer_scene_gles3.h"
 #include "rasterizer_storage_gles3.h"
 #include "servers/rendering/renderer_compositor.h"
-#include "storage/canvas_texture_storage.h"
 #include "storage/config.h"
-#include "storage/decal_atlas_storage.h"
 #include "storage/material_storage.h"
 #include "storage/mesh_storage.h"
-#include "storage/render_target_storage.h"
 #include "storage/texture_storage.h"
 
 class RasterizerGLES3 : public RendererCompositor {
@@ -54,9 +51,7 @@ private:
 
 protected:
 	GLES3::Config config;
-	GLES3::CanvasTextureStorage canvas_texture_storage;
 	GLES3::TextureStorage texture_storage;
-	GLES3::DecalAtlasStorage decal_atlas_storage;
 	GLES3::MaterialStorage material_storage;
 	GLES3::MeshStorage mesh_storage;
 	RasterizerStorageGLES3 storage;
@@ -66,11 +61,9 @@ protected:
 	void _blit_render_target_to_screen(RID p_render_target, DisplayServer::WindowID p_screen, const Rect2 &p_screen_rect);
 
 public:
-	RendererCanvasTextureStorage *get_canvas_texture_storage() { return &canvas_texture_storage; }
 	RendererMaterialStorage *get_material_storage() { return &material_storage; }
 	RendererMeshStorage *get_mesh_storage() { return &mesh_storage; }
 	RendererTextureStorage *get_texture_storage() { return &texture_storage; }
-	RendererDecalAtlasStorage *get_decal_atlas_storage() { return &decal_atlas_storage; }
 	RendererStorage *get_storage() { return &storage; }
 	RendererCanvasRender *get_canvas() { return &canvas; }
 	RendererSceneRender *get_scene() { return &scene; }

+ 7 - 844
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -38,8 +38,6 @@
 #include "rasterizer_scene_gles3.h"
 #include "servers/rendering/shader_language.h"
 
-GLuint RasterizerStorageGLES3::system_fbo = 0;
-
 void RasterizerStorageGLES3::bind_quad_array() const {
 	//glBindBuffer(GL_ARRAY_BUFFER, resources.quadie);
 	//glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0);
@@ -658,758 +656,6 @@ AABB RasterizerStorageGLES3::visibility_notifier_get_aabb(RID p_notifier) const
 void RasterizerStorageGLES3::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) {
 }
 
-/* RENDER TARGET */
-
-void RasterizerStorageGLES3::_set_current_render_target(RID p_render_target) {
-	GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-
-	if (rt) {
-		if (rt->allocate_is_dirty) {
-			rt->allocate_is_dirty = false;
-			_render_target_allocate(rt);
-		}
-
-		frame.current_rt = rt;
-		ERR_FAIL_COND(!rt);
-		frame.clear_request = false;
-
-		glViewport(0, 0, rt->width, rt->height);
-
-		_dims.rt_width = rt->width;
-		_dims.rt_height = rt->height;
-		_dims.win_width = rt->width;
-		_dims.win_height = rt->height;
-
-	} else {
-		frame.current_rt = nullptr;
-		frame.clear_request = false;
-		bind_framebuffer_system();
-	}
-}
-
-void RasterizerStorageGLES3::_render_target_allocate(GLES3::RenderTarget *rt) {
-	// do not allocate a render target with no size
-	if (rt->width <= 0 || rt->height <= 0) {
-		return;
-	}
-
-	// do not allocate a render target that is attached to the screen
-	if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) {
-		rt->fbo = RasterizerStorageGLES3::system_fbo;
-		return;
-	}
-
-	GLuint color_internal_format;
-	GLuint color_format;
-	GLuint color_type = GL_UNSIGNED_BYTE;
-	Image::Format image_format;
-
-	if (rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) {
-#ifdef GLES_OVER_GL
-		color_internal_format = GL_RGBA8;
-#else
-		color_internal_format = GL_RGBA;
-#endif
-		color_format = GL_RGBA;
-		image_format = Image::FORMAT_RGBA8;
-	} else {
-#ifdef GLES_OVER_GL
-		color_internal_format = GL_RGB8;
-#else
-		color_internal_format = GL_RGB;
-#endif
-		color_format = GL_RGB;
-		image_format = Image::FORMAT_RGB8;
-	}
-
-	rt->used_dof_blur_near = false;
-	rt->mip_maps_allocated = false;
-
-	{
-		/* Front FBO */
-
-		GLES3::Texture *texture = GLES3::TextureStorage::get_singleton()->get_texture(rt->texture);
-		ERR_FAIL_COND(!texture);
-
-		// framebuffer
-		glGenFramebuffers(1, &rt->fbo);
-		bind_framebuffer(rt->fbo);
-
-		// color
-		glGenTextures(1, &rt->color);
-		glBindTexture(GL_TEXTURE_2D, rt->color);
-
-		glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, nullptr);
-
-		if (texture->flags & GLES3::TEXTURE_FLAG_FILTER) {
-			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-		} else {
-			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-		}
-
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0);
-
-		// depth
-
-		if (config->support_depth_texture) {
-			glGenTextures(1, &rt->depth);
-			glBindTexture(GL_TEXTURE_2D, rt->depth);
-			glTexImage2D(GL_TEXTURE_2D, 0, config->depth_internalformat, rt->width, rt->height, 0, GL_DEPTH_COMPONENT, config->depth_type, nullptr);
-
-			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
-		} else {
-			glGenRenderbuffers(1, &rt->depth);
-			glBindRenderbuffer(GL_RENDERBUFFER, rt->depth);
-
-			glRenderbufferStorage(GL_RENDERBUFFER, config->depth_buffer_internalformat, rt->width, rt->height);
-
-			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
-		}
-
-		GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-
-		if (status != GL_FRAMEBUFFER_COMPLETE) {
-			glDeleteFramebuffers(1, &rt->fbo);
-			if (config->support_depth_texture) {
-				glDeleteTextures(1, &rt->depth);
-			} else {
-				glDeleteRenderbuffers(1, &rt->depth);
-			}
-
-			glDeleteTextures(1, &rt->color);
-			rt->fbo = 0;
-			rt->width = 0;
-			rt->height = 0;
-			rt->color = 0;
-			rt->depth = 0;
-			texture->tex_id = 0;
-			texture->active = false;
-			WARN_PRINT("Could not create framebuffer!!");
-			return;
-		}
-
-		texture->format = image_format;
-		texture->gl_format_cache = color_format;
-		texture->gl_type_cache = GL_UNSIGNED_BYTE;
-		texture->gl_internal_format_cache = color_internal_format;
-		texture->tex_id = rt->color;
-		texture->width = rt->width;
-		texture->alloc_width = rt->width;
-		texture->height = rt->height;
-		texture->alloc_height = rt->height;
-		texture->active = true;
-
-		GLES3::TextureStorage::get_singleton()->texture_set_flags(rt->texture, texture->flags);
-	}
-
-	/* BACK FBO */
-	/* For MSAA */
-
-#ifndef JAVASCRIPT_ENABLED
-	if (rt->msaa >= RS::VIEWPORT_MSAA_2X && rt->msaa <= RS::VIEWPORT_MSAA_8X) {
-		rt->multisample_active = true;
-
-		static const int msaa_value[] = { 0, 2, 4, 8, 16 };
-		int msaa = msaa_value[rt->msaa];
-
-		int max_samples = 0;
-		glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
-		if (msaa > max_samples) {
-			WARN_PRINT("MSAA must be <= GL_MAX_SAMPLES, falling-back to GL_MAX_SAMPLES = " + itos(max_samples));
-			msaa = max_samples;
-		}
-
-		//regular fbo
-		glGenFramebuffers(1, &rt->multisample_fbo);
-		bind_framebuffer(rt->multisample_fbo);
-
-		glGenRenderbuffers(1, &rt->multisample_depth);
-		glBindRenderbuffer(GL_RENDERBUFFER, rt->multisample_depth);
-		glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, config->depth_buffer_internalformat, rt->width, rt->height);
-
-		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->multisample_depth);
-
-		glGenRenderbuffers(1, &rt->multisample_color);
-		glBindRenderbuffer(GL_RENDERBUFFER, rt->multisample_color);
-		glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, color_internal_format, rt->width, rt->height);
-
-		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rt->multisample_color);
-
-		GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-
-		if (status != GL_FRAMEBUFFER_COMPLETE) {
-			// Delete allocated resources and default to no MSAA
-			WARN_PRINT_ONCE("Cannot allocate back framebuffer for MSAA");
-			printf("err status: %x\n", status);
-			rt->multisample_active = false;
-
-			glDeleteFramebuffers(1, &rt->multisample_fbo);
-			rt->multisample_fbo = 0;
-
-			glDeleteRenderbuffers(1, &rt->multisample_depth);
-			rt->multisample_depth = 0;
-
-			glDeleteRenderbuffers(1, &rt->multisample_color);
-			rt->multisample_color = 0;
-		}
-
-		glBindRenderbuffer(GL_RENDERBUFFER, 0);
-		bind_framebuffer(0);
-
-	} else
-#endif // JAVASCRIPT_ENABLED
-	{
-		rt->multisample_active = false;
-	}
-
-	glClearColor(0, 0, 0, 0);
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
-	// copy texscreen buffers
-	//	if (!(rt->flags[RendererStorage::RENDER_TARGET_NO_SAMPLING])) {
-	if (true) {
-		glGenTextures(1, &rt->copy_screen_effect.color);
-		glBindTexture(GL_TEXTURE_2D, rt->copy_screen_effect.color);
-
-		if (rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) {
-			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
-		} else {
-			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rt->width, rt->height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
-		}
-
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-		glGenFramebuffers(1, &rt->copy_screen_effect.fbo);
-		bind_framebuffer(rt->copy_screen_effect.fbo);
-		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->copy_screen_effect.color, 0);
-
-		glClearColor(0, 0, 0, 0);
-		glClear(GL_COLOR_BUFFER_BIT);
-
-		GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-		if (status != GL_FRAMEBUFFER_COMPLETE) {
-			_render_target_clear(rt);
-			ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
-		}
-	}
-
-	// Allocate mipmap chains for post_process effects
-	//	if (!rt->flags[RendererStorage::RENDER_TARGET_NO_3D] && rt->width >= 2 && rt->height >= 2) {
-	if (rt->width >= 2 && rt->height >= 2) {
-		for (int i = 0; i < 2; i++) {
-			ERR_FAIL_COND(rt->mip_maps[i].sizes.size());
-			int w = rt->width;
-			int h = rt->height;
-
-			if (i > 0) {
-				w >>= 1;
-				h >>= 1;
-			}
-
-			int level = 0;
-			int fb_w = w;
-			int fb_h = h;
-
-			while (true) {
-				GLES3::RenderTarget::MipMaps::Size mm;
-				mm.width = w;
-				mm.height = h;
-				rt->mip_maps[i].sizes.push_back(mm);
-
-				w >>= 1;
-				h >>= 1;
-
-				if (w < 2 || h < 2) {
-					break;
-				}
-
-				level++;
-			}
-
-			GLsizei width = fb_w;
-			GLsizei height = fb_h;
-
-			if (config->render_to_mipmap_supported) {
-				glGenTextures(1, &rt->mip_maps[i].color);
-				glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].color);
-
-				for (int l = 0; l < level + 1; l++) {
-					glTexImage2D(GL_TEXTURE_2D, l, color_internal_format, width, height, 0, color_format, color_type, nullptr);
-					width = MAX(1, (width / 2));
-					height = MAX(1, (height / 2));
-				}
-#ifdef GLES_OVER_GL
-				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
-				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level);
-#endif
-			} else {
-				// Can't render to specific levels of a mipmap in ES 2.0 or Webgl so create a texture for each level
-				for (int l = 0; l < level + 1; l++) {
-					glGenTextures(1, &rt->mip_maps[i].sizes.write[l].color);
-					glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].sizes[l].color);
-					glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, width, height, 0, color_format, color_type, nullptr);
-					width = MAX(1, (width / 2));
-					height = MAX(1, (height / 2));
-					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-				}
-			}
-
-			glDisable(GL_SCISSOR_TEST);
-			glColorMask(1, 1, 1, 1);
-			glDepthMask(GL_TRUE);
-
-			for (int j = 0; j < rt->mip_maps[i].sizes.size(); j++) {
-				GLES3::RenderTarget::MipMaps::Size &mm = rt->mip_maps[i].sizes.write[j];
-
-				glGenFramebuffers(1, &mm.fbo);
-				bind_framebuffer(mm.fbo);
-
-				if (config->render_to_mipmap_supported) {
-					glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->mip_maps[i].color, j);
-				} else {
-					glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].sizes[j].color);
-					glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->mip_maps[i].sizes[j].color, 0);
-				}
-
-				bool used_depth = false;
-				if (j == 0 && i == 0) { //use always
-					if (config->support_depth_texture) {
-						glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
-					} else {
-						glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
-					}
-					used_depth = true;
-				}
-
-				GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-				if (status != GL_FRAMEBUFFER_COMPLETE) {
-					WARN_PRINT_ONCE("Cannot allocate mipmaps for 3D post processing effects");
-					bind_framebuffer_system();
-					return;
-				}
-
-				glClearColor(1.0, 0.0, 1.0, 0.0);
-				glClear(GL_COLOR_BUFFER_BIT);
-				if (used_depth) {
-					glClearDepth(1.0);
-					glClear(GL_DEPTH_BUFFER_BIT);
-				}
-			}
-
-			rt->mip_maps[i].levels = level;
-
-			if (config->render_to_mipmap_supported) {
-				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
-				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-			}
-		}
-		rt->mip_maps_allocated = true;
-	}
-
-	bind_framebuffer_system();
-}
-
-void RasterizerStorageGLES3::_render_target_clear(GLES3::RenderTarget *rt) {
-	// there is nothing to clear when DIRECT_TO_SCREEN is used
-	if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) {
-		return;
-	}
-
-	if (rt->fbo) {
-		glDeleteFramebuffers(1, &rt->fbo);
-		glDeleteTextures(1, &rt->color);
-		rt->fbo = 0;
-	}
-
-	if (rt->external.fbo != 0) {
-		// free this
-		glDeleteFramebuffers(1, &rt->external.fbo);
-
-		// clean up our texture
-		GLES3::Texture *t = GLES3::TextureStorage::get_singleton()->get_texture(rt->external.texture);
-		t->alloc_height = 0;
-		t->alloc_width = 0;
-		t->width = 0;
-		t->height = 0;
-		t->active = false;
-		GLES3::TextureStorage::get_singleton()->texture_free(rt->external.texture);
-		memdelete(t);
-
-		rt->external.fbo = 0;
-	}
-
-	if (rt->depth) {
-		if (config->support_depth_texture) {
-			glDeleteTextures(1, &rt->depth);
-		} else {
-			glDeleteRenderbuffers(1, &rt->depth);
-		}
-
-		rt->depth = 0;
-	}
-
-	GLES3::Texture *tex = GLES3::TextureStorage::get_singleton()->get_texture(rt->texture);
-	tex->alloc_height = 0;
-	tex->alloc_width = 0;
-	tex->width = 0;
-	tex->height = 0;
-	tex->active = false;
-
-	if (rt->copy_screen_effect.color) {
-		glDeleteFramebuffers(1, &rt->copy_screen_effect.fbo);
-		rt->copy_screen_effect.fbo = 0;
-
-		glDeleteTextures(1, &rt->copy_screen_effect.color);
-		rt->copy_screen_effect.color = 0;
-	}
-
-	for (int i = 0; i < 2; i++) {
-		if (rt->mip_maps[i].sizes.size()) {
-			for (int j = 0; j < rt->mip_maps[i].sizes.size(); j++) {
-				glDeleteFramebuffers(1, &rt->mip_maps[i].sizes[j].fbo);
-				glDeleteTextures(1, &rt->mip_maps[i].sizes[j].color);
-			}
-
-			glDeleteTextures(1, &rt->mip_maps[i].color);
-			rt->mip_maps[i].sizes.clear();
-			rt->mip_maps[i].levels = 0;
-			rt->mip_maps[i].color = 0;
-		}
-	}
-
-	if (rt->multisample_active) {
-		glDeleteFramebuffers(1, &rt->multisample_fbo);
-		rt->multisample_fbo = 0;
-
-		glDeleteRenderbuffers(1, &rt->multisample_depth);
-		rt->multisample_depth = 0;
-
-		glDeleteRenderbuffers(1, &rt->multisample_color);
-
-		rt->multisample_color = 0;
-	}
-}
-
-RID RasterizerStorageGLES3::render_target_create() {
-	GLES3::RenderTarget *rt = memnew(GLES3::RenderTarget);
-	GLES3::Texture *t = memnew(GLES3::Texture);
-
-	t->type = RenderingDevice::TEXTURE_TYPE_2D;
-	t->flags = 0;
-	t->width = 0;
-	t->height = 0;
-	t->alloc_height = 0;
-	t->alloc_width = 0;
-	t->format = Image::FORMAT_R8;
-	t->target = GL_TEXTURE_2D;
-	t->gl_format_cache = 0;
-	t->gl_internal_format_cache = 0;
-	t->gl_type_cache = 0;
-	t->data_size = 0;
-	t->total_data_size = 0;
-	t->ignore_mipmaps = false;
-	t->compressed = false;
-	t->mipmaps = 1;
-	t->active = true;
-	t->tex_id = 0;
-	t->render_target = rt;
-
-	rt->texture = GLES3::TextureStorage::get_singleton()->make_rid(t);
-	return render_target_owner.make_rid(rt);
-}
-
-void RasterizerStorageGLES3::render_target_set_position(RID p_render_target, int p_x, int p_y) {
-	GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-
-	rt->x = p_x;
-	rt->y = p_y;
-}
-
-void RasterizerStorageGLES3::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) {
-	GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-
-	if (p_width == rt->width && p_height == rt->height) {
-		return;
-	}
-
-	_render_target_clear(rt);
-
-	rt->width = p_width;
-	rt->height = p_height;
-
-	// print_line("render_target_set_size " + itos(p_render_target.get_id()) + ", w " + itos(p_width) + " h " + itos(p_height));
-
-	rt->allocate_is_dirty = true;
-	//_render_target_allocate(rt);
-}
-
-// TODO: convert to Size2i internally
-Size2i RasterizerStorageGLES3::render_target_get_size(RID p_render_target) {
-	GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, Size2());
-
-	return Size2i(rt->width, rt->height);
-}
-
-RID RasterizerStorageGLES3::render_target_get_texture(RID p_render_target) {
-	GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, RID());
-
-	if (rt->external.fbo == 0) {
-		return rt->texture;
-	} else {
-		return rt->external.texture;
-	}
-}
-
-void RasterizerStorageGLES3::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) {
-	GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-
-	if (p_texture_id == 0) {
-		if (rt->external.fbo != 0) {
-			// free this
-			glDeleteFramebuffers(1, &rt->external.fbo);
-
-			// and this
-			if (rt->external.depth != 0) {
-				glDeleteRenderbuffers(1, &rt->external.depth);
-			}
-
-			// clean up our texture
-			GLES3::Texture *t = GLES3::TextureStorage::get_singleton()->get_texture(rt->external.texture);
-			t->alloc_height = 0;
-			t->alloc_width = 0;
-			t->width = 0;
-			t->height = 0;
-			t->active = false;
-			GLES3::TextureStorage::get_singleton()->texture_free(rt->external.texture);
-			memdelete(t);
-
-			rt->external.fbo = 0;
-			rt->external.color = 0;
-			rt->external.depth = 0;
-		}
-	} else {
-		GLES3::Texture *t;
-
-		if (rt->external.fbo == 0) {
-			// create our fbo
-			glGenFramebuffers(1, &rt->external.fbo);
-			bind_framebuffer(rt->external.fbo);
-
-			// allocate a texture
-			t = memnew(GLES3::Texture);
-
-			t->type = RenderingDevice::TEXTURE_TYPE_2D;
-			t->flags = 0;
-			t->width = 0;
-			t->height = 0;
-			t->alloc_height = 0;
-			t->alloc_width = 0;
-			t->format = Image::FORMAT_RGBA8;
-			t->target = GL_TEXTURE_2D;
-			t->gl_format_cache = 0;
-			t->gl_internal_format_cache = 0;
-			t->gl_type_cache = 0;
-			t->data_size = 0;
-			t->compressed = false;
-			t->srgb = false;
-			t->total_data_size = 0;
-			t->ignore_mipmaps = false;
-			t->mipmaps = 1;
-			t->active = true;
-			t->tex_id = 0;
-			t->render_target = rt;
-
-			rt->external.texture = GLES3::TextureStorage::get_singleton()->make_rid(t);
-
-		} else {
-			// bind our frame buffer
-			bind_framebuffer(rt->external.fbo);
-
-			// find our texture
-			t = GLES3::TextureStorage::get_singleton()->get_texture(rt->external.texture);
-		}
-
-		// set our texture
-		t->tex_id = p_texture_id;
-		rt->external.color = p_texture_id;
-
-		// size shouldn't be different
-		t->width = rt->width;
-		t->height = rt->height;
-		t->alloc_height = rt->width;
-		t->alloc_width = rt->height;
-
-		// Switch our texture on our frame buffer
-		{
-			// set our texture as the destination for our framebuffer
-			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_texture_id, 0);
-
-			// seeing we're rendering into this directly, better also use our depth buffer, just use our existing one :)
-			if (config->support_depth_texture) {
-				glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
-			} else {
-				glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
-			}
-		}
-
-		// check status and unbind
-		GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-		bind_framebuffer_system();
-
-		if (status != GL_FRAMEBUFFER_COMPLETE) {
-			printf("framebuffer fail, status: %x\n", status);
-		}
-
-		ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
-	}
-}
-
-void RasterizerStorageGLES3::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) {
-	GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-
-	// When setting DIRECT_TO_SCREEN, you need to clear before the value is set, but allocate after as
-	// those functions change how they operate depending on the value of DIRECT_TO_SCREEN
-	if (p_flag == RENDER_TARGET_DIRECT_TO_SCREEN && p_value != rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) {
-		_render_target_clear(rt);
-		rt->flags[p_flag] = p_value;
-		_render_target_allocate(rt);
-	}
-
-	rt->flags[p_flag] = p_value;
-
-	switch (p_flag) {
-		case RENDER_TARGET_TRANSPARENT:
-			/*
-		case RENDER_TARGET_HDR:
-		case RENDER_TARGET_NO_3D:
-		case RENDER_TARGET_NO_SAMPLING:
-		case RENDER_TARGET_NO_3D_EFFECTS: */
-			{
-				//must reset for these formats
-				_render_target_clear(rt);
-				_render_target_allocate(rt);
-			}
-			break;
-		default: {
-		}
-	}
-}
-
-bool RasterizerStorageGLES3::render_target_was_used(RID p_render_target) {
-	GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, false);
-
-	return rt->used_in_frame;
-}
-
-void RasterizerStorageGLES3::render_target_clear_used(RID p_render_target) {
-	GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-
-	rt->used_in_frame = false;
-}
-
-void RasterizerStorageGLES3::render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) {
-	GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-
-	if (rt->msaa == p_msaa) {
-		return;
-	}
-
-	_render_target_clear(rt);
-	rt->msaa = p_msaa;
-	_render_target_allocate(rt);
-}
-
-//RasterizerStorageGLES3::GLES3::RenderTarget * RasterizerStorageGLES3::render_target_get(RID p_render_target)
-//{
-//	return render_target_owner.get_or_null(p_render_target);
-//}
-
-void RasterizerStorageGLES3::render_target_set_use_fxaa(RID p_render_target, bool p_fxaa) {
-	GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-
-	rt->use_fxaa = p_fxaa;
-}
-
-void RasterizerStorageGLES3::render_target_set_use_debanding(RID p_render_target, bool p_debanding) {
-	GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-
-	if (p_debanding) {
-		WARN_PRINT_ONCE("Debanding is not supported in the OpenGL backend. Switch to the Vulkan backend and make sure HDR is enabled.");
-	}
-
-	rt->use_debanding = p_debanding;
-}
-
-void RasterizerStorageGLES3::render_target_request_clear(RID p_render_target, const Color &p_clear_color) {
-	GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-	rt->clear_requested = true;
-	rt->clear_color = p_clear_color;
-
-	//	ERR_FAIL_COND(!frame.current_rt);
-	//	frame.clear_request = true;
-	//	frame.clear_request_color = p_color;
-}
-
-bool RasterizerStorageGLES3::render_target_is_clear_requested(RID p_render_target) {
-	GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, false);
-	return rt->clear_requested;
-}
-Color RasterizerStorageGLES3::render_target_get_clear_request_color(RID p_render_target) {
-	GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, Color());
-	return rt->clear_color;
-}
-
-void RasterizerStorageGLES3::render_target_disable_clear_request(RID p_render_target) {
-	GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-	rt->clear_requested = false;
-}
-
-void RasterizerStorageGLES3::render_target_do_clear_request(RID p_render_target) {
-}
-
-void RasterizerStorageGLES3::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) {
-}
-
-Rect2i RasterizerStorageGLES3::render_target_get_sdf_rect(RID p_render_target) const {
-	return Rect2i();
-}
-
-void RasterizerStorageGLES3::render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) {
-}
-
 /* CANVAS SHADOW */
 
 RID RasterizerStorageGLES3::canvas_light_shadow_buffer_create(int p_width) {
@@ -1425,7 +671,7 @@ RID RasterizerStorageGLES3::canvas_light_shadow_buffer_create(int p_width) {
 	glActiveTexture(GL_TEXTURE0);
 
 	glGenFramebuffers(1, &cls->fbo);
-	bind_framebuffer(cls->fbo);
+	glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo);
 
 	glGenRenderbuffers(1, &cls->depth);
 	glBindRenderbuffer(GL_RENDERBUFFER, cls->depth);
@@ -1452,7 +698,7 @@ RID RasterizerStorageGLES3::canvas_light_shadow_buffer_create(int p_width) {
 
 	GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
 	//printf("errnum: %x\n",status);
-	bind_framebuffer_system();
+	glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
 
 	if (status != GL_FRAMEBUFFER_COMPLETE) {
 		memdelete(cls);
@@ -1585,24 +831,14 @@ RS::InstanceType RasterizerStorageGLES3::get_base_type(RID p_rid) const {
 }
 
 bool RasterizerStorageGLES3::free(RID p_rid) {
-	if (render_target_owner.owns(p_rid)) {
-		GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_rid);
-		_render_target_clear(rt);
-
-		GLES3::Texture *t = GLES3::TextureStorage::get_singleton()->get_texture(rt->texture);
-		if (t) {
-			GLES3::TextureStorage::get_singleton()->texture_free(rt->texture);
-			memdelete(t);
-		}
-		render_target_owner.free(p_rid);
-		memdelete(rt);
-
+	if (GLES3::TextureStorage::get_singleton()->owns_render_target(p_rid)) {
+		GLES3::TextureStorage::get_singleton()->render_target_free(p_rid);
 		return true;
 	} else if (GLES3::TextureStorage::get_singleton()->owns_texture(p_rid)) {
 		GLES3::TextureStorage::get_singleton()->texture_free(p_rid);
 		return true;
-	} else if (GLES3::CanvasTextureStorage::get_singleton()->owns_canvas_texture(p_rid)) {
-		GLES3::CanvasTextureStorage::get_singleton()->canvas_texture_free(p_rid);
+	} else if (GLES3::TextureStorage::get_singleton()->owns_canvas_texture(p_rid)) {
+		GLES3::TextureStorage::get_singleton()->canvas_texture_free(p_rid);
 		return true;
 	} else if (sky_owner.owns(p_rid)) {
 		Sky *sky = sky_owner.get_or_null(p_rid);
@@ -1859,84 +1095,12 @@ RenderingDevice::DeviceType RasterizerStorageGLES3::get_video_adapter_type() con
 }
 
 void RasterizerStorageGLES3::initialize() {
-	RasterizerStorageGLES3::system_fbo = 0;
 	config = GLES3::Config::get_singleton();
-	config->initialize();
-
-	//determine formats for depth textures (or renderbuffers)
-	if (config->support_depth_texture) {
-		// Will use texture for depth
-		// have to manually see if we can create a valid framebuffer texture using UNSIGNED_INT,
-		// as there is no extension to test for this.
-		GLuint fbo;
-		glGenFramebuffers(1, &fbo);
-		bind_framebuffer(fbo);
-		GLuint depth;
-		glGenTextures(1, &depth);
-		glBindTexture(GL_TEXTURE_2D, depth);
-		glTexImage2D(GL_TEXTURE_2D, 0, config->depth_internalformat, 32, 32, 0, GL_DEPTH_COMPONENT, config->depth_type, nullptr);
-
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0);
-
-		GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-
-		bind_framebuffer_system();
-		glDeleteFramebuffers(1, &fbo);
-		glBindTexture(GL_TEXTURE_2D, 0);
-		glDeleteTextures(1, &depth);
-
-		if (status != GL_FRAMEBUFFER_COMPLETE) {
-			// If it fails, test to see if it supports a framebuffer texture using UNSIGNED_SHORT
-			// This is needed because many OSX devices don't support either UNSIGNED_INT or UNSIGNED_SHORT
-#ifdef GLES_OVER_GL
-			config->depth_internalformat = GL_DEPTH_COMPONENT16;
-#else
-			// OES_depth_texture extension only specifies GL_DEPTH_COMPONENT.
-			config->depth_internalformat = GL_DEPTH_COMPONENT;
-#endif
-			config->depth_type = GL_UNSIGNED_SHORT;
-
-			glGenFramebuffers(1, &fbo);
-			bind_framebuffer(fbo);
-
-			glGenTextures(1, &depth);
-			glBindTexture(GL_TEXTURE_2D, depth);
-			glTexImage2D(GL_TEXTURE_2D, 0, config->depth_internalformat, 32, 32, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, nullptr);
-
-			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0);
-
-			status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-			if (status != GL_FRAMEBUFFER_COMPLETE) {
-				//if it fails again depth textures aren't supported, use rgba shadows and renderbuffer for depth
-				config->support_depth_texture = false;
-				config->use_rgba_3d_shadows = true;
-			}
-
-			bind_framebuffer_system();
-			glDeleteFramebuffers(1, &fbo);
-			glBindTexture(GL_TEXTURE_2D, 0);
-			glDeleteTextures(1, &depth);
-		}
-	}
+	// config->initialize();
 
 	//picky requirements for these
 	config->support_shadow_cubemaps = config->support_depth_texture && config->support_write_depth && config->support_depth_cubemaps;
 
-	frame.count = 0;
-	frame.delta = 0;
-	frame.current_rt = nullptr;
-	frame.clear_request = false;
-
 	// the use skeleton software path should be used if either float texture is not supported,
 	// OR max_vertex_texture_image_units is zero
 	config->use_skeleton_software = (config->float_texture_supported == false) || (config->max_vertex_texture_image_units == 0);
@@ -2105,7 +1269,6 @@ void RasterizerStorageGLES3::update_dirty_resources() {
 }
 
 RasterizerStorageGLES3::RasterizerStorageGLES3() {
-	RasterizerStorageGLES3::system_fbo = 0;
 }
 
 RasterizerStorageGLES3::~RasterizerStorageGLES3() {

+ 0 - 84
drivers/gles3/rasterizer_storage_gles3.h

@@ -40,10 +40,8 @@
 #include "servers/rendering/renderer_storage.h"
 #include "servers/rendering/shader_compiler.h"
 #include "servers/rendering/shader_language.h"
-#include "storage/canvas_texture_storage.h"
 #include "storage/config.h"
 #include "storage/material_storage.h"
-#include "storage/render_target_storage.h"
 #include "storage/texture_storage.h"
 
 // class RasterizerCanvasGLES3;
@@ -54,8 +52,6 @@ public:
 	// RasterizerCanvasGLES3 *canvas;
 	// RasterizerSceneGLES3 *scene;
 
-	static GLuint system_fbo;
-
 	GLES3::Config *config;
 
 	struct Resources {
@@ -363,43 +359,6 @@ public:
 	AABB visibility_notifier_get_aabb(RID p_notifier) const override;
 	void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) override;
 
-	// RENDER TARGET
-
-	mutable RID_PtrOwner<GLES3::RenderTarget> render_target_owner;
-
-	void _render_target_clear(GLES3::RenderTarget *rt);
-	void _render_target_allocate(GLES3::RenderTarget *rt);
-	void _set_current_render_target(RID p_render_target);
-
-	RID render_target_create() override;
-	void render_target_set_position(RID p_render_target, int p_x, int p_y) override;
-	void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) override;
-	Size2i render_target_get_size(RID p_render_target);
-	RID render_target_get_texture(RID p_render_target) override;
-	void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) override;
-
-	void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) override;
-	bool render_target_was_used(RID p_render_target) override;
-	void render_target_clear_used(RID p_render_target);
-	void render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa);
-	void render_target_set_use_fxaa(RID p_render_target, bool p_fxaa);
-	void render_target_set_use_debanding(RID p_render_target, bool p_debanding);
-
-	// new
-	void render_target_set_as_unused(RID p_render_target) override {
-		render_target_clear_used(p_render_target);
-	}
-
-	void render_target_request_clear(RID p_render_target, const Color &p_clear_color) override;
-	bool render_target_is_clear_requested(RID p_render_target) override;
-	Color render_target_get_clear_request_color(RID p_render_target) override;
-	void render_target_disable_clear_request(RID p_render_target) override;
-	void render_target_do_clear_request(RID p_render_target) override;
-
-	void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) override;
-	Rect2i render_target_get_sdf_rect(RID p_render_target) const override;
-	void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) override;
-
 	// access from canvas
 	//	GLES3::RenderTarget * render_target_get(RID p_render_target);
 
@@ -439,24 +398,6 @@ public:
 
 	bool free(RID p_rid) override;
 
-	struct Frame {
-		GLES3::RenderTarget *current_rt;
-
-		// these 2 may have been superseded by the equivalents in the render target.
-		// these may be able to be removed.
-		bool clear_request;
-		Color clear_request_color;
-
-		float time;
-		float delta;
-		uint64_t count;
-
-		Frame() {
-			//			current_rt = nullptr;
-			//			clear_request = false;
-		}
-	} frame;
-
 	void initialize();
 	void finalize();
 
@@ -498,34 +439,9 @@ public:
 		return String();
 	}
 
-	// make access easier to these
-	struct Dimensions {
-		// render target
-		int rt_width;
-		int rt_height;
-
-		// window
-		int win_width;
-		int win_height;
-		Dimensions() {
-			rt_width = 0;
-			rt_height = 0;
-			win_width = 0;
-			win_height = 0;
-		}
-	} _dims;
-
 	void buffer_orphan_and_upload(unsigned int p_buffer_size, unsigned int p_offset, unsigned int p_data_size, const void *p_data, GLenum p_target = GL_ARRAY_BUFFER, GLenum p_usage = GL_DYNAMIC_DRAW, bool p_optional_orphan = false) const;
 	bool safe_buffer_sub_data(unsigned int p_total_buffer_size, GLenum p_target, unsigned int p_offset, unsigned int p_data_size, const void *p_data, unsigned int &r_offset_after) const;
 
-	void bind_framebuffer(GLuint framebuffer) {
-		glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
-	}
-
-	void bind_framebuffer_system() {
-		glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
-	}
-
 	RasterizerStorageGLES3();
 	~RasterizerStorageGLES3();
 };

+ 0 - 96
drivers/gles3/storage/canvas_texture_storage.cpp

@@ -1,96 +0,0 @@
-/*************************************************************************/
-/*  canvas_texture_storage.cpp                                           */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#ifdef GLES3_ENABLED
-
-#include "canvas_texture_storage.h"
-
-using namespace GLES3;
-
-CanvasTextureStorage *CanvasTextureStorage::singleton = nullptr;
-
-CanvasTextureStorage *CanvasTextureStorage::get_singleton() {
-	return singleton;
-}
-
-CanvasTextureStorage::CanvasTextureStorage() {
-	singleton = this;
-}
-
-CanvasTextureStorage::~CanvasTextureStorage() {
-	singleton = nullptr;
-}
-
-RID CanvasTextureStorage::canvas_texture_allocate() {
-	return canvas_texture_owner.allocate_rid();
-}
-
-void CanvasTextureStorage::canvas_texture_initialize(RID p_rid) {
-	canvas_texture_owner.initialize_rid(p_rid);
-}
-
-void CanvasTextureStorage::canvas_texture_free(RID p_rid) {
-	canvas_texture_owner.free(p_rid);
-}
-
-void CanvasTextureStorage::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
-	CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
-	switch (p_channel) {
-		case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: {
-			ct->diffuse = p_texture;
-		} break;
-		case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: {
-			ct->normal_map = p_texture;
-		} break;
-		case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: {
-			ct->specular = p_texture;
-		} break;
-	}
-}
-
-void CanvasTextureStorage::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) {
-	CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
-	ct->specular_color.r = p_specular_color.r;
-	ct->specular_color.g = p_specular_color.g;
-	ct->specular_color.b = p_specular_color.b;
-	ct->specular_color.a = p_shininess;
-}
-
-void CanvasTextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {
-	CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
-	ct->texture_filter = p_filter;
-}
-
-void CanvasTextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
-	CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
-	ct->texture_repeat = p_repeat;
-}
-
-#endif // !GLES3_ENABLED

+ 0 - 87
drivers/gles3/storage/canvas_texture_storage.h

@@ -1,87 +0,0 @@
-/*************************************************************************/
-/*  canvas_texture_storage.h                                             */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#ifndef CANVAS_TEXTURE_STORAGE_GLES3_H
-#define CANVAS_TEXTURE_STORAGE_GLES3_H
-
-#ifdef GLES3_ENABLED
-
-#include "core/templates/rid_owner.h"
-#include "servers/rendering/storage/canvas_texture_storage.h"
-
-namespace GLES3 {
-
-struct CanvasTexture {
-	RID diffuse;
-	RID normal_map;
-	RID specular;
-	Color specular_color = Color(1, 1, 1, 1);
-	float shininess = 1.0;
-
-	RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT;
-	RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT;
-
-	Size2i size_cache = Size2i(1, 1);
-	bool use_normal_cache = false;
-	bool use_specular_cache = false;
-	bool cleared_cache = true;
-};
-
-class CanvasTextureStorage : public RendererCanvasTextureStorage {
-private:
-	static CanvasTextureStorage *singleton;
-
-	RID_Owner<CanvasTexture, true> canvas_texture_owner;
-
-public:
-	static CanvasTextureStorage *get_singleton();
-
-	CanvasTextureStorage();
-	virtual ~CanvasTextureStorage();
-
-	CanvasTexture *get_canvas_texture(RID p_rid) { return canvas_texture_owner.get_or_null(p_rid); };
-	bool owns_canvas_texture(RID p_rid) { return canvas_texture_owner.owns(p_rid); };
-
-	virtual RID canvas_texture_allocate() override;
-	virtual void canvas_texture_initialize(RID p_rid) override;
-	virtual void canvas_texture_free(RID p_rid) override;
-
-	virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override;
-	virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override;
-
-	virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override;
-	virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override;
-};
-
-} // namespace GLES3
-
-#endif // !GLES3_ENABLED
-
-#endif // !CANVAS_TEXTURE_STORAGE_GLES3_H

+ 4 - 0
drivers/gles3/storage/config.cpp

@@ -40,6 +40,10 @@ Config *Config::singleton = nullptr;
 Config::Config() {
 	singleton = this;
 	should_orphan = true;
+
+	// If this is to early we need to change our code similar to what we're doing in RendererRD,
+	// and instantiate our storage classes when we are ready to do so in the order we want.
+	initialize();
 }
 
 Config::~Config() {

+ 0 - 75
drivers/gles3/storage/decal_atlas_storage.cpp

@@ -1,75 +0,0 @@
-/*************************************************************************/
-/*  decal_atlas_storage.cpp                                              */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#ifdef GLES3_ENABLED
-
-#include "decal_atlas_storage.h"
-
-using namespace GLES3;
-
-RID DecalAtlasStorage::decal_allocate() {
-	return RID();
-}
-
-void DecalAtlasStorage::decal_initialize(RID p_rid) {
-}
-
-void DecalAtlasStorage::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
-}
-
-void DecalAtlasStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
-}
-
-void DecalAtlasStorage::decal_set_emission_energy(RID p_decal, float p_energy) {
-}
-
-void DecalAtlasStorage::decal_set_albedo_mix(RID p_decal, float p_mix) {
-}
-
-void DecalAtlasStorage::decal_set_modulate(RID p_decal, const Color &p_modulate) {
-}
-
-void DecalAtlasStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
-}
-
-void DecalAtlasStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
-}
-
-void DecalAtlasStorage::decal_set_fade(RID p_decal, float p_above, float p_below) {
-}
-
-void DecalAtlasStorage::decal_set_normal_fade(RID p_decal, float p_fade) {
-}
-
-AABB DecalAtlasStorage::decal_get_aabb(RID p_decal) const {
-	return AABB();
-}
-
-#endif // !GLES3_ENABLED

+ 0 - 67
drivers/gles3/storage/decal_atlas_storage.h

@@ -1,67 +0,0 @@
-/*************************************************************************/
-/*  decal_atlas_storage.h                                                */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#ifndef DECAL_ATLAS_STORAGE_GLES3_H
-#define DECAL_ATLAS_STORAGE_GLES3_H
-
-#ifdef GLES3_ENABLED
-
-#include "core/templates/rid_owner.h"
-#include "servers/rendering/storage/decal_atlas_storage.h"
-
-namespace GLES3 {
-
-class DecalAtlasStorage : public RendererDecalAtlasStorage {
-public:
-	virtual RID decal_allocate() override;
-	virtual void decal_initialize(RID p_rid) override;
-	virtual void decal_free(RID p_rid) override{};
-
-	virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override;
-	virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override;
-	virtual void decal_set_emission_energy(RID p_decal, float p_energy) override;
-	virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override;
-	virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override;
-	virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override;
-	virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override;
-	virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override;
-	virtual void decal_set_normal_fade(RID p_decal, float p_fade) override;
-
-	virtual AABB decal_get_aabb(RID p_decal) const override;
-
-	virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
-	virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
-};
-
-} // namespace GLES3
-
-#endif // !GLES3_ENABLED
-
-#endif // !DECAL_ATLAS_STORAGE_GLES3_H

+ 0 - 132
drivers/gles3/storage/render_target_storage.h

@@ -1,132 +0,0 @@
-/*************************************************************************/
-/*  render_target_storage.h                                              */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#ifndef RENDER_TARGET_STORAGE_GLES3_H
-#define RENDER_TARGET_STORAGE_GLES3_H
-
-#ifdef GLES3_ENABLED
-
-#include "core/templates/rid_owner.h"
-#include "servers/rendering/renderer_compositor.h"
-#include "servers/rendering/renderer_storage.h" // included until we move stuff into storage/render_target_storage.h
-// #include "servers/rendering/storage/render_target_storage.h"
-
-// This must come first to avoid windows.h mess
-#include "platform_config.h"
-#ifndef OPENGL_INCLUDE_H
-#include <GLES3/gl3.h>
-#else
-#include OPENGL_INCLUDE_H
-#endif
-
-namespace GLES3 {
-
-// NOTE, this class currently is just a container for the the RenderTarget struct and is not yet implemented further, we'll do that next after we finish with TextureStorage
-
-struct RenderTarget {
-	RID self;
-	GLuint fbo = 0;
-	GLuint color = 0;
-	GLuint depth = 0;
-
-	GLuint multisample_fbo = 0;
-	GLuint multisample_color = 0;
-	GLuint multisample_depth = 0;
-	bool multisample_active = false;
-
-	struct Effect {
-		GLuint fbo = 0;
-		int width = 0;
-		int height = 0;
-
-		GLuint color = 0;
-	};
-
-	Effect copy_screen_effect;
-
-	struct MipMaps {
-		struct Size {
-			GLuint fbo = 0;
-			GLuint color = 0;
-			int width = 0;
-			int height = 0;
-		};
-
-		Vector<Size> sizes;
-		GLuint color = 0;
-		int levels = 0;
-	};
-
-	MipMaps mip_maps[2];
-
-	struct External {
-		GLuint fbo = 0;
-		GLuint color = 0;
-		GLuint depth = 0;
-		RID texture;
-	} external;
-
-	int x = 0;
-	int y = 0;
-	int width = 0;
-	int height = 0;
-
-	bool flags[RendererStorage::RENDER_TARGET_FLAG_MAX] = {};
-
-	// instead of allocating sized render targets immediately,
-	// defer this for faster startup
-	bool allocate_is_dirty = false;
-	bool used_in_frame = false;
-	RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED;
-
-	bool use_fxaa = false;
-	bool use_debanding = false;
-
-	RID texture;
-
-	bool used_dof_blur_near = false;
-	bool mip_maps_allocated = false;
-
-	Color clear_color = Color(1, 1, 1, 1);
-	bool clear_requested = false;
-
-	RenderTarget() {
-		for (int i = 0; i < RendererStorage::RENDER_TARGET_FLAG_MAX; ++i) {
-			flags[i] = false;
-		}
-		external.fbo = 0;
-	}
-};
-
-} // namespace GLES3
-
-#endif // !GLES3_ENABLED
-
-#endif // !RENDER_TARGET_STORAGE_GLES3_H

+ 932 - 0
drivers/gles3/storage/texture_storage.cpp

@@ -43,6 +43,81 @@ TextureStorage *TextureStorage::get_singleton() {
 
 TextureStorage::TextureStorage() {
 	singleton = this;
+
+	system_fbo = 0;
+
+	frame.count = 0;
+	frame.delta = 0;
+	frame.current_rt = nullptr;
+	frame.clear_request = false;
+
+	Config *config = Config::get_singleton();
+
+	//determine formats for depth textures (or renderbuffers)
+	if (config->support_depth_texture) {
+		// Will use texture for depth
+		// have to manually see if we can create a valid framebuffer texture using UNSIGNED_INT,
+		// as there is no extension to test for this.
+		GLuint fbo;
+		glGenFramebuffers(1, &fbo);
+		glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+		GLuint depth;
+		glGenTextures(1, &depth);
+		glBindTexture(GL_TEXTURE_2D, depth);
+		glTexImage2D(GL_TEXTURE_2D, 0, config->depth_internalformat, 32, 32, 0, GL_DEPTH_COMPONENT, config->depth_type, nullptr);
+
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0);
+
+		GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+
+		glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
+		glDeleteFramebuffers(1, &fbo);
+		glBindTexture(GL_TEXTURE_2D, 0);
+		glDeleteTextures(1, &depth);
+
+		if (status != GL_FRAMEBUFFER_COMPLETE) {
+			// If it fails, test to see if it supports a framebuffer texture using UNSIGNED_SHORT
+			// This is needed because many OSX devices don't support either UNSIGNED_INT or UNSIGNED_SHORT
+#ifdef GLES_OVER_GL
+			config->depth_internalformat = GL_DEPTH_COMPONENT16;
+#else
+			// OES_depth_texture extension only specifies GL_DEPTH_COMPONENT.
+			config->depth_internalformat = GL_DEPTH_COMPONENT;
+#endif
+			config->depth_type = GL_UNSIGNED_SHORT;
+
+			glGenFramebuffers(1, &fbo);
+			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+			glGenTextures(1, &depth);
+			glBindTexture(GL_TEXTURE_2D, depth);
+			glTexImage2D(GL_TEXTURE_2D, 0, config->depth_internalformat, 32, 32, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, nullptr);
+
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0);
+
+			status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+			if (status != GL_FRAMEBUFFER_COMPLETE) {
+				//if it fails again depth textures aren't supported, use rgba shadows and renderbuffer for depth
+				config->support_depth_texture = false;
+				config->use_rgba_3d_shadows = true;
+			}
+
+			glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
+			glDeleteFramebuffers(1, &fbo);
+			glBindTexture(GL_TEXTURE_2D, 0);
+			glDeleteTextures(1, &depth);
+		}
+	}
 }
 
 TextureStorage::~TextureStorage() {
@@ -65,6 +140,55 @@ bool TextureStorage::can_create_resources_async() const {
 	return false;
 }
 
+/* Canvas Texture API */
+
+RID TextureStorage::canvas_texture_allocate() {
+	return canvas_texture_owner.allocate_rid();
+}
+
+void TextureStorage::canvas_texture_initialize(RID p_rid) {
+	canvas_texture_owner.initialize_rid(p_rid);
+}
+
+void TextureStorage::canvas_texture_free(RID p_rid) {
+	canvas_texture_owner.free(p_rid);
+}
+
+void TextureStorage::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
+	CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
+	switch (p_channel) {
+		case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: {
+			ct->diffuse = p_texture;
+		} break;
+		case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: {
+			ct->normal_map = p_texture;
+		} break;
+		case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: {
+			ct->specular = p_texture;
+		} break;
+	}
+}
+
+void TextureStorage::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) {
+	CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
+	ct->specular_color.r = p_specular_color.r;
+	ct->specular_color.g = p_specular_color.g;
+	ct->specular_color.b = p_specular_color.b;
+	ct->specular_color.a = p_shininess;
+}
+
+void TextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {
+	CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
+	ct->texture_filter = p_filter;
+}
+
+void TextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
+	CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
+	ct->texture_repeat = p_repeat;
+}
+
+/* Texture API */
+
 static const GLenum _cube_side_enum[6] = {
 	GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
 	GL_TEXTURE_CUBE_MAP_POSITIVE_X,
@@ -1208,4 +1332,812 @@ void TextureStorage::textures_keep_original(bool p_enable) {
 	Config::get_singleton()->keep_original_textures = p_enable;
 }
 
+/* DECAL API */
+
+RID TextureStorage::decal_allocate() {
+	return RID();
+}
+
+void TextureStorage::decal_initialize(RID p_rid) {
+}
+
+void TextureStorage::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
+}
+
+void TextureStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
+}
+
+void TextureStorage::decal_set_emission_energy(RID p_decal, float p_energy) {
+}
+
+void TextureStorage::decal_set_albedo_mix(RID p_decal, float p_mix) {
+}
+
+void TextureStorage::decal_set_modulate(RID p_decal, const Color &p_modulate) {
+}
+
+void TextureStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
+}
+
+void TextureStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
+}
+
+void TextureStorage::decal_set_fade(RID p_decal, float p_above, float p_below) {
+}
+
+void TextureStorage::decal_set_normal_fade(RID p_decal, float p_fade) {
+}
+
+AABB TextureStorage::decal_get_aabb(RID p_decal) const {
+	return AABB();
+}
+
+/* RENDER TARGET API */
+
+GLuint TextureStorage::system_fbo = 0;
+
+void TextureStorage::_set_current_render_target(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+
+	if (rt) {
+		if (rt->allocate_is_dirty) {
+			rt->allocate_is_dirty = false;
+			_render_target_allocate(rt);
+		}
+
+		frame.current_rt = rt;
+		ERR_FAIL_COND(!rt);
+		frame.clear_request = false;
+
+		glViewport(0, 0, rt->width, rt->height);
+
+		_dims.rt_width = rt->width;
+		_dims.rt_height = rt->height;
+		_dims.win_width = rt->width;
+		_dims.win_height = rt->height;
+
+	} else {
+		frame.current_rt = nullptr;
+		frame.clear_request = false;
+		glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
+	}
+}
+
+void TextureStorage::_render_target_allocate(RenderTarget *rt) {
+	Config *config = Config::get_singleton();
+
+	// do not allocate a render target with no size
+	if (rt->width <= 0 || rt->height <= 0) {
+		return;
+	}
+
+	// do not allocate a render target that is attached to the screen
+	if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) {
+		rt->fbo = system_fbo;
+		return;
+	}
+
+	GLuint color_internal_format;
+	GLuint color_format;
+	GLuint color_type = GL_UNSIGNED_BYTE;
+	Image::Format image_format;
+
+	if (rt->flags[TextureStorage::RENDER_TARGET_TRANSPARENT]) {
+#ifdef GLES_OVER_GL
+		color_internal_format = GL_RGBA8;
+#else
+		color_internal_format = GL_RGBA;
+#endif
+		color_format = GL_RGBA;
+		image_format = Image::FORMAT_RGBA8;
+	} else {
+#ifdef GLES_OVER_GL
+		color_internal_format = GL_RGB8;
+#else
+		color_internal_format = GL_RGB;
+#endif
+		color_format = GL_RGB;
+		image_format = Image::FORMAT_RGB8;
+	}
+
+	rt->used_dof_blur_near = false;
+	rt->mip_maps_allocated = false;
+
+	{
+		/* Front FBO */
+
+		Texture *texture = get_texture(rt->texture);
+		ERR_FAIL_COND(!texture);
+
+		// framebuffer
+		glGenFramebuffers(1, &rt->fbo);
+		glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
+
+		// color
+		glGenTextures(1, &rt->color);
+		glBindTexture(GL_TEXTURE_2D, rt->color);
+
+		glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, nullptr);
+
+		if (texture->flags & TEXTURE_FLAG_FILTER) {
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+		} else {
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+		}
+
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0);
+
+		// depth
+
+		if (config->support_depth_texture) {
+			glGenTextures(1, &rt->depth);
+			glBindTexture(GL_TEXTURE_2D, rt->depth);
+			glTexImage2D(GL_TEXTURE_2D, 0, config->depth_internalformat, rt->width, rt->height, 0, GL_DEPTH_COMPONENT, config->depth_type, nullptr);
+
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
+		} else {
+			glGenRenderbuffers(1, &rt->depth);
+			glBindRenderbuffer(GL_RENDERBUFFER, rt->depth);
+
+			glRenderbufferStorage(GL_RENDERBUFFER, config->depth_buffer_internalformat, rt->width, rt->height);
+
+			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
+		}
+
+		GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+
+		if (status != GL_FRAMEBUFFER_COMPLETE) {
+			glDeleteFramebuffers(1, &rt->fbo);
+			if (config->support_depth_texture) {
+				glDeleteTextures(1, &rt->depth);
+			} else {
+				glDeleteRenderbuffers(1, &rt->depth);
+			}
+
+			glDeleteTextures(1, &rt->color);
+			rt->fbo = 0;
+			rt->width = 0;
+			rt->height = 0;
+			rt->color = 0;
+			rt->depth = 0;
+			texture->tex_id = 0;
+			texture->active = false;
+			WARN_PRINT("Could not create framebuffer!!");
+			return;
+		}
+
+		texture->format = image_format;
+		texture->gl_format_cache = color_format;
+		texture->gl_type_cache = GL_UNSIGNED_BYTE;
+		texture->gl_internal_format_cache = color_internal_format;
+		texture->tex_id = rt->color;
+		texture->width = rt->width;
+		texture->alloc_width = rt->width;
+		texture->height = rt->height;
+		texture->alloc_height = rt->height;
+		texture->active = true;
+
+		texture_set_flags(rt->texture, texture->flags);
+	}
+
+	/* BACK FBO */
+	/* For MSAA */
+
+#ifndef JAVASCRIPT_ENABLED
+	if (rt->msaa >= RS::VIEWPORT_MSAA_2X && rt->msaa <= RS::VIEWPORT_MSAA_8X) {
+		rt->multisample_active = true;
+
+		static const int msaa_value[] = { 0, 2, 4, 8, 16 };
+		int msaa = msaa_value[rt->msaa];
+
+		int max_samples = 0;
+		glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
+		if (msaa > max_samples) {
+			WARN_PRINT("MSAA must be <= GL_MAX_SAMPLES, falling-back to GL_MAX_SAMPLES = " + itos(max_samples));
+			msaa = max_samples;
+		}
+
+		//regular fbo
+		glGenFramebuffers(1, &rt->multisample_fbo);
+		glBindFramebuffer(GL_FRAMEBUFFER, rt->multisample_fbo);
+
+		glGenRenderbuffers(1, &rt->multisample_depth);
+		glBindRenderbuffer(GL_RENDERBUFFER, rt->multisample_depth);
+		glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, config->depth_buffer_internalformat, rt->width, rt->height);
+
+		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->multisample_depth);
+
+		glGenRenderbuffers(1, &rt->multisample_color);
+		glBindRenderbuffer(GL_RENDERBUFFER, rt->multisample_color);
+		glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, color_internal_format, rt->width, rt->height);
+
+		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rt->multisample_color);
+
+		GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+
+		if (status != GL_FRAMEBUFFER_COMPLETE) {
+			// Delete allocated resources and default to no MSAA
+			WARN_PRINT_ONCE("Cannot allocate back framebuffer for MSAA");
+			printf("err status: %x\n", status);
+			rt->multisample_active = false;
+
+			glDeleteFramebuffers(1, &rt->multisample_fbo);
+			rt->multisample_fbo = 0;
+
+			glDeleteRenderbuffers(1, &rt->multisample_depth);
+			rt->multisample_depth = 0;
+
+			glDeleteRenderbuffers(1, &rt->multisample_color);
+			rt->multisample_color = 0;
+		}
+
+		glBindRenderbuffer(GL_RENDERBUFFER, 0);
+		glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+	} else
+#endif // JAVASCRIPT_ENABLED
+	{
+		rt->multisample_active = false;
+	}
+
+	glClearColor(0, 0, 0, 0);
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+	// copy texscreen buffers
+	//	if (!(rt->flags[TextureStorage::RENDER_TARGET_NO_SAMPLING])) {
+	if (true) {
+		glGenTextures(1, &rt->copy_screen_effect.color);
+		glBindTexture(GL_TEXTURE_2D, rt->copy_screen_effect.color);
+
+		if (rt->flags[TextureStorage::RENDER_TARGET_TRANSPARENT]) {
+			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+		} else {
+			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rt->width, rt->height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
+		}
+
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+		glGenFramebuffers(1, &rt->copy_screen_effect.fbo);
+		glBindFramebuffer(GL_FRAMEBUFFER, rt->copy_screen_effect.fbo);
+		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->copy_screen_effect.color, 0);
+
+		glClearColor(0, 0, 0, 0);
+		glClear(GL_COLOR_BUFFER_BIT);
+
+		GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+		if (status != GL_FRAMEBUFFER_COMPLETE) {
+			_render_target_clear(rt);
+			ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
+		}
+	}
+
+	// Allocate mipmap chains for post_process effects
+	//	if (!rt->flags[RendererStorage::RENDER_TARGET_NO_3D] && rt->width >= 2 && rt->height >= 2) {
+	if (rt->width >= 2 && rt->height >= 2) {
+		for (int i = 0; i < 2; i++) {
+			ERR_FAIL_COND(rt->mip_maps[i].sizes.size());
+			int w = rt->width;
+			int h = rt->height;
+
+			if (i > 0) {
+				w >>= 1;
+				h >>= 1;
+			}
+
+			int level = 0;
+			int fb_w = w;
+			int fb_h = h;
+
+			while (true) {
+				RenderTarget::MipMaps::Size mm;
+				mm.width = w;
+				mm.height = h;
+				rt->mip_maps[i].sizes.push_back(mm);
+
+				w >>= 1;
+				h >>= 1;
+
+				if (w < 2 || h < 2) {
+					break;
+				}
+
+				level++;
+			}
+
+			GLsizei width = fb_w;
+			GLsizei height = fb_h;
+
+			if (config->render_to_mipmap_supported) {
+				glGenTextures(1, &rt->mip_maps[i].color);
+				glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].color);
+
+				for (int l = 0; l < level + 1; l++) {
+					glTexImage2D(GL_TEXTURE_2D, l, color_internal_format, width, height, 0, color_format, color_type, nullptr);
+					width = MAX(1, (width / 2));
+					height = MAX(1, (height / 2));
+				}
+#ifdef GLES_OVER_GL
+				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
+				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level);
+#endif
+			} else {
+				// Can't render to specific levels of a mipmap in ES 2.0 or Webgl so create a texture for each level
+				for (int l = 0; l < level + 1; l++) {
+					glGenTextures(1, &rt->mip_maps[i].sizes.write[l].color);
+					glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].sizes[l].color);
+					glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, width, height, 0, color_format, color_type, nullptr);
+					width = MAX(1, (width / 2));
+					height = MAX(1, (height / 2));
+					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+				}
+			}
+
+			glDisable(GL_SCISSOR_TEST);
+			glColorMask(1, 1, 1, 1);
+			glDepthMask(GL_TRUE);
+
+			for (int j = 0; j < rt->mip_maps[i].sizes.size(); j++) {
+				RenderTarget::MipMaps::Size &mm = rt->mip_maps[i].sizes.write[j];
+
+				glGenFramebuffers(1, &mm.fbo);
+				glBindFramebuffer(GL_FRAMEBUFFER, mm.fbo);
+
+				if (config->render_to_mipmap_supported) {
+					glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->mip_maps[i].color, j);
+				} else {
+					glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].sizes[j].color);
+					glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->mip_maps[i].sizes[j].color, 0);
+				}
+
+				bool used_depth = false;
+				if (j == 0 && i == 0) { //use always
+					if (config->support_depth_texture) {
+						glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
+					} else {
+						glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
+					}
+					used_depth = true;
+				}
+
+				GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+				if (status != GL_FRAMEBUFFER_COMPLETE) {
+					WARN_PRINT_ONCE("Cannot allocate mipmaps for 3D post processing effects");
+					glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
+					return;
+				}
+
+				glClearColor(1.0, 0.0, 1.0, 0.0);
+				glClear(GL_COLOR_BUFFER_BIT);
+				if (used_depth) {
+					glClearDepth(1.0);
+					glClear(GL_DEPTH_BUFFER_BIT);
+				}
+			}
+
+			rt->mip_maps[i].levels = level;
+
+			if (config->render_to_mipmap_supported) {
+				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+			}
+		}
+		rt->mip_maps_allocated = true;
+	}
+
+	glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
+}
+
+void TextureStorage::_render_target_clear(RenderTarget *rt) {
+	Config *config = Config::get_singleton();
+
+	// there is nothing to clear when DIRECT_TO_SCREEN is used
+	if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) {
+		return;
+	}
+
+	if (rt->fbo) {
+		glDeleteFramebuffers(1, &rt->fbo);
+		glDeleteTextures(1, &rt->color);
+		rt->fbo = 0;
+	}
+
+	if (rt->external.fbo != 0) {
+		// free this
+		glDeleteFramebuffers(1, &rt->external.fbo);
+
+		// clean up our texture
+		Texture *t = get_texture(rt->external.texture);
+		t->alloc_height = 0;
+		t->alloc_width = 0;
+		t->width = 0;
+		t->height = 0;
+		t->active = false;
+		texture_free(rt->external.texture);
+		memdelete(t);
+
+		rt->external.fbo = 0;
+	}
+
+	if (rt->depth) {
+		if (config->support_depth_texture) {
+			glDeleteTextures(1, &rt->depth);
+		} else {
+			glDeleteRenderbuffers(1, &rt->depth);
+		}
+
+		rt->depth = 0;
+	}
+
+	Texture *tex = get_texture(rt->texture);
+	tex->alloc_height = 0;
+	tex->alloc_width = 0;
+	tex->width = 0;
+	tex->height = 0;
+	tex->active = false;
+
+	if (rt->copy_screen_effect.color) {
+		glDeleteFramebuffers(1, &rt->copy_screen_effect.fbo);
+		rt->copy_screen_effect.fbo = 0;
+
+		glDeleteTextures(1, &rt->copy_screen_effect.color);
+		rt->copy_screen_effect.color = 0;
+	}
+
+	for (int i = 0; i < 2; i++) {
+		if (rt->mip_maps[i].sizes.size()) {
+			for (int j = 0; j < rt->mip_maps[i].sizes.size(); j++) {
+				glDeleteFramebuffers(1, &rt->mip_maps[i].sizes[j].fbo);
+				glDeleteTextures(1, &rt->mip_maps[i].sizes[j].color);
+			}
+
+			glDeleteTextures(1, &rt->mip_maps[i].color);
+			rt->mip_maps[i].sizes.clear();
+			rt->mip_maps[i].levels = 0;
+			rt->mip_maps[i].color = 0;
+		}
+	}
+
+	if (rt->multisample_active) {
+		glDeleteFramebuffers(1, &rt->multisample_fbo);
+		rt->multisample_fbo = 0;
+
+		glDeleteRenderbuffers(1, &rt->multisample_depth);
+		rt->multisample_depth = 0;
+
+		glDeleteRenderbuffers(1, &rt->multisample_color);
+
+		rt->multisample_color = 0;
+	}
+}
+
+RID TextureStorage::render_target_create() {
+	RenderTarget *rt = memnew(RenderTarget);
+	Texture *t = memnew(Texture);
+
+	t->type = RenderingDevice::TEXTURE_TYPE_2D;
+	t->flags = 0;
+	t->width = 0;
+	t->height = 0;
+	t->alloc_height = 0;
+	t->alloc_width = 0;
+	t->format = Image::FORMAT_R8;
+	t->target = GL_TEXTURE_2D;
+	t->gl_format_cache = 0;
+	t->gl_internal_format_cache = 0;
+	t->gl_type_cache = 0;
+	t->data_size = 0;
+	t->total_data_size = 0;
+	t->ignore_mipmaps = false;
+	t->compressed = false;
+	t->mipmaps = 1;
+	t->active = true;
+	t->tex_id = 0;
+	t->render_target = rt;
+
+	rt->texture = make_rid(t);
+	return render_target_owner.make_rid(rt);
+}
+
+void TextureStorage::render_target_free(RID p_rid) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_rid);
+	_render_target_clear(rt);
+
+	Texture *t = get_texture(rt->texture);
+	if (t) {
+		texture_free(rt->texture);
+		memdelete(t);
+	}
+	render_target_owner.free(p_rid);
+	memdelete(rt);
+}
+
+void TextureStorage::render_target_set_position(RID p_render_target, int p_x, int p_y) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+
+	rt->x = p_x;
+	rt->y = p_y;
+}
+
+void TextureStorage::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+
+	if (p_width == rt->width && p_height == rt->height) {
+		return;
+	}
+
+	_render_target_clear(rt);
+
+	rt->width = p_width;
+	rt->height = p_height;
+
+	// print_line("render_target_set_size " + itos(p_render_target.get_id()) + ", w " + itos(p_width) + " h " + itos(p_height));
+
+	rt->allocate_is_dirty = true;
+	//_render_target_allocate(rt);
+}
+
+// TODO: convert to Size2i internally
+Size2i TextureStorage::render_target_get_size(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, Size2());
+
+	return Size2i(rt->width, rt->height);
+}
+
+RID TextureStorage::render_target_get_texture(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, RID());
+
+	if (rt->external.fbo == 0) {
+		return rt->texture;
+	} else {
+		return rt->external.texture;
+	}
+}
+
+void TextureStorage::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+
+	Config *config = Config::get_singleton();
+
+	if (p_texture_id == 0) {
+		if (rt->external.fbo != 0) {
+			// free this
+			glDeleteFramebuffers(1, &rt->external.fbo);
+
+			// and this
+			if (rt->external.depth != 0) {
+				glDeleteRenderbuffers(1, &rt->external.depth);
+			}
+
+			// clean up our texture
+			Texture *t = get_texture(rt->external.texture);
+			t->alloc_height = 0;
+			t->alloc_width = 0;
+			t->width = 0;
+			t->height = 0;
+			t->active = false;
+			texture_free(rt->external.texture);
+			memdelete(t);
+
+			rt->external.fbo = 0;
+			rt->external.color = 0;
+			rt->external.depth = 0;
+		}
+	} else {
+		Texture *t;
+
+		if (rt->external.fbo == 0) {
+			// create our fbo
+			glGenFramebuffers(1, &rt->external.fbo);
+			glBindFramebuffer(GL_FRAMEBUFFER, rt->external.fbo);
+
+			// allocate a texture
+			t = memnew(Texture);
+
+			t->type = RenderingDevice::TEXTURE_TYPE_2D;
+			t->flags = 0;
+			t->width = 0;
+			t->height = 0;
+			t->alloc_height = 0;
+			t->alloc_width = 0;
+			t->format = Image::FORMAT_RGBA8;
+			t->target = GL_TEXTURE_2D;
+			t->gl_format_cache = 0;
+			t->gl_internal_format_cache = 0;
+			t->gl_type_cache = 0;
+			t->data_size = 0;
+			t->compressed = false;
+			t->srgb = false;
+			t->total_data_size = 0;
+			t->ignore_mipmaps = false;
+			t->mipmaps = 1;
+			t->active = true;
+			t->tex_id = 0;
+			t->render_target = rt;
+
+			rt->external.texture = make_rid(t);
+
+		} else {
+			// bind our frame buffer
+			glBindFramebuffer(GL_FRAMEBUFFER, rt->external.fbo);
+
+			// find our texture
+			t = get_texture(rt->external.texture);
+		}
+
+		// set our texture
+		t->tex_id = p_texture_id;
+		rt->external.color = p_texture_id;
+
+		// size shouldn't be different
+		t->width = rt->width;
+		t->height = rt->height;
+		t->alloc_height = rt->width;
+		t->alloc_width = rt->height;
+
+		// Switch our texture on our frame buffer
+		{
+			// set our texture as the destination for our framebuffer
+			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_texture_id, 0);
+
+			// seeing we're rendering into this directly, better also use our depth buffer, just use our existing one :)
+			if (config->support_depth_texture) {
+				glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
+			} else {
+				glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
+			}
+		}
+
+		// check status and unbind
+		GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+		glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
+
+		if (status != GL_FRAMEBUFFER_COMPLETE) {
+			printf("framebuffer fail, status: %x\n", status);
+		}
+
+		ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
+	}
+}
+
+void TextureStorage::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+
+	// When setting DIRECT_TO_SCREEN, you need to clear before the value is set, but allocate after as
+	// those functions change how they operate depending on the value of DIRECT_TO_SCREEN
+	if (p_flag == RENDER_TARGET_DIRECT_TO_SCREEN && p_value != rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) {
+		_render_target_clear(rt);
+		rt->flags[p_flag] = p_value;
+		_render_target_allocate(rt);
+	}
+
+	rt->flags[p_flag] = p_value;
+
+	switch (p_flag) {
+		case RENDER_TARGET_TRANSPARENT:
+			/*
+		case RENDER_TARGET_HDR:
+		case RENDER_TARGET_NO_3D:
+		case RENDER_TARGET_NO_SAMPLING:
+		case RENDER_TARGET_NO_3D_EFFECTS: */
+			{
+				//must reset for these formats
+				_render_target_clear(rt);
+				_render_target_allocate(rt);
+			}
+			break;
+		default: {
+		}
+	}
+}
+
+bool TextureStorage::render_target_was_used(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, false);
+
+	return rt->used_in_frame;
+}
+
+void TextureStorage::render_target_clear_used(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+
+	rt->used_in_frame = false;
+}
+
+void TextureStorage::render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+
+	if (rt->msaa == p_msaa) {
+		return;
+	}
+
+	_render_target_clear(rt);
+	rt->msaa = p_msaa;
+	_render_target_allocate(rt);
+}
+
+void TextureStorage::render_target_set_use_fxaa(RID p_render_target, bool p_fxaa) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+
+	rt->use_fxaa = p_fxaa;
+}
+
+void TextureStorage::render_target_set_use_debanding(RID p_render_target, bool p_debanding) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+
+	if (p_debanding) {
+		WARN_PRINT_ONCE("Debanding is not supported in the OpenGL backend. Switch to the Vulkan backend and make sure HDR is enabled.");
+	}
+
+	rt->use_debanding = p_debanding;
+}
+
+void TextureStorage::render_target_request_clear(RID p_render_target, const Color &p_clear_color) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+	rt->clear_requested = true;
+	rt->clear_color = p_clear_color;
+
+	//	ERR_FAIL_COND(!frame.current_rt);
+	//	frame.clear_request = true;
+	//	frame.clear_request_color = p_color;
+}
+
+bool TextureStorage::render_target_is_clear_requested(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, false);
+	return rt->clear_requested;
+}
+Color TextureStorage::render_target_get_clear_request_color(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, Color());
+	return rt->clear_color;
+}
+
+void TextureStorage::render_target_disable_clear_request(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+	rt->clear_requested = false;
+}
+
+void TextureStorage::render_target_do_clear_request(RID p_render_target) {
+}
+
+void TextureStorage::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) {
+}
+
+Rect2i TextureStorage::render_target_get_sdf_rect(RID p_render_target) const {
+	return Rect2i();
+}
+
+void TextureStorage::render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) {
+}
+
 #endif // GLES3_ENABLED

+ 226 - 2
drivers/gles3/storage/texture_storage.h

@@ -33,13 +33,20 @@
 
 #ifdef GLES3_ENABLED
 
-#include "canvas_texture_storage.h"
 #include "config.h"
 #include "core/os/os.h"
 #include "core/templates/rid_owner.h"
-#include "render_target_storage.h"
+#include "servers/rendering/renderer_compositor.h"
 #include "servers/rendering/storage/texture_storage.h"
 
+// This must come first to avoid windows.h mess
+#include "platform_config.h"
+#ifndef OPENGL_INCLUDE_H
+#include <GLES3/gl3.h>
+#else
+#include OPENGL_INCLUDE_H
+#endif
+
 namespace GLES3 {
 
 #define _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
@@ -90,6 +97,24 @@ enum OpenGLTextureFlags {
 	TEXTURE_FLAGS_DEFAULT = TEXTURE_FLAG_REPEAT | TEXTURE_FLAG_MIPMAPS | TEXTURE_FLAG_FILTER
 };
 
+struct CanvasTexture {
+	RID diffuse;
+	RID normal_map;
+	RID specular;
+	Color specular_color = Color(1, 1, 1, 1);
+	float shininess = 1.0;
+
+	RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT;
+	RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT;
+
+	Size2i size_cache = Size2i(1, 1);
+	bool use_normal_cache = false;
+	bool use_specular_cache = false;
+	bool cleared_cache = true;
+};
+
+struct RenderTarget;
+
 struct Texture {
 	RID self;
 
@@ -296,6 +321,81 @@ private:
 	RS::CanvasItemTextureRepeat state_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED;
 };
 
+struct RenderTarget {
+	RID self;
+	GLuint fbo = 0;
+	GLuint color = 0;
+	GLuint depth = 0;
+
+	GLuint multisample_fbo = 0;
+	GLuint multisample_color = 0;
+	GLuint multisample_depth = 0;
+	bool multisample_active = false;
+
+	struct Effect {
+		GLuint fbo = 0;
+		int width = 0;
+		int height = 0;
+
+		GLuint color = 0;
+	};
+
+	Effect copy_screen_effect;
+
+	struct MipMaps {
+		struct Size {
+			GLuint fbo = 0;
+			GLuint color = 0;
+			int width = 0;
+			int height = 0;
+		};
+
+		Vector<Size> sizes;
+		GLuint color = 0;
+		int levels = 0;
+	};
+
+	MipMaps mip_maps[2];
+
+	struct External {
+		GLuint fbo = 0;
+		GLuint color = 0;
+		GLuint depth = 0;
+		RID texture;
+	} external;
+
+	int x = 0;
+	int y = 0;
+	int width = 0;
+	int height = 0;
+
+	bool flags[RendererTextureStorage::RENDER_TARGET_FLAG_MAX] = {};
+
+	// instead of allocating sized render targets immediately,
+	// defer this for faster startup
+	bool allocate_is_dirty = false;
+	bool used_in_frame = false;
+	RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED;
+
+	bool use_fxaa = false;
+	bool use_debanding = false;
+
+	RID texture;
+
+	bool used_dof_blur_near = false;
+	bool mip_maps_allocated = false;
+
+	Color clear_color = Color(1, 1, 1, 1);
+	bool clear_requested = false;
+
+	RenderTarget() {
+		for (int i = 0; i < RendererTextureStorage::RENDER_TARGET_FLAG_MAX; ++i) {
+			flags[i] = false;
+		}
+		external.fbo = 0;
+	}
+};
+
 class TextureStorage : public RendererTextureStorage {
 private:
 	static TextureStorage *singleton;
@@ -303,6 +403,12 @@ private:
 	Thread::ID _main_thread_id = 0;
 	bool _is_main_thread();
 
+	/* Canvas Texture API */
+
+	RID_Owner<CanvasTexture, true> canvas_texture_owner;
+
+	/* Texture API */
+
 	mutable RID_PtrOwner<Texture> texture_owner;
 
 	Ref<Image> _get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_force_decompress) const;
@@ -310,12 +416,50 @@ private:
 
 	void texture_set_proxy(RID p_texture, RID p_proxy);
 
+	/* Render Target API */
+
+	mutable RID_PtrOwner<RenderTarget> render_target_owner;
+
+	// make access easier to these
+	struct Dimensions {
+		// render target
+		int rt_width;
+		int rt_height;
+
+		// window
+		int win_width;
+		int win_height;
+		Dimensions() {
+			rt_width = 0;
+			rt_height = 0;
+			win_width = 0;
+			win_height = 0;
+		}
+	} _dims;
+
 public:
 	static TextureStorage *get_singleton();
 
 	TextureStorage();
 	virtual ~TextureStorage();
 
+	/* Canvas Texture API */
+
+	CanvasTexture *get_canvas_texture(RID p_rid) { return canvas_texture_owner.get_or_null(p_rid); };
+	bool owns_canvas_texture(RID p_rid) { return canvas_texture_owner.owns(p_rid); };
+
+	virtual RID canvas_texture_allocate() override;
+	virtual void canvas_texture_initialize(RID p_rid) override;
+	virtual void canvas_texture_free(RID p_rid) override;
+
+	virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override;
+	virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override;
+
+	virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override;
+	virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override;
+
+	/* Texture API */
+
 	Texture *get_texture(RID p_rid) { return texture_owner.get_or_null(p_rid); };
 	bool owns_texture(RID p_rid) { return texture_owner.owns(p_rid); };
 	RID make_rid(Texture *p_texture) { return texture_owner.make_rid(p_texture); };
@@ -380,6 +524,86 @@ public:
 	void texture_set_shrink_all_x2_on_set_data(bool p_enable);
 	RID texture_create_radiance_cubemap(RID p_source, int p_resolution = -1) const;
 	void textures_keep_original(bool p_enable);
+
+	/* DECAL API */
+
+	virtual RID decal_allocate() override;
+	virtual void decal_initialize(RID p_rid) override;
+	virtual void decal_free(RID p_rid) override{};
+
+	virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override;
+	virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override;
+	virtual void decal_set_emission_energy(RID p_decal, float p_energy) override;
+	virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override;
+	virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override;
+	virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override;
+	virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override;
+	virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override;
+	virtual void decal_set_normal_fade(RID p_decal, float p_fade) override;
+
+	virtual AABB decal_get_aabb(RID p_decal) const override;
+
+	virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
+	virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
+
+	/* RENDER TARGET API */
+
+	static GLuint system_fbo;
+
+	struct Frame {
+		GLES3::RenderTarget *current_rt;
+
+		// these 2 may have been superseded by the equivalents in the render target.
+		// these may be able to be removed.
+		bool clear_request;
+		Color clear_request_color;
+
+		float time;
+		float delta;
+		uint64_t count;
+
+		Frame() {
+			//			current_rt = nullptr;
+			//			clear_request = false;
+		}
+	} frame;
+
+	RenderTarget *get_render_target(RID p_rid) { return render_target_owner.get_or_null(p_rid); };
+	bool owns_render_target(RID p_rid) { return render_target_owner.owns(p_rid); };
+
+	void _render_target_clear(RenderTarget *rt);
+	void _render_target_allocate(RenderTarget *rt);
+	void _set_current_render_target(RID p_render_target);
+
+	virtual RID render_target_create() override;
+	virtual void render_target_free(RID p_rid) override;
+	virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) override;
+	virtual void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) override;
+	Size2i render_target_get_size(RID p_render_target);
+	virtual RID render_target_get_texture(RID p_render_target) override;
+	virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) override;
+
+	virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) override;
+	virtual bool render_target_was_used(RID p_render_target) override;
+	void render_target_clear_used(RID p_render_target);
+	void render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa);
+	void render_target_set_use_fxaa(RID p_render_target, bool p_fxaa);
+	void render_target_set_use_debanding(RID p_render_target, bool p_debanding);
+
+	// new
+	void render_target_set_as_unused(RID p_render_target) override {
+		render_target_clear_used(p_render_target);
+	}
+
+	void render_target_request_clear(RID p_render_target, const Color &p_clear_color) override;
+	bool render_target_is_clear_requested(RID p_render_target) override;
+	Color render_target_get_clear_request_color(RID p_render_target) override;
+	void render_target_disable_clear_request(RID p_render_target) override;
+	void render_target_do_clear_request(RID p_render_target) override;
+
+	void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) override;
+	Rect2i render_target_get_sdf_rect(RID p_render_target) const override;
+	void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) override;
 };
 
 } // namespace GLES3

+ 2 - 1
modules/openxr/extensions/openxr_vulkan_extension.cpp

@@ -34,6 +34,7 @@
 #include "../openxr_api.h"
 #include "../openxr_util.h"
 #include "servers/rendering/renderer_rd/renderer_storage_rd.h"
+#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
 #include "servers/rendering/rendering_server_globals.h"
 #include "servers/rendering_server.h"
 
@@ -439,7 +440,7 @@ bool OpenXRVulkanExtension::copy_render_target_to_image(RID p_from_render_target
 	ERR_FAIL_COND_V(p_from_render_target.is_null(), false);
 	ERR_FAIL_NULL_V(RendererStorageRD::base_singleton, false);
 
-	RID source_image = RendererStorageRD::base_singleton->render_target_get_rd_texture(p_from_render_target);
+	RID source_image = RendererRD::TextureStorage::get_singleton()->render_target_get_rd_texture(p_from_render_target);
 	ERR_FAIL_COND_V(source_image.is_null(), false);
 
 	RID depth_image; // TODO implement

+ 0 - 6
servers/rendering/dummy/rasterizer_dummy.h

@@ -37,8 +37,6 @@
 #include "servers/rendering/dummy/rasterizer_canvas_dummy.h"
 #include "servers/rendering/dummy/rasterizer_scene_dummy.h"
 #include "servers/rendering/dummy/rasterizer_storage_dummy.h"
-#include "servers/rendering/dummy/storage/canvas_texture_storage.h"
-#include "servers/rendering/dummy/storage/decal_atlas_storage.h"
 #include "servers/rendering/dummy/storage/material_storage.h"
 #include "servers/rendering/dummy/storage/mesh_storage.h"
 #include "servers/rendering/dummy/storage/texture_storage.h"
@@ -52,20 +50,16 @@ private:
 
 protected:
 	RasterizerCanvasDummy canvas;
-	RendererDummy::CanvasTextureStorage canvas_texture_storage;
 	RendererDummy::MaterialStorage material_storage;
 	RendererDummy::MeshStorage mesh_storage;
 	RendererDummy::TextureStorage texture_storage;
-	RendererDummy::DecalAtlasStorage decal_atlas_storage;
 	RasterizerStorageDummy storage;
 	RasterizerSceneDummy scene;
 
 public:
-	RendererCanvasTextureStorage *get_canvas_texture_storage() override { return &canvas_texture_storage; };
 	RendererMaterialStorage *get_material_storage() override { return &material_storage; };
 	RendererMeshStorage *get_mesh_storage() override { return &mesh_storage; };
 	RendererTextureStorage *get_texture_storage() override { return &texture_storage; };
-	RendererDecalAtlasStorage *get_decal_atlas_storage() override { return &decal_atlas_storage; };
 	RendererStorage *get_storage() override { return &storage; }
 	RendererCanvasRender *get_canvas() override { return &canvas; }
 	RendererSceneRender *get_scene() override { return &scene; }

+ 1 - 20
servers/rendering/dummy/rasterizer_storage_dummy.h

@@ -268,26 +268,7 @@ public:
 	virtual AABB visibility_notifier_get_aabb(RID p_notifier) const override { return AABB(); }
 	virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) override {}
 
-	/* RENDER TARGET */
-
-	RID render_target_create() override { return RID(); }
-	void render_target_set_position(RID p_render_target, int p_x, int p_y) override {}
-	void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) override {}
-	RID render_target_get_texture(RID p_render_target) override { return RID(); }
-	void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) override {}
-	void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) override {}
-	bool render_target_was_used(RID p_render_target) override { return false; }
-	void render_target_set_as_unused(RID p_render_target) override {}
-
-	void render_target_request_clear(RID p_render_target, const Color &p_clear_color) override {}
-	bool render_target_is_clear_requested(RID p_render_target) override { return false; }
-	Color render_target_get_clear_request_color(RID p_render_target) override { return Color(); }
-	void render_target_disable_clear_request(RID p_render_target) override {}
-	void render_target_do_clear_request(RID p_render_target) override {}
-
-	void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) override {}
-	Rect2i render_target_get_sdf_rect(RID p_render_target) const override { return Rect2i(); }
-	void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) override {}
+	/* STORAGE */
 
 	RS::InstanceType get_base_type(RID p_rid) const override { return RS::INSTANCE_NONE; }
 	bool free(RID p_rid) override {

+ 0 - 53
servers/rendering/dummy/storage/canvas_texture_storage.h

@@ -1,53 +0,0 @@
-/*************************************************************************/
-/*  canvas_texture_storage.h                                             */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#ifndef CANVAS_TEXTURE_STORAGE_DUMMY_H
-#define CANVAS_TEXTURE_STORAGE_DUMMY_H
-
-#include "servers/rendering/storage/canvas_texture_storage.h"
-
-namespace RendererDummy {
-
-class CanvasTextureStorage : public RendererCanvasTextureStorage {
-public:
-	virtual RID canvas_texture_allocate() override { return RID(); };
-	virtual void canvas_texture_initialize(RID p_rid) override{};
-	virtual void canvas_texture_free(RID p_rid) override{};
-
-	virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override{};
-	virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override{};
-
-	virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override{};
-	virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override{};
-};
-
-} // namespace RendererDummy
-
-#endif // !CANVAS_TEXTURE_STORAGE_DUMMY_H

+ 0 - 62
servers/rendering/dummy/storage/decal_atlas_storage.h

@@ -1,62 +0,0 @@
-/*************************************************************************/
-/*  decal_atlas_storage.h                                                */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#ifndef DECAL_ATLAS_STORAGE_DUMMY_H
-#define DECAL_ATLAS_STORAGE_DUMMY_H
-
-#include "servers/rendering/storage/decal_atlas_storage.h"
-
-namespace RendererDummy {
-
-class DecalAtlasStorage : public RendererDecalAtlasStorage {
-public:
-	virtual RID decal_allocate() override { return RID(); }
-	virtual void decal_initialize(RID p_rid) override {}
-	virtual void decal_free(RID p_rid) override{};
-
-	virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override {}
-	virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override {}
-	virtual void decal_set_emission_energy(RID p_decal, float p_energy) override {}
-	virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override {}
-	virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override {}
-	virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override {}
-	virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override {}
-	virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override {}
-	virtual void decal_set_normal_fade(RID p_decal, float p_fade) override {}
-
-	virtual AABB decal_get_aabb(RID p_decal) const override { return AABB(); }
-
-	virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
-	virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
-};
-
-} // namespace RendererDummy
-
-#endif // !DECAL_ATLAS_STORAGE_DUMMY_H

+ 56 - 0
servers/rendering/dummy/storage/texture_storage.h

@@ -52,6 +52,20 @@ public:
 
 	virtual bool can_create_resources_async() const override { return false; }
 
+	/* Canvas Texture API */
+
+	virtual RID canvas_texture_allocate() override { return RID(); };
+	virtual void canvas_texture_initialize(RID p_rid) override{};
+	virtual void canvas_texture_free(RID p_rid) override{};
+
+	virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override{};
+	virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override{};
+
+	virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override{};
+	virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override{};
+
+	/* Texture API */
+
 	DummyTexture *get_texture(RID p_rid) { return texture_owner.get_or_null(p_rid); };
 	bool owns_texture(RID p_rid) { return texture_owner.owns(p_rid); };
 
@@ -109,6 +123,48 @@ public:
 	virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) override{};
 
 	virtual Size2 texture_size_with_proxy(RID p_proxy) override { return Size2(); };
+
+	/* DECAL API */
+	virtual RID decal_allocate() override { return RID(); }
+	virtual void decal_initialize(RID p_rid) override {}
+	virtual void decal_free(RID p_rid) override{};
+
+	virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override {}
+	virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override {}
+	virtual void decal_set_emission_energy(RID p_decal, float p_energy) override {}
+	virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override {}
+	virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override {}
+	virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override {}
+	virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override {}
+	virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override {}
+	virtual void decal_set_normal_fade(RID p_decal, float p_fade) override {}
+
+	virtual AABB decal_get_aabb(RID p_decal) const override { return AABB(); }
+
+	virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
+	virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
+
+	/* RENDER TARGET */
+
+	virtual RID render_target_create() override { return RID(); }
+	virtual void render_target_free(RID p_rid) override {}
+	virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) override {}
+	virtual void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) override {}
+	virtual RID render_target_get_texture(RID p_render_target) override { return RID(); }
+	virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) override {}
+	virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) override {}
+	virtual bool render_target_was_used(RID p_render_target) override { return false; }
+	virtual void render_target_set_as_unused(RID p_render_target) override {}
+
+	virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color) override {}
+	virtual bool render_target_is_clear_requested(RID p_render_target) override { return false; }
+	virtual Color render_target_get_clear_request_color(RID p_render_target) override { return Color(); }
+	virtual void render_target_disable_clear_request(RID p_render_target) override {}
+	virtual void render_target_do_clear_request(RID p_render_target) override {}
+
+	virtual void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) override {}
+	virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const override { return Rect2i(); }
+	virtual void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) override {}
 };
 
 } // namespace RendererDummy

+ 7 - 7
servers/rendering/renderer_canvas_cull.cpp

@@ -34,7 +34,7 @@
 #include "renderer_viewport.h"
 #include "rendering_server_default.h"
 #include "rendering_server_globals.h"
-#include "servers/rendering/storage/canvas_texture_storage.h"
+#include "servers/rendering/storage/texture_storage.h"
 
 static const int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1;
 
@@ -1851,26 +1851,26 @@ void RendererCanvasCull::canvas_set_shadow_texture_size(int p_size) {
 }
 
 RID RendererCanvasCull::canvas_texture_allocate() {
-	return RSG::canvas_texture_storage->canvas_texture_allocate();
+	return RSG::texture_storage->canvas_texture_allocate();
 }
 void RendererCanvasCull::canvas_texture_initialize(RID p_rid) {
-	RSG::canvas_texture_storage->canvas_texture_initialize(p_rid);
+	RSG::texture_storage->canvas_texture_initialize(p_rid);
 }
 
 void RendererCanvasCull::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
-	RSG::canvas_texture_storage->canvas_texture_set_channel(p_canvas_texture, p_channel, p_texture);
+	RSG::texture_storage->canvas_texture_set_channel(p_canvas_texture, p_channel, p_texture);
 }
 
 void RendererCanvasCull::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) {
-	RSG::canvas_texture_storage->canvas_texture_set_shading_parameters(p_canvas_texture, p_base_color, p_shininess);
+	RSG::texture_storage->canvas_texture_set_shading_parameters(p_canvas_texture, p_base_color, p_shininess);
 }
 
 void RendererCanvasCull::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {
-	RSG::canvas_texture_storage->canvas_texture_set_texture_filter(p_canvas_texture, p_filter);
+	RSG::texture_storage->canvas_texture_set_texture_filter(p_canvas_texture, p_filter);
 }
 
 void RendererCanvasCull::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
-	RSG::canvas_texture_storage->canvas_texture_set_texture_repeat(p_canvas_texture, p_repeat);
+	RSG::texture_storage->canvas_texture_set_texture_repeat(p_canvas_texture, p_repeat);
 }
 
 void RendererCanvasCull::canvas_item_set_default_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) {

+ 0 - 4
servers/rendering/renderer_compositor.h

@@ -34,8 +34,6 @@
 #include "servers/rendering/renderer_canvas_render.h"
 #include "servers/rendering/renderer_scene.h"
 #include "servers/rendering/renderer_storage.h"
-#include "servers/rendering/storage/canvas_texture_storage.h"
-#include "servers/rendering/storage/decal_atlas_storage.h"
 #include "servers/rendering/storage/material_storage.h"
 #include "servers/rendering/storage/mesh_storage.h"
 #include "servers/rendering/storage/texture_storage.h"
@@ -75,11 +73,9 @@ protected:
 public:
 	static RendererCompositor *create();
 
-	virtual RendererCanvasTextureStorage *get_canvas_texture_storage() = 0;
 	virtual RendererMaterialStorage *get_material_storage() = 0;
 	virtual RendererMeshStorage *get_mesh_storage() = 0;
 	virtual RendererTextureStorage *get_texture_storage() = 0;
-	virtual RendererDecalAtlasStorage *get_decal_atlas_storage() = 0;
 	virtual RendererStorage *get_storage() = 0;
 	virtual RendererCanvasRender *get_canvas() = 0;
 	virtual RendererSceneRender *get_scene() = 0;

+ 3 - 3
servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp

@@ -30,8 +30,8 @@
 
 #include "render_forward_clustered.h"
 #include "core/config/project_settings.h"
-#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
+#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
 #include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"
 #include "servers/rendering/rendering_device.h"
 #include "servers/rendering/rendering_server_default.h"
@@ -2167,7 +2167,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() {
 			RD::Uniform u;
 			u.binding = 11;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
-			RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture();
+			RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture();
 			u.append_id(decal_atlas);
 			uniforms.push_back(u);
 		}
@@ -2175,7 +2175,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() {
 			RD::Uniform u;
 			u.binding = 12;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
-			RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture_srgb();
+			RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture_srgb();
 			u.append_id(decal_atlas);
 			uniforms.push_back(u);
 		}

+ 3 - 3
servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp

@@ -30,8 +30,8 @@
 
 #include "render_forward_mobile.h"
 #include "core/config/project_settings.h"
-#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
+#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
 #include "servers/rendering/rendering_device.h"
 #include "servers/rendering/rendering_server_default.h"
 
@@ -1279,7 +1279,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() {
 			RD::Uniform u;
 			u.binding = 11;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
-			RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture();
+			RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture();
 			u.append_id(decal_atlas);
 			uniforms.push_back(u);
 		}
@@ -1287,7 +1287,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() {
 			RD::Uniform u;
 			u.binding = 12;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
-			RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture_srgb();
+			RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture_srgb();
 			u.append_id(decal_atlas);
 			uniforms.push_back(u);
 		}

+ 43 - 37
servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp

@@ -35,8 +35,6 @@
 #include "core/math/math_defs.h"
 #include "core/math/math_funcs.h"
 #include "renderer_compositor_rd.h"
-#include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h"
-#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
 #include "servers/rendering/rendering_server_default.h"
@@ -364,7 +362,7 @@ void RendererCanvasRenderRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RI
 	bool use_normal;
 	bool use_specular;
 
-	bool success = RendererRD::CanvasTextureStorage::get_singleton()->canvas_texture_get_uniform_set(p_texture, p_base_filter, p_base_repeat, shader.default_version_rd_shader, CANVAS_TEXTURE_UNIFORM_SET, uniform_set, size, specular_shininess, use_normal, use_specular);
+	bool success = RendererRD::TextureStorage::get_singleton()->canvas_texture_get_uniform_set(p_texture, p_base_filter, p_base_repeat, shader.default_version_rd_shader, CANVAS_TEXTURE_UNIFORM_SET, uniform_set, size, specular_shininess, use_normal, use_specular);
 	//something odd happened
 	if (!success) {
 		_bind_canvas_texture(p_draw_list, default_canvas_texture, p_base_filter, p_base_repeat, r_last_texture, push_constant, r_texpixel_size);
@@ -401,6 +399,7 @@ void RendererCanvasRenderRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RI
 
 void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights, PipelineVariants *p_pipeline_variants) {
 	//create an empty push constant
+	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
 	RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton();
 
 	RS::CanvasItemTextureFilter current_filter = default_filter;
@@ -809,7 +808,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
 					mesh = storage->particles_get_draw_pass_mesh(pt->particles, 0); //higher ones are ignored
 					texture = pt->texture;
 
-					if (storage->particles_has_collision(pt->particles) && storage->render_target_is_sdf_enabled(p_render_target)) {
+					if (storage->particles_has_collision(pt->particles) && texture_storage->render_target_is_sdf_enabled(p_render_target)) {
 						//pass collision information
 						Transform2D xform;
 						if (local_coords) {
@@ -818,11 +817,11 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
 							xform = p_canvas_transform_inverse;
 						}
 
-						RID sdf_texture = storage->render_target_get_sdf_texture(p_render_target);
+						RID sdf_texture = texture_storage->render_target_get_sdf_texture(p_render_target);
 
 						Rect2 to_screen;
 						{
-							Rect2 sdf_rect = storage->render_target_get_sdf_rect(p_render_target);
+							Rect2 sdf_rect = texture_storage->render_target_get_sdf_rect(p_render_target);
 
 							to_screen.size = Vector2(1.0 / sdf_rect.size.width, 1.0 / sdf_rect.size.height);
 							to_screen.position = -sdf_rect.position * to_screen.size;
@@ -931,6 +930,8 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
 }
 
 RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, bool p_backbuffer) {
+	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+
 	//re create canvas state
 	Vector<RD::Uniform> uniforms;
 
@@ -954,7 +955,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo
 		RD::Uniform u;
 		u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 		u.binding = 3;
-		u.append_id(RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture());
+		u.append_id(RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture());
 		uniforms.push_back(u);
 	}
 
@@ -980,9 +981,9 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo
 		u.binding = 6;
 		RID screen;
 		if (p_backbuffer) {
-			screen = storage->render_target_get_rd_texture(p_to_render_target);
+			screen = texture_storage->render_target_get_rd_texture(p_to_render_target);
 		} else {
-			screen = storage->render_target_get_rd_backbuffer(p_to_render_target);
+			screen = texture_storage->render_target_get_rd_backbuffer(p_to_render_target);
 			if (screen.is_null()) { //unallocated backbuffer
 				screen = RendererRD::TextureStorage::get_singleton()->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE);
 			}
@@ -995,7 +996,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo
 		RD::Uniform u;
 		u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 		u.binding = 7;
-		RID sdf = storage->render_target_get_sdf_texture(p_to_render_target);
+		RID sdf = texture_storage->render_target_get_sdf_texture(p_to_render_target);
 		u.append_id(sdf);
 		uniforms.push_back(u);
 	}
@@ -1033,9 +1034,9 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo
 
 	RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, BASE_UNIFORM_SET);
 	if (p_backbuffer) {
-		storage->render_target_set_backbuffer_uniform_set(p_to_render_target, uniform_set);
+		texture_storage->render_target_set_backbuffer_uniform_set(p_to_render_target, uniform_set);
 	} else {
-		storage->render_target_set_framebuffer_uniform_set(p_to_render_target, uniform_set);
+		texture_storage->render_target_set_framebuffer_uniform_set(p_to_render_target, uniform_set);
 	}
 
 	return uniform_set;
@@ -1043,6 +1044,8 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo
 
 void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer) {
 	RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
+	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+
 	Item *current_clip = nullptr;
 
 	Transform2D canvas_transform_inverse = p_canvas_transform_inverse;
@@ -1053,21 +1056,21 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co
 	Vector<Color> clear_colors;
 
 	if (p_to_backbuffer) {
-		framebuffer = storage->render_target_get_rd_backbuffer_framebuffer(p_to_render_target);
-		fb_uniform_set = storage->render_target_get_backbuffer_uniform_set(p_to_render_target);
+		framebuffer = texture_storage->render_target_get_rd_backbuffer_framebuffer(p_to_render_target);
+		fb_uniform_set = texture_storage->render_target_get_backbuffer_uniform_set(p_to_render_target);
 	} else {
-		framebuffer = storage->render_target_get_rd_framebuffer(p_to_render_target);
+		framebuffer = texture_storage->render_target_get_rd_framebuffer(p_to_render_target);
 
-		if (storage->render_target_is_clear_requested(p_to_render_target)) {
+		if (texture_storage->render_target_is_clear_requested(p_to_render_target)) {
 			clear = true;
-			clear_colors.push_back(storage->render_target_get_clear_request_color(p_to_render_target));
-			storage->render_target_disable_clear_request(p_to_render_target);
+			clear_colors.push_back(texture_storage->render_target_get_clear_request_color(p_to_render_target));
+			texture_storage->render_target_disable_clear_request(p_to_render_target);
 		}
 #ifndef _MSC_VER
 #warning TODO obtain from framebuffer format eventually when this is implemented
 #endif
 
-		fb_uniform_set = storage->render_target_get_framebuffer_uniform_set(p_to_render_target);
+		fb_uniform_set = texture_storage->render_target_get_framebuffer_uniform_set(p_to_render_target);
 	}
 
 	if (fb_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(fb_uniform_set)) {
@@ -1136,6 +1139,7 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co
 }
 
 void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_light_list, const Transform2D &p_canvas_transform, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) {
+	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
 	RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
 	RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton();
 
@@ -1264,7 +1268,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
 			}
 
 			if (clight->texture.is_valid()) {
-				Rect2 atlas_rect = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture_rect(clight->texture);
+				Rect2 atlas_rect = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture_rect(clight->texture);
 				state.light_uniforms[index].atlas_rect[0] = atlas_rect.position.x;
 				state.light_uniforms[index].atlas_rect[1] = atlas_rect.position.y;
 				state.light_uniforms[index].atlas_rect[2] = atlas_rect.size.width;
@@ -1294,7 +1298,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
 		//update canvas state uniform buffer
 		State::Buffer state_buffer;
 
-		Size2i ssize = storage->render_target_get_size(p_to_render_target);
+		Size2i ssize = texture_storage->render_target_get_size(p_to_render_target);
 
 		Transform3D screen_transform;
 		screen_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f);
@@ -1313,7 +1317,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
 		state_buffer.canvas_modulate[2] = p_modulate.b;
 		state_buffer.canvas_modulate[3] = p_modulate.a;
 
-		Size2 render_target_size = storage->render_target_get_size(p_to_render_target);
+		Size2 render_target_size = texture_storage->render_target_get_size(p_to_render_target);
 		state_buffer.screen_pixel_size[0] = 1.0 / render_target_size.x;
 		state_buffer.screen_pixel_size[1] = 1.0 / render_target_size.y;
 
@@ -1330,7 +1334,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
 		state_buffer.screen_to_sdf[0] = 1.0 / state_buffer.sdf_to_screen[0];
 		state_buffer.screen_to_sdf[1] = 1.0 / state_buffer.sdf_to_screen[1];
 
-		Rect2 sdf_rect = storage->render_target_get_sdf_rect(p_to_render_target);
+		Rect2 sdf_rect = texture_storage->render_target_get_sdf_rect(p_to_render_target);
 		Rect2 sdf_tex_rect(sdf_rect.position / canvas_scale, sdf_rect.size / canvas_scale);
 
 		state_buffer.sdf_to_tex[0] = 1.0 / sdf_tex_rect.size.width;
@@ -1420,9 +1424,9 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
 				Rect2i group_rect = ci->canvas_group_owner->global_rect_cache;
 
 				if (ci->canvas_group_owner->canvas_group->mode == RS::CANVAS_GROUP_MODE_OPAQUE) {
-					storage->render_target_copy_to_back_buffer(p_to_render_target, group_rect, false);
+					texture_storage->render_target_copy_to_back_buffer(p_to_render_target, group_rect, false);
 				} else {
-					storage->render_target_clear_back_buffer(p_to_render_target, group_rect, Color(0, 0, 0, 0));
+					texture_storage->render_target_clear_back_buffer(p_to_render_target, group_rect, Color(0, 0, 0, 0));
 				}
 
 				backbuffer_copy = false;
@@ -1442,7 +1446,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
 			item_count = 0;
 
 			if (ci->canvas_group->blur_mipmaps) {
-				storage->render_target_gen_back_buffer_mipmaps(p_to_render_target, ci->global_rect_cache);
+				texture_storage->render_target_gen_back_buffer_mipmaps(p_to_render_target, ci->global_rect_cache);
 			}
 
 			canvas_group_owner = nullptr;
@@ -1457,7 +1461,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
 			_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list);
 			item_count = 0;
 
-			storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, true);
+			texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, true);
 
 			backbuffer_copy = false;
 			material_screen_texture_found = true; //after a backbuffer copy, screen texture makes no further copies
@@ -1490,7 +1494,7 @@ RID RendererCanvasRenderRD::light_create() {
 }
 
 void RendererCanvasRenderRD::light_set_texture(RID p_rid, RID p_texture) {
-	RendererRD::DecalAtlasStorage *decal_atlas_storage = RendererRD::DecalAtlasStorage::get_singleton();
+	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
 
 	CanvasLight *cl = canvas_light_owner.get_or_null(p_rid);
 	ERR_FAIL_COND(!cl);
@@ -1498,12 +1502,12 @@ void RendererCanvasRenderRD::light_set_texture(RID p_rid, RID p_texture) {
 		return;
 	}
 	if (cl->texture.is_valid()) {
-		decal_atlas_storage->texture_remove_from_decal_atlas(cl->texture);
+		texture_storage->texture_remove_from_decal_atlas(cl->texture);
 	}
 	cl->texture = p_texture;
 
 	if (cl->texture.is_valid()) {
-		decal_atlas_storage->texture_add_to_decal_atlas(cl->texture);
+		texture_storage->texture_add_to_decal_atlas(cl->texture);
 	}
 }
 
@@ -1703,8 +1707,10 @@ void RendererCanvasRenderRD::light_update_directional_shadow(RID p_rid, int p_sh
 }
 
 void RendererCanvasRenderRD::render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) {
-	RID fb = storage->render_target_get_sdf_framebuffer(p_render_target);
-	Rect2i rect = storage->render_target_get_sdf_rect(p_render_target);
+	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+
+	RID fb = texture_storage->render_target_get_sdf_framebuffer(p_render_target);
+	Rect2i rect = texture_storage->render_target_get_sdf_rect(p_render_target);
 
 	Transform2D to_sdf;
 	to_sdf.elements[0] *= rect.size.width;
@@ -1761,7 +1767,7 @@ void RendererCanvasRenderRD::render_sdf(RID p_render_target, LightOccluderInstan
 
 	RD::get_singleton()->draw_list_end();
 
-	storage->render_target_sdf_process(p_render_target); //done rendering, process it
+	texture_storage->render_target_sdf_process(p_render_target); //done rendering, process it
 }
 
 RID RendererCanvasRenderRD::occluder_polygon_create() {
@@ -2258,7 +2264,7 @@ void RendererCanvasRenderRD::update() {
 }
 
 RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
-	RendererRD::CanvasTextureStorage *canvas_texture_storage = RendererRD::CanvasTextureStorage::get_singleton();
+	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
 	RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
 	storage = p_storage;
 
@@ -2590,8 +2596,8 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
 		state.default_transforms_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, TRANSFORMS_UNIFORM_SET);
 	}
 
-	default_canvas_texture = canvas_texture_storage->canvas_texture_allocate();
-	canvas_texture_storage->canvas_texture_initialize(default_canvas_texture);
+	default_canvas_texture = texture_storage->canvas_texture_allocate();
+	texture_storage->canvas_texture_initialize(default_canvas_texture);
 
 	state.shadow_texture_size = GLOBAL_GET("rendering/2d/shadow_atlas/size");
 
@@ -2712,6 +2718,6 @@ RendererCanvasRenderRD::~RendererCanvasRenderRD() {
 	}
 	RD::get_singleton()->free(state.shadow_texture);
 
-	RendererRD::CanvasTextureStorage::get_singleton()->canvas_texture_free(default_canvas_texture);
+	RendererRD::TextureStorage::get_singleton()->canvas_texture_free(default_canvas_texture);
 	//pipelines don't need freeing, they are all gone after shaders are gone
 }

+ 1 - 5
servers/rendering/renderer_rd/renderer_compositor_rd.cpp

@@ -44,7 +44,7 @@ void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID
 	}
 
 	for (int i = 0; i < p_amount; i++) {
-		RID texture = storage->render_target_get_texture(p_render_targets[i].render_target);
+		RID texture = texture_storage->render_target_get_texture(p_render_targets[i].render_target);
 		ERR_CONTINUE(texture.is_null());
 		RID rd_texture = texture_storage->texture_get_rd_texture(texture);
 		ERR_CONTINUE(rd_texture.is_null());
@@ -155,11 +155,9 @@ void RendererCompositorRD::finalize() {
 	memdelete(scene);
 	memdelete(canvas);
 	memdelete(storage);
-	memdelete(decal_atlas_storage);
 	memdelete(mesh_storage);
 	memdelete(material_storage);
 	memdelete(texture_storage);
-	memdelete(canvas_texture_storage);
 
 	//only need to erase these, the rest are erased by cascade
 	blit.shader.version_free(blit.shader_version);
@@ -288,9 +286,7 @@ RendererCompositorRD::RendererCompositorRD() {
 	singleton = this;
 	time = 0;
 
-	canvas_texture_storage = memnew(RendererRD::CanvasTextureStorage);
 	texture_storage = memnew(RendererRD::TextureStorage);
-	decal_atlas_storage = memnew(RendererRD::DecalAtlasStorage);
 	material_storage = memnew(RendererRD::MaterialStorage);
 	mesh_storage = memnew(RendererRD::MeshStorage);
 	storage = memnew(RendererStorageRD);

+ 0 - 6
servers/rendering/renderer_rd/renderer_compositor_rd.h

@@ -39,8 +39,6 @@
 #include "servers/rendering/renderer_rd/renderer_canvas_render_rd.h"
 #include "servers/rendering/renderer_rd/renderer_storage_rd.h"
 #include "servers/rendering/renderer_rd/shaders/blit.glsl.gen.h"
-#include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h"
-#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
@@ -50,11 +48,9 @@ class RendererCompositorRD : public RendererCompositor {
 protected:
 	UniformSetCacheRD *uniform_set_cache = nullptr;
 	RendererCanvasRenderRD *canvas = nullptr;
-	RendererRD::CanvasTextureStorage *canvas_texture_storage;
 	RendererRD::MaterialStorage *material_storage;
 	RendererRD::MeshStorage *mesh_storage;
 	RendererRD::TextureStorage *texture_storage;
-	RendererRD::DecalAtlasStorage *decal_atlas_storage;
 	RendererStorageRD *storage = nullptr;
 	RendererSceneRenderRD *scene = nullptr;
 
@@ -98,8 +94,6 @@ protected:
 	static uint64_t frame;
 
 public:
-	RendererCanvasTextureStorage *get_canvas_texture_storage() { return canvas_texture_storage; }
-	RendererDecalAtlasStorage *get_decal_atlas_storage() { return decal_atlas_storage; }
 	RendererMaterialStorage *get_material_storage() { return material_storage; };
 	RendererMeshStorage *get_mesh_storage() { return mesh_storage; };
 	RendererTextureStorage *get_texture_storage() { return texture_storage; };

+ 3 - 2
servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp

@@ -32,6 +32,7 @@
 
 #include "core/config/project_settings.h"
 #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
+#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
 #include "servers/rendering/rendering_server_default.h"
 
 const Vector3i RendererSceneGIRD::SDFGI::Cascade::DIRTY_ALL = Vector3i(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF);
@@ -1245,8 +1246,8 @@ void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, cons
 	RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_width, p_height, 1);
 	RD::get_singleton()->compute_list_end();
 
-	Size2 rtsize = storage->render_target_get_size(p_render_target);
-	storage->get_effects()->copy_to_fb_rect(p_texture, storage->render_target_get_rd_framebuffer(p_render_target), Rect2(Vector2(), rtsize), true);
+	Size2 rtsize = texture_storage->render_target_get_size(p_render_target);
+	storage->get_effects()->copy_to_fb_rect(p_texture, texture_storage->render_target_get_rd_framebuffer(p_render_target), Rect2(Vector2(), rtsize), true);
 }
 
 void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform) {

+ 0 - 1
servers/rendering/renderer_rd/renderer_scene_gi_rd.h

@@ -45,7 +45,6 @@
 #include "servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl.gen.h"
 #include "servers/rendering/renderer_rd/shaders/voxel_gi.glsl.gen.h"
 #include "servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl.gen.h"
-#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
 #include "servers/rendering/renderer_scene_render.h"
 #include "servers/rendering/rendering_device.h"
 

+ 55 - 51
servers/rendering/renderer_rd/renderer_scene_render_rd.cpp

@@ -33,7 +33,6 @@
 #include "core/config/project_settings.h"
 #include "core/os/os.h"
 #include "renderer_compositor_rd.h"
-#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
 #include "servers/rendering/rendering_server_default.h"
@@ -2557,7 +2556,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
 		tonemap.luminance_multiplier = _render_buffers_get_luminance_multiplier();
 		tonemap.view_count = p_render_data->view_count;
 
-		storage->get_effects()->tonemapper(rb->internal_texture, storage->render_target_get_rd_framebuffer(rb->render_target), tonemap);
+		storage->get_effects()->tonemapper(rb->internal_texture, texture_storage->render_target_get_rd_framebuffer(rb->render_target), tonemap);
 
 		RD::get_singleton()->draw_command_end_label();
 	}
@@ -2570,7 +2569,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
 		RD::get_singleton()->draw_command_end_label();
 	}
 
-	storage->render_target_disable_clear_request(rb->render_target);
+	texture_storage->render_target_disable_clear_request(rb->render_target);
 }
 
 void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_framebuffer, const RenderDataRD *p_render_data) {
@@ -2647,7 +2646,8 @@ void RendererSceneRenderRD::_disable_clear_request(const RenderDataRD *p_render_
 	RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers);
 	ERR_FAIL_COND(!rb);
 
-	storage->render_target_disable_clear_request(rb->render_target);
+	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+	texture_storage->render_target_disable_clear_request(rb->render_target);
 }
 
 void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas, RID p_occlusion_buffer) {
@@ -2665,64 +2665,64 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID
 				shadow_atlas_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK);
 			}
 
-			Size2 rtsize = storage->render_target_get_size(rb->render_target);
-			effects->copy_to_fb_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true);
+			Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
+			effects->copy_to_fb_rect(shadow_atlas_texture, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true);
 		}
 	}
 
 	if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS) {
 		if (directional_shadow_get_texture().is_valid()) {
 			RID shadow_atlas_texture = directional_shadow_get_texture();
-			Size2 rtsize = storage->render_target_get_size(rb->render_target);
+			Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
 
-			effects->copy_to_fb_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true);
+			effects->copy_to_fb_rect(shadow_atlas_texture, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true);
 		}
 	}
 
 	if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_DECAL_ATLAS) {
-		RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture();
+		RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture();
 
 		if (decal_atlas.is_valid()) {
-			Size2 rtsize = storage->render_target_get_size(rb->render_target);
+			Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
 
-			effects->copy_to_fb_rect(decal_atlas, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, false, true);
+			effects->copy_to_fb_rect(decal_atlas, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, false, true);
 		}
 	}
 
 	if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE) {
 		if (rb->luminance.current.is_valid()) {
-			Size2 rtsize = storage->render_target_get_size(rb->render_target);
+			Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
 
-			effects->copy_to_fb_rect(rb->luminance.current, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 8), false, true);
+			effects->copy_to_fb_rect(rb->luminance.current, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 8), false, true);
 		}
 	}
 
 	if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SSAO && rb->ss_effects.ssao.ao_final.is_valid()) {
-		Size2 rtsize = storage->render_target_get_size(rb->render_target);
-		effects->copy_to_fb_rect(rb->ss_effects.ssao.ao_final, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true);
+		Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
+		effects->copy_to_fb_rect(rb->ss_effects.ssao.ao_final, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true);
 	}
 
 	if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SSIL && rb->ss_effects.ssil.ssil_final.is_valid()) {
-		Size2 rtsize = storage->render_target_get_size(rb->render_target);
-		effects->copy_to_fb_rect(rb->ss_effects.ssil.ssil_final, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false);
+		Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
+		effects->copy_to_fb_rect(rb->ss_effects.ssil.ssil_final, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false);
 	}
 
 	if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER && _render_buffers_get_normal_texture(p_render_buffers).is_valid()) {
-		Size2 rtsize = storage->render_target_get_size(rb->render_target);
-		effects->copy_to_fb_rect(_render_buffers_get_normal_texture(p_render_buffers), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false);
+		Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
+		effects->copy_to_fb_rect(_render_buffers_get_normal_texture(p_render_buffers), texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false);
 	}
 
 	if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && rb->ambient_buffer.is_valid()) {
-		Size2 rtsize = storage->render_target_get_size(rb->render_target);
+		Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
 		RID ambient_texture = rb->ambient_buffer;
 		RID reflection_texture = rb->reflection_buffer;
-		effects->copy_to_fb_rect(ambient_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false, false, true, reflection_texture);
+		effects->copy_to_fb_rect(ambient_texture, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false, false, true, reflection_texture);
 	}
 
 	if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_OCCLUDERS) {
 		if (p_occlusion_buffer.is_valid()) {
-			Size2 rtsize = storage->render_target_get_size(rb->render_target);
-			effects->copy_to_fb_rect(texture_storage->texture_get_rd_texture(p_occlusion_buffer), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize), true, false);
+			Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
+			effects->copy_to_fb_rect(texture_storage->texture_get_rd_texture(p_occlusion_buffer), texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize), true, false);
 		}
 	}
 }
@@ -2943,6 +2943,8 @@ bool RendererSceneRenderRD::_render_buffers_can_be_storage() {
 }
 
 void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding, uint32_t p_view_count) {
+	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+
 	ERR_FAIL_COND_MSG(p_view_count == 0, "Must have at least 1 view");
 
 	if (!_render_buffers_can_be_storage()) {
@@ -3040,7 +3042,7 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
 		rb->texture_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, rb->view_count);
 	}
 
-	RID target_texture = storage->render_target_get_rd_texture(rb->render_target);
+	RID target_texture = texture_storage->render_target_get_rd_texture(rb->render_target);
 	rb->data->configure(rb->internal_texture, rb->depth_texture, target_texture, p_internal_width, p_internal_height, p_msaa, p_view_count);
 
 	if (is_clustered_enabled()) {
@@ -3268,7 +3270,7 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti
 }
 
 void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Transform3D &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count, bool &r_directional_light_soft_shadows) {
-	RendererRD::DecalAtlasStorage *decal_atlas_storage = RendererRD::DecalAtlasStorage::get_singleton();
+	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
 
 	Transform3D inverse_transform = p_camera_transform.affine_inverse();
 
@@ -3553,7 +3555,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 		RID projector = storage->light_get_projector(base);
 
 		if (projector.is_valid()) {
-			Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(projector);
+			Rect2 rect = texture_storage->decal_atlas_get_texture_rect(projector);
 
 			if (type == RS::LIGHT_SPOT) {
 				light_data.projector_rect[0] = rect.position.x;
@@ -3669,7 +3671,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 }
 
 void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const Transform3D &p_camera_inverse_xform) {
-	RendererRD::DecalAtlasStorage *decal_atlas_storage = RendererRD::DecalAtlasStorage::get_singleton();
+	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
 
 	Transform3D uv_xform;
 	uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0));
@@ -3694,9 +3696,9 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
 
 		real_t distance = -p_camera_inverse_xform.xform(xform.origin).z;
 
-		if (decal_atlas_storage->decal_is_distance_fade_enabled(decal)) {
-			float fade_begin = decal_atlas_storage->decal_get_distance_fade_begin(decal);
-			float fade_length = decal_atlas_storage->decal_get_distance_fade_length(decal);
+		if (texture_storage->decal_is_distance_fade_enabled(decal)) {
+			float fade_begin = texture_storage->decal_get_distance_fade_begin(decal);
+			float fade_length = texture_storage->decal_get_distance_fade_length(decal);
 
 			if (distance > fade_begin) {
 				if (distance > fade_begin + fade_length) {
@@ -3724,15 +3726,15 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
 			_map_forward_id(FORWARD_ID_TYPE_DECAL, di->forward_id, i);
 		}
 
-		di->cull_mask = decal_atlas_storage->decal_get_cull_mask(decal);
+		di->cull_mask = texture_storage->decal_get_cull_mask(decal);
 
 		Transform3D xform = di->transform;
 		float fade = 1.0;
 
-		if (decal_atlas_storage->decal_is_distance_fade_enabled(decal)) {
+		if (texture_storage->decal_is_distance_fade_enabled(decal)) {
 			real_t distance = -p_camera_inverse_xform.xform(xform.origin).z;
-			float fade_begin = decal_atlas_storage->decal_get_distance_fade_begin(decal);
-			float fade_length = decal_atlas_storage->decal_get_distance_fade_length(decal);
+			float fade_begin = texture_storage->decal_get_distance_fade_begin(decal);
+			float fade_length = texture_storage->decal_get_distance_fade_length(decal);
 
 			if (distance > fade_begin) {
 				fade = 1.0 - (distance - fade_begin) / fade_length;
@@ -3741,7 +3743,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
 
 		Cluster::DecalData &dd = cluster.decals[i];
 
-		Vector3 decal_extents = decal_atlas_storage->decal_get_extents(decal);
+		Vector3 decal_extents = texture_storage->decal_get_extents(decal);
 
 		Transform3D scale_xform;
 		scale_xform.basis.scale(decal_extents);
@@ -3754,12 +3756,12 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
 		dd.normal[0] = normal.x;
 		dd.normal[1] = normal.y;
 		dd.normal[2] = normal.z;
-		dd.normal_fade = decal_atlas_storage->decal_get_normal_fade(decal);
+		dd.normal_fade = texture_storage->decal_get_normal_fade(decal);
 
-		RID albedo_tex = decal_atlas_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ALBEDO);
-		RID emission_tex = decal_atlas_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_EMISSION);
+		RID albedo_tex = texture_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ALBEDO);
+		RID emission_tex = texture_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_EMISSION);
 		if (albedo_tex.is_valid()) {
-			Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(albedo_tex);
+			Rect2 rect = texture_storage->decal_atlas_get_texture_rect(albedo_tex);
 			dd.albedo_rect[0] = rect.position.x;
 			dd.albedo_rect[1] = rect.position.y;
 			dd.albedo_rect[2] = rect.size.x;
@@ -3774,10 +3776,10 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
 			dd.albedo_rect[3] = 0;
 		}
 
-		RID normal_tex = decal_atlas_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_NORMAL);
+		RID normal_tex = texture_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_NORMAL);
 
 		if (normal_tex.is_valid()) {
-			Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(normal_tex);
+			Rect2 rect = texture_storage->decal_atlas_get_texture_rect(normal_tex);
 			dd.normal_rect[0] = rect.position.x;
 			dd.normal_rect[1] = rect.position.y;
 			dd.normal_rect[2] = rect.size.x;
@@ -3792,9 +3794,9 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
 			dd.normal_rect[3] = 0;
 		}
 
-		RID orm_tex = decal_atlas_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ORM);
+		RID orm_tex = texture_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ORM);
 		if (orm_tex.is_valid()) {
-			Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(orm_tex);
+			Rect2 rect = texture_storage->decal_atlas_get_texture_rect(orm_tex);
 			dd.orm_rect[0] = rect.position.x;
 			dd.orm_rect[1] = rect.position.y;
 			dd.orm_rect[2] = rect.size.x;
@@ -3807,7 +3809,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
 		}
 
 		if (emission_tex.is_valid()) {
-			Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(emission_tex);
+			Rect2 rect = texture_storage->decal_atlas_get_texture_rect(emission_tex);
 			dd.emission_rect[0] = rect.position.x;
 			dd.emission_rect[1] = rect.position.y;
 			dd.emission_rect[2] = rect.size.x;
@@ -3819,16 +3821,16 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
 			dd.emission_rect[3] = 0;
 		}
 
-		Color modulate = decal_atlas_storage->decal_get_modulate(decal);
+		Color modulate = texture_storage->decal_get_modulate(decal);
 		dd.modulate[0] = modulate.r;
 		dd.modulate[1] = modulate.g;
 		dd.modulate[2] = modulate.b;
 		dd.modulate[3] = modulate.a * fade;
-		dd.emission_energy = decal_atlas_storage->decal_get_emission_energy(decal) * fade;
-		dd.albedo_mix = decal_atlas_storage->decal_get_albedo_mix(decal);
-		dd.mask = decal_atlas_storage->decal_get_cull_mask(decal);
-		dd.upper_fade = decal_atlas_storage->decal_get_upper_fade(decal);
-		dd.lower_fade = decal_atlas_storage->decal_get_lower_fade(decal);
+		dd.emission_energy = texture_storage->decal_get_emission_energy(decal) * fade;
+		dd.albedo_mix = texture_storage->decal_get_albedo_mix(decal);
+		dd.mask = texture_storage->decal_get_cull_mask(decal);
+		dd.upper_fade = texture_storage->decal_get_upper_fade(decal);
+		dd.lower_fade = texture_storage->decal_get_lower_fade(decal);
 
 		if (current_cluster_builder != nullptr) {
 			current_cluster_builder->add_box(ClusterBuilderRD::BOX_TYPE_DECAL, xform, decal_extents);
@@ -4974,6 +4976,8 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
 }
 
 void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RendererScene::RenderInfo *r_render_info) {
+	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+
 	// getting this here now so we can direct call a bunch of things more easily
 	RenderBuffers *rb = nullptr;
 	if (p_render_buffers.is_valid()) {
@@ -5052,7 +5056,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData
 
 	Color clear_color;
 	if (p_render_buffers.is_valid()) {
-		clear_color = storage->render_target_get_clear_request_color(rb->render_target);
+		clear_color = texture_storage->render_target_get_clear_request_color(rb->render_target);
 	} else {
 		clear_color = storage->get_default_clear_color();
 	}

+ 13 - 736
servers/rendering/renderer_rd/renderer_storage_rd.cpp

@@ -35,8 +35,6 @@
 #include "core/io/resource_loader.h"
 #include "core/math/math_defs.h"
 #include "renderer_compositor_rd.h"
-#include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h"
-#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
 #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
 #include "servers/rendering/rendering_server_globals.h"
@@ -2030,7 +2028,7 @@ void RendererStorageRD::light_set_shadow(RID p_light, bool p_enabled) {
 }
 
 void RendererStorageRD::light_set_projector(RID p_light, RID p_texture) {
-	RendererRD::DecalAtlasStorage *decal_atlas_storage = RendererRD::DecalAtlasStorage::get_singleton();
+	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
 	Light *light = light_owner.get_or_null(p_light);
 	ERR_FAIL_COND(!light);
 
@@ -2039,14 +2037,14 @@ void RendererStorageRD::light_set_projector(RID p_light, RID p_texture) {
 	}
 
 	if (light->type != RS::LIGHT_DIRECTIONAL && light->projector.is_valid()) {
-		decal_atlas_storage->texture_remove_from_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
+		texture_storage->texture_remove_from_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
 	}
 
 	light->projector = p_texture;
 
 	if (light->type != RS::LIGHT_DIRECTIONAL) {
 		if (light->projector.is_valid()) {
-			decal_atlas_storage->texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
+			texture_storage->texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
 		}
 		light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
 	}
@@ -2950,698 +2948,6 @@ AABB RendererStorageRD::lightmap_get_aabb(RID p_lightmap) const {
 	return lm->bounds;
 }
 
-/* RENDER TARGET API */
-
-void RendererStorageRD::_clear_render_target(RenderTarget *rt) {
-	//free in reverse dependency order
-	if (rt->framebuffer.is_valid()) {
-		RD::get_singleton()->free(rt->framebuffer);
-		rt->framebuffer_uniform_set = RID(); //chain deleted
-	}
-
-	if (rt->color.is_valid()) {
-		RD::get_singleton()->free(rt->color);
-	}
-
-	if (rt->backbuffer.is_valid()) {
-		RD::get_singleton()->free(rt->backbuffer);
-		rt->backbuffer = RID();
-		rt->backbuffer_mipmaps.clear();
-		rt->backbuffer_uniform_set = RID(); //chain deleted
-	}
-
-	_render_target_clear_sdf(rt);
-
-	rt->framebuffer = RID();
-	rt->color = RID();
-}
-
-void RendererStorageRD::_update_render_target(RenderTarget *rt) {
-	if (rt->texture.is_null()) {
-		//create a placeholder until updated
-		rt->texture = RendererRD::TextureStorage::get_singleton()->texture_allocate();
-		RendererRD::TextureStorage::get_singleton()->texture_2d_placeholder_initialize(rt->texture);
-		RendererRD::Texture *tex = RendererRD::TextureStorage::get_singleton()->get_texture(rt->texture);
-		tex->is_render_target = true;
-	}
-
-	_clear_render_target(rt);
-
-	if (rt->size.width == 0 || rt->size.height == 0) {
-		return;
-	}
-	//until we implement support for HDR monitors (and render target is attached to screen), this is enough.
-	rt->color_format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
-	rt->color_format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
-	rt->image_format = rt->flags[RENDER_TARGET_TRANSPARENT] ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8;
-
-	RD::TextureFormat rd_format;
-	RD::TextureView rd_view;
-	{ //attempt register
-		rd_format.format = rt->color_format;
-		rd_format.width = rt->size.width;
-		rd_format.height = rt->size.height;
-		rd_format.depth = 1;
-		rd_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
-		rd_format.mipmaps = 1;
-		if (rd_format.array_layers > 1) { // why are we not using rt->texture_type ??
-			rd_format.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
-		} else {
-			rd_format.texture_type = RD::TEXTURE_TYPE_2D;
-		}
-		rd_format.samples = RD::TEXTURE_SAMPLES_1;
-		rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
-		rd_format.shareable_formats.push_back(rt->color_format);
-		rd_format.shareable_formats.push_back(rt->color_format_srgb);
-	}
-
-	rt->color = RD::get_singleton()->texture_create(rd_format, rd_view);
-	ERR_FAIL_COND(rt->color.is_null());
-
-	Vector<RID> fb_textures;
-	fb_textures.push_back(rt->color);
-	rt->framebuffer = RD::get_singleton()->framebuffer_create(fb_textures, RenderingDevice::INVALID_ID, rt->view_count);
-	if (rt->framebuffer.is_null()) {
-		_clear_render_target(rt);
-		ERR_FAIL_COND(rt->framebuffer.is_null());
-	}
-
-	{ //update texture
-
-		RendererRD::Texture *tex = RendererRD::TextureStorage::get_singleton()->get_texture(rt->texture);
-
-		//free existing textures
-		if (RD::get_singleton()->texture_is_valid(tex->rd_texture)) {
-			RD::get_singleton()->free(tex->rd_texture);
-		}
-		if (RD::get_singleton()->texture_is_valid(tex->rd_texture_srgb)) {
-			RD::get_singleton()->free(tex->rd_texture_srgb);
-		}
-
-		tex->rd_texture = RID();
-		tex->rd_texture_srgb = RID();
-
-		//create shared textures to the color buffer,
-		//so transparent can be supported
-		RD::TextureView view;
-		view.format_override = rt->color_format;
-		if (!rt->flags[RENDER_TARGET_TRANSPARENT]) {
-			view.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
-		}
-		tex->rd_texture = RD::get_singleton()->texture_create_shared(view, rt->color);
-		if (rt->color_format_srgb != RD::DATA_FORMAT_MAX) {
-			view.format_override = rt->color_format_srgb;
-			tex->rd_texture_srgb = RD::get_singleton()->texture_create_shared(view, rt->color);
-		}
-		tex->rd_view = view;
-		tex->width = rt->size.width;
-		tex->height = rt->size.height;
-		tex->width_2d = rt->size.width;
-		tex->height_2d = rt->size.height;
-		tex->rd_format = rt->color_format;
-		tex->rd_format_srgb = rt->color_format_srgb;
-		tex->format = rt->image_format;
-
-		Vector<RID> proxies = tex->proxies; //make a copy, since update may change it
-		for (int i = 0; i < proxies.size(); i++) {
-			RendererRD::TextureStorage::get_singleton()->texture_proxy_update(proxies[i], rt->texture);
-		}
-	}
-}
-
-void RendererStorageRD::_create_render_target_backbuffer(RenderTarget *rt) {
-	ERR_FAIL_COND(rt->backbuffer.is_valid());
-
-	uint32_t mipmaps_required = Image::get_image_required_mipmaps(rt->size.width, rt->size.height, Image::FORMAT_RGBA8);
-	RD::TextureFormat tf;
-	tf.format = rt->color_format;
-	tf.width = rt->size.width;
-	tf.height = rt->size.height;
-	tf.texture_type = RD::TEXTURE_TYPE_2D;
-	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;
-	tf.mipmaps = mipmaps_required;
-
-	rt->backbuffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
-	RD::get_singleton()->set_resource_name(rt->backbuffer, "Render Target Back Buffer");
-	rt->backbuffer_mipmap0 = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, 0);
-	RD::get_singleton()->set_resource_name(rt->backbuffer_mipmap0, "Back Buffer slice mipmap 0");
-
-	{
-		Vector<RID> fb_tex;
-		fb_tex.push_back(rt->backbuffer_mipmap0);
-		rt->backbuffer_fb = RD::get_singleton()->framebuffer_create(fb_tex);
-	}
-
-	if (rt->framebuffer_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rt->framebuffer_uniform_set)) {
-		//the new one will require the backbuffer.
-		RD::get_singleton()->free(rt->framebuffer_uniform_set);
-		rt->framebuffer_uniform_set = RID();
-	}
-	//create mipmaps
-	for (uint32_t i = 1; i < mipmaps_required; i++) {
-		RID mipmap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, i);
-		RD::get_singleton()->set_resource_name(mipmap, "Back Buffer slice mip: " + itos(i));
-
-		rt->backbuffer_mipmaps.push_back(mipmap);
-	}
-}
-
-RID RendererStorageRD::render_target_create() {
-	RenderTarget render_target;
-
-	render_target.was_used = false;
-	render_target.clear_requested = false;
-
-	for (int i = 0; i < RENDER_TARGET_FLAG_MAX; i++) {
-		render_target.flags[i] = false;
-	}
-	_update_render_target(&render_target);
-	return render_target_owner.make_rid(render_target);
-}
-
-void RendererStorageRD::render_target_set_position(RID p_render_target, int p_x, int p_y) {
-	//unused for this render target
-}
-
-void RendererStorageRD::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-	if (rt->size.x != p_width || rt->size.y != p_height || rt->view_count != p_view_count) {
-		rt->size.x = p_width;
-		rt->size.y = p_height;
-		rt->view_count = p_view_count;
-		_update_render_target(rt);
-	}
-}
-
-RID RendererStorageRD::render_target_get_texture(RID p_render_target) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, RID());
-
-	return rt->texture;
-}
-
-void RendererStorageRD::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) {
-}
-
-void RendererStorageRD::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-	rt->flags[p_flag] = p_value;
-	_update_render_target(rt);
-}
-
-bool RendererStorageRD::render_target_was_used(RID p_render_target) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, false);
-	return rt->was_used;
-}
-
-void RendererStorageRD::render_target_set_as_unused(RID p_render_target) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-	rt->was_used = false;
-}
-
-Size2 RendererStorageRD::render_target_get_size(RID p_render_target) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, Size2());
-
-	return rt->size;
-}
-
-RID RendererStorageRD::render_target_get_rd_framebuffer(RID p_render_target) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, RID());
-
-	return rt->framebuffer;
-}
-
-RID RendererStorageRD::render_target_get_rd_texture(RID p_render_target) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, RID());
-
-	return rt->color;
-}
-
-RID RendererStorageRD::render_target_get_rd_backbuffer(RID p_render_target) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, RID());
-	return rt->backbuffer;
-}
-
-RID RendererStorageRD::render_target_get_rd_backbuffer_framebuffer(RID p_render_target) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, RID());
-
-	if (!rt->backbuffer.is_valid()) {
-		_create_render_target_backbuffer(rt);
-	}
-
-	return rt->backbuffer_fb;
-}
-
-void RendererStorageRD::render_target_request_clear(RID p_render_target, const Color &p_clear_color) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-	rt->clear_requested = true;
-	rt->clear_color = p_clear_color;
-}
-
-bool RendererStorageRD::render_target_is_clear_requested(RID p_render_target) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, false);
-	return rt->clear_requested;
-}
-
-Color RendererStorageRD::render_target_get_clear_request_color(RID p_render_target) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, Color());
-	return rt->clear_color;
-}
-
-void RendererStorageRD::render_target_disable_clear_request(RID p_render_target) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-	rt->clear_requested = false;
-}
-
-void RendererStorageRD::render_target_do_clear_request(RID p_render_target) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-	if (!rt->clear_requested) {
-		return;
-	}
-	Vector<Color> clear_colors;
-	clear_colors.push_back(rt->clear_color);
-	RD::get_singleton()->draw_list_begin(rt->framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, clear_colors);
-	RD::get_singleton()->draw_list_end();
-	rt->clear_requested = false;
-}
-
-void RendererStorageRD::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-	if (rt->sdf_oversize == p_size && rt->sdf_scale == p_scale) {
-		return;
-	}
-
-	rt->sdf_oversize = p_size;
-	rt->sdf_scale = p_scale;
-
-	_render_target_clear_sdf(rt);
-}
-
-Rect2i RendererStorageRD::_render_target_get_sdf_rect(const RenderTarget *rt) const {
-	Size2i margin;
-	int scale;
-	switch (rt->sdf_oversize) {
-		case RS::VIEWPORT_SDF_OVERSIZE_100_PERCENT: {
-			scale = 100;
-		} break;
-		case RS::VIEWPORT_SDF_OVERSIZE_120_PERCENT: {
-			scale = 120;
-		} break;
-		case RS::VIEWPORT_SDF_OVERSIZE_150_PERCENT: {
-			scale = 150;
-		} break;
-		case RS::VIEWPORT_SDF_OVERSIZE_200_PERCENT: {
-			scale = 200;
-		} break;
-		default: {
-		}
-	}
-
-	margin = (rt->size * scale / 100) - rt->size;
-
-	Rect2i r(Vector2i(), rt->size);
-	r.position -= margin;
-	r.size += margin * 2;
-
-	return r;
-}
-
-Rect2i RendererStorageRD::render_target_get_sdf_rect(RID p_render_target) const {
-	const RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, Rect2i());
-
-	return _render_target_get_sdf_rect(rt);
-}
-
-void RendererStorageRD::render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-
-	rt->sdf_enabled = p_enabled;
-}
-
-bool RendererStorageRD::render_target_is_sdf_enabled(RID p_render_target) const {
-	const RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, false);
-
-	return rt->sdf_enabled;
-}
-
-RID RendererStorageRD::render_target_get_sdf_texture(RID p_render_target) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, RID());
-	if (rt->sdf_buffer_read.is_null()) {
-		// no texture, create a dummy one for the 2D uniform set
-		RD::TextureFormat tformat;
-		tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
-		tformat.width = 4;
-		tformat.height = 4;
-		tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT;
-		tformat.texture_type = RD::TEXTURE_TYPE_2D;
-
-		Vector<uint8_t> pv;
-		pv.resize(16 * 4);
-		memset(pv.ptrw(), 0, 16 * 4);
-		Vector<Vector<uint8_t>> vpv;
-
-		rt->sdf_buffer_read = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
-	}
-
-	return rt->sdf_buffer_read;
-}
-
-void RendererStorageRD::_render_target_allocate_sdf(RenderTarget *rt) {
-	ERR_FAIL_COND(rt->sdf_buffer_write_fb.is_valid());
-	if (rt->sdf_buffer_read.is_valid()) {
-		RD::get_singleton()->free(rt->sdf_buffer_read);
-		rt->sdf_buffer_read = RID();
-	}
-
-	Size2i size = _render_target_get_sdf_rect(rt).size;
-
-	RD::TextureFormat tformat;
-	tformat.format = RD::DATA_FORMAT_R8_UNORM;
-	tformat.width = size.width;
-	tformat.height = size.height;
-	tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
-	tformat.texture_type = RD::TEXTURE_TYPE_2D;
-
-	rt->sdf_buffer_write = RD::get_singleton()->texture_create(tformat, RD::TextureView());
-
-	{
-		Vector<RID> write_fb;
-		write_fb.push_back(rt->sdf_buffer_write);
-		rt->sdf_buffer_write_fb = RD::get_singleton()->framebuffer_create(write_fb);
-	}
-
-	int scale;
-	switch (rt->sdf_scale) {
-		case RS::VIEWPORT_SDF_SCALE_100_PERCENT: {
-			scale = 100;
-		} break;
-		case RS::VIEWPORT_SDF_SCALE_50_PERCENT: {
-			scale = 50;
-		} break;
-		case RS::VIEWPORT_SDF_SCALE_25_PERCENT: {
-			scale = 25;
-		} break;
-		default: {
-			scale = 100;
-		} break;
-	}
-
-	rt->process_size = size * scale / 100;
-	rt->process_size.x = MAX(rt->process_size.x, 1);
-	rt->process_size.y = MAX(rt->process_size.y, 1);
-
-	tformat.format = RD::DATA_FORMAT_R16G16_SINT;
-	tformat.width = rt->process_size.width;
-	tformat.height = rt->process_size.height;
-	tformat.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;
-
-	rt->sdf_buffer_process[0] = RD::get_singleton()->texture_create(tformat, RD::TextureView());
-	rt->sdf_buffer_process[1] = RD::get_singleton()->texture_create(tformat, RD::TextureView());
-
-	tformat.format = RD::DATA_FORMAT_R16_SNORM;
-	tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
-
-	rt->sdf_buffer_read = RD::get_singleton()->texture_create(tformat, RD::TextureView());
-
-	{
-		Vector<RD::Uniform> uniforms;
-		{
-			RD::Uniform u;
-			u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
-			u.binding = 1;
-			u.append_id(rt->sdf_buffer_write);
-			uniforms.push_back(u);
-		}
-		{
-			RD::Uniform u;
-			u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
-			u.binding = 2;
-			u.append_id(rt->sdf_buffer_read);
-			uniforms.push_back(u);
-		}
-		{
-			RD::Uniform u;
-			u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
-			u.binding = 3;
-			u.append_id(rt->sdf_buffer_process[0]);
-			uniforms.push_back(u);
-		}
-		{
-			RD::Uniform u;
-			u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
-			u.binding = 4;
-			u.append_id(rt->sdf_buffer_process[1]);
-			uniforms.push_back(u);
-		}
-
-		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);
-		RID aux2 = uniforms.write[2].get_id(0);
-		RID aux3 = uniforms.write[3].get_id(0);
-		uniforms.write[2].set_id(0, aux3);
-		uniforms.write[3].set_id(0, aux2);
-		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);
-	}
-}
-
-void RendererStorageRD::_render_target_clear_sdf(RenderTarget *rt) {
-	if (rt->sdf_buffer_read.is_valid()) {
-		RD::get_singleton()->free(rt->sdf_buffer_read);
-		rt->sdf_buffer_read = RID();
-	}
-	if (rt->sdf_buffer_write_fb.is_valid()) {
-		RD::get_singleton()->free(rt->sdf_buffer_write);
-		RD::get_singleton()->free(rt->sdf_buffer_process[0]);
-		RD::get_singleton()->free(rt->sdf_buffer_process[1]);
-		rt->sdf_buffer_write = RID();
-		rt->sdf_buffer_write_fb = RID();
-		rt->sdf_buffer_process[0] = RID();
-		rt->sdf_buffer_process[1] = RID();
-		rt->sdf_buffer_process_uniform_sets[0] = RID();
-		rt->sdf_buffer_process_uniform_sets[1] = RID();
-	}
-}
-
-RID RendererStorageRD::render_target_get_sdf_framebuffer(RID p_render_target) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, RID());
-
-	if (rt->sdf_buffer_write_fb.is_null()) {
-		_render_target_allocate_sdf(rt);
-	}
-
-	return rt->sdf_buffer_write_fb;
-}
-void RendererStorageRD::render_target_sdf_process(RID p_render_target) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-	ERR_FAIL_COND(rt->sdf_buffer_write_fb.is_null());
-
-	RenderTargetSDF::PushConstant push_constant;
-
-	Rect2i r = _render_target_get_sdf_rect(rt);
-
-	push_constant.size[0] = r.size.width;
-	push_constant.size[1] = r.size.height;
-	push_constant.stride = 0;
-	push_constant.shift = 0;
-	push_constant.base_size[0] = r.size.width;
-	push_constant.base_size[1] = r.size.height;
-
-	bool shrink = false;
-
-	switch (rt->sdf_scale) {
-		case RS::VIEWPORT_SDF_SCALE_50_PERCENT: {
-			push_constant.size[0] >>= 1;
-			push_constant.size[1] >>= 1;
-			push_constant.shift = 1;
-			shrink = true;
-		} break;
-		case RS::VIEWPORT_SDF_SCALE_25_PERCENT: {
-			push_constant.size[0] >>= 2;
-			push_constant.size[1] >>= 2;
-			push_constant.shift = 2;
-			shrink = true;
-		} break;
-		default: {
-		};
-	}
-
-	RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
-
-	/* Load */
-
-	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, rt_sdf.pipelines[shrink ? RenderTargetSDF::SHADER_LOAD_SHRINK : RenderTargetSDF::SHADER_LOAD]);
-	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[1], 0); //fill [0]
-	RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant));
-
-	RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1);
-
-	/* Process */
-
-	int stride = nearest_power_of_2_templated(MAX(push_constant.size[0], push_constant.size[1]) / 2);
-
-	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, rt_sdf.pipelines[RenderTargetSDF::SHADER_PROCESS]);
-
-	RD::get_singleton()->compute_list_add_barrier(compute_list);
-	bool swap = false;
-
-	//jumpflood
-	while (stride > 0) {
-		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[swap ? 1 : 0], 0);
-		push_constant.stride = stride;
-		RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant));
-		RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1);
-		stride /= 2;
-		swap = !swap;
-		RD::get_singleton()->compute_list_add_barrier(compute_list);
-	}
-
-	/* Store */
-
-	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, rt_sdf.pipelines[shrink ? RenderTargetSDF::SHADER_STORE_SHRINK : RenderTargetSDF::SHADER_STORE]);
-	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[swap ? 1 : 0], 0);
-	RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant));
-	RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1);
-
-	RD::get_singleton()->compute_list_end();
-}
-
-void RendererStorageRD::render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-	if (!rt->backbuffer.is_valid()) {
-		_create_render_target_backbuffer(rt);
-	}
-
-	Rect2i region;
-	if (p_region == Rect2i()) {
-		region.size = rt->size;
-	} else {
-		region = Rect2i(Size2i(), rt->size).intersection(p_region);
-		if (region.size == Size2i()) {
-			return; //nothing to do
-		}
-	}
-
-	//single texture copy for backbuffer
-	//RD::get_singleton()->texture_copy(rt->color, rt->backbuffer_mipmap0, Vector3(region.position.x, region.position.y, 0), Vector3(region.position.x, region.position.y, 0), Vector3(region.size.x, region.size.y, 1), 0, 0, 0, 0, true);
-	effects->copy_to_rect(rt->color, rt->backbuffer_mipmap0, region, false, false, false, true, true);
-
-	if (!p_gen_mipmaps) {
-		return;
-	}
-	RD::get_singleton()->draw_command_begin_label("Gaussian Blur Mipmaps");
-	//then mipmap blur
-	RID prev_texture = rt->color; //use color, not backbuffer, as bb has mipmaps.
-
-	for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
-		region.position.x >>= 1;
-		region.position.y >>= 1;
-		region.size.x = MAX(1, region.size.x >> 1);
-		region.size.y = MAX(1, region.size.y >> 1);
-
-		RID mipmap = rt->backbuffer_mipmaps[i];
-		effects->gaussian_blur(prev_texture, mipmap, region, true);
-		prev_texture = mipmap;
-	}
-	RD::get_singleton()->draw_command_end_label();
-}
-
-void RendererStorageRD::render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-	if (!rt->backbuffer.is_valid()) {
-		_create_render_target_backbuffer(rt);
-	}
-
-	Rect2i region;
-	if (p_region == Rect2i()) {
-		region.size = rt->size;
-	} else {
-		region = Rect2i(Size2i(), rt->size).intersection(p_region);
-		if (region.size == Size2i()) {
-			return; //nothing to do
-		}
-	}
-
-	//single texture copy for backbuffer
-	effects->set_color(rt->backbuffer_mipmap0, p_color, region, true);
-}
-
-void RendererStorageRD::render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-	if (!rt->backbuffer.is_valid()) {
-		_create_render_target_backbuffer(rt);
-	}
-
-	Rect2i region;
-	if (p_region == Rect2i()) {
-		region.size = rt->size;
-	} else {
-		region = Rect2i(Size2i(), rt->size).intersection(p_region);
-		if (region.size == Size2i()) {
-			return; //nothing to do
-		}
-	}
-	RD::get_singleton()->draw_command_begin_label("Gaussian Blur Mipmaps2");
-	//then mipmap blur
-	RID prev_texture = rt->backbuffer_mipmap0;
-
-	for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
-		region.position.x >>= 1;
-		region.position.y >>= 1;
-		region.size.x = MAX(1, region.size.x >> 1);
-		region.size.y = MAX(1, region.size.y >> 1);
-
-		RID mipmap = rt->backbuffer_mipmaps[i];
-		effects->gaussian_blur(prev_texture, mipmap, region, true);
-		prev_texture = mipmap;
-	}
-	RD::get_singleton()->draw_command_end_label();
-}
-
-RID RendererStorageRD::render_target_get_framebuffer_uniform_set(RID p_render_target) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, RID());
-	return rt->framebuffer_uniform_set;
-}
-RID RendererStorageRD::render_target_get_backbuffer_uniform_set(RID p_render_target) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND_V(!rt, RID());
-	return rt->backbuffer_uniform_set;
-}
-
-void RendererStorageRD::render_target_set_framebuffer_uniform_set(RID p_render_target, RID p_uniform_set) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-	rt->framebuffer_uniform_set = p_uniform_set;
-}
-void RendererStorageRD::render_target_set_backbuffer_uniform_set(RID p_render_target, RID p_uniform_set) {
-	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
-	ERR_FAIL_COND(!rt);
-	rt->backbuffer_uniform_set = p_uniform_set;
-}
-
 void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_instance) {
 	if (RendererRD::MeshStorage::get_singleton()->owns_mesh(p_base)) {
 		RendererRD::Mesh *mesh = RendererRD::MeshStorage::get_singleton()->get_mesh(p_base);
@@ -3655,8 +2961,8 @@ void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_
 	} else if (reflection_probe_owner.owns(p_base)) {
 		ReflectionProbe *rp = reflection_probe_owner.get_or_null(p_base);
 		p_instance->update_dependency(&rp->dependency);
-	} else if (RendererRD::DecalAtlasStorage::get_singleton()->owns_decal(p_base)) {
-		RendererRD::Decal *decal = RendererRD::DecalAtlasStorage::get_singleton()->get_decal(p_base);
+	} else if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_base)) {
+		RendererRD::Decal *decal = RendererRD::TextureStorage::get_singleton()->get_decal(p_base);
 		p_instance->update_dependency(&decal->dependency);
 	} else if (voxel_gi_owner.owns(p_base)) {
 		VoxelGI *gip = voxel_gi_owner.get_or_null(p_base);
@@ -3692,7 +2998,7 @@ RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const {
 	if (reflection_probe_owner.owns(p_rid)) {
 		return RS::INSTANCE_REFLECTION_PROBE;
 	}
-	if (RendererRD::DecalAtlasStorage::get_singleton()->owns_decal(p_rid)) {
+	if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_rid)) {
 		return RS::INSTANCE_DECAL;
 	}
 	if (voxel_gi_owner.owns(p_rid)) {
@@ -3725,7 +3031,7 @@ void RendererStorageRD::update_dirty_resources() {
 	RendererRD::MaterialStorage::get_singleton()->_update_queued_materials();
 	RendererRD::MeshStorage::get_singleton()->_update_dirty_multimeshes();
 	RendererRD::MeshStorage::get_singleton()->_update_dirty_skeletons();
-	RendererRD::DecalAtlasStorage::get_singleton()->update_decal_atlas();
+	RendererRD::TextureStorage::get_singleton()->update_decal_atlas();
 }
 
 bool RendererStorageRD::has_os_feature(const String &p_feature) const {
@@ -3751,8 +3057,8 @@ bool RendererStorageRD::has_os_feature(const String &p_feature) const {
 bool RendererStorageRD::free(RID p_rid) {
 	if (RendererRD::TextureStorage::get_singleton()->owns_texture(p_rid)) {
 		RendererRD::TextureStorage::get_singleton()->texture_free(p_rid);
-	} else if (RendererRD::CanvasTextureStorage::get_singleton()->owns_canvas_texture(p_rid)) {
-		RendererRD::CanvasTextureStorage::get_singleton()->canvas_texture_free(p_rid);
+	} else if (RendererRD::TextureStorage::get_singleton()->owns_canvas_texture(p_rid)) {
+		RendererRD::TextureStorage::get_singleton()->canvas_texture_free(p_rid);
 	} else if (RendererRD::MaterialStorage::get_singleton()->owns_shader(p_rid)) {
 		RendererRD::MaterialStorage::get_singleton()->shader_free(p_rid);
 	} else if (RendererRD::MaterialStorage::get_singleton()->owns_material(p_rid)) {
@@ -3769,8 +3075,8 @@ bool RendererStorageRD::free(RID p_rid) {
 		ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_rid);
 		reflection_probe->dependency.deleted_notify(p_rid);
 		reflection_probe_owner.free(p_rid);
-	} else if (RendererRD::DecalAtlasStorage::get_singleton()->owns_decal(p_rid)) {
-		RendererRD::DecalAtlasStorage::get_singleton()->decal_free(p_rid);
+	} else if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_rid)) {
+		RendererRD::TextureStorage::get_singleton()->decal_free(p_rid);
 	} else if (voxel_gi_owner.owns(p_rid)) {
 		voxel_gi_allocate_data(p_rid, Transform3D(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate
 		VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_rid);
@@ -3813,18 +3119,8 @@ bool RendererStorageRD::free(RID p_rid) {
 		FogVolume *fog_volume = fog_volume_owner.get_or_null(p_rid);
 		fog_volume->dependency.deleted_notify(p_rid);
 		fog_volume_owner.free(p_rid);
-	} else if (render_target_owner.owns(p_rid)) {
-		RenderTarget *rt = render_target_owner.get_or_null(p_rid);
-
-		_clear_render_target(rt);
-
-		if (rt->texture.is_valid()) {
-			RendererRD::Texture *tex = RendererRD::TextureStorage::get_singleton()->get_texture(rt->texture);
-			tex->is_render_target = false;
-			free(rt->texture);
-		}
-
-		render_target_owner.free(p_rid);
+	} else if (RendererRD::TextureStorage::get_singleton()->owns_render_target(p_rid)) {
+		RendererRD::TextureStorage::get_singleton()->render_target_free(p_rid);
 	} else {
 		return false;
 	}
@@ -4159,24 +3455,6 @@ void process() {
 			}
 		}
 	}
-
-	{
-		Vector<String> sdf_modes;
-		sdf_modes.push_back("\n#define MODE_LOAD\n");
-		sdf_modes.push_back("\n#define MODE_LOAD_SHRINK\n");
-		sdf_modes.push_back("\n#define MODE_PROCESS\n");
-		sdf_modes.push_back("\n#define MODE_PROCESS_OPTIMIZED\n");
-		sdf_modes.push_back("\n#define MODE_STORE\n");
-		sdf_modes.push_back("\n#define MODE_STORE_SHRINK\n");
-
-		rt_sdf.shader.initialize(sdf_modes);
-
-		rt_sdf.shader_version = rt_sdf.shader.version_create();
-
-		for (int i = 0; i < RenderTargetSDF::SHADER_MAX; i++) {
-			rt_sdf.pipelines[i] = RD::get_singleton()->compute_pipeline_create(rt_sdf.shader.version_get_shader(rt_sdf.shader_version, i));
-		}
-	}
 }
 
 RendererStorageRD::~RendererStorageRD() {
@@ -4199,7 +3477,6 @@ RendererStorageRD::~RendererStorageRD() {
 	}
 
 	particles_shader.copy_shader.version_free(particles_shader.copy_shader_version);
-	rt_sdf.shader.version_free(rt_sdf.shader_version);
 
 	material_storage->material_free(particles_shader.default_material);
 	material_storage->shader_free(particles_shader.default_shader);

+ 0 - 120
servers/rendering/renderer_rd/renderer_storage_rd.h

@@ -36,7 +36,6 @@
 #include "core/templates/rid_owner.h"
 #include "servers/rendering/renderer_compositor.h"
 #include "servers/rendering/renderer_rd/effects_rd.h"
-#include "servers/rendering/renderer_rd/shaders/canvas_sdf.glsl.gen.h"
 #include "servers/rendering/renderer_rd/shaders/particles.glsl.gen.h"
 #include "servers/rendering/renderer_rd/shaders/particles_copy.glsl.gen.h"
 #include "servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl.gen.h"
@@ -627,83 +626,6 @@ private:
 
 	float lightmap_probe_capture_update_speed = 4;
 
-	/* RENDER TARGET */
-
-	struct RenderTarget {
-		Size2i size;
-		uint32_t view_count;
-		RID framebuffer;
-		RID color;
-
-		//used for retrieving from CPU
-		RD::DataFormat color_format = RD::DATA_FORMAT_R4G4_UNORM_PACK8;
-		RD::DataFormat color_format_srgb = RD::DATA_FORMAT_R4G4_UNORM_PACK8;
-		Image::Format image_format = Image::FORMAT_L8;
-
-		bool flags[RENDER_TARGET_FLAG_MAX];
-
-		bool sdf_enabled = false;
-
-		RID backbuffer; //used for effects
-		RID backbuffer_fb;
-		RID backbuffer_mipmap0;
-
-		Vector<RID> backbuffer_mipmaps;
-
-		RID framebuffer_uniform_set;
-		RID backbuffer_uniform_set;
-
-		RID sdf_buffer_write;
-		RID sdf_buffer_write_fb;
-		RID sdf_buffer_process[2];
-		RID sdf_buffer_read;
-		RID sdf_buffer_process_uniform_sets[2];
-		RS::ViewportSDFOversize sdf_oversize = RS::VIEWPORT_SDF_OVERSIZE_120_PERCENT;
-		RS::ViewportSDFScale sdf_scale = RS::VIEWPORT_SDF_SCALE_50_PERCENT;
-		Size2i process_size;
-
-		//texture generated for this owner (nor RD).
-		RID texture;
-		bool was_used;
-
-		//clear request
-		bool clear_requested;
-		Color clear_color;
-	};
-
-	mutable RID_Owner<RenderTarget> render_target_owner;
-
-	void _clear_render_target(RenderTarget *rt);
-	void _update_render_target(RenderTarget *rt);
-	void _create_render_target_backbuffer(RenderTarget *rt);
-	void _render_target_allocate_sdf(RenderTarget *rt);
-	void _render_target_clear_sdf(RenderTarget *rt);
-	Rect2i _render_target_get_sdf_rect(const RenderTarget *rt) const;
-
-	struct RenderTargetSDF {
-		enum {
-			SHADER_LOAD,
-			SHADER_LOAD_SHRINK,
-			SHADER_PROCESS,
-			SHADER_PROCESS_OPTIMIZED,
-			SHADER_STORE,
-			SHADER_STORE_SHRINK,
-			SHADER_MAX
-		};
-
-		struct PushConstant {
-			int32_t size[2];
-			int32_t stride;
-			int32_t shift;
-			int32_t base_size[2];
-			int32_t pad[2];
-		};
-
-		CanvasSdfShaderRD shader;
-		RID shader_version;
-		RID pipelines[SHADER_MAX];
-	} rt_sdf;
-
 	/* EFFECTS */
 
 	EffectsRD *effects = nullptr;
@@ -1149,48 +1071,6 @@ public:
 	virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform);
 	virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active);
 
-	/* RENDER TARGET API */
-
-	RID render_target_create();
-	void render_target_set_position(RID p_render_target, int p_x, int p_y);
-	void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count);
-	RID render_target_get_texture(RID p_render_target);
-	void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id);
-	void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value);
-	bool render_target_was_used(RID p_render_target);
-	void render_target_set_as_unused(RID p_render_target);
-	void render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps);
-	void render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color);
-	void render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region);
-
-	RID render_target_get_back_buffer_uniform_set(RID p_render_target, RID p_base_shader);
-
-	virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color);
-	virtual bool render_target_is_clear_requested(RID p_render_target);
-	virtual Color render_target_get_clear_request_color(RID p_render_target);
-	virtual void render_target_disable_clear_request(RID p_render_target);
-	virtual void render_target_do_clear_request(RID p_render_target);
-
-	virtual void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale);
-	RID render_target_get_sdf_texture(RID p_render_target);
-	RID render_target_get_sdf_framebuffer(RID p_render_target);
-	void render_target_sdf_process(RID p_render_target);
-	virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const;
-	void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled);
-	bool render_target_is_sdf_enabled(RID p_render_target) const;
-
-	Size2 render_target_get_size(RID p_render_target);
-	RID render_target_get_rd_framebuffer(RID p_render_target);
-	RID render_target_get_rd_texture(RID p_render_target);
-	RID render_target_get_rd_backbuffer(RID p_render_target);
-	RID render_target_get_rd_backbuffer_framebuffer(RID p_render_target);
-
-	RID render_target_get_framebuffer_uniform_set(RID p_render_target);
-	RID render_target_get_backbuffer_uniform_set(RID p_render_target);
-
-	void render_target_set_framebuffer_uniform_set(RID p_render_target, RID p_uniform_set);
-	void render_target_set_backbuffer_uniform_set(RID p_render_target, RID p_uniform_set);
-
 	RS::InstanceType get_base_type(RID p_rid) const;
 
 	bool free(RID p_rid);

+ 0 - 235
servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.cpp

@@ -1,235 +0,0 @@
-/*************************************************************************/
-/*  canvas_texture_storage.cpp                                           */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#include "canvas_texture_storage.h"
-#include "texture_storage.h"
-
-// Until we move things into their own storage classes, also include our old class
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
-
-using namespace RendererRD;
-
-///////////////////////////////////////////////////////////////////////////
-// CanvasTexture
-
-void CanvasTexture::clear_sets() {
-	if (cleared_cache) {
-		return;
-	}
-	for (int i = 1; i < RS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) {
-		for (int j = 1; j < RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) {
-			if (RD::get_singleton()->uniform_set_is_valid(uniform_sets[i][j])) {
-				RD::get_singleton()->free(uniform_sets[i][j]);
-				uniform_sets[i][j] = RID();
-			}
-		}
-	}
-	cleared_cache = true;
-}
-
-CanvasTexture::~CanvasTexture() {
-	clear_sets();
-}
-
-///////////////////////////////////////////////////////////////////////////
-// CanvasTextureStorage
-
-CanvasTextureStorage *CanvasTextureStorage::singleton = nullptr;
-
-CanvasTextureStorage *CanvasTextureStorage::get_singleton() {
-	return singleton;
-}
-
-CanvasTextureStorage::CanvasTextureStorage() {
-	singleton = this;
-}
-
-CanvasTextureStorage::~CanvasTextureStorage() {
-	singleton = nullptr;
-}
-
-RID CanvasTextureStorage::canvas_texture_allocate() {
-	return canvas_texture_owner.allocate_rid();
-}
-
-void CanvasTextureStorage::canvas_texture_initialize(RID p_rid) {
-	canvas_texture_owner.initialize_rid(p_rid);
-}
-
-void CanvasTextureStorage::canvas_texture_free(RID p_rid) {
-	canvas_texture_owner.free(p_rid);
-}
-
-void CanvasTextureStorage::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
-	CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
-	ERR_FAIL_NULL(ct);
-
-	switch (p_channel) {
-		case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: {
-			ct->diffuse = p_texture;
-		} break;
-		case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: {
-			ct->normal_map = p_texture;
-		} break;
-		case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: {
-			ct->specular = p_texture;
-		} break;
-	}
-
-	ct->clear_sets();
-}
-
-void CanvasTextureStorage::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) {
-	CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
-	ERR_FAIL_NULL(ct);
-
-	ct->specular_color.r = p_specular_color.r;
-	ct->specular_color.g = p_specular_color.g;
-	ct->specular_color.b = p_specular_color.b;
-	ct->specular_color.a = p_shininess;
-	ct->clear_sets();
-}
-
-void CanvasTextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {
-	CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
-	ERR_FAIL_NULL(ct);
-
-	ct->texture_filter = p_filter;
-	ct->clear_sets();
-}
-
-void CanvasTextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
-	CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
-	ERR_FAIL_NULL(ct);
-	ct->texture_repeat = p_repeat;
-	ct->clear_sets();
-}
-
-bool CanvasTextureStorage::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, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular) {
-	RendererStorageRD *storage = RendererStorageRD::base_singleton;
-
-	CanvasTexture *ct = nullptr;
-	TextureStorage *texture_storage = TextureStorage::get_singleton();
-	Texture *t = texture_storage->get_texture(p_texture);
-
-	// TODO once we have our texture storage split off we'll look into moving this code into canvas_texture
-
-	if (t) {
-		//regular texture
-		if (!t->canvas_texture) {
-			t->canvas_texture = memnew(CanvasTexture);
-			t->canvas_texture->diffuse = p_texture;
-		}
-
-		ct = t->canvas_texture;
-	} else {
-		ct = get_canvas_texture(p_texture);
-	}
-
-	if (!ct) {
-		return false; //invalid texture RID
-	}
-
-	RS::CanvasItemTextureFilter filter = ct->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT ? ct->texture_filter : p_base_filter;
-	ERR_FAIL_COND_V(filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, false);
-
-	RS::CanvasItemTextureRepeat repeat = ct->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT ? ct->texture_repeat : p_base_repeat;
-	ERR_FAIL_COND_V(repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, false);
-
-	RID uniform_set = ct->uniform_sets[filter][repeat];
-	if (!RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
-		//create and update
-		Vector<RD::Uniform> uniforms;
-		{ //diffuse
-			RD::Uniform u;
-			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
-			u.binding = 0;
-
-			t = texture_storage->get_texture(ct->diffuse);
-			if (!t) {
-				u.append_id(texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE));
-				ct->size_cache = Size2i(1, 1);
-			} else {
-				u.append_id(t->rd_texture);
-				ct->size_cache = Size2i(t->width_2d, t->height_2d);
-			}
-			uniforms.push_back(u);
-		}
-		{ //normal
-			RD::Uniform u;
-			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
-			u.binding = 1;
-
-			t = texture_storage->get_texture(ct->normal_map);
-			if (!t) {
-				u.append_id(texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL));
-				ct->use_normal_cache = false;
-			} else {
-				u.append_id(t->rd_texture);
-				ct->use_normal_cache = true;
-			}
-			uniforms.push_back(u);
-		}
-		{ //specular
-			RD::Uniform u;
-			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
-			u.binding = 2;
-
-			t = texture_storage->get_texture(ct->specular);
-			if (!t) {
-				u.append_id(texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE));
-				ct->use_specular_cache = false;
-			} else {
-				u.append_id(t->rd_texture);
-				ct->use_specular_cache = true;
-			}
-			uniforms.push_back(u);
-		}
-		{ //sampler
-			RD::Uniform u;
-			u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
-			u.binding = 3;
-			u.append_id(storage->sampler_rd_get_default(filter, repeat));
-			uniforms.push_back(u);
-		}
-
-		uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_base_shader, p_base_set);
-		ct->uniform_sets[filter][repeat] = uniform_set;
-		ct->cleared_cache = false;
-	}
-
-	r_uniform_set = uniform_set;
-	r_size = ct->size_cache;
-	r_specular_shininess = ct->specular_color;
-	r_use_normal = ct->use_normal_cache;
-	r_use_specular = ct->use_specular_cache;
-
-	return true;
-}

+ 0 - 90
servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h

@@ -1,90 +0,0 @@
-/*************************************************************************/
-/*  canvas_texture_storage.h                                             */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#ifndef CANVAS_TEXTURE_STORAGE_RD_H
-#define CANVAS_TEXTURE_STORAGE_RD_H
-
-#include "core/templates/rid_owner.h"
-#include "servers/rendering/storage/canvas_texture_storage.h"
-
-namespace RendererRD {
-
-class CanvasTexture {
-public:
-	RID diffuse;
-	RID normal_map;
-	RID specular;
-	Color specular_color = Color(1, 1, 1, 1);
-	float shininess = 1.0;
-
-	RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT;
-	RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT;
-	RID uniform_sets[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX];
-
-	Size2i size_cache = Size2i(1, 1);
-	bool use_normal_cache = false;
-	bool use_specular_cache = false;
-	bool cleared_cache = true;
-
-	void clear_sets();
-	~CanvasTexture();
-};
-
-class CanvasTextureStorage : public RendererCanvasTextureStorage {
-private:
-	static CanvasTextureStorage *singleton;
-
-	RID_Owner<RendererRD::CanvasTexture, true> canvas_texture_owner;
-
-public:
-	static CanvasTextureStorage *get_singleton();
-
-	CanvasTextureStorage();
-	virtual ~CanvasTextureStorage();
-
-	CanvasTexture *get_canvas_texture(RID p_rid) { return canvas_texture_owner.get_or_null(p_rid); };
-	bool owns_canvas_texture(RID p_rid) { return canvas_texture_owner.owns(p_rid); };
-
-	virtual RID canvas_texture_allocate() override;
-	virtual void canvas_texture_initialize(RID p_rid) override;
-	virtual void canvas_texture_free(RID p_rid) override;
-
-	virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override;
-	virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override;
-
-	virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override;
-	virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override;
-
-	bool 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, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular);
-};
-
-} // namespace RendererRD
-
-#endif // !CANVAS_TEXTURE_STORAGE_RD_H

+ 0 - 437
servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.cpp

@@ -1,437 +0,0 @@
-/*************************************************************************/
-/*  decal_atlas_storage.cpp                                              */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#include "decal_atlas_storage.h"
-#include "texture_storage.h"
-
-// Should be able to remove this once we move effects into their own file and include the correct effects
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
-
-using namespace RendererRD;
-
-DecalAtlasStorage *DecalAtlasStorage::singleton = nullptr;
-
-DecalAtlasStorage *DecalAtlasStorage::get_singleton() {
-	return singleton;
-}
-
-DecalAtlasStorage::DecalAtlasStorage() {
-	singleton = this;
-
-	{ // default atlas texture
-		RD::TextureFormat tformat;
-		tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
-		tformat.width = 4;
-		tformat.height = 4;
-		tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
-		tformat.texture_type = RD::TEXTURE_TYPE_2D;
-
-		Vector<uint8_t> pv;
-		pv.resize(16 * 4);
-
-		for (int i = 0; i < 16; i++) {
-			pv.set(i * 4 + 0, 0);
-			pv.set(i * 4 + 1, 0);
-			pv.set(i * 4 + 2, 0);
-			pv.set(i * 4 + 3, 255);
-		}
-
-		{
-			//take the chance and initialize decal atlas to something
-			Vector<Vector<uint8_t>> vpv;
-			vpv.push_back(pv);
-			decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
-			decal_atlas.texture_srgb = decal_atlas.texture;
-		}
-	}
-}
-
-DecalAtlasStorage::~DecalAtlasStorage() {
-	if (decal_atlas.textures.size()) {
-		ERR_PRINT("Decal Atlas: " + itos(decal_atlas.textures.size()) + " textures were not removed from the atlas.");
-	}
-
-	if (decal_atlas.texture.is_valid()) {
-		RD::get_singleton()->free(decal_atlas.texture);
-	}
-
-	singleton = nullptr;
-}
-
-RID DecalAtlasStorage::decal_atlas_get_texture() const {
-	return decal_atlas.texture;
-}
-
-RID DecalAtlasStorage::decal_atlas_get_texture_srgb() const {
-	return decal_atlas.texture_srgb;
-}
-
-RID DecalAtlasStorage::decal_allocate() {
-	return decal_owner.allocate_rid();
-}
-
-void DecalAtlasStorage::decal_initialize(RID p_decal) {
-	decal_owner.initialize_rid(p_decal, Decal());
-}
-
-void DecalAtlasStorage::decal_free(RID p_rid) {
-	Decal *decal = decal_owner.get_or_null(p_rid);
-	for (int i = 0; i < RS::DECAL_TEXTURE_MAX; i++) {
-		if (decal->textures[i].is_valid() && TextureStorage::get_singleton()->owns_texture(decal->textures[i])) {
-			texture_remove_from_decal_atlas(decal->textures[i]);
-		}
-	}
-	decal->dependency.deleted_notify(p_rid);
-	decal_owner.free(p_rid);
-}
-
-void DecalAtlasStorage::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
-	Decal *decal = decal_owner.get_or_null(p_decal);
-	ERR_FAIL_COND(!decal);
-	decal->extents = p_extents;
-	decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
-}
-
-void DecalAtlasStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
-	Decal *decal = decal_owner.get_or_null(p_decal);
-	ERR_FAIL_COND(!decal);
-	ERR_FAIL_INDEX(p_type, RS::DECAL_TEXTURE_MAX);
-
-	if (decal->textures[p_type] == p_texture) {
-		return;
-	}
-
-	ERR_FAIL_COND(p_texture.is_valid() && !TextureStorage::get_singleton()->owns_texture(p_texture));
-
-	if (decal->textures[p_type].is_valid() && TextureStorage::get_singleton()->owns_texture(decal->textures[p_type])) {
-		texture_remove_from_decal_atlas(decal->textures[p_type]);
-	}
-
-	decal->textures[p_type] = p_texture;
-
-	if (decal->textures[p_type].is_valid()) {
-		texture_add_to_decal_atlas(decal->textures[p_type]);
-	}
-
-	decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_DECAL);
-}
-
-void DecalAtlasStorage::decal_set_emission_energy(RID p_decal, float p_energy) {
-	Decal *decal = decal_owner.get_or_null(p_decal);
-	ERR_FAIL_COND(!decal);
-	decal->emission_energy = p_energy;
-}
-
-void DecalAtlasStorage::decal_set_albedo_mix(RID p_decal, float p_mix) {
-	Decal *decal = decal_owner.get_or_null(p_decal);
-	ERR_FAIL_COND(!decal);
-	decal->albedo_mix = p_mix;
-}
-
-void DecalAtlasStorage::decal_set_modulate(RID p_decal, const Color &p_modulate) {
-	Decal *decal = decal_owner.get_or_null(p_decal);
-	ERR_FAIL_COND(!decal);
-	decal->modulate = p_modulate;
-}
-
-void DecalAtlasStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
-	Decal *decal = decal_owner.get_or_null(p_decal);
-	ERR_FAIL_COND(!decal);
-	decal->cull_mask = p_layers;
-	decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
-}
-
-void DecalAtlasStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
-	Decal *decal = decal_owner.get_or_null(p_decal);
-	ERR_FAIL_COND(!decal);
-	decal->distance_fade = p_enabled;
-	decal->distance_fade_begin = p_begin;
-	decal->distance_fade_length = p_length;
-}
-
-void DecalAtlasStorage::decal_set_fade(RID p_decal, float p_above, float p_below) {
-	Decal *decal = decal_owner.get_or_null(p_decal);
-	ERR_FAIL_COND(!decal);
-	decal->upper_fade = p_above;
-	decal->lower_fade = p_below;
-}
-
-void DecalAtlasStorage::decal_set_normal_fade(RID p_decal, float p_fade) {
-	Decal *decal = decal_owner.get_or_null(p_decal);
-	ERR_FAIL_COND(!decal);
-	decal->normal_fade = p_fade;
-}
-
-void DecalAtlasStorage::decal_atlas_mark_dirty_on_texture(RID p_texture) {
-	if (decal_atlas.textures.has(p_texture)) {
-		//belongs to decal atlas..
-
-		decal_atlas.dirty = true; //mark it dirty since it was most likely modified
-	}
-}
-
-void DecalAtlasStorage::decal_atlas_remove_texture(RID p_texture) {
-	if (decal_atlas.textures.has(p_texture)) {
-		decal_atlas.textures.erase(p_texture);
-		//there is not much a point of making it dirty, just let it be.
-	}
-}
-
-AABB DecalAtlasStorage::decal_get_aabb(RID p_decal) const {
-	Decal *decal = decal_owner.get_or_null(p_decal);
-	ERR_FAIL_COND_V(!decal, AABB());
-
-	return AABB(-decal->extents, decal->extents * 2.0);
-}
-
-void DecalAtlasStorage::update_decal_atlas() {
-	EffectsRD *effects = RendererStorageRD::base_singleton->get_effects();
-
-	if (!decal_atlas.dirty) {
-		return; //nothing to do
-	}
-
-	decal_atlas.dirty = false;
-
-	if (decal_atlas.texture.is_valid()) {
-		RD::get_singleton()->free(decal_atlas.texture);
-		decal_atlas.texture = RID();
-		decal_atlas.texture_srgb = RID();
-		decal_atlas.texture_mipmaps.clear();
-	}
-
-	int border = 1 << decal_atlas.mipmaps;
-
-	if (decal_atlas.textures.size()) {
-		//generate atlas
-		Vector<DecalAtlas::SortItem> itemsv;
-		itemsv.resize(decal_atlas.textures.size());
-		int base_size = 8;
-		const RID *K = nullptr;
-
-		int idx = 0;
-		while ((K = decal_atlas.textures.next(K))) {
-			DecalAtlas::SortItem &si = itemsv.write[idx];
-
-			Texture *src_tex = TextureStorage::get_singleton()->get_texture(*K);
-
-			si.size.width = (src_tex->width / border) + 1;
-			si.size.height = (src_tex->height / border) + 1;
-			si.pixel_size = Size2i(src_tex->width, src_tex->height);
-
-			if (base_size < si.size.width) {
-				base_size = nearest_power_of_2_templated(si.size.width);
-			}
-
-			si.texture = *K;
-			idx++;
-		}
-
-		//sort items by size
-		itemsv.sort();
-
-		//attempt to create atlas
-		int item_count = itemsv.size();
-		DecalAtlas::SortItem *items = itemsv.ptrw();
-
-		int atlas_height = 0;
-
-		while (true) {
-			Vector<int> v_offsetsv;
-			v_offsetsv.resize(base_size);
-
-			int *v_offsets = v_offsetsv.ptrw();
-			memset(v_offsets, 0, sizeof(int) * base_size);
-
-			int max_height = 0;
-
-			for (int i = 0; i < item_count; i++) {
-				//best fit
-				DecalAtlas::SortItem &si = items[i];
-				int best_idx = -1;
-				int best_height = 0x7FFFFFFF;
-				for (int j = 0; j <= base_size - si.size.width; j++) {
-					int height = 0;
-					for (int k = 0; k < si.size.width; k++) {
-						int h = v_offsets[k + j];
-						if (h > height) {
-							height = h;
-							if (height > best_height) {
-								break; //already bad
-							}
-						}
-					}
-
-					if (height < best_height) {
-						best_height = height;
-						best_idx = j;
-					}
-				}
-
-				//update
-				for (int k = 0; k < si.size.width; k++) {
-					v_offsets[k + best_idx] = best_height + si.size.height;
-				}
-
-				si.pos.x = best_idx;
-				si.pos.y = best_height;
-
-				if (si.pos.y + si.size.height > max_height) {
-					max_height = si.pos.y + si.size.height;
-				}
-			}
-
-			if (max_height <= base_size * 2) {
-				atlas_height = max_height;
-				break; //good ratio, break;
-			}
-
-			base_size *= 2;
-		}
-
-		decal_atlas.size.width = base_size * border;
-		decal_atlas.size.height = nearest_power_of_2_templated(atlas_height * border);
-
-		for (int i = 0; i < item_count; i++) {
-			DecalAtlas::Texture *t = decal_atlas.textures.getptr(items[i].texture);
-			t->uv_rect.position = items[i].pos * border + Vector2i(border / 2, border / 2);
-			t->uv_rect.size = items[i].pixel_size;
-
-			t->uv_rect.position /= Size2(decal_atlas.size);
-			t->uv_rect.size /= Size2(decal_atlas.size);
-		}
-	} else {
-		//use border as size, so it at least has enough mipmaps
-		decal_atlas.size.width = border;
-		decal_atlas.size.height = border;
-	}
-
-	//blit textures
-
-	RD::TextureFormat tformat;
-	tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
-	tformat.width = decal_atlas.size.width;
-	tformat.height = decal_atlas.size.height;
-	tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
-	tformat.texture_type = RD::TEXTURE_TYPE_2D;
-	tformat.mipmaps = decal_atlas.mipmaps;
-	tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_UNORM);
-	tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB);
-
-	decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView());
-	RD::get_singleton()->texture_clear(decal_atlas.texture, Color(0, 0, 0, 0), 0, decal_atlas.mipmaps, 0, 1);
-
-	{
-		//create the framebuffer
-
-		Size2i s = decal_atlas.size;
-
-		for (int i = 0; i < decal_atlas.mipmaps; i++) {
-			DecalAtlas::MipMap mm;
-			mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), decal_atlas.texture, 0, i);
-			Vector<RID> fb;
-			fb.push_back(mm.texture);
-			mm.fb = RD::get_singleton()->framebuffer_create(fb);
-			mm.size = s;
-			decal_atlas.texture_mipmaps.push_back(mm);
-
-			s.width = MAX(1, s.width >> 1);
-			s.height = MAX(1, s.height >> 1);
-		}
-		{
-			//create the SRGB variant
-			RD::TextureView rd_view;
-			rd_view.format_override = RD::DATA_FORMAT_R8G8B8A8_SRGB;
-			decal_atlas.texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, decal_atlas.texture);
-		}
-	}
-
-	RID prev_texture;
-	for (int i = 0; i < decal_atlas.texture_mipmaps.size(); i++) {
-		const DecalAtlas::MipMap &mm = decal_atlas.texture_mipmaps[i];
-
-		Color clear_color(0, 0, 0, 0);
-
-		if (decal_atlas.textures.size()) {
-			if (i == 0) {
-				Vector<Color> cc;
-				cc.push_back(clear_color);
-
-				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);
-
-				const RID *K = nullptr;
-				while ((K = decal_atlas.textures.next(K))) {
-					DecalAtlas::Texture *t = decal_atlas.textures.getptr(*K);
-					Texture *src_tex = TextureStorage::get_singleton()->get_texture(*K);
-					effects->copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0);
-				}
-
-				RD::get_singleton()->draw_list_end();
-
-				prev_texture = mm.texture;
-			} else {
-				effects->copy_to_fb_rect(prev_texture, mm.fb, Rect2i(Point2i(), mm.size));
-				prev_texture = mm.texture;
-			}
-		} else {
-			RD::get_singleton()->texture_clear(mm.texture, clear_color, 0, 1, 0, 1);
-		}
-	}
-}
-
-void DecalAtlasStorage::texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp) {
-	if (!decal_atlas.textures.has(p_texture)) {
-		DecalAtlas::Texture t;
-		t.users = 1;
-		t.panorama_to_dp_users = p_panorama_to_dp ? 1 : 0;
-		decal_atlas.textures[p_texture] = t;
-		decal_atlas.dirty = true;
-	} else {
-		DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
-		t->users++;
-		if (p_panorama_to_dp) {
-			t->panorama_to_dp_users++;
-		}
-	}
-}
-
-void DecalAtlasStorage::texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp) {
-	DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
-	ERR_FAIL_COND(!t);
-	t->users--;
-	if (p_panorama_to_dp) {
-		ERR_FAIL_COND(t->panorama_to_dp_users == 0);
-		t->panorama_to_dp_users--;
-	}
-	if (t->users == 0) {
-		decal_atlas.textures.erase(p_texture);
-		//do not mark it dirty, there is no need to since it remains working
-	}
-}

+ 0 - 211
servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h

@@ -1,211 +0,0 @@
-/*************************************************************************/
-/*  decal_atlas_storage.h                                                */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#ifndef DECAL_ATLAS_STORAGE_RD_H
-#define DECAL_ATLAS_STORAGE_RD_H
-
-#include "core/templates/rid_owner.h"
-#include "servers/rendering/renderer_storage.h"
-#include "servers/rendering/storage/decal_atlas_storage.h"
-
-namespace RendererRD {
-
-struct DecalAtlas {
-	struct Texture {
-		int panorama_to_dp_users;
-		int users;
-		Rect2 uv_rect;
-	};
-
-	struct SortItem {
-		RID texture;
-		Size2i pixel_size;
-		Size2i size;
-		Point2i pos;
-
-		bool operator<(const SortItem &p_item) const {
-			//sort larger to smaller
-			if (size.height == p_item.size.height) {
-				return size.width > p_item.size.width;
-			} else {
-				return size.height > p_item.size.height;
-			}
-		}
-	};
-
-	HashMap<RID, Texture> textures;
-	bool dirty = true;
-	int mipmaps = 5;
-
-	RID texture;
-	RID texture_srgb;
-	struct MipMap {
-		RID fb;
-		RID texture;
-		Size2i size;
-	};
-	Vector<MipMap> texture_mipmaps;
-
-	Size2i size;
-};
-
-struct Decal {
-	Vector3 extents = Vector3(1, 1, 1);
-	RID textures[RS::DECAL_TEXTURE_MAX];
-	float emission_energy = 1.0;
-	float albedo_mix = 1.0;
-	Color modulate = Color(1, 1, 1, 1);
-	uint32_t cull_mask = (1 << 20) - 1;
-	float upper_fade = 0.3;
-	float lower_fade = 0.3;
-	bool distance_fade = false;
-	float distance_fade_begin = 10;
-	float distance_fade_length = 1;
-	float normal_fade = 0.0;
-
-	RendererStorage::Dependency dependency;
-};
-
-class DecalAtlasStorage : public RendererDecalAtlasStorage {
-private:
-	static DecalAtlasStorage *singleton;
-
-	DecalAtlas decal_atlas;
-
-	mutable RID_Owner<Decal, true> decal_owner;
-
-public:
-	static DecalAtlasStorage *get_singleton();
-
-	void update_decal_atlas();
-
-	DecalAtlasStorage();
-	virtual ~DecalAtlasStorage();
-
-	Decal *get_decal(RID p_rid) { return decal_owner.get_or_null(p_rid); };
-	bool owns_decal(RID p_rid) { return decal_owner.owns(p_rid); };
-
-	RID decal_atlas_get_texture() const;
-	RID decal_atlas_get_texture_srgb() const;
-	_FORCE_INLINE_ Rect2 decal_atlas_get_texture_rect(RID p_texture) {
-		DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
-		if (!t) {
-			return Rect2();
-		}
-
-		return t->uv_rect;
-	}
-
-	virtual RID decal_allocate() override;
-	virtual void decal_initialize(RID p_decal) override;
-	virtual void decal_free(RID p_rid) override;
-
-	virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override;
-	virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override;
-	virtual void decal_set_emission_energy(RID p_decal, float p_energy) override;
-	virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override;
-	virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override;
-	virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override;
-	virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override;
-	virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override;
-	virtual void decal_set_normal_fade(RID p_decal, float p_fade) override;
-
-	void decal_atlas_mark_dirty_on_texture(RID p_texture);
-	void decal_atlas_remove_texture(RID p_texture);
-
-	virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override;
-	virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override;
-
-	_FORCE_INLINE_ Vector3 decal_get_extents(RID p_decal) {
-		const Decal *decal = decal_owner.get_or_null(p_decal);
-		return decal->extents;
-	}
-
-	_FORCE_INLINE_ RID decal_get_texture(RID p_decal, RS::DecalTexture p_texture) {
-		const Decal *decal = decal_owner.get_or_null(p_decal);
-		return decal->textures[p_texture];
-	}
-
-	_FORCE_INLINE_ Color decal_get_modulate(RID p_decal) {
-		const Decal *decal = decal_owner.get_or_null(p_decal);
-		return decal->modulate;
-	}
-
-	_FORCE_INLINE_ float decal_get_emission_energy(RID p_decal) {
-		const Decal *decal = decal_owner.get_or_null(p_decal);
-		return decal->emission_energy;
-	}
-
-	_FORCE_INLINE_ float decal_get_albedo_mix(RID p_decal) {
-		const Decal *decal = decal_owner.get_or_null(p_decal);
-		return decal->albedo_mix;
-	}
-
-	_FORCE_INLINE_ uint32_t decal_get_cull_mask(RID p_decal) {
-		const Decal *decal = decal_owner.get_or_null(p_decal);
-		return decal->cull_mask;
-	}
-
-	_FORCE_INLINE_ float decal_get_upper_fade(RID p_decal) {
-		const Decal *decal = decal_owner.get_or_null(p_decal);
-		return decal->upper_fade;
-	}
-
-	_FORCE_INLINE_ float decal_get_lower_fade(RID p_decal) {
-		const Decal *decal = decal_owner.get_or_null(p_decal);
-		return decal->lower_fade;
-	}
-
-	_FORCE_INLINE_ float decal_get_normal_fade(RID p_decal) {
-		const Decal *decal = decal_owner.get_or_null(p_decal);
-		return decal->normal_fade;
-	}
-
-	_FORCE_INLINE_ bool decal_is_distance_fade_enabled(RID p_decal) {
-		const Decal *decal = decal_owner.get_or_null(p_decal);
-		return decal->distance_fade;
-	}
-
-	_FORCE_INLINE_ float decal_get_distance_fade_begin(RID p_decal) {
-		const Decal *decal = decal_owner.get_or_null(p_decal);
-		return decal->distance_fade_begin;
-	}
-
-	_FORCE_INLINE_ float decal_get_distance_fade_length(RID p_decal) {
-		const Decal *decal = decal_owner.get_or_null(p_decal);
-		return decal->distance_fade_length;
-	}
-
-	virtual AABB decal_get_aabb(RID p_decal) const override;
-};
-
-} // namespace RendererRD
-
-#endif // !DECAL_ATLAS_STORAGE_RD_H

+ 1315 - 3
servers/rendering/renderer_rd/storage_rd/texture_storage.cpp

@@ -29,10 +29,33 @@
 /*************************************************************************/
 
 #include "texture_storage.h"
-#include "decal_atlas_storage.h"
+
+#include "../renderer_storage_rd.h"
 
 using namespace RendererRD;
 
+///////////////////////////////////////////////////////////////////////////
+// CanvasTexture
+
+void CanvasTexture::clear_sets() {
+	if (cleared_cache) {
+		return;
+	}
+	for (int i = 1; i < RS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) {
+		for (int j = 1; j < RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) {
+			if (RD::get_singleton()->uniform_set_is_valid(uniform_sets[i][j])) {
+				RD::get_singleton()->free(uniform_sets[i][j]);
+				uniform_sets[i][j] = RID();
+			}
+		}
+	}
+	cleared_cache = true;
+}
+
+CanvasTexture::~CanvasTexture() {
+	clear_sets();
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // Texture
 
@@ -315,9 +338,64 @@ TextureStorage::TextureStorage() {
 			default_rd_textures[DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
 		}
 	}
+
+	{ // default atlas texture
+		RD::TextureFormat tformat;
+		tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+		tformat.width = 4;
+		tformat.height = 4;
+		tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
+		tformat.texture_type = RD::TEXTURE_TYPE_2D;
+
+		Vector<uint8_t> pv;
+		pv.resize(16 * 4);
+
+		for (int i = 0; i < 16; i++) {
+			pv.set(i * 4 + 0, 0);
+			pv.set(i * 4 + 1, 0);
+			pv.set(i * 4 + 2, 0);
+			pv.set(i * 4 + 3, 255);
+		}
+
+		{
+			//take the chance and initialize decal atlas to something
+			Vector<Vector<uint8_t>> vpv;
+			vpv.push_back(pv);
+			decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
+			decal_atlas.texture_srgb = decal_atlas.texture;
+		}
+	}
+
+	{
+		Vector<String> sdf_modes;
+		sdf_modes.push_back("\n#define MODE_LOAD\n");
+		sdf_modes.push_back("\n#define MODE_LOAD_SHRINK\n");
+		sdf_modes.push_back("\n#define MODE_PROCESS\n");
+		sdf_modes.push_back("\n#define MODE_PROCESS_OPTIMIZED\n");
+		sdf_modes.push_back("\n#define MODE_STORE\n");
+		sdf_modes.push_back("\n#define MODE_STORE_SHRINK\n");
+
+		rt_sdf.shader.initialize(sdf_modes);
+
+		rt_sdf.shader_version = rt_sdf.shader.version_create();
+
+		for (int i = 0; i < RenderTargetSDF::SHADER_MAX; i++) {
+			rt_sdf.pipelines[i] = RD::get_singleton()->compute_pipeline_create(rt_sdf.shader.version_get_shader(rt_sdf.shader_version, i));
+		}
+	}
 }
 
 TextureStorage::~TextureStorage() {
+	rt_sdf.shader.version_free(rt_sdf.shader_version);
+
+	if (decal_atlas.textures.size()) {
+		ERR_PRINT("Decal Atlas: " + itos(decal_atlas.textures.size()) + " textures were not removed from the atlas.");
+	}
+
+	if (decal_atlas.texture.is_valid()) {
+		RD::get_singleton()->free(decal_atlas.texture);
+	}
+
 	//def textures
 	for (int i = 0; i < DEFAULT_RD_TEXTURE_MAX; i++) {
 		if (default_rd_textures[i].is_valid()) {
@@ -332,6 +410,168 @@ bool TextureStorage::can_create_resources_async() const {
 	return true;
 }
 
+/* Canvas Texture API */
+
+RID TextureStorage::canvas_texture_allocate() {
+	return canvas_texture_owner.allocate_rid();
+}
+
+void TextureStorage::canvas_texture_initialize(RID p_rid) {
+	canvas_texture_owner.initialize_rid(p_rid);
+}
+
+void TextureStorage::canvas_texture_free(RID p_rid) {
+	canvas_texture_owner.free(p_rid);
+}
+
+void TextureStorage::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
+	CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
+	ERR_FAIL_NULL(ct);
+
+	switch (p_channel) {
+		case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: {
+			ct->diffuse = p_texture;
+		} break;
+		case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: {
+			ct->normal_map = p_texture;
+		} break;
+		case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: {
+			ct->specular = p_texture;
+		} break;
+	}
+
+	ct->clear_sets();
+}
+
+void TextureStorage::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) {
+	CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
+	ERR_FAIL_NULL(ct);
+
+	ct->specular_color.r = p_specular_color.r;
+	ct->specular_color.g = p_specular_color.g;
+	ct->specular_color.b = p_specular_color.b;
+	ct->specular_color.a = p_shininess;
+	ct->clear_sets();
+}
+
+void TextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {
+	CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
+	ERR_FAIL_NULL(ct);
+
+	ct->texture_filter = p_filter;
+	ct->clear_sets();
+}
+
+void TextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
+	CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
+	ERR_FAIL_NULL(ct);
+	ct->texture_repeat = p_repeat;
+	ct->clear_sets();
+}
+
+bool 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, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular) {
+	RendererStorageRD *storage = RendererStorageRD::base_singleton;
+
+	CanvasTexture *ct = nullptr;
+	Texture *t = get_texture(p_texture);
+
+	// TODO once we have our texture storage split off we'll look into moving this code into canvas_texture
+
+	if (t) {
+		//regular texture
+		if (!t->canvas_texture) {
+			t->canvas_texture = memnew(CanvasTexture);
+			t->canvas_texture->diffuse = p_texture;
+		}
+
+		ct = t->canvas_texture;
+	} else {
+		ct = get_canvas_texture(p_texture);
+	}
+
+	if (!ct) {
+		return false; //invalid texture RID
+	}
+
+	RS::CanvasItemTextureFilter filter = ct->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT ? ct->texture_filter : p_base_filter;
+	ERR_FAIL_COND_V(filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, false);
+
+	RS::CanvasItemTextureRepeat repeat = ct->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT ? ct->texture_repeat : p_base_repeat;
+	ERR_FAIL_COND_V(repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, false);
+
+	RID uniform_set = ct->uniform_sets[filter][repeat];
+	if (!RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+		//create and update
+		Vector<RD::Uniform> uniforms;
+		{ //diffuse
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+			u.binding = 0;
+
+			t = get_texture(ct->diffuse);
+			if (!t) {
+				u.append_id(texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE));
+				ct->size_cache = Size2i(1, 1);
+			} else {
+				u.append_id(t->rd_texture);
+				ct->size_cache = Size2i(t->width_2d, t->height_2d);
+			}
+			uniforms.push_back(u);
+		}
+		{ //normal
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+			u.binding = 1;
+
+			t = get_texture(ct->normal_map);
+			if (!t) {
+				u.append_id(texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL));
+				ct->use_normal_cache = false;
+			} else {
+				u.append_id(t->rd_texture);
+				ct->use_normal_cache = true;
+			}
+			uniforms.push_back(u);
+		}
+		{ //specular
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+			u.binding = 2;
+
+			t = get_texture(ct->specular);
+			if (!t) {
+				u.append_id(texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE));
+				ct->use_specular_cache = false;
+			} else {
+				u.append_id(t->rd_texture);
+				ct->use_specular_cache = true;
+			}
+			uniforms.push_back(u);
+		}
+		{ //sampler
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+			u.binding = 3;
+			u.append_id(storage->sampler_rd_get_default(filter, repeat));
+			uniforms.push_back(u);
+		}
+
+		uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_base_shader, p_base_set);
+		ct->uniform_sets[filter][repeat] = uniform_set;
+		ct->cleared_cache = false;
+	}
+
+	r_uniform_set = uniform_set;
+	r_size = ct->size_cache;
+	r_specular_shininess = ct->specular_color;
+	r_use_normal = ct->use_normal_cache;
+	r_use_specular = ct->use_specular_cache;
+
+	return true;
+}
+
+/* Texture API */
+
 RID TextureStorage::texture_allocate() {
 	return texture_owner.allocate_rid();
 }
@@ -350,7 +590,7 @@ void TextureStorage::texture_free(RID p_texture) {
 		}
 	}
 
-	DecalAtlasStorage::get_singleton()->decal_atlas_remove_texture(p_texture);
+	decal_atlas_remove_texture(p_texture);
 
 	for (int i = 0; i < t->proxies.size(); i++) {
 		Texture *p = texture_owner.get_or_null(t->proxies[i]);
@@ -949,7 +1189,7 @@ void TextureStorage::texture_replace(RID p_texture, RID p_by_texture) {
 	//delete last, so proxies can be updated
 	texture_owner.free(p_by_texture);
 
-	DecalAtlasStorage::get_singleton()->decal_atlas_mark_dirty_on_texture(p_texture);
+	decal_atlas_mark_dirty_on_texture(p_texture);
 }
 
 void TextureStorage::texture_set_size_override(RID p_texture, int p_width, int p_height) {
@@ -1438,3 +1678,1075 @@ Ref<Image> TextureStorage::_validate_texture_format(const Ref<Image> &p_image, T
 
 	return image;
 }
+
+/* DECAL API */
+
+RID TextureStorage::decal_atlas_get_texture() const {
+	return decal_atlas.texture;
+}
+
+RID TextureStorage::decal_atlas_get_texture_srgb() const {
+	return decal_atlas.texture_srgb;
+}
+
+RID TextureStorage::decal_allocate() {
+	return decal_owner.allocate_rid();
+}
+
+void TextureStorage::decal_initialize(RID p_decal) {
+	decal_owner.initialize_rid(p_decal, Decal());
+}
+
+void TextureStorage::decal_free(RID p_rid) {
+	Decal *decal = decal_owner.get_or_null(p_rid);
+	for (int i = 0; i < RS::DECAL_TEXTURE_MAX; i++) {
+		if (decal->textures[i].is_valid() && owns_texture(decal->textures[i])) {
+			texture_remove_from_decal_atlas(decal->textures[i]);
+		}
+	}
+	decal->dependency.deleted_notify(p_rid);
+	decal_owner.free(p_rid);
+}
+
+void TextureStorage::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
+	Decal *decal = decal_owner.get_or_null(p_decal);
+	ERR_FAIL_COND(!decal);
+	decal->extents = p_extents;
+	decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+}
+
+void TextureStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
+	Decal *decal = decal_owner.get_or_null(p_decal);
+	ERR_FAIL_COND(!decal);
+	ERR_FAIL_INDEX(p_type, RS::DECAL_TEXTURE_MAX);
+
+	if (decal->textures[p_type] == p_texture) {
+		return;
+	}
+
+	ERR_FAIL_COND(p_texture.is_valid() && !owns_texture(p_texture));
+
+	if (decal->textures[p_type].is_valid() && owns_texture(decal->textures[p_type])) {
+		texture_remove_from_decal_atlas(decal->textures[p_type]);
+	}
+
+	decal->textures[p_type] = p_texture;
+
+	if (decal->textures[p_type].is_valid()) {
+		texture_add_to_decal_atlas(decal->textures[p_type]);
+	}
+
+	decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_DECAL);
+}
+
+void TextureStorage::decal_set_emission_energy(RID p_decal, float p_energy) {
+	Decal *decal = decal_owner.get_or_null(p_decal);
+	ERR_FAIL_COND(!decal);
+	decal->emission_energy = p_energy;
+}
+
+void TextureStorage::decal_set_albedo_mix(RID p_decal, float p_mix) {
+	Decal *decal = decal_owner.get_or_null(p_decal);
+	ERR_FAIL_COND(!decal);
+	decal->albedo_mix = p_mix;
+}
+
+void TextureStorage::decal_set_modulate(RID p_decal, const Color &p_modulate) {
+	Decal *decal = decal_owner.get_or_null(p_decal);
+	ERR_FAIL_COND(!decal);
+	decal->modulate = p_modulate;
+}
+
+void TextureStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
+	Decal *decal = decal_owner.get_or_null(p_decal);
+	ERR_FAIL_COND(!decal);
+	decal->cull_mask = p_layers;
+	decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+}
+
+void TextureStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
+	Decal *decal = decal_owner.get_or_null(p_decal);
+	ERR_FAIL_COND(!decal);
+	decal->distance_fade = p_enabled;
+	decal->distance_fade_begin = p_begin;
+	decal->distance_fade_length = p_length;
+}
+
+void TextureStorage::decal_set_fade(RID p_decal, float p_above, float p_below) {
+	Decal *decal = decal_owner.get_or_null(p_decal);
+	ERR_FAIL_COND(!decal);
+	decal->upper_fade = p_above;
+	decal->lower_fade = p_below;
+}
+
+void TextureStorage::decal_set_normal_fade(RID p_decal, float p_fade) {
+	Decal *decal = decal_owner.get_or_null(p_decal);
+	ERR_FAIL_COND(!decal);
+	decal->normal_fade = p_fade;
+}
+
+void TextureStorage::decal_atlas_mark_dirty_on_texture(RID p_texture) {
+	if (decal_atlas.textures.has(p_texture)) {
+		//belongs to decal atlas..
+
+		decal_atlas.dirty = true; //mark it dirty since it was most likely modified
+	}
+}
+
+void TextureStorage::decal_atlas_remove_texture(RID p_texture) {
+	if (decal_atlas.textures.has(p_texture)) {
+		decal_atlas.textures.erase(p_texture);
+		//there is not much a point of making it dirty, just let it be.
+	}
+}
+
+AABB TextureStorage::decal_get_aabb(RID p_decal) const {
+	Decal *decal = decal_owner.get_or_null(p_decal);
+	ERR_FAIL_COND_V(!decal, AABB());
+
+	return AABB(-decal->extents, decal->extents * 2.0);
+}
+
+void TextureStorage::update_decal_atlas() {
+	EffectsRD *effects = RendererStorageRD::base_singleton->get_effects();
+	ERR_FAIL_NULL(effects);
+
+	if (!decal_atlas.dirty) {
+		return; //nothing to do
+	}
+
+	decal_atlas.dirty = false;
+
+	if (decal_atlas.texture.is_valid()) {
+		RD::get_singleton()->free(decal_atlas.texture);
+		decal_atlas.texture = RID();
+		decal_atlas.texture_srgb = RID();
+		decal_atlas.texture_mipmaps.clear();
+	}
+
+	int border = 1 << decal_atlas.mipmaps;
+
+	if (decal_atlas.textures.size()) {
+		//generate atlas
+		Vector<DecalAtlas::SortItem> itemsv;
+		itemsv.resize(decal_atlas.textures.size());
+		int base_size = 8;
+		const RID *K = nullptr;
+
+		int idx = 0;
+		while ((K = decal_atlas.textures.next(K))) {
+			DecalAtlas::SortItem &si = itemsv.write[idx];
+
+			Texture *src_tex = get_texture(*K);
+
+			si.size.width = (src_tex->width / border) + 1;
+			si.size.height = (src_tex->height / border) + 1;
+			si.pixel_size = Size2i(src_tex->width, src_tex->height);
+
+			if (base_size < si.size.width) {
+				base_size = nearest_power_of_2_templated(si.size.width);
+			}
+
+			si.texture = *K;
+			idx++;
+		}
+
+		//sort items by size
+		itemsv.sort();
+
+		//attempt to create atlas
+		int item_count = itemsv.size();
+		DecalAtlas::SortItem *items = itemsv.ptrw();
+
+		int atlas_height = 0;
+
+		while (true) {
+			Vector<int> v_offsetsv;
+			v_offsetsv.resize(base_size);
+
+			int *v_offsets = v_offsetsv.ptrw();
+			memset(v_offsets, 0, sizeof(int) * base_size);
+
+			int max_height = 0;
+
+			for (int i = 0; i < item_count; i++) {
+				//best fit
+				DecalAtlas::SortItem &si = items[i];
+				int best_idx = -1;
+				int best_height = 0x7FFFFFFF;
+				for (int j = 0; j <= base_size - si.size.width; j++) {
+					int height = 0;
+					for (int k = 0; k < si.size.width; k++) {
+						int h = v_offsets[k + j];
+						if (h > height) {
+							height = h;
+							if (height > best_height) {
+								break; //already bad
+							}
+						}
+					}
+
+					if (height < best_height) {
+						best_height = height;
+						best_idx = j;
+					}
+				}
+
+				//update
+				for (int k = 0; k < si.size.width; k++) {
+					v_offsets[k + best_idx] = best_height + si.size.height;
+				}
+
+				si.pos.x = best_idx;
+				si.pos.y = best_height;
+
+				if (si.pos.y + si.size.height > max_height) {
+					max_height = si.pos.y + si.size.height;
+				}
+			}
+
+			if (max_height <= base_size * 2) {
+				atlas_height = max_height;
+				break; //good ratio, break;
+			}
+
+			base_size *= 2;
+		}
+
+		decal_atlas.size.width = base_size * border;
+		decal_atlas.size.height = nearest_power_of_2_templated(atlas_height * border);
+
+		for (int i = 0; i < item_count; i++) {
+			DecalAtlas::Texture *t = decal_atlas.textures.getptr(items[i].texture);
+			t->uv_rect.position = items[i].pos * border + Vector2i(border / 2, border / 2);
+			t->uv_rect.size = items[i].pixel_size;
+
+			t->uv_rect.position /= Size2(decal_atlas.size);
+			t->uv_rect.size /= Size2(decal_atlas.size);
+		}
+	} else {
+		//use border as size, so it at least has enough mipmaps
+		decal_atlas.size.width = border;
+		decal_atlas.size.height = border;
+	}
+
+	//blit textures
+
+	RD::TextureFormat tformat;
+	tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+	tformat.width = decal_atlas.size.width;
+	tformat.height = decal_atlas.size.height;
+	tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+	tformat.texture_type = RD::TEXTURE_TYPE_2D;
+	tformat.mipmaps = decal_atlas.mipmaps;
+	tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_UNORM);
+	tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB);
+
+	decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView());
+	RD::get_singleton()->texture_clear(decal_atlas.texture, Color(0, 0, 0, 0), 0, decal_atlas.mipmaps, 0, 1);
+
+	{
+		//create the framebuffer
+
+		Size2i s = decal_atlas.size;
+
+		for (int i = 0; i < decal_atlas.mipmaps; i++) {
+			DecalAtlas::MipMap mm;
+			mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), decal_atlas.texture, 0, i);
+			Vector<RID> fb;
+			fb.push_back(mm.texture);
+			mm.fb = RD::get_singleton()->framebuffer_create(fb);
+			mm.size = s;
+			decal_atlas.texture_mipmaps.push_back(mm);
+
+			s.width = MAX(1, s.width >> 1);
+			s.height = MAX(1, s.height >> 1);
+		}
+		{
+			//create the SRGB variant
+			RD::TextureView rd_view;
+			rd_view.format_override = RD::DATA_FORMAT_R8G8B8A8_SRGB;
+			decal_atlas.texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, decal_atlas.texture);
+		}
+	}
+
+	RID prev_texture;
+	for (int i = 0; i < decal_atlas.texture_mipmaps.size(); i++) {
+		const DecalAtlas::MipMap &mm = decal_atlas.texture_mipmaps[i];
+
+		Color clear_color(0, 0, 0, 0);
+
+		if (decal_atlas.textures.size()) {
+			if (i == 0) {
+				Vector<Color> cc;
+				cc.push_back(clear_color);
+
+				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);
+
+				const RID *K = nullptr;
+				while ((K = decal_atlas.textures.next(K))) {
+					DecalAtlas::Texture *t = decal_atlas.textures.getptr(*K);
+					Texture *src_tex = get_texture(*K);
+					effects->copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0);
+				}
+
+				RD::get_singleton()->draw_list_end();
+
+				prev_texture = mm.texture;
+			} else {
+				effects->copy_to_fb_rect(prev_texture, mm.fb, Rect2i(Point2i(), mm.size));
+				prev_texture = mm.texture;
+			}
+		} else {
+			RD::get_singleton()->texture_clear(mm.texture, clear_color, 0, 1, 0, 1);
+		}
+	}
+}
+
+void TextureStorage::texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp) {
+	if (!decal_atlas.textures.has(p_texture)) {
+		DecalAtlas::Texture t;
+		t.users = 1;
+		t.panorama_to_dp_users = p_panorama_to_dp ? 1 : 0;
+		decal_atlas.textures[p_texture] = t;
+		decal_atlas.dirty = true;
+	} else {
+		DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
+		t->users++;
+		if (p_panorama_to_dp) {
+			t->panorama_to_dp_users++;
+		}
+	}
+}
+
+void TextureStorage::texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp) {
+	DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
+	ERR_FAIL_COND(!t);
+	t->users--;
+	if (p_panorama_to_dp) {
+		ERR_FAIL_COND(t->panorama_to_dp_users == 0);
+		t->panorama_to_dp_users--;
+	}
+	if (t->users == 0) {
+		decal_atlas.textures.erase(p_texture);
+		//do not mark it dirty, there is no need to since it remains working
+	}
+}
+
+/* RENDER TARGET API */
+
+void TextureStorage::_clear_render_target(RenderTarget *rt) {
+	//free in reverse dependency order
+	if (rt->framebuffer.is_valid()) {
+		RD::get_singleton()->free(rt->framebuffer);
+		rt->framebuffer_uniform_set = RID(); //chain deleted
+	}
+
+	if (rt->color.is_valid()) {
+		RD::get_singleton()->free(rt->color);
+	}
+
+	if (rt->backbuffer.is_valid()) {
+		RD::get_singleton()->free(rt->backbuffer);
+		rt->backbuffer = RID();
+		rt->backbuffer_mipmaps.clear();
+		rt->backbuffer_uniform_set = RID(); //chain deleted
+	}
+
+	_render_target_clear_sdf(rt);
+
+	rt->framebuffer = RID();
+	rt->color = RID();
+}
+
+void TextureStorage::_update_render_target(RenderTarget *rt) {
+	if (rt->texture.is_null()) {
+		//create a placeholder until updated
+		rt->texture = texture_allocate();
+		texture_2d_placeholder_initialize(rt->texture);
+		Texture *tex = get_texture(rt->texture);
+		tex->is_render_target = true;
+	}
+
+	_clear_render_target(rt);
+
+	if (rt->size.width == 0 || rt->size.height == 0) {
+		return;
+	}
+	//until we implement support for HDR monitors (and render target is attached to screen), this is enough.
+	rt->color_format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+	rt->color_format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
+	rt->image_format = rt->flags[RENDER_TARGET_TRANSPARENT] ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8;
+
+	RD::TextureFormat rd_format;
+	RD::TextureView rd_view;
+	{ //attempt register
+		rd_format.format = rt->color_format;
+		rd_format.width = rt->size.width;
+		rd_format.height = rt->size.height;
+		rd_format.depth = 1;
+		rd_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
+		rd_format.mipmaps = 1;
+		if (rd_format.array_layers > 1) { // why are we not using rt->texture_type ??
+			rd_format.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+		} else {
+			rd_format.texture_type = RD::TEXTURE_TYPE_2D;
+		}
+		rd_format.samples = RD::TEXTURE_SAMPLES_1;
+		rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
+		rd_format.shareable_formats.push_back(rt->color_format);
+		rd_format.shareable_formats.push_back(rt->color_format_srgb);
+	}
+
+	rt->color = RD::get_singleton()->texture_create(rd_format, rd_view);
+	ERR_FAIL_COND(rt->color.is_null());
+
+	Vector<RID> fb_textures;
+	fb_textures.push_back(rt->color);
+	rt->framebuffer = RD::get_singleton()->framebuffer_create(fb_textures, RenderingDevice::INVALID_ID, rt->view_count);
+	if (rt->framebuffer.is_null()) {
+		_clear_render_target(rt);
+		ERR_FAIL_COND(rt->framebuffer.is_null());
+	}
+
+	{ //update texture
+
+		Texture *tex = get_texture(rt->texture);
+
+		//free existing textures
+		if (RD::get_singleton()->texture_is_valid(tex->rd_texture)) {
+			RD::get_singleton()->free(tex->rd_texture);
+		}
+		if (RD::get_singleton()->texture_is_valid(tex->rd_texture_srgb)) {
+			RD::get_singleton()->free(tex->rd_texture_srgb);
+		}
+
+		tex->rd_texture = RID();
+		tex->rd_texture_srgb = RID();
+
+		//create shared textures to the color buffer,
+		//so transparent can be supported
+		RD::TextureView view;
+		view.format_override = rt->color_format;
+		if (!rt->flags[RENDER_TARGET_TRANSPARENT]) {
+			view.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
+		}
+		tex->rd_texture = RD::get_singleton()->texture_create_shared(view, rt->color);
+		if (rt->color_format_srgb != RD::DATA_FORMAT_MAX) {
+			view.format_override = rt->color_format_srgb;
+			tex->rd_texture_srgb = RD::get_singleton()->texture_create_shared(view, rt->color);
+		}
+		tex->rd_view = view;
+		tex->width = rt->size.width;
+		tex->height = rt->size.height;
+		tex->width_2d = rt->size.width;
+		tex->height_2d = rt->size.height;
+		tex->rd_format = rt->color_format;
+		tex->rd_format_srgb = rt->color_format_srgb;
+		tex->format = rt->image_format;
+
+		Vector<RID> proxies = tex->proxies; //make a copy, since update may change it
+		for (int i = 0; i < proxies.size(); i++) {
+			texture_proxy_update(proxies[i], rt->texture);
+		}
+	}
+}
+
+void TextureStorage::_create_render_target_backbuffer(RenderTarget *rt) {
+	ERR_FAIL_COND(rt->backbuffer.is_valid());
+
+	uint32_t mipmaps_required = Image::get_image_required_mipmaps(rt->size.width, rt->size.height, Image::FORMAT_RGBA8);
+	RD::TextureFormat tf;
+	tf.format = rt->color_format;
+	tf.width = rt->size.width;
+	tf.height = rt->size.height;
+	tf.texture_type = RD::TEXTURE_TYPE_2D;
+	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;
+	tf.mipmaps = mipmaps_required;
+
+	rt->backbuffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
+	RD::get_singleton()->set_resource_name(rt->backbuffer, "Render Target Back Buffer");
+	rt->backbuffer_mipmap0 = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, 0);
+	RD::get_singleton()->set_resource_name(rt->backbuffer_mipmap0, "Back Buffer slice mipmap 0");
+
+	{
+		Vector<RID> fb_tex;
+		fb_tex.push_back(rt->backbuffer_mipmap0);
+		rt->backbuffer_fb = RD::get_singleton()->framebuffer_create(fb_tex);
+	}
+
+	if (rt->framebuffer_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rt->framebuffer_uniform_set)) {
+		//the new one will require the backbuffer.
+		RD::get_singleton()->free(rt->framebuffer_uniform_set);
+		rt->framebuffer_uniform_set = RID();
+	}
+	//create mipmaps
+	for (uint32_t i = 1; i < mipmaps_required; i++) {
+		RID mipmap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, i);
+		RD::get_singleton()->set_resource_name(mipmap, "Back Buffer slice mip: " + itos(i));
+
+		rt->backbuffer_mipmaps.push_back(mipmap);
+	}
+}
+
+RID TextureStorage::render_target_create() {
+	RenderTarget render_target;
+
+	render_target.was_used = false;
+	render_target.clear_requested = false;
+
+	for (int i = 0; i < RENDER_TARGET_FLAG_MAX; i++) {
+		render_target.flags[i] = false;
+	}
+	_update_render_target(&render_target);
+	return render_target_owner.make_rid(render_target);
+}
+
+void TextureStorage::render_target_free(RID p_rid) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_rid);
+
+	_clear_render_target(rt);
+
+	if (rt->texture.is_valid()) {
+		Texture *tex = get_texture(rt->texture);
+		tex->is_render_target = false;
+		texture_free(rt->texture);
+	}
+
+	render_target_owner.free(p_rid);
+}
+
+void TextureStorage::render_target_set_position(RID p_render_target, int p_x, int p_y) {
+	//unused for this render target
+}
+
+void TextureStorage::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+	if (rt->size.x != p_width || rt->size.y != p_height || rt->view_count != p_view_count) {
+		rt->size.x = p_width;
+		rt->size.y = p_height;
+		rt->view_count = p_view_count;
+		_update_render_target(rt);
+	}
+}
+
+RID TextureStorage::render_target_get_texture(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, RID());
+
+	return rt->texture;
+}
+
+void TextureStorage::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) {
+}
+
+void TextureStorage::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+	rt->flags[p_flag] = p_value;
+	_update_render_target(rt);
+}
+
+bool TextureStorage::render_target_was_used(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, false);
+	return rt->was_used;
+}
+
+void TextureStorage::render_target_set_as_unused(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+	rt->was_used = false;
+}
+
+Size2 TextureStorage::render_target_get_size(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, Size2());
+
+	return rt->size;
+}
+
+RID TextureStorage::render_target_get_rd_framebuffer(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, RID());
+
+	return rt->framebuffer;
+}
+
+RID TextureStorage::render_target_get_rd_texture(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, RID());
+
+	return rt->color;
+}
+
+RID TextureStorage::render_target_get_rd_backbuffer(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, RID());
+	return rt->backbuffer;
+}
+
+RID TextureStorage::render_target_get_rd_backbuffer_framebuffer(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, RID());
+
+	if (!rt->backbuffer.is_valid()) {
+		_create_render_target_backbuffer(rt);
+	}
+
+	return rt->backbuffer_fb;
+}
+
+void TextureStorage::render_target_request_clear(RID p_render_target, const Color &p_clear_color) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+	rt->clear_requested = true;
+	rt->clear_color = p_clear_color;
+}
+
+bool TextureStorage::render_target_is_clear_requested(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, false);
+	return rt->clear_requested;
+}
+
+Color TextureStorage::render_target_get_clear_request_color(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, Color());
+	return rt->clear_color;
+}
+
+void TextureStorage::render_target_disable_clear_request(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+	rt->clear_requested = false;
+}
+
+void TextureStorage::render_target_do_clear_request(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+	if (!rt->clear_requested) {
+		return;
+	}
+	Vector<Color> clear_colors;
+	clear_colors.push_back(rt->clear_color);
+	RD::get_singleton()->draw_list_begin(rt->framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, clear_colors);
+	RD::get_singleton()->draw_list_end();
+	rt->clear_requested = false;
+}
+
+void TextureStorage::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+	if (rt->sdf_oversize == p_size && rt->sdf_scale == p_scale) {
+		return;
+	}
+
+	rt->sdf_oversize = p_size;
+	rt->sdf_scale = p_scale;
+
+	_render_target_clear_sdf(rt);
+}
+
+Rect2i TextureStorage::_render_target_get_sdf_rect(const RenderTarget *rt) const {
+	Size2i margin;
+	int scale;
+	switch (rt->sdf_oversize) {
+		case RS::VIEWPORT_SDF_OVERSIZE_100_PERCENT: {
+			scale = 100;
+		} break;
+		case RS::VIEWPORT_SDF_OVERSIZE_120_PERCENT: {
+			scale = 120;
+		} break;
+		case RS::VIEWPORT_SDF_OVERSIZE_150_PERCENT: {
+			scale = 150;
+		} break;
+		case RS::VIEWPORT_SDF_OVERSIZE_200_PERCENT: {
+			scale = 200;
+		} break;
+		default: {
+		}
+	}
+
+	margin = (rt->size * scale / 100) - rt->size;
+
+	Rect2i r(Vector2i(), rt->size);
+	r.position -= margin;
+	r.size += margin * 2;
+
+	return r;
+}
+
+Rect2i TextureStorage::render_target_get_sdf_rect(RID p_render_target) const {
+	const RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, Rect2i());
+
+	return _render_target_get_sdf_rect(rt);
+}
+
+void TextureStorage::render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+
+	rt->sdf_enabled = p_enabled;
+}
+
+bool TextureStorage::render_target_is_sdf_enabled(RID p_render_target) const {
+	const RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, false);
+
+	return rt->sdf_enabled;
+}
+
+RID TextureStorage::render_target_get_sdf_texture(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, RID());
+	if (rt->sdf_buffer_read.is_null()) {
+		// no texture, create a dummy one for the 2D uniform set
+		RD::TextureFormat tformat;
+		tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+		tformat.width = 4;
+		tformat.height = 4;
+		tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT;
+		tformat.texture_type = RD::TEXTURE_TYPE_2D;
+
+		Vector<uint8_t> pv;
+		pv.resize(16 * 4);
+		memset(pv.ptrw(), 0, 16 * 4);
+		Vector<Vector<uint8_t>> vpv;
+
+		rt->sdf_buffer_read = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
+	}
+
+	return rt->sdf_buffer_read;
+}
+
+void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) {
+	ERR_FAIL_COND(rt->sdf_buffer_write_fb.is_valid());
+	if (rt->sdf_buffer_read.is_valid()) {
+		RD::get_singleton()->free(rt->sdf_buffer_read);
+		rt->sdf_buffer_read = RID();
+	}
+
+	Size2i size = _render_target_get_sdf_rect(rt).size;
+
+	RD::TextureFormat tformat;
+	tformat.format = RD::DATA_FORMAT_R8_UNORM;
+	tformat.width = size.width;
+	tformat.height = size.height;
+	tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+	tformat.texture_type = RD::TEXTURE_TYPE_2D;
+
+	rt->sdf_buffer_write = RD::get_singleton()->texture_create(tformat, RD::TextureView());
+
+	{
+		Vector<RID> write_fb;
+		write_fb.push_back(rt->sdf_buffer_write);
+		rt->sdf_buffer_write_fb = RD::get_singleton()->framebuffer_create(write_fb);
+	}
+
+	int scale;
+	switch (rt->sdf_scale) {
+		case RS::VIEWPORT_SDF_SCALE_100_PERCENT: {
+			scale = 100;
+		} break;
+		case RS::VIEWPORT_SDF_SCALE_50_PERCENT: {
+			scale = 50;
+		} break;
+		case RS::VIEWPORT_SDF_SCALE_25_PERCENT: {
+			scale = 25;
+		} break;
+		default: {
+			scale = 100;
+		} break;
+	}
+
+	rt->process_size = size * scale / 100;
+	rt->process_size.x = MAX(rt->process_size.x, 1);
+	rt->process_size.y = MAX(rt->process_size.y, 1);
+
+	tformat.format = RD::DATA_FORMAT_R16G16_SINT;
+	tformat.width = rt->process_size.width;
+	tformat.height = rt->process_size.height;
+	tformat.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;
+
+	rt->sdf_buffer_process[0] = RD::get_singleton()->texture_create(tformat, RD::TextureView());
+	rt->sdf_buffer_process[1] = RD::get_singleton()->texture_create(tformat, RD::TextureView());
+
+	tformat.format = RD::DATA_FORMAT_R16_SNORM;
+	tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+
+	rt->sdf_buffer_read = RD::get_singleton()->texture_create(tformat, RD::TextureView());
+
+	{
+		Vector<RD::Uniform> uniforms;
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+			u.binding = 1;
+			u.append_id(rt->sdf_buffer_write);
+			uniforms.push_back(u);
+		}
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+			u.binding = 2;
+			u.append_id(rt->sdf_buffer_read);
+			uniforms.push_back(u);
+		}
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+			u.binding = 3;
+			u.append_id(rt->sdf_buffer_process[0]);
+			uniforms.push_back(u);
+		}
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+			u.binding = 4;
+			u.append_id(rt->sdf_buffer_process[1]);
+			uniforms.push_back(u);
+		}
+
+		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);
+		RID aux2 = uniforms.write[2].get_id(0);
+		RID aux3 = uniforms.write[3].get_id(0);
+		uniforms.write[2].set_id(0, aux3);
+		uniforms.write[3].set_id(0, aux2);
+		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);
+	}
+}
+
+void TextureStorage::_render_target_clear_sdf(RenderTarget *rt) {
+	if (rt->sdf_buffer_read.is_valid()) {
+		RD::get_singleton()->free(rt->sdf_buffer_read);
+		rt->sdf_buffer_read = RID();
+	}
+	if (rt->sdf_buffer_write_fb.is_valid()) {
+		RD::get_singleton()->free(rt->sdf_buffer_write);
+		RD::get_singleton()->free(rt->sdf_buffer_process[0]);
+		RD::get_singleton()->free(rt->sdf_buffer_process[1]);
+		rt->sdf_buffer_write = RID();
+		rt->sdf_buffer_write_fb = RID();
+		rt->sdf_buffer_process[0] = RID();
+		rt->sdf_buffer_process[1] = RID();
+		rt->sdf_buffer_process_uniform_sets[0] = RID();
+		rt->sdf_buffer_process_uniform_sets[1] = RID();
+	}
+}
+
+RID TextureStorage::render_target_get_sdf_framebuffer(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, RID());
+
+	if (rt->sdf_buffer_write_fb.is_null()) {
+		_render_target_allocate_sdf(rt);
+	}
+
+	return rt->sdf_buffer_write_fb;
+}
+void TextureStorage::render_target_sdf_process(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+	ERR_FAIL_COND(rt->sdf_buffer_write_fb.is_null());
+
+	RenderTargetSDF::PushConstant push_constant;
+
+	Rect2i r = _render_target_get_sdf_rect(rt);
+
+	push_constant.size[0] = r.size.width;
+	push_constant.size[1] = r.size.height;
+	push_constant.stride = 0;
+	push_constant.shift = 0;
+	push_constant.base_size[0] = r.size.width;
+	push_constant.base_size[1] = r.size.height;
+
+	bool shrink = false;
+
+	switch (rt->sdf_scale) {
+		case RS::VIEWPORT_SDF_SCALE_50_PERCENT: {
+			push_constant.size[0] >>= 1;
+			push_constant.size[1] >>= 1;
+			push_constant.shift = 1;
+			shrink = true;
+		} break;
+		case RS::VIEWPORT_SDF_SCALE_25_PERCENT: {
+			push_constant.size[0] >>= 2;
+			push_constant.size[1] >>= 2;
+			push_constant.shift = 2;
+			shrink = true;
+		} break;
+		default: {
+		};
+	}
+
+	RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+
+	/* Load */
+
+	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, rt_sdf.pipelines[shrink ? RenderTargetSDF::SHADER_LOAD_SHRINK : RenderTargetSDF::SHADER_LOAD]);
+	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[1], 0); //fill [0]
+	RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant));
+
+	RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1);
+
+	/* Process */
+
+	int stride = nearest_power_of_2_templated(MAX(push_constant.size[0], push_constant.size[1]) / 2);
+
+	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, rt_sdf.pipelines[RenderTargetSDF::SHADER_PROCESS]);
+
+	RD::get_singleton()->compute_list_add_barrier(compute_list);
+	bool swap = false;
+
+	//jumpflood
+	while (stride > 0) {
+		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[swap ? 1 : 0], 0);
+		push_constant.stride = stride;
+		RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant));
+		RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1);
+		stride /= 2;
+		swap = !swap;
+		RD::get_singleton()->compute_list_add_barrier(compute_list);
+	}
+
+	/* Store */
+
+	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, rt_sdf.pipelines[shrink ? RenderTargetSDF::SHADER_STORE_SHRINK : RenderTargetSDF::SHADER_STORE]);
+	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[swap ? 1 : 0], 0);
+	RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant));
+	RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1);
+
+	RD::get_singleton()->compute_list_end();
+}
+
+void TextureStorage::render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps) {
+	EffectsRD *effects = RendererStorageRD::base_singleton->get_effects();
+	ERR_FAIL_NULL(effects);
+
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+	if (!rt->backbuffer.is_valid()) {
+		_create_render_target_backbuffer(rt);
+	}
+
+	Rect2i region;
+	if (p_region == Rect2i()) {
+		region.size = rt->size;
+	} else {
+		region = Rect2i(Size2i(), rt->size).intersection(p_region);
+		if (region.size == Size2i()) {
+			return; //nothing to do
+		}
+	}
+
+	//single texture copy for backbuffer
+	//RD::get_singleton()->texture_copy(rt->color, rt->backbuffer_mipmap0, Vector3(region.position.x, region.position.y, 0), Vector3(region.position.x, region.position.y, 0), Vector3(region.size.x, region.size.y, 1), 0, 0, 0, 0, true);
+	effects->copy_to_rect(rt->color, rt->backbuffer_mipmap0, region, false, false, false, true, true);
+
+	if (!p_gen_mipmaps) {
+		return;
+	}
+	RD::get_singleton()->draw_command_begin_label("Gaussian Blur Mipmaps");
+	//then mipmap blur
+	RID prev_texture = rt->color; //use color, not backbuffer, as bb has mipmaps.
+
+	for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
+		region.position.x >>= 1;
+		region.position.y >>= 1;
+		region.size.x = MAX(1, region.size.x >> 1);
+		region.size.y = MAX(1, region.size.y >> 1);
+
+		RID mipmap = rt->backbuffer_mipmaps[i];
+		effects->gaussian_blur(prev_texture, mipmap, region, true);
+		prev_texture = mipmap;
+	}
+	RD::get_singleton()->draw_command_end_label();
+}
+
+void TextureStorage::render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+
+	EffectsRD *effects = RendererStorageRD::base_singleton->get_effects();
+	ERR_FAIL_NULL(effects);
+
+	if (!rt->backbuffer.is_valid()) {
+		_create_render_target_backbuffer(rt);
+	}
+
+	Rect2i region;
+	if (p_region == Rect2i()) {
+		region.size = rt->size;
+	} else {
+		region = Rect2i(Size2i(), rt->size).intersection(p_region);
+		if (region.size == Size2i()) {
+			return; //nothing to do
+		}
+	}
+
+	//single texture copy for backbuffer
+	effects->set_color(rt->backbuffer_mipmap0, p_color, region, true);
+}
+
+void TextureStorage::render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+
+	EffectsRD *effects = RendererStorageRD::base_singleton->get_effects();
+	ERR_FAIL_NULL(effects);
+
+	if (!rt->backbuffer.is_valid()) {
+		_create_render_target_backbuffer(rt);
+	}
+
+	Rect2i region;
+	if (p_region == Rect2i()) {
+		region.size = rt->size;
+	} else {
+		region = Rect2i(Size2i(), rt->size).intersection(p_region);
+		if (region.size == Size2i()) {
+			return; //nothing to do
+		}
+	}
+	RD::get_singleton()->draw_command_begin_label("Gaussian Blur Mipmaps2");
+	//then mipmap blur
+	RID prev_texture = rt->backbuffer_mipmap0;
+
+	for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
+		region.position.x >>= 1;
+		region.position.y >>= 1;
+		region.size.x = MAX(1, region.size.x >> 1);
+		region.size.y = MAX(1, region.size.y >> 1);
+
+		RID mipmap = rt->backbuffer_mipmaps[i];
+		effects->gaussian_blur(prev_texture, mipmap, region, true);
+		prev_texture = mipmap;
+	}
+	RD::get_singleton()->draw_command_end_label();
+}
+
+RID TextureStorage::render_target_get_framebuffer_uniform_set(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, RID());
+	return rt->framebuffer_uniform_set;
+}
+RID TextureStorage::render_target_get_backbuffer_uniform_set(RID p_render_target) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND_V(!rt, RID());
+	return rt->backbuffer_uniform_set;
+}
+
+void TextureStorage::render_target_set_framebuffer_uniform_set(RID p_render_target, RID p_uniform_set) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+	rt->framebuffer_uniform_set = p_uniform_set;
+}
+
+void TextureStorage::render_target_set_backbuffer_uniform_set(RID p_render_target, RID p_uniform_set) {
+	RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+	ERR_FAIL_COND(!rt);
+	rt->backbuffer_uniform_set = p_uniform_set;
+}

+ 336 - 1
servers/rendering/renderer_rd/storage_rd/texture_storage.h

@@ -31,8 +31,9 @@
 #ifndef TEXTURE_STORAGE_RD_H
 #define TEXTURE_STORAGE_RD_H
 
-#include "canvas_texture_storage.h"
 #include "core/templates/rid_owner.h"
+#include "servers/rendering/renderer_rd/shaders/canvas_sdf.glsl.gen.h"
+#include "servers/rendering/renderer_storage.h"
 #include "servers/rendering/storage/texture_storage.h"
 
 namespace RendererRD {
@@ -54,6 +55,27 @@ enum DefaultRDTexture {
 	DEFAULT_RD_TEXTURE_MAX
 };
 
+class CanvasTexture {
+public:
+	RID diffuse;
+	RID normal_map;
+	RID specular;
+	Color specular_color = Color(1, 1, 1, 1);
+	float shininess = 1.0;
+
+	RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT;
+	RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT;
+	RID uniform_sets[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX];
+
+	Size2i size_cache = Size2i(1, 1);
+	bool use_normal_cache = false;
+	bool use_specular_cache = false;
+	bool cleared_cache = true;
+
+	void clear_sets();
+	~CanvasTexture();
+};
+
 class Texture {
 public:
 	enum Type {
@@ -118,10 +140,138 @@ public:
 	void cleanup();
 };
 
+struct DecalAtlas {
+	struct Texture {
+		int panorama_to_dp_users;
+		int users;
+		Rect2 uv_rect;
+	};
+
+	struct SortItem {
+		RID texture;
+		Size2i pixel_size;
+		Size2i size;
+		Point2i pos;
+
+		bool operator<(const SortItem &p_item) const {
+			//sort larger to smaller
+			if (size.height == p_item.size.height) {
+				return size.width > p_item.size.width;
+			} else {
+				return size.height > p_item.size.height;
+			}
+		}
+	};
+
+	HashMap<RID, Texture> textures;
+	bool dirty = true;
+	int mipmaps = 5;
+
+	RID texture;
+	RID texture_srgb;
+	struct MipMap {
+		RID fb;
+		RID texture;
+		Size2i size;
+	};
+	Vector<MipMap> texture_mipmaps;
+
+	Size2i size;
+};
+
+struct Decal {
+	Vector3 extents = Vector3(1, 1, 1);
+	RID textures[RS::DECAL_TEXTURE_MAX];
+	float emission_energy = 1.0;
+	float albedo_mix = 1.0;
+	Color modulate = Color(1, 1, 1, 1);
+	uint32_t cull_mask = (1 << 20) - 1;
+	float upper_fade = 0.3;
+	float lower_fade = 0.3;
+	bool distance_fade = false;
+	float distance_fade_begin = 10;
+	float distance_fade_length = 1;
+	float normal_fade = 0.0;
+
+	RendererStorage::Dependency dependency;
+};
+
+struct RenderTarget {
+	Size2i size;
+	uint32_t view_count;
+	RID framebuffer;
+	RID color;
+
+	//used for retrieving from CPU
+	RD::DataFormat color_format = RD::DATA_FORMAT_R4G4_UNORM_PACK8;
+	RD::DataFormat color_format_srgb = RD::DATA_FORMAT_R4G4_UNORM_PACK8;
+	Image::Format image_format = Image::FORMAT_L8;
+
+	bool flags[RendererTextureStorage::RENDER_TARGET_FLAG_MAX];
+
+	bool sdf_enabled = false;
+
+	RID backbuffer; //used for effects
+	RID backbuffer_fb;
+	RID backbuffer_mipmap0;
+
+	Vector<RID> backbuffer_mipmaps;
+
+	RID framebuffer_uniform_set;
+	RID backbuffer_uniform_set;
+
+	RID sdf_buffer_write;
+	RID sdf_buffer_write_fb;
+	RID sdf_buffer_process[2];
+	RID sdf_buffer_read;
+	RID sdf_buffer_process_uniform_sets[2];
+	RS::ViewportSDFOversize sdf_oversize = RS::VIEWPORT_SDF_OVERSIZE_120_PERCENT;
+	RS::ViewportSDFScale sdf_scale = RS::VIEWPORT_SDF_SCALE_50_PERCENT;
+	Size2i process_size;
+
+	//texture generated for this owner (nor RD).
+	RID texture;
+	bool was_used;
+
+	//clear request
+	bool clear_requested;
+	Color clear_color;
+};
+
+struct RenderTargetSDF {
+	enum {
+		SHADER_LOAD,
+		SHADER_LOAD_SHRINK,
+		SHADER_PROCESS,
+		SHADER_PROCESS_OPTIMIZED,
+		SHADER_STORE,
+		SHADER_STORE_SHRINK,
+		SHADER_MAX
+	};
+
+	struct PushConstant {
+		int32_t size[2];
+		int32_t stride;
+		int32_t shift;
+		int32_t base_size[2];
+		int32_t pad[2];
+	};
+
+	CanvasSdfShaderRD shader;
+	RID shader_version;
+	RID pipelines[SHADER_MAX];
+};
+
 class TextureStorage : public RendererTextureStorage {
 private:
 	static TextureStorage *singleton;
 
+	/* Canvas Texture API */
+
+	RID_Owner<RendererRD::CanvasTexture, true> canvas_texture_owner;
+
+	/* Texture API */
+
 	//textures can be created from threads, so this RID_Owner is thread safe
 	mutable RID_Owner<Texture, true> texture_owner;
 
@@ -145,6 +295,25 @@ private:
 	Ref<Image> _validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format);
 	void _texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0, bool p_immediate = false);
 
+	/* DECAL API */
+
+	DecalAtlas decal_atlas;
+
+	mutable RID_Owner<Decal, true> decal_owner;
+
+	/* RENDER TARGET API */
+
+	mutable RID_Owner<RenderTarget> render_target_owner;
+
+	void _clear_render_target(RenderTarget *rt);
+	void _update_render_target(RenderTarget *rt);
+	void _create_render_target_backbuffer(RenderTarget *rt);
+	void _render_target_allocate_sdf(RenderTarget *rt);
+	void _render_target_clear_sdf(RenderTarget *rt);
+	Rect2i _render_target_get_sdf_rect(const RenderTarget *rt) const;
+
+	RenderTargetSDF rt_sdf;
+
 public:
 	static TextureStorage *get_singleton();
 
@@ -157,6 +326,25 @@ public:
 	TextureStorage();
 	virtual ~TextureStorage();
 
+	/* Canvas Texture API */
+
+	CanvasTexture *get_canvas_texture(RID p_rid) { return canvas_texture_owner.get_or_null(p_rid); };
+	bool owns_canvas_texture(RID p_rid) { return canvas_texture_owner.owns(p_rid); };
+
+	virtual RID canvas_texture_allocate() override;
+	virtual void canvas_texture_initialize(RID p_rid) override;
+	virtual void canvas_texture_free(RID p_rid) override;
+
+	virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override;
+	virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override;
+
+	virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override;
+	virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override;
+
+	bool 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, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular);
+
+	/* Texture API */
+
 	Texture *get_texture(RID p_rid) { return texture_owner.get_or_null(p_rid); };
 	bool owns_texture(RID p_rid) { return texture_owner.owns(p_rid); };
 
@@ -224,6 +412,153 @@ public:
 		}
 		return Size2i(tex->width_2d, tex->height_2d);
 	}
+
+	/* DECAL API */
+
+	void update_decal_atlas();
+
+	Decal *get_decal(RID p_rid) { return decal_owner.get_or_null(p_rid); };
+	bool owns_decal(RID p_rid) { return decal_owner.owns(p_rid); };
+
+	RID decal_atlas_get_texture() const;
+	RID decal_atlas_get_texture_srgb() const;
+	_FORCE_INLINE_ Rect2 decal_atlas_get_texture_rect(RID p_texture) {
+		DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
+		if (!t) {
+			return Rect2();
+		}
+
+		return t->uv_rect;
+	}
+
+	virtual RID decal_allocate() override;
+	virtual void decal_initialize(RID p_decal) override;
+	virtual void decal_free(RID p_rid) override;
+
+	virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override;
+	virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override;
+	virtual void decal_set_emission_energy(RID p_decal, float p_energy) override;
+	virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override;
+	virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override;
+	virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override;
+	virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override;
+	virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override;
+	virtual void decal_set_normal_fade(RID p_decal, float p_fade) override;
+
+	void decal_atlas_mark_dirty_on_texture(RID p_texture);
+	void decal_atlas_remove_texture(RID p_texture);
+
+	virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override;
+	virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override;
+
+	_FORCE_INLINE_ Vector3 decal_get_extents(RID p_decal) {
+		const Decal *decal = decal_owner.get_or_null(p_decal);
+		return decal->extents;
+	}
+
+	_FORCE_INLINE_ RID decal_get_texture(RID p_decal, RS::DecalTexture p_texture) {
+		const Decal *decal = decal_owner.get_or_null(p_decal);
+		return decal->textures[p_texture];
+	}
+
+	_FORCE_INLINE_ Color decal_get_modulate(RID p_decal) {
+		const Decal *decal = decal_owner.get_or_null(p_decal);
+		return decal->modulate;
+	}
+
+	_FORCE_INLINE_ float decal_get_emission_energy(RID p_decal) {
+		const Decal *decal = decal_owner.get_or_null(p_decal);
+		return decal->emission_energy;
+	}
+
+	_FORCE_INLINE_ float decal_get_albedo_mix(RID p_decal) {
+		const Decal *decal = decal_owner.get_or_null(p_decal);
+		return decal->albedo_mix;
+	}
+
+	_FORCE_INLINE_ uint32_t decal_get_cull_mask(RID p_decal) {
+		const Decal *decal = decal_owner.get_or_null(p_decal);
+		return decal->cull_mask;
+	}
+
+	_FORCE_INLINE_ float decal_get_upper_fade(RID p_decal) {
+		const Decal *decal = decal_owner.get_or_null(p_decal);
+		return decal->upper_fade;
+	}
+
+	_FORCE_INLINE_ float decal_get_lower_fade(RID p_decal) {
+		const Decal *decal = decal_owner.get_or_null(p_decal);
+		return decal->lower_fade;
+	}
+
+	_FORCE_INLINE_ float decal_get_normal_fade(RID p_decal) {
+		const Decal *decal = decal_owner.get_or_null(p_decal);
+		return decal->normal_fade;
+	}
+
+	_FORCE_INLINE_ bool decal_is_distance_fade_enabled(RID p_decal) {
+		const Decal *decal = decal_owner.get_or_null(p_decal);
+		return decal->distance_fade;
+	}
+
+	_FORCE_INLINE_ float decal_get_distance_fade_begin(RID p_decal) {
+		const Decal *decal = decal_owner.get_or_null(p_decal);
+		return decal->distance_fade_begin;
+	}
+
+	_FORCE_INLINE_ float decal_get_distance_fade_length(RID p_decal) {
+		const Decal *decal = decal_owner.get_or_null(p_decal);
+		return decal->distance_fade_length;
+	}
+
+	virtual AABB decal_get_aabb(RID p_decal) const override;
+
+	/* RENDER TARGET API */
+
+	RenderTarget *get_render_target(RID p_rid) { return render_target_owner.get_or_null(p_rid); };
+	bool owns_render_target(RID p_rid) { return render_target_owner.owns(p_rid); };
+
+	virtual RID render_target_create() override;
+	virtual void render_target_free(RID p_rid) override;
+
+	virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) override;
+	virtual void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) override;
+	virtual RID render_target_get_texture(RID p_render_target) override;
+	virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) override;
+	virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) override;
+	virtual bool render_target_was_used(RID p_render_target) override;
+	virtual void render_target_set_as_unused(RID p_render_target) override;
+
+	void render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps);
+	void render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color);
+	void render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region);
+	RID render_target_get_back_buffer_uniform_set(RID p_render_target, RID p_base_shader);
+
+	virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color) override;
+	virtual bool render_target_is_clear_requested(RID p_render_target) override;
+	virtual Color render_target_get_clear_request_color(RID p_render_target) override;
+	virtual void render_target_disable_clear_request(RID p_render_target) override;
+	virtual void render_target_do_clear_request(RID p_render_target) override;
+
+	virtual void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) override;
+	RID render_target_get_sdf_texture(RID p_render_target);
+	RID render_target_get_sdf_framebuffer(RID p_render_target);
+	void render_target_sdf_process(RID p_render_target);
+	virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const override;
+	virtual void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) override;
+	bool render_target_is_sdf_enabled(RID p_render_target) const;
+
+	Size2 render_target_get_size(RID p_render_target);
+	RID render_target_get_rd_framebuffer(RID p_render_target);
+	RID render_target_get_rd_texture(RID p_render_target);
+	RID render_target_get_rd_backbuffer(RID p_render_target);
+	RID render_target_get_rd_backbuffer_framebuffer(RID p_render_target);
+
+	RID render_target_get_framebuffer_uniform_set(RID p_render_target);
+	RID render_target_get_backbuffer_uniform_set(RID p_render_target);
+
+	void render_target_set_framebuffer_uniform_set(RID p_render_target, RID p_uniform_set);
+	void render_target_set_backbuffer_uniform_set(RID p_render_target, RID p_uniform_set);
 };
 
 } // namespace RendererRD

+ 1 - 1
servers/rendering/renderer_scene_cull.cpp

@@ -1887,7 +1887,7 @@ void RendererSceneCull::_update_instance_aabb(Instance *p_instance) {
 
 		} break;
 		case RenderingServer::INSTANCE_DECAL: {
-			new_aabb = RSG::decal_atlas_storage->decal_get_aabb(p_instance->base);
+			new_aabb = RSG::texture_storage->decal_get_aabb(p_instance->base);
 
 		} break;
 		case RenderingServer::INSTANCE_VOXEL_GI: {

+ 0 - 27
servers/rendering/renderer_storage.h

@@ -360,33 +360,6 @@ public:
 	virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) = 0;
 	virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) = 0;
 
-	/* RENDER TARGET */
-
-	enum RenderTargetFlags {
-		RENDER_TARGET_TRANSPARENT,
-		RENDER_TARGET_DIRECT_TO_SCREEN,
-		RENDER_TARGET_FLAG_MAX
-	};
-
-	virtual RID render_target_create() = 0;
-	virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) = 0;
-	virtual void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) = 0;
-	virtual RID render_target_get_texture(RID p_render_target) = 0;
-	virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) = 0;
-	virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) = 0;
-	virtual bool render_target_was_used(RID p_render_target) = 0;
-	virtual void render_target_set_as_unused(RID p_render_target) = 0;
-
-	virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color) = 0;
-	virtual bool render_target_is_clear_requested(RID p_render_target) = 0;
-	virtual Color render_target_get_clear_request_color(RID p_render_target) = 0;
-	virtual void render_target_disable_clear_request(RID p_render_target) = 0;
-	virtual void render_target_do_clear_request(RID p_render_target) = 0;
-
-	virtual void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) = 0;
-	virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const = 0;
-	virtual void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) = 0;
-
 	virtual RS::InstanceType get_base_type(RID p_rid) const = 0;
 	virtual bool free(RID p_rid) = 0;
 

+ 28 - 27
servers/rendering/renderer_viewport.cpp

@@ -34,6 +34,7 @@
 #include "renderer_canvas_cull.h"
 #include "renderer_scene_cull.h"
 #include "rendering_server_globals.h"
+#include "storage/texture_storage.h"
 
 static Transform2D _canvas_get_transform(RendererViewport::Viewport *p_viewport, RendererCanvasCull::Canvas *p_canvas, RendererViewport::Viewport::CanvasData *p_canvas_data, const Vector2 &p_vp_size) {
 	Transform2D xf = p_viewport->global_transform;
@@ -222,7 +223,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
 		_configure_3d_render_buffers(p_viewport);
 	}
 
-	RSG::storage->render_target_request_clear(p_viewport->render_target, bgcolor);
+	RSG::texture_storage->render_target_request_clear(p_viewport->render_target, bgcolor);
 
 	if (!scenario_draw_canvas_bg && can_draw_3d) {
 		_draw_3d(p_viewport);
@@ -243,7 +244,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
 		if (p_viewport->sdf_active) {
 			//process SDF
 
-			Rect2 sdf_rect = RSG::storage->render_target_get_sdf_rect(p_viewport->render_target);
+			Rect2 sdf_rect = RSG::texture_storage->render_target_get_sdf_rect(p_viewport->render_target);
 
 			RendererCanvasRender::LightOccluderInstance *occluders = nullptr;
 
@@ -266,11 +267,11 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
 			}
 
 			RSG::canvas_render->render_sdf(p_viewport->render_target, occluders);
-			RSG::storage->render_target_mark_sdf_enabled(p_viewport->render_target, true);
+			RSG::texture_storage->render_target_mark_sdf_enabled(p_viewport->render_target, true);
 
 			p_viewport->sdf_active = false; // if used, gets set active again
 		} else {
-			RSG::storage->render_target_mark_sdf_enabled(p_viewport->render_target, false);
+			RSG::texture_storage->render_target_mark_sdf_enabled(p_viewport->render_target, false);
 		}
 
 		Rect2 shadow_rect;
@@ -529,9 +530,9 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
 		}
 	}
 
-	if (RSG::storage->render_target_is_clear_requested(p_viewport->render_target)) {
+	if (RSG::texture_storage->render_target_is_clear_requested(p_viewport->render_target)) {
 		//was never cleared in the end, force clear it
-		RSG::storage->render_target_do_clear_request(p_viewport->render_target);
+		RSG::texture_storage->render_target_do_clear_request(p_viewport->render_target);
 	}
 
 	if (p_viewport->measure_render_time) {
@@ -595,7 +596,7 @@ void RendererViewport::draw_viewports() {
 				vp->occlusion_buffer_dirty = vp->occlusion_buffer_dirty || (vp->size != xr_size);
 				vp->size = xr_size;
 				uint32_t view_count = xr_interface->get_view_count();
-				RSG::storage->render_target_set_size(vp->render_target, vp->size.x, vp->size.y, view_count);
+				RSG::texture_storage->render_target_set_size(vp->render_target, vp->size.x, vp->size.y, view_count);
 
 				// Inform xr interface we're about to render its viewport, if this returns false we don't render
 				visible = xr_interface->pre_draw_viewport(vp->render_target);
@@ -610,7 +611,7 @@ void RendererViewport::draw_viewports() {
 			visible = true;
 		}
 
-		if (vp->update_mode == RS::VIEWPORT_UPDATE_WHEN_VISIBLE && RSG::storage->render_target_was_used(vp->render_target)) {
+		if (vp->update_mode == RS::VIEWPORT_UPDATE_WHEN_VISIBLE && RSG::texture_storage->render_target_was_used(vp->render_target)) {
 			visible = true;
 		}
 
@@ -641,11 +642,11 @@ void RendererViewport::draw_viewports() {
 
 		RENDER_TIMESTAMP("> Render Viewport " + itos(i));
 
-		RSG::storage->render_target_set_as_unused(vp->render_target);
+		RSG::texture_storage->render_target_set_as_unused(vp->render_target);
 		if (vp->use_xr && xr_interface.is_valid()) {
 			// check for an external texture destination (disabled for now, not yet supported)
-			// RSG::storage->render_target_set_external_texture(vp->render_target, xr_interface->get_external_texture_for_eye(leftOrMono));
-			RSG::storage->render_target_set_external_texture(vp->render_target, 0);
+			// RSG::texture_storage->render_target_set_external_texture(vp->render_target, xr_interface->get_external_texture_for_eye(leftOrMono));
+			RSG::texture_storage->render_target_set_external_texture(vp->render_target, 0);
 
 			// render...
 			RSG::scene->set_debug_draw_mode(vp->debug_draw);
@@ -667,7 +668,7 @@ void RendererViewport::draw_viewports() {
 				}
 			}
 		} else {
-			RSG::storage->render_target_set_external_texture(vp->render_target, 0);
+			RSG::texture_storage->render_target_set_external_texture(vp->render_target, 0);
 
 			RSG::scene->set_debug_draw_mode(vp->debug_draw);
 
@@ -726,7 +727,7 @@ void RendererViewport::viewport_initialize(RID p_rid) {
 	viewport_owner.initialize_rid(p_rid);
 	Viewport *viewport = viewport_owner.get_or_null(p_rid);
 	viewport->self = p_rid;
-	viewport->render_target = RSG::storage->render_target_create();
+	viewport->render_target = RSG::texture_storage->render_target_create();
 	viewport->shadow_atlas = RSG::scene->shadow_atlas_create();
 	viewport->viewport_render_direct_to_screen = false;
 
@@ -808,7 +809,7 @@ void RendererViewport::viewport_set_size(RID p_viewport, int p_width, int p_heig
 	viewport->size = Size2(p_width, p_height);
 
 	uint32_t view_count = viewport->get_view_count();
-	RSG::storage->render_target_set_size(viewport->render_target, p_width, p_height, view_count);
+	RSG::texture_storage->render_target_set_size(viewport->render_target, p_width, p_height, view_count);
 	_configure_3d_render_buffers(viewport);
 
 	viewport->occlusion_buffer_dirty = true;
@@ -849,8 +850,8 @@ void RendererViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_
 		// If using OpenGL we can optimize this operation by rendering directly to system_fbo
 		// instead of rendering to fbo and copying to system_fbo after
 		if (RSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) {
-			RSG::storage->render_target_set_size(viewport->render_target, p_rect.size.x, p_rect.size.y, viewport->get_view_count());
-			RSG::storage->render_target_set_position(viewport->render_target, p_rect.position.x, p_rect.position.y);
+			RSG::texture_storage->render_target_set_size(viewport->render_target, p_rect.size.x, p_rect.size.y, viewport->get_view_count());
+			RSG::texture_storage->render_target_set_position(viewport->render_target, p_rect.position.x, p_rect.position.y);
 		}
 
 		viewport->viewport_to_screen_rect = p_rect;
@@ -858,8 +859,8 @@ void RendererViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_
 	} else {
 		// if render_direct_to_screen was used, reset size and position
 		if (RSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) {
-			RSG::storage->render_target_set_position(viewport->render_target, 0, 0);
-			RSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y, viewport->get_view_count());
+			RSG::texture_storage->render_target_set_position(viewport->render_target, 0, 0);
+			RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y, viewport->get_view_count());
 		}
 
 		viewport->viewport_to_screen_rect = Rect2();
@@ -877,17 +878,17 @@ void RendererViewport::viewport_set_render_direct_to_screen(RID p_viewport, bool
 
 	// if disabled, reset render_target size and position
 	if (!p_enable) {
-		RSG::storage->render_target_set_position(viewport->render_target, 0, 0);
-		RSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y, viewport->get_view_count());
+		RSG::texture_storage->render_target_set_position(viewport->render_target, 0, 0);
+		RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y, viewport->get_view_count());
 	}
 
-	RSG::storage->render_target_set_flag(viewport->render_target, RendererStorage::RENDER_TARGET_DIRECT_TO_SCREEN, p_enable);
+	RSG::texture_storage->render_target_set_flag(viewport->render_target, RendererTextureStorage::RENDER_TARGET_DIRECT_TO_SCREEN, p_enable);
 	viewport->viewport_render_direct_to_screen = p_enable;
 
 	// if attached to screen already, setup screen size and position, this needs to happen after setting flag to avoid an unnecessary buffer allocation
 	if (RSG::rasterizer->is_low_end() && viewport->viewport_to_screen_rect != Rect2() && p_enable) {
-		RSG::storage->render_target_set_size(viewport->render_target, viewport->viewport_to_screen_rect.size.x, viewport->viewport_to_screen_rect.size.y, viewport->get_view_count());
-		RSG::storage->render_target_set_position(viewport->render_target, viewport->viewport_to_screen_rect.position.x, viewport->viewport_to_screen_rect.position.y);
+		RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->viewport_to_screen_rect.size.x, viewport->viewport_to_screen_rect.size.y, viewport->get_view_count());
+		RSG::texture_storage->render_target_set_position(viewport->render_target, viewport->viewport_to_screen_rect.position.x, viewport->viewport_to_screen_rect.position.y);
 	}
 }
 
@@ -902,7 +903,7 @@ RID RendererViewport::viewport_get_texture(RID p_viewport) const {
 	const Viewport *viewport = viewport_owner.get_or_null(p_viewport);
 	ERR_FAIL_COND_V(!viewport, RID());
 
-	return RSG::storage->render_target_get_texture(viewport->render_target);
+	return RSG::texture_storage->render_target_get_texture(viewport->render_target);
 }
 
 RID RendererViewport::viewport_get_occluder_debug_texture(RID p_viewport) const {
@@ -995,7 +996,7 @@ void RendererViewport::viewport_set_transparent_background(RID p_viewport, bool
 	Viewport *viewport = viewport_owner.get_or_null(p_viewport);
 	ERR_FAIL_COND(!viewport);
 
-	RSG::storage->render_target_set_flag(viewport->render_target, RendererStorage::RENDER_TARGET_TRANSPARENT, p_enabled);
+	RSG::texture_storage->render_target_set_flag(viewport->render_target, RendererTextureStorage::RENDER_TARGET_TRANSPARENT, p_enabled);
 	viewport->transparent_bg = p_enabled;
 }
 
@@ -1178,14 +1179,14 @@ void RendererViewport::viewport_set_sdf_oversize_and_scale(RID p_viewport, RS::V
 	Viewport *viewport = viewport_owner.get_or_null(p_viewport);
 	ERR_FAIL_COND(!viewport);
 
-	RSG::storage->render_target_set_sdf_size_and_scale(viewport->render_target, p_size, p_scale);
+	RSG::texture_storage->render_target_set_sdf_size_and_scale(viewport->render_target, p_size, p_scale);
 }
 
 bool RendererViewport::free(RID p_rid) {
 	if (viewport_owner.owns(p_rid)) {
 		Viewport *viewport = viewport_owner.get_or_null(p_rid);
 
-		RSG::storage->free(viewport->render_target);
+		RSG::texture_storage->render_target_free(viewport->render_target);
 		RSG::scene->free(viewport->shadow_atlas);
 		if (viewport->render_buffers.is_valid()) {
 			RSG::scene->free(viewport->render_buffers);

+ 0 - 2
servers/rendering/rendering_server_default.cpp

@@ -398,8 +398,6 @@ RenderingServerDefault::RenderingServerDefault(bool p_create_thread) :
 	RendererSceneCull *sr = memnew(RendererSceneCull);
 	RSG::scene = sr;
 	RSG::rasterizer = RendererCompositor::create();
-	RSG::canvas_texture_storage = RSG::rasterizer->get_canvas_texture_storage();
-	RSG::decal_atlas_storage = RSG::rasterizer->get_decal_atlas_storage();
 	RSG::material_storage = RSG::rasterizer->get_material_storage();
 	RSG::mesh_storage = RSG::rasterizer->get_mesh_storage();
 	RSG::texture_storage = RSG::rasterizer->get_texture_storage();

+ 2 - 2
servers/rendering/rendering_server_default.h

@@ -399,8 +399,8 @@ public:
 #undef ServerName
 #undef server_name
 
-#define ServerName RendererDecalAtlasStorage
-#define server_name RSG::decal_atlas_storage
+#define ServerName RendererTextureStorage
+#define server_name RSG::texture_storage
 
 	FUNCRIDSPLIT(decal)
 

+ 0 - 2
servers/rendering/rendering_server_globals.cpp

@@ -32,8 +32,6 @@
 
 bool RenderingServerGlobals::threaded = false;
 
-RendererCanvasTextureStorage *RenderingServerGlobals::canvas_texture_storage = nullptr;
-RendererDecalAtlasStorage *RenderingServerGlobals::decal_atlas_storage = nullptr;
 RendererMaterialStorage *RenderingServerGlobals::material_storage = nullptr;
 RendererMeshStorage *RenderingServerGlobals::mesh_storage = nullptr;
 RendererTextureStorage *RenderingServerGlobals::texture_storage = nullptr;

+ 0 - 4
servers/rendering/rendering_server_globals.h

@@ -34,8 +34,6 @@
 #include "servers/rendering/renderer_canvas_cull.h"
 #include "servers/rendering/renderer_canvas_render.h"
 #include "servers/rendering/renderer_scene.h"
-#include "servers/rendering/storage/canvas_texture_storage.h"
-#include "servers/rendering/storage/decal_atlas_storage.h"
 #include "servers/rendering/storage/material_storage.h"
 #include "servers/rendering/storage/mesh_storage.h"
 #include "servers/rendering/storage/texture_storage.h"
@@ -48,11 +46,9 @@ class RenderingServerGlobals {
 public:
 	static bool threaded;
 
-	static RendererCanvasTextureStorage *canvas_texture_storage;
 	static RendererMaterialStorage *material_storage;
 	static RendererMeshStorage *mesh_storage;
 	static RendererTextureStorage *texture_storage;
-	static RendererDecalAtlasStorage *decal_atlas_storage;
 	static RendererStorage *storage;
 	static RendererCanvasRender *canvas_render;
 	static RendererCompositor *rasterizer;

+ 0 - 51
servers/rendering/storage/canvas_texture_storage.h

@@ -1,51 +0,0 @@
-/*************************************************************************/
-/*  canvas_texture_storage.h                                             */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#ifndef CANVAS_TEXTURE_STORAGE_H
-#define CANVAS_TEXTURE_STORAGE_H
-
-#include "servers/rendering_server.h"
-
-class RendererCanvasTextureStorage {
-public:
-	virtual ~RendererCanvasTextureStorage(){};
-
-	virtual RID canvas_texture_allocate() = 0;
-	virtual void canvas_texture_initialize(RID p_rid) = 0;
-	virtual void canvas_texture_free(RID p_rid) = 0;
-
-	virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) = 0;
-	virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) = 0;
-
-	virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) = 0;
-	virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) = 0;
-};
-
-#endif // !CANVAS_TEXTURE_STORAGE_H

+ 0 - 60
servers/rendering/storage/decal_atlas_storage.h

@@ -1,60 +0,0 @@
-/*************************************************************************/
-/*  decal_atlas_storage.h                                                */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#ifndef DECAL_ATLAS_STORAGE_H
-#define DECAL_ATLAS_STORAGE_H
-
-#include "servers/rendering_server.h"
-
-class RendererDecalAtlasStorage {
-public:
-	virtual ~RendererDecalAtlasStorage(){};
-
-	virtual RID decal_allocate() = 0;
-	virtual void decal_initialize(RID p_rid) = 0;
-	virtual void decal_free(RID p_rid) = 0;
-
-	virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 0;
-	virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) = 0;
-	virtual void decal_set_emission_energy(RID p_decal, float p_energy) = 0;
-	virtual void decal_set_albedo_mix(RID p_decal, float p_mix) = 0;
-	virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) = 0;
-	virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) = 0;
-	virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) = 0;
-	virtual void decal_set_fade(RID p_decal, float p_above, float p_below) = 0;
-	virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0;
-
-	virtual AABB decal_get_aabb(RID p_decal) const = 0;
-
-	virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
-	virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
-};
-
-#endif // !DECAL_ATLAS_STORAGE_H

+ 62 - 0
servers/rendering/storage/texture_storage.h

@@ -35,6 +35,19 @@
 
 class RendererTextureStorage {
 public:
+	/* Canvas Texture API */
+
+	virtual RID canvas_texture_allocate() = 0;
+	virtual void canvas_texture_initialize(RID p_rid) = 0;
+	virtual void canvas_texture_free(RID p_rid) = 0;
+
+	virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) = 0;
+	virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) = 0;
+
+	virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) = 0;
+	virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) = 0;
+
+	/* Texture API */
 	virtual bool can_create_resources_async() const = 0;
 
 	virtual ~RendererTextureStorage(){};
@@ -75,6 +88,55 @@ public:
 	virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0;
 
 	virtual Size2 texture_size_with_proxy(RID p_proxy) = 0;
+
+	/* Decal API */
+	virtual RID decal_allocate() = 0;
+	virtual void decal_initialize(RID p_rid) = 0;
+	virtual void decal_free(RID p_rid) = 0;
+
+	virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 0;
+	virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) = 0;
+	virtual void decal_set_emission_energy(RID p_decal, float p_energy) = 0;
+	virtual void decal_set_albedo_mix(RID p_decal, float p_mix) = 0;
+	virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) = 0;
+	virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) = 0;
+	virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) = 0;
+	virtual void decal_set_fade(RID p_decal, float p_above, float p_below) = 0;
+	virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0;
+
+	virtual AABB decal_get_aabb(RID p_decal) const = 0;
+
+	virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
+	virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
+
+	/* RENDER TARGET */
+
+	enum RenderTargetFlags {
+		RENDER_TARGET_TRANSPARENT,
+		RENDER_TARGET_DIRECT_TO_SCREEN,
+		RENDER_TARGET_FLAG_MAX
+	};
+
+	virtual RID render_target_create() = 0;
+	virtual void render_target_free(RID p_rid) = 0;
+
+	virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) = 0;
+	virtual void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) = 0;
+	virtual RID render_target_get_texture(RID p_render_target) = 0;
+	virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) = 0;
+	virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) = 0;
+	virtual bool render_target_was_used(RID p_render_target) = 0;
+	virtual void render_target_set_as_unused(RID p_render_target) = 0;
+
+	virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color) = 0;
+	virtual bool render_target_is_clear_requested(RID p_render_target) = 0;
+	virtual Color render_target_get_clear_request_color(RID p_render_target) = 0;
+	virtual void render_target_disable_clear_request(RID p_render_target) = 0;
+	virtual void render_target_do_clear_request(RID p_render_target) = 0;
+
+	virtual void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) = 0;
+	virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const = 0;
+	virtual void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) = 0;
 };
 
 #endif // !TEXTURE_STORAGE_H

+ 4 - 3
servers/xr/xr_interface_extension.cpp

@@ -30,6 +30,7 @@
 
 #include "xr_interface_extension.h"
 #include "servers/rendering/renderer_rd/renderer_storage_rd.h"
+#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
 #include "servers/rendering/renderer_storage.h"
 #include "servers/rendering/rendering_server_globals.h"
 
@@ -339,10 +340,10 @@ void XRInterfaceExtension::notification(int p_what) {
 RID XRInterfaceExtension::get_render_target_texture(RID p_render_target) {
 	// In due time this will need to be enhance to return the correct INTERNAL RID for the chosen rendering engine.
 	// So once a GLES driver is implemented we'll return that and the implemented plugin needs to handle this correctly too.
-	RendererStorageRD *rd_storage = RendererStorageRD::base_singleton;
-	ERR_FAIL_NULL_V_MSG(rd_storage, RID(), "Renderer storage not setup");
+	RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
+	ERR_FAIL_NULL_V_MSG(texture_storage, RID(), "Texture storage not setup");
 
-	return rd_storage->render_target_get_rd_texture(p_render_target);
+	return texture_storage->render_target_get_rd_texture(p_render_target);
 }
 
 /*