Merge pull request #74711 from BastiaanOlij/add_texture_native_handle

Provide access to internal graphics handles for textures
This commit is contained in:
Rémi Verschelde 2023-05-09 19:28:26 +02:00
commit 564d1b34e0
No known key found for this signature in database
GPG key ID: C3336907360768E1
13 changed files with 45 additions and 0 deletions

View file

@ -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.
</description>
</method>
<method name="texture_get_native_handle" qualifiers="const">
<return type="int" />
<param index="0" name="texture" type="RID" />
<param index="1" name="srgb" type="bool" default="false" />
<description>
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).
</description>
</method>
<method name="texture_get_path" qualifiers="const">
<return type="String" />
<param index="0" name="texture" type="RID" />

View file

@ -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<Image> &p_image, int p_layer) {
Texture *texture = texture_owner.get_or_null(p_texture);

View file

@ -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<Image> &p_image, int p_layer = 0);
void texture_set_data_partial(RID p_texture, const Ref<Image> &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);

View file

@ -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<BarrierMask> p_post_barrier) {
_THREAD_SAFE_METHOD_

View file

@ -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<BarrierMask> 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<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS);

View file

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

View file

@ -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<Image> TextureStorage::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) {
Ref<Image> image = p_image->duplicate();

View file

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

View file

@ -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<BarrierMask> 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<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0;

View file

@ -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 */

View file

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

View file

@ -1699,6 +1699,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);

View file

@ -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 */