Editor additions for MipMaps and rd_textures

This commit is contained in:
DDarby-Lewis 2026-02-23 21:50:18 +00:00 committed by Thaddeus Crews
parent f630133a01
commit bf326793ba
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC
19 changed files with 244 additions and 47 deletions

View file

@ -38,6 +38,40 @@
Re-calculates the mipmaps for this texture on demand.
</description>
</method>
<method name="get_use_mipmaps" qualifiers="const">
<return type="bool" />
<description>
Returns [code]true[/code] if mipmaps are set to be used on this DrawableTexture.
</description>
</method>
<method name="set_format">
<return type="void" />
<param index="0" name="format" type="int" enum="DrawableTexture2D.DrawableFormat" />
<description>
Sets the format of this DrawableTexture.
</description>
</method>
<method name="set_height">
<return type="void" />
<param index="0" name="height" type="int" />
<description>
Sets the height of this DrawableTexture.
</description>
</method>
<method name="set_use_mipmaps">
<return type="void" />
<param index="0" name="mipmaps" type="bool" />
<description>
Sets if mipmaps should be used on this DrawableTexture.
</description>
</method>
<method name="set_width">
<return type="void" />
<param index="0" name="width" type="int" />
<description>
Sets the width of this DrawableTexture.
</description>
</method>
<method name="setup" experimental="This function and its parameters are likely to change in the 4.7 Dev Cycle">
<return type="void" />
<param index="0" name="width" type="int" />

View file

@ -36,12 +36,6 @@
Creates a new [ImageTexture] and initializes it by allocating and setting the data from an [Image].
</description>
</method>
<method name="get_format" qualifiers="const">
<return type="int" enum="Image.Format" />
<description>
Returns the format of the texture.
</description>
</method>
<method name="set_image">
<return type="void" />
<param index="0" name="image" type="Image" />

View file

@ -31,12 +31,6 @@
Return the compression mode used (valid after initialized).
</description>
</method>
<method name="get_format" qualifiers="const">
<return type="int" enum="Image.Format" />
<description>
Return the image format used (valid after initialized).
</description>
</method>
<method name="is_keeping_all_compressed_buffers" qualifiers="static">
<return type="bool" />
<description>

View file

@ -48,12 +48,30 @@
[b]Note:[/b] This is only used in 2D rendering, not 3D.
</description>
</method>
<method name="_get_format" qualifiers="virtual const">
<return type="int" enum="Image.Format" />
<description>
Called when [method get_format] is called.
</description>
</method>
<method name="_get_height" qualifiers="virtual required const">
<return type="int" />
<description>
Called when the [Texture2D]'s height is queried.
</description>
</method>
<method name="_get_image" qualifiers="virtual const">
<return type="Image" />
<description>
Called when [method get_image] is called.
</description>
</method>
<method name="_get_mipmap_count" qualifiers="virtual const">
<return type="int" />
<description>
Called when [method get_mipmap_count] is called.
</description>
</method>
<method name="_get_width" qualifiers="virtual required const">
<return type="int" />
<description>
@ -66,6 +84,12 @@
Called when the presence of an alpha channel in the [Texture2D] is queried.
</description>
</method>
<method name="_has_mipmaps" qualifiers="virtual const">
<return type="bool" />
<description>
Called when [method has_mipmaps] is called.
</description>
</method>
<method name="_is_pixel_opaque" qualifiers="virtual const">
<return type="bool" />
<param index="0" name="x" type="int" />
@ -113,6 +137,12 @@
Draws a part of the texture using a [CanvasItem] with the [RenderingServer] API.
</description>
</method>
<method name="get_format" qualifiers="const">
<return type="int" enum="Image.Format" />
<description>
Returns the image format of the texture.
</description>
</method>
<method name="get_height" qualifiers="const">
<return type="int" />
<description>
@ -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.
</description>
</method>
<method name="get_mipmap_count" qualifiers="const">
<return type="int" />
<description>
Returns the number of mipmaps of the texture.
</description>
</method>
<method name="get_size" qualifiers="const">
<return type="Vector2" />
<description>
@ -145,5 +181,11 @@
Returns [code]true[/code] if this [Texture2D] has an alpha channel.
</description>
</method>
<method name="has_mipmaps" qualifiers="const">
<return type="bool" />
<description>
Returns [code]true[/code] if the texture has mipmaps.
</description>
</method>
</methods>
</class>

