Skip to content

Commit

Permalink
Expose API for converting ImageTexture RID to RenderingDevice texture…
Browse files Browse the repository at this point in the history
… RID; API for creating ImageTexture with custom usage bits
  • Loading branch information
huisedenanhai committed Aug 17, 2022
1 parent d5d22ab commit 32a05a5
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 6 deletions.
16 changes: 16 additions & 0 deletions drivers/gles3/storage/texture_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,22 @@ void TextureStorage::texture_proxy_initialize(RID p_texture, RID p_base) {
texture_owner.initialize_rid(p_texture, proxy_tex);
}

void TextureStorage::texture_2d_with_usage_initialize(RID p_texture, const Ref<Image> &p_image, uint32_t p_usage_bits) {
texture_2d_initialize(p_texture, p_image);
}

void TextureStorage::texture_2d_layered_with_usage_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type, uint32_t p_usage_bits) {
texture_2d_layered_initialize(p_texture, p_layers, p_layered_type);
}

void TextureStorage::texture_3d_with_usage_initialize(RID p_texture, Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data, uint32_t p_usage_bits) {
texture_3d_initialize(p_texture, p_format, p_width, p_height, p_depth, p_mipmaps, p_data);
}

RID TextureStorage::texture_get_rd_rid(RID p_texture) const {
return RID();
}

void TextureStorage::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) {
// only 1 layer so far
texture_set_data(p_texture, p_image);
Expand Down
5 changes: 5 additions & 0 deletions drivers/gles3/storage/texture_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,11 @@ class TextureStorage : public RendererTextureStorage {
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 void texture_2d_with_usage_initialize(RID p_texture, const Ref<Image> &p_image, uint32_t p_usage_bits) override;
virtual void texture_2d_layered_with_usage_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type, uint32_t p_usage_bits) override;
virtual void texture_3d_with_usage_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data, uint32_t p_usage_bits) override;
virtual RID texture_get_rd_rid(RID p_texture) const 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;
Expand Down
32 changes: 29 additions & 3 deletions scene/resources/texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@
#include "mesh.h"
#include "scene/resources/bit_map.h"
#include "servers/camera/camera_feed.h"
#include <stdint.h>

RID Texture::get_rd_texture_rid() const {
return RenderingServer::get_singleton()->texture_get_rd_rid(get_rid());
}

void Texture::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_rd_texture_rid"), &ImageTexture::get_rd_texture_rid);
}

int Texture2D::get_width() const {
int ret;
if (GDVIRTUAL_REQUIRED_CALL(_get_width, ret)) {
Expand Down Expand Up @@ -168,25 +178,39 @@ void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const {
}

Ref<ImageTexture> ImageTexture::create_from_image(const Ref<Image> &p_image) {
return create_from_image_with_usage(p_image, 0);
}

Ref<ImageTexture> ImageTexture::create_from_image_with_usage(const Ref<Image> &p_image, uint32_t usage) {
ERR_FAIL_COND_V_MSG(p_image.is_null() || p_image->is_empty(), Ref<ImageTexture>(), "Invalid image");

Ref<ImageTexture> image_texture;
image_texture.instantiate();
image_texture->set_image(p_image);
image_texture->set_image_with_usage(p_image, usage);
return image_texture;
}

void ImageTexture::set_image(const Ref<Image> &p_image) {
set_image_with_usage(p_image, 0);
}

void ImageTexture::set_image_with_usage(const Ref<Image> &p_image, uint32_t usage_bits) {
ERR_FAIL_COND_MSG(p_image.is_null() || p_image->is_empty(), "Invalid image");
w = p_image->get_width();
h = p_image->get_height();
format = p_image->get_format();
mipmaps = p_image->has_mipmaps();

RID new_texture{};
if (usage_bits) {
new_texture = RenderingServer::get_singleton()->texture_2d_with_usage_create(p_image, usage_bits);
} else {
new_texture = RenderingServer::get_singleton()->texture_2d_create(p_image);
}

if (texture.is_null()) {
texture = RenderingServer::get_singleton()->texture_2d_create(p_image);
texture = new_texture;
} else {
RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_image);
RenderingServer::get_singleton()->texture_replace(texture, new_texture);
}
notify_property_list_changed();
Expand Down Expand Up @@ -321,9 +345,11 @@ 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_static_method("ImageTexture", D_METHOD("create_from_image_with_usage", "image", "usage_bits"), &ImageTexture::create_from_image_with_usage);
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("set_image_with_usage", "image", "usage_bits"), &ImageTexture::set_image_with_usage);
ClassDB::bind_method(D_METHOD("update", "image"), &ImageTexture::update);
ClassDB::bind_method(D_METHOD("set_size_override", "size"), &ImageTexture::set_size_override);
}
Expand Down
8 changes: 8 additions & 0 deletions scene/resources/texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,18 @@
#include "scene/resources/gradient.h"
#include "servers/camera_server.h"
#include "servers/rendering_server.h"
#include <stdint.h>

