summaryrefslogtreecommitdiffstats
path: root/servers/rendering/renderer_rd/storage_rd
diff options
context:
space:
mode:
authorDavid Snopek <dsnopek@gmail.com>2024-09-12 12:54:57 -0500
committerDavid Snopek <dsnopek@gmail.com>2024-09-19 09:05:32 -0500
commit7d56b09f2375a32e1adbfaa3aca54823abcd2508 (patch)
tree8957f683fe5d9482542adde62a45cc9357e8dc16 /servers/rendering/renderer_rd/storage_rd
parent83d54ab2ad476ae265b323c2b88f4623b922f4c6 (diff)
downloadredot-engine-7d56b09f2375a32e1adbfaa3aca54823abcd2508.tar.gz
Expose a function to create textures from a native handle in the compatibility renderer
Diffstat (limited to 'servers/rendering/renderer_rd/storage_rd')
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.cpp189
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.h2
2 files changed, 191 insertions, 0 deletions
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
index be29716f45..81ab384edc 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
@@ -1108,6 +1108,195 @@ void TextureStorage::texture_proxy_initialize(RID p_texture, RID p_base) {
tex->proxies.push_back(p_texture);
}
+// Note: We make some big assumptions about format and usage. If developers need more control,
+// they should use RD::texture_create_from_extension() instead.
+RID TextureStorage::texture_create_from_native_handle(RS::TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers, RS::TextureLayeredType p_layered_type) {
+ RD::TextureType type;
+ switch (p_type) {
+ case RS::TEXTURE_TYPE_2D:
+ type = RD::TEXTURE_TYPE_2D;
+ break;
+
+ case RS::TEXTURE_TYPE_3D:
+ type = RD::TEXTURE_TYPE_3D;
+ break;
+
+ case RS::TEXTURE_TYPE_LAYERED:
+ if (p_layered_type == RS::TEXTURE_LAYERED_2D_ARRAY) {
+ type = RD::TEXTURE_TYPE_2D_ARRAY;
+ } else if (p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP) {
+ type = RD::TEXTURE_TYPE_CUBE;
+ } else if (p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY) {
+ type = RD::TEXTURE_TYPE_CUBE_ARRAY;
+ } else {
+ // Arbitrary fallback.
+ type = RD::TEXTURE_TYPE_2D_ARRAY;
+ }
+ break;
+
+ default:
+ // Arbitrary fallback.
+ type = RD::TEXTURE_TYPE_2D;
+ }
+
+ // Only a rough conversion - see note above.
+ RD::DataFormat format;
+ switch (p_format) {
+ case Image::FORMAT_L8:
+ case Image::FORMAT_R8:
+ format = RD::DATA_FORMAT_R8_UNORM;
+ break;
+
+ case Image::FORMAT_LA8:
+ case Image::FORMAT_RG8:
+ format = RD::DATA_FORMAT_R8G8_UNORM;
+ break;
+
+ case Image::FORMAT_RGB8:
+ format = RD::DATA_FORMAT_R8G8B8_UNORM;
+ break;
+
+ case Image::FORMAT_RGBA8:
+ format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ break;
+
+ case Image::FORMAT_RGBA4444:
+ format = RD::DATA_FORMAT_B4G4R4A4_UNORM_PACK16;
+ break;
+
+ case Image::FORMAT_RGB565:
+ format = RD::DATA_FORMAT_B5G6R5_UNORM_PACK16;
+ break;
+
+ case Image::FORMAT_RF:
+ format = RD::DATA_FORMAT_R32_SFLOAT;
+ break;
+
+ case Image::FORMAT_RGF:
+ format = RD::DATA_FORMAT_R32G32_SFLOAT;
+ break;
+
+ case Image::FORMAT_RGBF:
+ format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
+ break;
+
+ case Image::FORMAT_RGBAF:
+ format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
+ break;
+
+ case Image::FORMAT_RH:
+ format = RD::DATA_FORMAT_R16_SFLOAT;
+ break;
+
+ case Image::FORMAT_RGH:
+ format = RD::DATA_FORMAT_R16G16_SFLOAT;
+ break;
+
+ case Image::FORMAT_RGBH:
+ format = RD::DATA_FORMAT_R16G16B16_SFLOAT;
+ break;
+
+ case Image::FORMAT_RGBAH:
+ format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ break;
+
+ case Image::FORMAT_RGBE9995:
+ format = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32;
+ break;
+
+ case Image::FORMAT_DXT1:
+ format = RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_DXT3:
+ format = RD::DATA_FORMAT_BC2_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_DXT5:
+ format = RD::DATA_FORMAT_BC3_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_RGTC_R:
+ format = RD::DATA_FORMAT_BC4_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_RGTC_RG:
+ format = RD::DATA_FORMAT_BC5_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_BPTC_RGBA:
+ format = RD::DATA_FORMAT_BC7_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_BPTC_RGBF:
+ format = RD::DATA_FORMAT_BC6H_SFLOAT_BLOCK;
+ break;
+
+ case Image::FORMAT_BPTC_RGBFU:
+ format = RD::DATA_FORMAT_BC6H_UFLOAT_BLOCK;
+ break;
+
+ case Image::FORMAT_ETC:
+ format = RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ETC2_R11:
+ format = RD::DATA_FORMAT_EAC_R11_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ETC2_R11S:
+ format = RD::DATA_FORMAT_EAC_R11_SNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ETC2_RG11:
+ format = RD::DATA_FORMAT_EAC_R11G11_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ETC2_RG11S:
+ format = RD::DATA_FORMAT_EAC_R11G11_SNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ETC2_RGB8:
+ format = RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ETC2_RGBA8:
+ format = RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ETC2_RGB8A1:
+ format = RD::DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ETC2_RA_AS_RG:
+ format = RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_DXT5_RA_AS_RG:
+ format = RD::DATA_FORMAT_BC3_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ASTC_4x4:
+ case Image::FORMAT_ASTC_4x4_HDR:
+ format = RD::DATA_FORMAT_ASTC_4x4_UNORM_BLOCK;
+ break;
+
+ case Image::FORMAT_ASTC_8x8:
+ case Image::FORMAT_ASTC_8x8_HDR:
+ format = RD::DATA_FORMAT_ASTC_8x8_UNORM_BLOCK;
+ break;
+
+ default:
+ // Arbitrary fallback.
+ format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ }
+
+ // Assumed to be a color attachment - see note above.
+ uint64_t usage_flags = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+
+ return RD::get_singleton()->texture_create_from_extension(type, format, RD::TEXTURE_SAMPLES_1, usage_flags, p_native_handle, p_width, p_height, p_depth, p_layers);
+}
+
void TextureStorage::_texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate) {
ERR_FAIL_COND(p_image.is_null() || p_image->is_empty());
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
index 704f5fb1bd..d352690fff 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
@@ -493,6 +493,8 @@ public:
virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override;
virtual void texture_proxy_initialize(RID p_texture, RID p_base) override; //all slices, then all the mipmaps, must be coherent
+ virtual RID texture_create_from_native_handle(RS::TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers = 1, RS::TextureLayeredType p_layered_type = RS::TEXTURE_LAYERED_2D_ARRAY) override;
+
virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override;
virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) override;
virtual void texture_proxy_update(RID p_proxy, RID p_base) override;