diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index 3a4a25df6f7..59286acccc9 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -3281,6 +3281,15 @@
[b]Note:[/b] The [param texture] must have the same width, height, depth and format as the current texture data. Otherwise, an error will be printed and the original texture won't be modified. If you need to use different width, height, depth or format, use [method texture_replace] instead.
+
+
+
+
+
+ Returns the internal graphics handle for this texture object. For use when communicating with 3rd party APIs mostly with GDExternal.
+ [b]Note:[/b] This functions returns a [code]uint64_t[/code] which internally maps to a [code]GLuint[/code] (OpenGL) or [code]VkImage[/code] (Vulkan).
+
+
diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp
index d147cee54fc..3fd54e91803 100644
--- a/drivers/gles3/storage/texture_storage.cpp
+++ b/drivers/gles3/storage/texture_storage.cpp
@@ -1140,6 +1140,13 @@ RID TextureStorage::texture_get_rd_texture(RID p_texture, bool p_srgb) const {
return RID();
}
+uint64_t TextureStorage::texture_get_native_handle(RID p_texture, bool p_srgb) const {
+ const Texture *texture = texture_owner.get_or_null(p_texture);
+ ERR_FAIL_COND_V(!texture, 0);
+
+ return texture->tex_id;
+}
+
void TextureStorage::texture_set_data(RID p_texture, const Ref &p_image, int p_layer) {
Texture *texture = texture_owner.get_or_null(p_texture);
diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h
index 85d2ae03140..c6bdd39dbda 100644
--- a/drivers/gles3/storage/texture_storage.h
+++ b/drivers/gles3/storage/texture_storage.h
@@ -537,6 +537,7 @@ public:
virtual Size2 texture_size_with_proxy(RID p_proxy) override;
virtual RID texture_get_rd_texture(RID p_texture, bool p_srgb = false) const override;
+ virtual uint64_t texture_get_native_handle(RID p_texture, bool p_srgb = false) const override;
void texture_set_data(RID p_texture, const Ref &p_image, int p_layer = 0);
void texture_set_data_partial(RID p_texture, const Ref &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, int p_layer = 0);
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 84b391d18ac..13315671ae6 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -2881,6 +2881,15 @@ Size2i RenderingDeviceVulkan::texture_size(RID p_texture) {
return Size2i(tex->width, tex->height);
}
+uint64_t RenderingDeviceVulkan::texture_native_handle(RID p_texture) {
+ _THREAD_SAFE_METHOD_
+
+ Texture *tex = texture_owner.get_or_null(p_texture);
+ ERR_FAIL_COND_V(!tex, 0);
+
+ return (uint64_t)tex->image;
+}
+
Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, BitField p_post_barrier) {
_THREAD_SAFE_METHOD_
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index 2ec1574955d..4150e0a8e6d 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -1057,6 +1057,7 @@ public:
virtual bool texture_is_shared(RID p_texture);
virtual bool texture_is_valid(RID p_texture);
virtual Size2i texture_size(RID p_texture);
+ virtual uint64_t texture_native_handle(RID p_texture);
virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, BitField p_post_barrier = BARRIER_MASK_ALL_BARRIERS);
virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, BitField p_post_barrier = BARRIER_MASK_ALL_BARRIERS);
diff --git a/servers/rendering/dummy/storage/texture_storage.h b/servers/rendering/dummy/storage/texture_storage.h
index e880cacc029..768b1ba7026 100644
--- a/servers/rendering/dummy/storage/texture_storage.h
+++ b/servers/rendering/dummy/storage/texture_storage.h
@@ -128,6 +128,7 @@ public:
virtual Size2 texture_size_with_proxy(RID p_proxy) override { return Size2(); };
virtual RID texture_get_rd_texture(RID p_texture, bool p_srgb = false) const override { return RID(); };
+ virtual uint64_t texture_get_native_handle(RID p_texture, bool p_srgb = false) const override { return 0; };
/* DECAL API */
virtual RID decal_allocate() override { return RID(); }
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
index 8808d63a829..3d6092a9f64 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
@@ -1442,6 +1442,17 @@ RID TextureStorage::texture_get_rd_texture(RID p_texture, bool p_srgb) const {
return (p_srgb && tex->rd_texture_srgb.is_valid()) ? tex->rd_texture_srgb : tex->rd_texture;
}
+uint64_t TextureStorage::texture_get_native_handle(RID p_texture, bool p_srgb) const {
+ Texture *tex = texture_owner.get_or_null(p_texture);
+ ERR_FAIL_COND_V(!tex, 0);
+
+ if (p_srgb && tex->rd_texture_srgb.is_valid()) {
+ return RD::get_singleton()->texture_native_handle(tex->rd_texture_srgb);
+ } else {
+ return RD::get_singleton()->texture_native_handle(tex->rd_texture);
+ }
+}
+
Ref TextureStorage::_validate_texture_format(const Ref &p_image, TextureToRDFormat &r_format) {
Ref image = p_image->duplicate();
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
index 3e4ac3b8332..8f021f31791 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
@@ -499,6 +499,7 @@ public:
virtual Size2 texture_size_with_proxy(RID p_proxy) override;
virtual RID texture_get_rd_texture(RID p_texture, bool p_srgb = false) const override;
+ virtual uint64_t texture_get_native_handle(RID p_texture, bool p_srgb = false) const override;
//internal usage
_FORCE_INLINE_ TextureType texture_get_type(RID p_texture) {
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index e55db0a2373..a8dd3317769 100644
--- a/servers/rendering/rendering_device.h
+++ b/servers/rendering/rendering_device.h
@@ -539,6 +539,7 @@ public:
virtual bool texture_is_shared(RID p_texture) = 0;
virtual bool texture_is_valid(RID p_texture) = 0;
virtual Size2i texture_size(RID p_texture) = 0;
+ virtual uint64_t texture_native_handle(RID p_texture) = 0;
virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, BitField p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0;
virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, BitField p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0;
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index d39bec8399f..797fe73ba03 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -214,6 +214,7 @@ public:
FUNC2(texture_set_force_redraw_if_visible, RID, bool)
FUNC2RC(RID, texture_get_rd_texture, RID, bool)
+ FUNC2RC(uint64_t, texture_get_native_handle, RID, bool)
/* SHADER API */
diff --git a/servers/rendering/storage/texture_storage.h b/servers/rendering/storage/texture_storage.h
index 0a59c70526c..93b32bd3722 100644
--- a/servers/rendering/storage/texture_storage.h
+++ b/servers/rendering/storage/texture_storage.h
@@ -101,6 +101,7 @@ public:
virtual Size2 texture_size_with_proxy(RID p_proxy) = 0;
virtual RID texture_get_rd_texture(RID p_texture, bool p_srgb = false) const = 0;
+ virtual uint64_t texture_get_native_handle(RID p_texture, bool p_srgb = false) const = 0;
/* Decal API */
virtual RID decal_allocate() = 0;
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index b8b642fac18..853745298e5 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -1698,6 +1698,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("texture_set_force_redraw_if_visible", "texture", "enable"), &RenderingServer::texture_set_force_redraw_if_visible);
ClassDB::bind_method(D_METHOD("texture_get_rd_texture", "texture", "srgb"), &RenderingServer::texture_get_rd_texture, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("texture_get_native_handle", "texture", "srgb"), &RenderingServer::texture_get_native_handle, DEFVAL(false));
BIND_ENUM_CONSTANT(TEXTURE_LAYERED_2D_ARRAY);
BIND_ENUM_CONSTANT(TEXTURE_LAYERED_CUBEMAP);
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index a5548db7431..deac2a59f92 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -159,6 +159,7 @@ public:
virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0;
virtual RID texture_get_rd_texture(RID p_texture, bool p_srgb = false) const = 0;
+ virtual uint64_t texture_get_native_handle(RID p_texture, bool p_srgb = false) const = 0;
/* SHADER API */