class Texture : public Resource {
GDCLASS(Texture, Resource);

public:
Texture() {}

RID get_rd_texture_rid() const;

protected:
static void _bind_methods();
};

class Texture2D : public Texture {
Expand Down Expand Up @@ -111,7 +117,9 @@ class ImageTexture : public Texture2D {

public:
void set_image(const Ref<Image> &p_image);
void set_image_with_usage(const Ref<Image> &p_image, uint32_t usage_bits);
static Ref<ImageTexture> create_from_image(const Ref<Image> &p_image);
static Ref<ImageTexture> create_from_image_with_usage(const Ref<Image> &p_image, uint32_t usage_bits);

Image::Format get_format() const;

Expand Down
5 changes: 5 additions & 0 deletions servers/rendering/dummy/storage/texture_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ class TextureStorage : public RendererTextureStorage {
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 void texture_2d_with_usage_initialize(RID p_texture, const Ref<Image> &p_image, uint32_t p_usage_bits) override {}
virtual void texture_2d_layered_with_usage_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type, uint32_t p_usage_bits) override {}
virtual void texture_3d_with_usage_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data, uint32_t p_usage_bits) override {}
virtual RID texture_get_rd_rid(RID p_texture) const override { return RID(); }

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{};
Expand Down
25 changes: 22 additions & 3 deletions servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "texture_storage.h"
#include "../effects/copy_effects.h"
#include "material_storage.h"
#include <stdint.h>

using namespace RendererRD;

Expand Down Expand Up @@ -673,6 +674,10 @@ void TextureStorage::texture_free(RID p_texture) {
}

void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) {
texture_2d_with_usage_initialize(p_texture, p_image, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT);
}

void TextureStorage::texture_2d_with_usage_initialize(RID p_texture, const Ref<Image> &p_image, uint32_t p_usage_bits) {
TextureToRDFormat ret_format;
Ref<Image> image = _validate_texture_format(p_image, ret_format);

Expand Down Expand Up @@ -703,7 +708,7 @@ void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_im
rd_format.mipmaps = texture.mipmaps;
rd_format.texture_type = texture.rd_type;
rd_format.samples = RD::TEXTURE_SAMPLES_1;
rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
rd_format.usage_bits = p_usage_bits;
if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
rd_format.shareable_formats.push_back(texture.rd_format);
rd_format.shareable_formats.push_back(texture.rd_format_srgb);
Expand Down Expand Up @@ -740,6 +745,10 @@ void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_im
}

void TextureStorage::texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) {
texture_2d_layered_with_usage_initialize(p_texture, p_layers, p_layered_type, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT);
}

