From bf326793ba564f02af8f8836431818eb68b5eeb2 Mon Sep 17 00:00:00 2001
From: DDarby-Lewis <37579938+DDarby-Lewis@users.noreply.github.com>
Date: Mon, 23 Feb 2026 21:50:18 +0000
Subject: [PATCH] Editor additions for MipMaps and rd_textures
---
doc/classes/DrawableTexture2D.xml | 34 +++++++
doc/classes/ImageTexture.xml | 6 --
doc/classes/PortableCompressedTexture2D.xml | 6 --
doc/classes/Texture2D.xml | 42 +++++++++
.../scene/texture/texture_editor_plugin.cpp | 90 ++++++++++++++-----
editor/scene/texture/texture_editor_plugin.h | 6 +-
.../4.6-stable/GH-109004.txt | 6 ++
scene/resources/compressed_texture.h | 2 +-
scene/resources/drawable_texture_2d.cpp | 25 +++++-
scene/resources/drawable_texture_2d.h | 5 +-
scene/resources/image_texture.cpp | 1 -
scene/resources/image_texture.h | 2 +-
.../resources/portable_compressed_texture.cpp | 1 -
scene/resources/portable_compressed_texture.h | 2 +-
scene/resources/texture.cpp | 31 +++++++
scene/resources/texture.h | 9 +-
.../storage_rd/texture_storage.cpp | 14 ++-
servers/rendering/rendering_device.cpp | 8 ++
servers/rendering/rendering_device.h | 1 +
19 files changed, 244 insertions(+), 47 deletions(-)
create mode 100644 misc/extension_api_validation/4.6-stable/GH-109004.txt
diff --git a/doc/classes/DrawableTexture2D.xml b/doc/classes/DrawableTexture2D.xml
index 638410a995..c07a294c9d 100644
--- a/doc/classes/DrawableTexture2D.xml
+++ b/doc/classes/DrawableTexture2D.xml
@@ -38,6 +38,40 @@
Re-calculates the mipmaps for this texture on demand.
+
+
+
+ Returns [code]true[/code] if mipmaps are set to be used on this DrawableTexture.
+
+
+
+
+
+
+ Sets the format of this DrawableTexture.
+
+
+
+
+
+
+ Sets the height of this DrawableTexture.
+
+
+
+
+
+
+ Sets if mipmaps should be used on this DrawableTexture.
+
+
+
+
+
+
+ Sets the width of this DrawableTexture.
+
+
diff --git a/doc/classes/ImageTexture.xml b/doc/classes/ImageTexture.xml
index e1ab84584b..9d55049497 100644
--- a/doc/classes/ImageTexture.xml
+++ b/doc/classes/ImageTexture.xml
@@ -36,12 +36,6 @@
Creates a new [ImageTexture] and initializes it by allocating and setting the data from an [Image].
-
-
-
- Returns the format of the texture.
-
-
diff --git a/doc/classes/PortableCompressedTexture2D.xml b/doc/classes/PortableCompressedTexture2D.xml
index 37445bf4d9..db768ad520 100644
--- a/doc/classes/PortableCompressedTexture2D.xml
+++ b/doc/classes/PortableCompressedTexture2D.xml
@@ -31,12 +31,6 @@
Return the compression mode used (valid after initialized).
-
-
-
- Return the image format used (valid after initialized).
-
-
diff --git a/doc/classes/Texture2D.xml b/doc/classes/Texture2D.xml
index d8b32f2c1b..fe604939f9 100644
--- a/doc/classes/Texture2D.xml
+++ b/doc/classes/Texture2D.xml
@@ -48,12 +48,30 @@
[b]Note:[/b] This is only used in 2D rendering, not 3D.
+
+
+
+ Called when [method get_format] is called.
+
+
Called when the [Texture2D]'s height is queried.
+
+
+
+ Called when [method get_image] is called.
+
+
+
+
+
+ Called when [method get_mipmap_count] is called.
+
+
@@ -66,6 +84,12 @@
Called when the presence of an alpha channel in the [Texture2D] is queried.
+
+
+
+ Called when [method has_mipmaps] is called.
+
+
@@ -113,6 +137,12 @@
Draws a part of the texture using a [CanvasItem] with the [RenderingServer] API.
+
+
+
+ Returns the image format of the texture.
+
+
@@ -127,6 +157,12 @@
[b]Note:[/b] This will fetch the texture data from the GPU, which might cause performance problems when overused. Avoid calling [method get_image] every frame, especially on large textures.
+
+
+
+ Returns the number of mipmaps of the texture.
+
+
@@ -145,5 +181,11 @@
Returns [code]true[/code] if this [Texture2D] has an alpha channel.
+
+
+
+ Returns [code]true[/code] if the texture has mipmaps.
+
+
diff --git a/editor/scene/texture/texture_editor_plugin.cpp b/editor/scene/texture/texture_editor_plugin.cpp
index d8f96942ed..c64a4d3b84 100644
--- a/editor/scene/texture/texture_editor_plugin.cpp
+++ b/editor/scene/texture/texture_editor_plugin.cpp
@@ -36,20 +36,26 @@
#include "scene/gui/aspect_ratio_container.h"
#include "scene/gui/color_rect.h"
#include "scene/gui/label.h"
+#include "scene/gui/spin_box.h"
#include "scene/gui/texture_rect.h"
#include "scene/resources/animated_texture.h"
#include "scene/resources/atlas_texture.h"
#include "scene/resources/compressed_texture.h"
#include "scene/resources/dpi_texture.h"
+#include "scene/resources/gradient_texture.h"
#include "scene/resources/image_texture.h"
#include "scene/resources/material.h"
#include "scene/resources/portable_compressed_texture.h"
+#include "scene/resources/style_box_flat.h"
+#include "scene/resources/texture_rd.h"
+#include "servers/rendering/rendering_device.h"
constexpr const char *texture_2d_shader_code = R"(
shader_type canvas_item;
render_mode blend_mix;
instance uniform vec4 u_channel_factors = vec4(1.0);
+instance uniform float lod = 0.0;
vec4 filter_preview_colors(vec4 input_color, vec4 factors) {
// Filter RGB.
@@ -70,7 +76,7 @@ vec4 filter_preview_colors(vec4 input_color, vec4 factors) {
}
void fragment() {
- COLOR = filter_preview_colors(texture(TEXTURE, UV), u_channel_factors);
+ COLOR = filter_preview_colors(textureLod(TEXTURE, UV, lod), u_channel_factors);
}
)";
@@ -128,25 +134,12 @@ void TexturePreview::_update_texture_display_ratio() {
}
static Image::Format get_texture_2d_format(const Ref &p_texture) {
- const Ref image_texture = p_texture;
- if (image_texture.is_valid()) {
- return image_texture->get_format();
+ const Ref rd_texture = p_texture;
+ if (rd_texture.is_valid() && RD::get_singleton() && RD::get_singleton()->texture_is_valid(rd_texture->get_texture_rd_rid())) {
+ return rd_texture->get_image()->get_format();
}
- const Ref compressed_texture = p_texture;
- if (compressed_texture.is_valid()) {
- return compressed_texture->get_format();
- }
-
- const Ref portable_compressed_texture = p_texture;
- if (portable_compressed_texture.is_valid()) {
- return portable_compressed_texture->get_format();
- }
-
- // AtlasTexture?
-
- // Unknown
- return Image::FORMAT_MAX;
+ return p_texture->get_format();
}
static int get_texture_mipmaps_count(const Ref &p_texture) {
@@ -155,6 +148,8 @@ static int get_texture_mipmaps_count(const Ref &p_texture) {
// We are having to download the image only to get its mipmaps count. It would be nice if we didn't have to.
Ref image;
Ref at = p_texture;
+ Ref rd_texture = p_texture;
+
if (at.is_valid()) {
// The AtlasTexture tries to obtain the region from the atlas as an image,
// which will fail if it is a compressed format.
@@ -162,6 +157,11 @@ static int get_texture_mipmaps_count(const Ref &p_texture) {
if (atlas.is_valid()) {
image = atlas->get_image();
}
+ } else if (rd_texture.is_valid()) {
+ if (RD::get_singleton() && RD::get_singleton()->texture_is_valid(rd_texture->get_texture_rd_rid())) {
+ return -1;
+ }
+ image = p_texture->get_image();
} else {
image = p_texture->get_image();
}
@@ -176,12 +176,21 @@ void TexturePreview::_update_metadata_label_text() {
const Ref texture = texture_display->get_texture();
ERR_FAIL_COND(texture.is_null());
- const Image::Format format = get_texture_2d_format(texture.ptr());
+ Image::Format format;
+ int mipmaps;
+
+ Ref image = texture->get_image();
+ if (image.is_valid()) {
+ format = image->get_format();
+ mipmaps = image->get_mipmap_count();
+ } else {
+ format = get_texture_2d_format(texture.ptr());
+ mipmaps = get_texture_mipmaps_count(texture);
+ }
const String format_name = format != Image::FORMAT_MAX ? Image::get_format_name(format) : texture->get_class();
const Vector2i resolution = texture->get_size();
- const int mipmaps = get_texture_mipmaps_count(texture);
if (format != Image::FORMAT_MAX) {
// Avoid signed integer overflow that could occur with huge texture sizes by casting everything to uint64_t.
@@ -230,6 +239,10 @@ void TexturePreview::on_selected_channels_changed() {
texture_display->set_instance_shader_parameter("u_channel_factors", channel_selector->get_selected_channel_factors());
}
+void TexturePreview::on_selected_mipmap_changed(double p_value) {
+ texture_display->set_instance_shader_parameter("lod", mipmap_spinbox->get_value());
+}
+
TexturePreview::TexturePreview(Ref p_texture, bool p_show_metadata) {
set_custom_minimum_size(Size2(0.0, 256.0) * EDSCALE);
@@ -277,6 +290,21 @@ TexturePreview::TexturePreview(Ref p_texture, bool p_show_metadata) {
const Image::Format format = p_texture.is_valid() ? get_texture_2d_format(p_texture.ptr()) : Image::FORMAT_MAX;
const uint32_t components_mask = format != Image::FORMAT_MAX ? Image::get_format_component_mask(format) : 0xf;
+ // Setup Mipmap selector.
+ const int mipmaps = get_texture_mipmaps_count(p_texture);
+ if (mipmaps > 0) {
+ mipmap_spinbox = memnew(SpinBox);
+ mipmap_spinbox->set_tooltip_text(TTRC("Mipmap level index selector."));
+ mipmap_spinbox->set_max(mipmaps);
+ mipmap_spinbox->set_modulate(Color(1, 1, 1, 0.8));
+ mipmap_spinbox->set_h_grow_direction(GROW_DIRECTION_BEGIN);
+ mipmap_spinbox->set_h_size_flags(Control::SIZE_SHRINK_END);
+ mipmap_spinbox->set_v_size_flags(Control::SIZE_SHRINK_BEGIN);
+ mipmap_spinbox->set_anchors_preset(Control::PRESET_TOP_RIGHT);
+ mipmap_spinbox->connect(SceneStringName(value_changed), callable_mp(this, &TexturePreview::on_selected_mipmap_changed));
+ add_child(mipmap_spinbox);
+ }
+
// Add color channel selector at the bottom left if more than 1 channel is available.
if (p_show_metadata && !Math::is_power_of_2(components_mask)) {
channel_selector = memnew(ColorChannelSelector);
@@ -312,7 +340,27 @@ TexturePreview::TexturePreview(Ref p_texture, bool p_show_metadata) {
}
bool EditorInspectorPluginTexture::can_handle(Object *p_object) {
- return Object::cast_to(p_object) != nullptr || Object::cast_to(p_object) != nullptr || Object::cast_to(p_object) != nullptr || Object::cast_to(p_object) != nullptr || Object::cast_to(p_object) != nullptr || Object::cast_to(p_object) != nullptr || Object::cast_to(p_object) != nullptr;
+ if (Object::cast_to(p_object) || Object::cast_to(p_object)) {
+ return false;
+ }
+
+ if (Object::cast_to(p_object) != nullptr ||
+ Object::cast_to(p_object) != nullptr ||
+ Object::cast_to(p_object) != nullptr ||
+ Object::cast_to(p_object) != nullptr ||
+ Object::cast_to(p_object) != nullptr ||
+ Object::cast_to(p_object) != nullptr ||
+ Object::cast_to(p_object) != nullptr ||
+ Object::cast_to(p_object) != nullptr) {
+ return true;
+ }
+
+ Ref texture_2d(Object::cast_to(p_object));
+ if (texture_2d.is_valid()) {
+ this_image = texture_2d->get_image();
+ return this_image.is_valid();
+ }
+ return false;
}
void EditorInspectorPluginTexture::parse_begin(Object *p_object) {
diff --git a/editor/scene/texture/texture_editor_plugin.h b/editor/scene/texture/texture_editor_plugin.h
index d66aa46a70..c9f0cdc48d 100644
--- a/editor/scene/texture/texture_editor_plugin.h
+++ b/editor/scene/texture/texture_editor_plugin.h
@@ -40,6 +40,7 @@ class ColorRect;
class TextureRect;
class ShaderMaterial;
class ColorChannelSelector;
+class SpinBox;
class TexturePreview : public MarginContainer {
GDCLASS(TexturePreview, MarginContainer);
@@ -61,6 +62,7 @@ private:
static inline Ref texture_material;
ColorChannelSelector *channel_selector = nullptr;
+ SpinBox *mipmap_spinbox = nullptr;
void _draw_outline();
void _update_metadata_label_text();
@@ -68,8 +70,8 @@ private:
protected:
void _notification(int p_what);
void _update_texture_display_ratio();
-
void on_selected_channels_changed();
+ void on_selected_mipmap_changed(double p_value);
public:
static void init_shaders();
@@ -82,6 +84,8 @@ public:
class EditorInspectorPluginTexture : public EditorInspectorPlugin {
GDCLASS(EditorInspectorPluginTexture, EditorInspectorPlugin);
+ Ref this_image;
+
public:
virtual bool can_handle(Object *p_object) override;
virtual void parse_begin(Object *p_object) override;
diff --git a/misc/extension_api_validation/4.6-stable/GH-109004.txt b/misc/extension_api_validation/4.6-stable/GH-109004.txt
new file mode 100644
index 0000000000..ef6853d08d
--- /dev/null
+++ b/misc/extension_api_validation/4.6-stable/GH-109004.txt
@@ -0,0 +1,6 @@
+GH-109004
+---------
+Validate extension JSON: API was removed: classes/ImageTexture/methods/get_format
+Validate extension JSON: API was removed: classes/PortableCompressedTexture2D/methods/get_format
+
+The above are now members of the base class Texture2D.
diff --git a/scene/resources/compressed_texture.h b/scene/resources/compressed_texture.h
index 3282096835..35f3677dcb 100644
--- a/scene/resources/compressed_texture.h
+++ b/scene/resources/compressed_texture.h
@@ -88,7 +88,7 @@ public:
static TextureFormatRoughnessRequestCallback request_roughness_callback;
static TextureFormatRequestCallback request_normal_callback;
- Image::Format get_format() const;
+ virtual Image::Format get_format() const override;
Error load(const String &p_path);
String get_load_path() const;
diff --git a/scene/resources/drawable_texture_2d.cpp b/scene/resources/drawable_texture_2d.cpp
index 64dc034d84..28fd3166e4 100644
--- a/scene/resources/drawable_texture_2d.cpp
+++ b/scene/resources/drawable_texture_2d.cpp
@@ -96,7 +96,7 @@ int DrawableTexture2D::get_height() const {
return height;
}
-void DrawableTexture2D::set_format(DrawableFormat p_format) {
+void DrawableTexture2D::set_drawable_format(DrawableFormat p_format) {
if (format == p_format) {
return;
}
@@ -105,10 +105,25 @@ void DrawableTexture2D::set_format(DrawableFormat p_format) {
emit_changed();
}
-DrawableTexture2D::DrawableFormat DrawableTexture2D::get_format() const {
+DrawableTexture2D::DrawableFormat DrawableTexture2D::get_drawable_format() const {
return format;
}
+Image::Format DrawableTexture2D::get_format() const {
+ switch (format) {
+ case DRAWABLE_FORMAT_RGBA8:
+ return Image::FORMAT_RGBA8;
+ case DRAWABLE_FORMAT_RGBA8_SRGB:
+ return Image::FORMAT_RGBA8;
+ case DRAWABLE_FORMAT_RGBAH:
+ return Image::FORMAT_RGBAH;
+ case DRAWABLE_FORMAT_RGBAF:
+ return Image::FORMAT_RGBAF;
+ default:
+ return Image::FORMAT_RGBA8;
+ }
+}
+
void DrawableTexture2D::set_use_mipmaps(bool p_mipmaps) {
if (mipmaps == p_mipmaps) {
return;
@@ -232,6 +247,12 @@ void DrawableTexture2D::generate_mipmaps() {
}
void DrawableTexture2D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_width", "width"), &DrawableTexture2D::set_width);
+ ClassDB::bind_method(D_METHOD("set_height", "height"), &DrawableTexture2D::set_height);
+ ClassDB::bind_method(D_METHOD("set_format", "format"), &DrawableTexture2D::set_drawable_format);
+ ClassDB::bind_method(D_METHOD("set_use_mipmaps", "mipmaps"), &DrawableTexture2D::set_use_mipmaps);
+ ClassDB::bind_method(D_METHOD("get_use_mipmaps"), &DrawableTexture2D::get_use_mipmaps);
+
ClassDB::bind_method(D_METHOD("setup", "width", "height", "format", "color", "use_mipmaps"), &DrawableTexture2D::setup, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(false));
ClassDB::bind_method(D_METHOD("blit_rect", "rect", "source", "modulate", "mipmap", "material"), &DrawableTexture2D::blit_rect, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(0), DEFVAL(Ref()));
ClassDB::bind_method(D_METHOD("blit_rect_multi", "rect", "sources", "extra_targets", "modulate", "mipmap", "material"), &DrawableTexture2D::blit_rect_multi, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(0), DEFVAL(Ref()));
diff --git a/scene/resources/drawable_texture_2d.h b/scene/resources/drawable_texture_2d.h
index 38616f703c..c699892075 100644
--- a/scene/resources/drawable_texture_2d.h
+++ b/scene/resources/drawable_texture_2d.h
@@ -68,11 +68,12 @@ public:
void set_height(int p_height);
int get_height() const override;
- void set_format(DrawableFormat p_format);
- DrawableFormat get_format() const;
+ void set_drawable_format(DrawableFormat p_format);
+ DrawableFormat get_drawable_format() const;
void set_use_mipmaps(bool p_mipmaps);
bool get_use_mipmaps() const;
+ virtual Image::Format get_format() const override;
virtual RID get_rid() const override;
virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const override;
diff --git a/scene/resources/image_texture.cpp b/scene/resources/image_texture.cpp
index 198c15ce16..7f38a38955 100644
--- a/scene/resources/image_texture.cpp
+++ b/scene/resources/image_texture.cpp
@@ -229,7 +229,6 @@ void ImageTexture::set_path(const String &p_path, bool p_take_over) {
void ImageTexture::_bind_methods() {
ClassDB::bind_static_method("ImageTexture", D_METHOD("create_from_image", "image"), &ImageTexture::create_from_image);
- ClassDB::bind_method(D_METHOD("get_format"), &ImageTexture::get_format);
ClassDB::bind_method(D_METHOD("set_image", "image"), &ImageTexture::set_image);
ClassDB::bind_method(D_METHOD("update", "image"), &ImageTexture::update);
diff --git a/scene/resources/image_texture.h b/scene/resources/image_texture.h
index 527d78ce8e..311f7182cf 100644
--- a/scene/resources/image_texture.h
+++ b/scene/resources/image_texture.h
@@ -55,7 +55,7 @@ public:
void set_image(const Ref &p_image);
static Ref create_from_image(const Ref &p_image);
- Image::Format get_format() const;
+ virtual Image::Format get_format() const override;
void update(const Ref &p_image);
Ref get_image() const override;
diff --git a/scene/resources/portable_compressed_texture.cpp b/scene/resources/portable_compressed_texture.cpp
index bdc27b5337..04eee9a079 100644
--- a/scene/resources/portable_compressed_texture.cpp
+++ b/scene/resources/portable_compressed_texture.cpp
@@ -369,7 +369,6 @@ void PortableCompressedTexture2D::set_basisu_compressor_params(int p_uastc_level
void PortableCompressedTexture2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_from_image", "image", "compression_mode", "normal_map", "lossy_quality"), &PortableCompressedTexture2D::create_from_image, DEFVAL(false), DEFVAL(0.8));
- ClassDB::bind_method(D_METHOD("get_format"), &PortableCompressedTexture2D::get_format);
ClassDB::bind_method(D_METHOD("get_compression_mode"), &PortableCompressedTexture2D::get_compression_mode);
ClassDB::bind_method(D_METHOD("set_size_override", "size"), &PortableCompressedTexture2D::set_size_override);
diff --git a/scene/resources/portable_compressed_texture.h b/scene/resources/portable_compressed_texture.h
index af4e192b8c..9f1d5c0871 100644
--- a/scene/resources/portable_compressed_texture.h
+++ b/scene/resources/portable_compressed_texture.h
@@ -83,7 +83,7 @@ public:
CompressionMode get_compression_mode() const;
void create_from_image(const Ref &p_image, CompressionMode p_compression_mode, bool p_normal_map = false, float p_lossy_quality = 0.8);
- Image::Format get_format() const;
+ virtual Image::Format get_format() const override;
void update(const Ref &p_image);
Ref get_image() const override;
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 0b33a1607c..10ba6a4fc1 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -34,6 +34,30 @@
#include "scene/resources/placeholder_textures.h"
#include "servers/rendering/rendering_server.h"
+Ref Texture2D::get_image() const {
+ Ref ret;
+ GDVIRTUAL_CALL(_get_image, ret);
+ return ret;
+}
+
+Image::Format Texture2D::get_format() const {
+ Image::Format ret = Image::FORMAT_MAX;
+ GDVIRTUAL_CALL(_get_format, ret);
+ return ret;
+}
+
+int Texture2D::get_mipmap_count() const {
+ int ret = 0;
+ GDVIRTUAL_CALL(_get_mipmap_count, ret);
+ return ret;
+}
+
+bool Texture2D::has_mipmaps() const {
+ bool ret = false;
+ GDVIRTUAL_CALL(_has_mipmaps, ret);
+ return ret;
+}
+
int Texture2D::get_width() const {
int ret = 0;
GDVIRTUAL_CALL(_get_width, ret);
@@ -97,10 +121,13 @@ Ref Texture2D::create_placeholder() const {
}
void Texture2D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_format"), &Texture2D::get_format);
+ ClassDB::bind_method(D_METHOD("get_mipmap_count"), &Texture2D::get_mipmap_count);
ClassDB::bind_method(D_METHOD("get_width"), &Texture2D::get_width);
ClassDB::bind_method(D_METHOD("get_height"), &Texture2D::get_height);
ClassDB::bind_method(D_METHOD("get_size"), &Texture2D::get_size);
ClassDB::bind_method(D_METHOD("has_alpha"), &Texture2D::has_alpha);
+ ClassDB::bind_method(D_METHOD("has_mipmaps"), &Texture2D::has_mipmaps);
ClassDB::bind_method(D_METHOD("draw", "canvas_item", "position", "modulate", "transpose"), &Texture2D::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(false));
ClassDB::bind_method(D_METHOD("draw_rect", "canvas_item", "rect", "tile", "modulate", "transpose"), &Texture2D::draw_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false));
ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose", "clip_uv"), &Texture2D::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(true));
@@ -109,10 +136,14 @@ void Texture2D::_bind_methods() {
ADD_GROUP("", "");
+ GDVIRTUAL_BIND(_get_image);
+ GDVIRTUAL_BIND(_get_format);
+ GDVIRTUAL_BIND(_get_mipmap_count);
GDVIRTUAL_BIND(_get_width);
GDVIRTUAL_BIND(_get_height);
GDVIRTUAL_BIND(_is_pixel_opaque, "x", "y");
GDVIRTUAL_BIND(_has_alpha);
+ GDVIRTUAL_BIND(_has_mipmaps);
GDVIRTUAL_BIND(_draw, "to_canvas_item", "pos", "modulate", "transpose")
GDVIRTUAL_BIND(_draw_rect, "to_canvas_item", "rect", "tile", "modulate", "transpose")
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index c648cd3ca4..f4bcea90cb 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -45,6 +45,10 @@ class Texture2D : public Texture {
protected:
static void _bind_methods();
+ GDVIRTUAL0RC(Image::Format, _get_format)
+ GDVIRTUAL0RC(Ref, _get_image)
+ GDVIRTUAL0RC(int, _get_mipmap_count)
+ GDVIRTUAL0RC(bool, _has_mipmaps)
GDVIRTUAL0RC_REQUIRED(int, _get_width)
GDVIRTUAL0RC_REQUIRED(int, _get_height)
GDVIRTUAL2RC(bool, _is_pixel_opaque, int, int)
@@ -55,6 +59,8 @@ protected:
GDVIRTUAL6C(_draw_rect_region, RID, Rect2, Rect2, Color, bool, bool)
public:
+ virtual Image::Format get_format() const;
+ virtual int get_mipmap_count() const;
virtual int get_width() const;
virtual int get_height() const;
virtual Size2 get_size() const;
@@ -62,6 +68,7 @@ public:
virtual bool is_pixel_opaque(int p_x, int p_y) const;
virtual bool has_alpha() const;
+ virtual bool has_mipmaps() const;
virtual RID get_scaled_rid() const { return get_rid(); }
virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
@@ -69,7 +76,7 @@ public:
virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, bool p_clip_uv = true) const;
virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const;
- virtual Ref get_image() const { return Ref(); }
+ virtual Ref get_image() const;
virtual Ref create_placeholder() const;
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
index f53426419b..e0c9e88921 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
@@ -2154,14 +2154,22 @@ void TextureStorage::texture_rd_initialize(RID p_texture, const RID &p_rd_textur
rd_view.swizzle_a = imfmt.swizzle_a;
texture.rd_type = tf.texture_type;
- texture.rd_view = rd_view;
texture.rd_format = imfmt.rd_format;
+ texture.rd_format_srgb = imfmt.rd_format_srgb;
+ texture.rd_view = rd_view;
+
+ if (imfmt.rd_format_srgb != RD::DATA_FORMAT_MAX) {
+ // Allow creating a shared sRGB texture even if users didn't explicitly add them.
+ RD::get_singleton()->_texture_ensure_shareable_format(p_rd_texture, texture.rd_format);
+ RD::get_singleton()->_texture_ensure_shareable_format(p_rd_texture, texture.rd_format_srgb);
+ }
+
// We create a shared texture here even if our view matches, so we don't obtain ownership.
texture.rd_texture = RD::get_singleton()->texture_create_shared(rd_view, p_rd_texture);
if (imfmt.rd_format_srgb != RD::DATA_FORMAT_MAX) {
- rd_view.format_override = imfmt.rd_format_srgb == tf.format ? RD::DATA_FORMAT_MAX : imfmt.rd_format;
+ // The texture supports sRGB override, create it for 3D usage.
+ rd_view.format_override = imfmt.rd_format_srgb == tf.format ? RD::DATA_FORMAT_MAX : imfmt.rd_format_srgb;
texture.rd_format_srgb = imfmt.rd_format_srgb;
- // We create a shared texture here even if our view matches, so we don't obtain ownership.
texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, p_rd_texture);
}
diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp
index 77fff88d86..ac624fc3fe 100644
--- a/servers/rendering/rendering_device.cpp
+++ b/servers/rendering/rendering_device.cpp
@@ -2204,6 +2204,14 @@ uint32_t RenderingDevice::_texture_vrs_method_to_usage_bits() const {
}
}
+void RenderingDevice::_texture_ensure_shareable_format(RID p_texture, const DataFormat &p_shareable_format) {
+ Texture *texture = texture_owner.get_or_null(p_texture);
+ ERR_FAIL_NULL(texture);
+ if (!texture->allowed_shared_formats.has(p_shareable_format)) {
+ texture->allowed_shared_formats.push_back(p_shareable_format);
+ }
+}
+
void RenderingDevice::_texture_check_pending_clear(RID p_texture_rid, Texture *p_texture) {
DEV_ASSERT(p_texture != nullptr);
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index 39d68a9b01..9ec9803cb7 100644
--- a/servers/rendering/rendering_device.h
+++ b/servers/rendering/rendering_device.h
@@ -413,6 +413,7 @@ public:
void _texture_clear_color(RID p_texture_rid, Texture *p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers);
void _texture_clear_depth_stencil(RID p_texture_rid, Texture *p_texture, float p_depth, uint8_t p_stencil, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers);
uint32_t _texture_vrs_method_to_usage_bits() const;
+ void _texture_ensure_shareable_format(RID p_texture, const DataFormat &p_shareable_format);
struct TextureGetDataRequest {
uint32_t frame_local_index = 0;