View file

@ -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<Texture2D> &p_texture) {
const Ref<ImageTexture> image_texture = p_texture;
if (image_texture.is_valid()) {
return image_texture->get_format();
const Ref<Texture2DRD> 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<CompressedTexture2D> compressed_texture = p_texture;
if (compressed_texture.is_valid()) {
return compressed_texture->get_format();
}
const Ref<PortableCompressedTexture2D> 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<Texture2D> &p_texture) {
@ -155,6 +148,8 @@ static int get_texture_mipmaps_count(const Ref<Texture2D> &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> image;
Ref<AtlasTexture> at = p_texture;
Ref<Texture2DRD> 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<Texture2D> &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<Texture2D> 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> 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<Texture2D> p_texture, bool p_show_metadata) {
set_custom_minimum_size(Size2(0.0, 256.0) * EDSCALE);
@ -277,6 +290,21 @@ TexturePreview::TexturePreview(Ref<Texture2D> 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<Texture2D> p_texture, bool p_show_metadata) {
}
bool EditorInspectorPluginTexture::can_handle(Object *p_object) {
return Object::cast_to<ImageTexture>(p_object) != nullptr || Object::cast_to<AtlasTexture>(p_object) != nullptr || Object::cast_to<CompressedTexture2D>(p_object) != nullptr || Object::cast_to<PortableCompressedTexture2D>(p_object) != nullptr || Object::cast_to<AnimatedTexture>(p_object) != nullptr || Object::cast_to<DPITexture>(p_object) != nullptr || Object::cast_to<Image>(p_object) != nullptr;
if (Object::cast_to<GradientTexture1D>(p_object) || Object::cast_to<GradientTexture2D>(p_object)) {
return false;
}
if (Object::cast_to<Image>(p_object) != nullptr ||
Object::cast_to<ImageTexture>(p_object) != nullptr ||
Object::cast_to<AtlasTexture>(p_object) != nullptr ||
Object::cast_to<CompressedTexture2D>(p_object) != nullptr ||
Object::cast_to<PortableCompressedTexture2D>(p_object) != nullptr ||
Object::cast_to<AnimatedTexture>(p_object) != nullptr ||
Object::cast_to<DPITexture>(p_object) != nullptr ||
Object::cast_to<Texture2DRD>(p_object) != nullptr) {
return true;
}
Ref<Texture2D> texture_2d(Object::cast_to<Texture2D>(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) {

View file

@ -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<ShaderMaterial> 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<Image> this_image;
public:
virtual bool can_handle(Object *p_object) override;
virtual void parse_begin(Object *p_object) override;

View file

@ -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.

View file

@ -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;

View file

@ -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<Material>()));
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<Material>()));

View file

@ -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;

View file

@ -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);

View file

@ -55,7 +55,7 @@ public:
void set_image(const Ref<Image> &p_image);
static Ref<ImageTexture> create_from_image(const Ref<Image> &p_image);
Image::Format get_format() const;
virtual Image::Format get_format() const override;
void update(const Ref<Image> &p_image);
Ref<Image> get_image() const override;

View file

@ -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);

View file

@ -83,7 +83,7 @@ public:
CompressionMode get_compression_mode() const;
void create_from_image(const Ref<Image> &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<Image> &p_image);
Ref<Image> get_image() const override;

View file

@ -34,6 +34,30 @@
#include "scene/resources/placeholder_textures.h"
#include "servers/rendering/rendering_server.h"
Ref<Image> Texture2D::get_image() const {
Ref<Image> 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<Resource> 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")

View file

@ -45,6 +45,10 @@ class Texture2D : public Texture {
protected:
static void _bind_methods();
GDVIRTUAL0RC(Image::Format, _get_format)
GDVIRTUAL0RC(Ref<Image>, _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<Image> get_image() const { return Ref<Image>(); }
virtual Ref<Image> get_image() const;
virtual Ref<Resource> create_placeholder() const;

View file

@ -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);
}

View file

@ -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);

View file

@ -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;