void TextureStorage::texture_2d_layered_with_usage_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type, uint32_t p_usage_bits) {
ERR_FAIL_COND(p_layers.size() == 0);

ERR_FAIL_COND(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6);
Expand Down Expand Up @@ -811,7 +820,7 @@ void TextureStorage::texture_2d_layered_initialize(RID p_texture, const Vector<R
rd_format.mipmaps = texture.mipmaps;
rd_format.texture_type = texture.rd_type;
rd_format.samples = RD::TEXTURE_SAMPLES_1;
rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
rd_format.usage_bits = p_usage_bits;
if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
rd_format.shareable_formats.push_back(texture.rd_format);
rd_format.shareable_formats.push_back(texture.rd_format_srgb);
Expand Down Expand Up @@ -850,6 +859,10 @@ void TextureStorage::texture_2d_layered_initialize(RID p_texture, const Vector<R
}

void TextureStorage::texture_3d_initialize(RID p_texture, Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) {
texture_3d_with_usage_initialize(p_texture, p_format, p_width, p_height, p_depth, p_mipmaps, p_data, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT);
}

void TextureStorage::texture_3d_with_usage_initialize(RID p_texture, Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data, uint32_t p_usage_bits) {
ERR_FAIL_COND(p_data.size() == 0);

Image::Image3DValidateError verr = Image::validate_3d_image(p_format, p_width, p_height, p_depth, p_mipmaps, p_data);
Expand Down Expand Up @@ -930,7 +943,7 @@ void TextureStorage::texture_3d_initialize(RID p_texture, Image::Format p_format
rd_format.mipmaps = texture.mipmaps;
rd_format.texture_type = texture.rd_type;
rd_format.samples = RD::TEXTURE_SAMPLES_1;
rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
rd_format.usage_bits = p_usage_bits;
if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
rd_format.shareable_formats.push_back(texture.rd_format);
rd_format.shareable_formats.push_back(texture.rd_format_srgb);
Expand Down Expand Up @@ -966,6 +979,12 @@ void TextureStorage::texture_3d_initialize(RID p_texture, Image::Format p_format
texture_owner.initialize_rid(p_texture, texture);
}

RID TextureStorage::texture_get_rd_rid(RID p_texture) const {
Texture *tex = texture_owner.get_or_null(p_texture);
ERR_FAIL_COND_V(!tex, RID());
return tex->rd_texture;
}

void TextureStorage::texture_proxy_initialize(RID p_texture, RID p_base) {
Texture *tex = texture_owner.get_or_null(p_base);
ERR_FAIL_COND(!tex);
Expand Down
7 changes: 7 additions & 0 deletions servers/rendering/renderer_rd/storage_rd/texture_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "servers/rendering/renderer_rd/shaders/canvas_sdf.glsl.gen.h"
#include "servers/rendering/storage/texture_storage.h"
#include "servers/rendering/storage/utilities.h"
#include <stdint.h>

namespace RendererRD {

Expand Down Expand Up @@ -369,6 +370,12 @@ class TextureStorage : public RendererTextureStorage {
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 void texture_2d_with_usage_initialize(RID p_texture, const Ref<Image> &p_image, uint32_t p_usage_bits) override;
virtual void texture_2d_layered_with_usage_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type, uint32_t p_usage_bits) override;
virtual void texture_3d_with_usage_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data, uint32_t p_usage_bits) override;

virtual RID texture_get_rd_rid(RID p_texture) const 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;
Expand Down
27 changes: 27 additions & 0 deletions servers/rendering/rendering_server_default.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,17 @@ class RenderingServerDefault : public RenderingServer {
return ret; \
}

#define FUNCRIDTEX3(m_type, m_type1, m_type2, m_type3) \
virtual RID m_type##_create(m_type1 p1, m_type2 p2, m_type3 p3) override { \
RID ret = RSG::texture_storage->texture_allocate(); \
if (Thread::get_caller_id() == server_thread || RSG::texture_storage->can_create_resources_async()) { \
RSG::texture_storage->m_type##_initialize(ret, p1, p2, p3); \
} else { \
command_queue.push(RSG::texture_storage, &RendererTextureStorage::m_type##_initialize, ret, p1, p2, p3); \
} \
return ret; \
}

#define FUNCRIDTEX6(m_type, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \
virtual RID m_type##_create(m_type1 p1, m_type2 p2, m_type3 p3, m_type4 p4, m_type5 p5, m_type6 p6) override { \
RID ret = RSG::texture_storage->texture_allocate(); \
Expand All @@ -175,12 +186,28 @@ class RenderingServerDefault : public RenderingServer {
return ret; \
}

#define FUNCRIDTEX7(m_type, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7) \
virtual RID m_type##_create(m_type1 p1, m_type2 p2, m_type3 p3, m_type4 p4, m_type5 p5, m_type6 p6, m_type7 p7) override { \
RID ret = RSG::texture_storage->texture_allocate(); \
if (Thread::get_caller_id() == server_thread || RSG::texture_storage->can_create_resources_async()) { \
RSG::texture_storage->m_type##_initialize(ret, p1, p2, p3, p4, p5, p6, p7); \
} else { \
command_queue.push(RSG::texture_storage, &RendererTextureStorage::m_type##_initialize, ret, p1, p2, p3, p4, p5, p6, p7); \
} \
return ret; \
}

//these go pass-through, as they can be called from any thread
FUNCRIDTEX1(texture_2d, const Ref<Image> &)
FUNCRIDTEX2(texture_2d_layered, const Vector<Ref<Image>> &, TextureLayeredType)
FUNCRIDTEX6(texture_3d, Image::Format, int, int, int, bool, const Vector<Ref<Image>> &)
FUNCRIDTEX1(texture_proxy, RID)

FUNCRIDTEX2(texture_2d_with_usage, const Ref<Image> &, uint32_t)
FUNCRIDTEX3(texture_2d_layered_with_usage, const Vector<Ref<Image>> &, TextureLayeredType, uint32_t)
FUNCRIDTEX7(texture_3d_with_usage, Image::Format, int, int, int, bool, const Vector<Ref<Image>> &, uint32_t)
FUNC1RC(RID, texture_get_rd_rid, RID)

//these go through command queue if they are in another thread
FUNC3(texture_2d_update, RID, const Ref<Image> &, int)
FUNC2(texture_3d_update, RID, const Vector<Ref<Image>> &)
Expand Down
6 changes: 6 additions & 0 deletions servers/rendering/storage/texture_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#define TEXTURE_STORAGE_H

#include "servers/rendering_server.h"
#include <stdint.h>

class RendererTextureStorage {
private:
Expand Down Expand Up @@ -71,6 +72,11 @@ class RendererTextureStorage {
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) = 0;
virtual void texture_proxy_initialize(RID p_texture, RID p_base) = 0; //all slices, then all the mipmaps, must be coherent

virtual void texture_2d_with_usage_initialize(RID p_texture, const Ref<Image> &p_image, uint32_t p_usage_bits) = 0;
virtual void texture_2d_layered_with_usage_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type, uint32_t p_usage_bits) = 0;
virtual void texture_3d_with_usage_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data, uint32_t p_usage_bits) = 0;
virtual RID texture_get_rd_rid(RID p_texture) const = 0;

virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0;
virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0;
virtual void texture_proxy_update(RID p_proxy, RID p_base) = 0;
Expand Down
Loading

0 comments on commit 32a05a5

Please sign in to comment.