summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gles3/shader_gles3.cpp8
-rw-r--r--drivers/gles3/shaders/canvas.glsl4
-rw-r--r--drivers/gles3/shaders/sky.glsl2
-rw-r--r--drivers/gles3/storage/config.cpp8
-rw-r--r--drivers/gles3/storage/config.h3
-rw-r--r--drivers/gles3/storage/material_storage.cpp11
-rw-r--r--drivers/gles3/storage/render_scene_buffers_gles3.h6
-rw-r--r--drivers/gles3/storage/texture_storage.cpp81
-rw-r--r--drivers/gles3/storage/texture_storage.h11
-rw-r--r--drivers/metal/metal_objects.h7
-rw-r--r--drivers/metal/metal_objects.mm4
11 files changed, 125 insertions, 20 deletions
diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp
index 5a0f394db0..b73debf04a 100644
--- a/drivers/gles3/shader_gles3.cpp
+++ b/drivers/gles3/shader_gles3.cpp
@@ -189,6 +189,14 @@ void ShaderGLES3::_build_variant_code(StringBuilder &builder, uint32_t p_variant
}
builder.append("\n"); //make sure defines begin at newline
+ // Optional support for external textures.
+ if (GLES3::Config::get_singleton()->external_texture_supported) {
+ builder.append("#extension GL_OES_EGL_image_external : enable\n");
+ builder.append("#extension GL_OES_EGL_image_external_essl3 : enable\n");
+ } else {
+ builder.append("#define samplerExternalOES sampler2D\n");
+ }
+
// Insert multiview extension loading, because it needs to appear before
// any non-preprocessor code (like the "precision highp..." lines below).
builder.append("#ifdef USE_MULTIVIEW\n");
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index e358230747..76881c8032 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -262,6 +262,8 @@ void main() {
color_interp = color;
+ vertex = (canvas_transform * vec4(vertex, 0.0, 1.0)).xy;
+
if (use_pixel_snap) {
vertex = floor(vertex + 0.5);
// precision issue on some hardware creates artifacts within texture
@@ -269,8 +271,6 @@ void main() {
uv += 1e-5;
}
- vertex = (canvas_transform * vec4(vertex, 0.0, 1.0)).xy;
-
vertex_interp = vertex;
uv_interp = uv;
diff --git a/drivers/gles3/shaders/sky.glsl b/drivers/gles3/shaders/sky.glsl
index f734e4b355..186b630bc8 100644
--- a/drivers/gles3/shaders/sky.glsl
+++ b/drivers/gles3/shaders/sky.glsl
@@ -212,9 +212,7 @@ void main() {
#endif
{
-
#CODE : SKY
-
}
color *= sky_energy_multiplier;
diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp
index 2b19bd581a..0100719151 100644
--- a/drivers/gles3/storage/config.cpp
+++ b/drivers/gles3/storage/config.cpp
@@ -140,6 +140,7 @@ Config::Config() {
// These are GLES only
rt_msaa_supported = extensions.has("GL_EXT_multisampled_render_to_texture");
rt_msaa_multiview_supported = extensions.has("GL_OVR_multiview_multisampled_render_to_texture");
+ external_texture_supported = extensions.has("GL_OES_EGL_image_external_essl3");
if (multiview_supported) {
eglFramebufferTextureMultiviewOVR = (PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC)eglGetProcAddress("glFramebufferTextureMultiviewOVR");
@@ -168,6 +169,13 @@ Config::Config() {
rt_msaa_multiview_supported = false;
}
}
+
+ if (external_texture_supported) {
+ eglEGLImageTargetTexture2DOES = (PFNEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES");
+ if (eglEGLImageTargetTexture2DOES == nullptr) {
+ external_texture_supported = false;
+ }
+ }
#endif
force_vertex_shading = false; //GLOBAL_GET("rendering/quality/shading/force_vertex_shading");
diff --git a/drivers/gles3/storage/config.h b/drivers/gles3/storage/config.h
index 112dfd0a5f..d60f295d66 100644
--- a/drivers/gles3/storage/config.h
+++ b/drivers/gles3/storage/config.h
@@ -45,6 +45,7 @@ typedef void (*PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC)(GLenum, GLenum, GLuint,
typedef void (*PFNGLTEXSTORAGE3DMULTISAMPLEPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei, GLboolean);
typedef void (*PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)(GLenum, GLenum, GLenum, GLuint, GLint, GLsizei);
typedef void (*PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC)(GLenum, GLenum, GLuint, GLint, GLsizei, GLint, GLsizei);
+typedef void (*PFNEGLIMAGETARGETTEXTURE2DOESPROC)(GLenum, void *);
#endif
namespace GLES3 {
@@ -92,6 +93,7 @@ public:
bool rt_msaa_supported = false;
bool rt_msaa_multiview_supported = false;
bool multiview_supported = false;
+ bool external_texture_supported = false;
// Adreno 3XX compatibility
bool disable_particles_workaround = false; // set to 'true' to disable 'GPUParticles'
@@ -105,6 +107,7 @@ public:
PFNGLTEXSTORAGE3DMULTISAMPLEPROC eglTexStorage3DMultisample = nullptr;
PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC eglFramebufferTexture2DMultisampleEXT = nullptr;
PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC eglFramebufferTextureMultisampleMultiviewOVR = nullptr;
+ PFNEGLIMAGETARGETTEXTURE2DOESPROC eglEGLImageTargetTexture2DOES = nullptr;
#endif
static Config *get_singleton() { return singleton; };
diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp
index 7d5af48384..c29c741c2a 100644
--- a/drivers/gles3/storage/material_storage.cpp
+++ b/drivers/gles3/storage/material_storage.cpp
@@ -675,6 +675,7 @@ static const GLenum target_from_type[ShaderLanguage::TYPE_MAX] = {
GL_TEXTURE_3D, // TYPE_USAMPLER3D,
GL_TEXTURE_CUBE_MAP, // TYPE_SAMPLERCUBE,
GL_TEXTURE_CUBE_MAP, // TYPE_SAMPLERCUBEARRAY,
+ _GL_TEXTURE_EXTERNAL_OES, // TYPE_SAMPLEREXT
GL_TEXTURE_2D, // TYPE_STRUCT
};
@@ -946,6 +947,9 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet
case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: {
ERR_PRINT_ONCE("Type: SamplerCubeArray not supported in GL Compatibility rendering backend, please use another type.");
} break;
+ case ShaderLanguage::TYPE_SAMPLEREXT: {
+ gl_texture = texture_storage->texture_gl_get_default(DEFAULT_GL_TEXTURE_EXT);
+ } break;
case ShaderLanguage::TYPE_ISAMPLER3D:
case ShaderLanguage::TYPE_USAMPLER3D:
@@ -1949,6 +1953,7 @@ void MaterialStorage::global_shader_parameters_load_settings(bool p_load_texture
"sampler2DArray",
"sampler3D",
"samplerCube",
+ "samplerExternalOES"
};
RS::GlobalShaderParameterType gvtype = RS::GLOBAL_VAR_TYPE_MAX;
@@ -2661,7 +2666,11 @@ static void bind_uniforms_generic(const Vector<RID> &p_textures, const Vector<Sh
const ShaderCompiler::GeneratedCode::Texture &texture_uniform = texture_uniforms[texture_uniform_index];
if (texture) {
glActiveTexture(GL_TEXTURE0 + texture_offset + ti);
- glBindTexture(target_from_type[texture_uniform.type], texture->tex_id);
+ GLenum target = target_from_type[texture_uniform.type];
+ if (target == _GL_TEXTURE_EXTERNAL_OES && !GLES3::Config::get_singleton()->external_texture_supported) {
+ target = GL_TEXTURE_2D;
+ }
+ glBindTexture(target, texture->tex_id);
if (texture->render_target) {
texture->render_target->used_in_frame = true;
}
diff --git a/drivers/gles3/storage/render_scene_buffers_gles3.h b/drivers/gles3/storage/render_scene_buffers_gles3.h
index a7a676ad33..9a2912f978 100644
--- a/drivers/gles3/storage/render_scene_buffers_gles3.h
+++ b/drivers/gles3/storage/render_scene_buffers_gles3.h
@@ -103,9 +103,9 @@ public:
virtual void configure(const RenderSceneBuffersConfiguration *p_config) override;
void configure_for_probe(Size2i p_size);
- virtual void set_fsr_sharpness(float p_fsr_sharpness) override{};
- virtual void set_texture_mipmap_bias(float p_texture_mipmap_bias) override{};
- virtual void set_use_debanding(bool p_use_debanding) override{};
+ virtual void set_fsr_sharpness(float p_fsr_sharpness) override {}
+ virtual void set_texture_mipmap_bias(float p_texture_mipmap_bias) override {}
+ virtual void set_use_debanding(bool p_use_debanding) override {}
void set_apply_color_adjustments_in_post(bool p_apply_in_post);
void free_render_buffer_data();
diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp
index 54012c20e9..27ba89aa5f 100644
--- a/drivers/gles3/storage/texture_storage.cpp
+++ b/drivers/gles3/storage/texture_storage.cpp
@@ -153,6 +153,11 @@ TextureStorage::TextureStorage() {
}
{
+ default_gl_textures[DEFAULT_GL_TEXTURE_EXT] = texture_allocate();
+ texture_external_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_EXT], 1, 1, 0);
+ }
+
+ {
unsigned char pixel_data[4 * 4 * 4];
for (int i = 0; i < 16; i++) {
pixel_data[i * 4 + 0] = 0;
@@ -729,7 +734,7 @@ void TextureStorage::texture_free(RID p_texture) {
}
}
} else {
- must_free_data = t->tex_id != 0 && !t->is_external;
+ must_free_data = t->tex_id != 0 && !t->is_from_native_handle;
}
if (must_free_data) {
GLES3::Utilities::get_singleton()->texture_free_data(t->tex_id);
@@ -769,6 +774,48 @@ void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_im
texture_set_data(p_texture, p_image);
}
+void TextureStorage::texture_external_initialize(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) {
+ Texture texture;
+ texture.active = true;
+ texture.alloc_width = texture.width = p_width;
+ texture.alloc_height = texture.height = p_height;
+ texture.real_format = texture.format = Image::FORMAT_RGB8;
+ texture.type = Texture::TYPE_2D;
+
+ if (GLES3::Config::get_singleton()->external_texture_supported) {
+ texture.target = _GL_TEXTURE_EXTERNAL_OES;
+ } else {
+ texture.target = GL_TEXTURE_2D;
+ }
+
+ glGenTextures(1, &texture.tex_id);
+ glBindTexture(texture.target, texture.tex_id);
+
+#ifdef ANDROID_ENABLED
+ if (texture.target == _GL_TEXTURE_EXTERNAL_OES) {
+ if (p_external_buffer) {
+ GLES3::Config::get_singleton()->eglEGLImageTargetTexture2DOES(_GL_TEXTURE_EXTERNAL_OES, reinterpret_cast<void *>(p_external_buffer));
+ }
+ texture.total_data_size = 0;
+ } else
+#endif
+ {
+ // If external textures aren't supported, allocate an empty 1x1 texture.
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
+ texture.total_data_size = 3;
+ }
+
+ glTexParameteri(texture.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(texture.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(texture.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(texture.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture External");
+ texture_owner.initialize_rid(p_texture, texture);
+
+ glBindTexture(texture.target, 0);
+}
+
void TextureStorage::texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) {
ERR_FAIL_COND(p_layers.is_empty());
@@ -874,26 +921,28 @@ void TextureStorage::texture_proxy_initialize(RID p_texture, RID p_base) {
texture_owner.initialize_rid(p_texture, proxy_tex);
}
-RID TextureStorage::texture_create_external(GLES3::Texture::Type p_type, Image::Format p_format, unsigned int p_image, int p_width, int p_height, int p_depth, int p_layers, RS::TextureLayeredType p_layered_type) {
+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) {
Texture texture;
texture.active = true;
- texture.is_external = true;
- texture.type = p_type;
+ texture.is_from_native_handle = true;
switch (p_type) {
- case Texture::TYPE_2D: {
+ case RS::TEXTURE_TYPE_2D: {
+ texture.type = Texture::TYPE_2D;
texture.target = GL_TEXTURE_2D;
} break;
- case Texture::TYPE_3D: {
+ case RS::TEXTURE_TYPE_3D: {
+ texture.type = Texture::TYPE_3D;
texture.target = GL_TEXTURE_3D;
} break;
- case Texture::TYPE_LAYERED: {
+ case RS::TEXTURE_TYPE_LAYERED: {
+ texture.type = Texture::TYPE_LAYERED;
texture.target = GL_TEXTURE_2D_ARRAY;
} break;
}
texture.real_format = texture.format = p_format;
- texture.tex_id = p_image;
+ texture.tex_id = p_native_handle;
texture.alloc_width = texture.width = p_width;
texture.alloc_height = texture.height = p_height;
texture.depth = p_depth;
@@ -928,6 +977,22 @@ void TextureStorage::texture_3d_update(RID p_texture, const Vector<Ref<Image>> &
GLES3::Utilities::get_singleton()->texture_resize_data(tex->tex_id, tex->total_data_size);
}
+void TextureStorage::texture_external_update(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) {
+ Texture *tex = texture_owner.get_or_null(p_texture);
+ ERR_FAIL_NULL(tex);
+
+ tex->alloc_width = tex->width = p_width;
+ tex->alloc_height = tex->height = p_height;
+
+#ifdef ANDROID_ENABLED
+ if (tex->target == _GL_TEXTURE_EXTERNAL_OES && p_external_buffer) {
+ glBindTexture(_GL_TEXTURE_EXTERNAL_OES, tex->tex_id);
+ GLES3::Config::get_singleton()->eglEGLImageTargetTexture2DOES(_GL_TEXTURE_EXTERNAL_OES, reinterpret_cast<void *>(p_external_buffer));
+ glBindTexture(_GL_TEXTURE_EXTERNAL_OES, 0);
+ }
+#endif
+}
+
void TextureStorage::texture_proxy_update(RID p_texture, RID p_proxy_to) {
Texture *tex = texture_owner.get_or_null(p_texture);
ERR_FAIL_NULL(tex);
diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h
index 5569abcc73..2bf8546c0f 100644
--- a/drivers/gles3/storage/texture_storage.h
+++ b/drivers/gles3/storage/texture_storage.h
@@ -126,6 +126,7 @@ enum DefaultGLTexture {
DEFAULT_GL_TEXTURE_3D_BLACK,
DEFAULT_GL_TEXTURE_2D_ARRAY_WHITE,
DEFAULT_GL_TEXTURE_2D_UINT,
+ DEFAULT_GL_TEXTURE_EXT,
DEFAULT_GL_TEXTURE_MAX
};
@@ -146,7 +147,7 @@ struct Texture {
RID self;
bool is_proxy = false;
- bool is_external = false;
+ bool is_from_native_handle = false;
bool is_render_target = false;
RID proxy_to;
@@ -209,7 +210,7 @@ struct Texture {
void copy_from(const Texture &o) {
proxy_to = o.proxy_to;
is_proxy = o.is_proxy;
- is_external = o.is_external;
+ is_from_native_handle = o.is_from_native_handle;
width = o.width;
height = o.height;
alloc_width = o.alloc_width;
@@ -512,12 +513,14 @@ public:
virtual void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) override;
virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) override;
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_external_initialize(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) override;
virtual void texture_proxy_initialize(RID p_texture, RID p_base) override; //all slices, then all the mipmaps, must be coherent
- RID texture_create_external(Texture::Type p_type, Image::Format p_format, unsigned int p_image, int p_width, int p_height, int p_depth, int p_layers, RS::TextureLayeredType p_layered_type = RS::TEXTURE_LAYERED_2D_ARRAY);
+ 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_external_update(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) override;
virtual void texture_proxy_update(RID p_proxy, RID p_base) override;
//these two APIs can be used together or in combination with the others.
@@ -582,7 +585,7 @@ public:
virtual RID decal_allocate() override;
virtual void decal_initialize(RID p_rid) override;
- virtual void decal_free(RID p_rid) override{};
+ virtual void decal_free(RID p_rid) override {}
virtual void decal_set_size(RID p_decal, const Vector3 &p_size) override;
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override;
diff --git a/drivers/metal/metal_objects.h b/drivers/metal/metal_objects.h
index 97f33bb1e8..030b353ee8 100644
--- a/drivers/metal/metal_objects.h
+++ b/drivers/metal/metal_objects.h
@@ -318,6 +318,13 @@ public:
dirty.set_flag(DirtyFlag::DIRTY_UNIFORMS);
}
+ _FORCE_INLINE_ void mark_blend_dirty() {
+ if (!blend_constants.has_value()) {
+ return;
+ }
+ dirty.set_flag(DirtyFlag::DIRTY_BLEND);
+ }
+
MTLScissorRect clip_to_render_area(MTLScissorRect p_rect) const {
uint32_t raLeft = render_area.position.x;
uint32_t raRight = raLeft + render_area.size.width;
diff --git a/drivers/metal/metal_objects.mm b/drivers/metal/metal_objects.mm
index d3c3d2b232..1d08a10781 100644
--- a/drivers/metal/metal_objects.mm
+++ b/drivers/metal/metal_objects.mm
@@ -143,6 +143,9 @@ void MDCommandBuffer::bind_pipeline(RDD::PipelineID p_pipeline) {
if (render.pipeline != nullptr && render.pipeline->depth_stencil != rp->depth_stencil) {
render.dirty.set_flag(RenderState::DIRTY_DEPTH);
}
+ if (rp->raster_state.blend.enabled) {
+ render.dirty.set_flag(RenderState::DIRTY_BLEND);
+ }
render.pipeline = rp;
}
} else if (p->type == MDPipelineType::Compute) {
@@ -301,6 +304,7 @@ void MDCommandBuffer::render_clear_attachments(VectorView<RDD::AttachmentClear>
render.mark_viewport_dirty();
render.mark_scissors_dirty();
render.mark_vertex_dirty();
+ render.mark_blend_dirty();
}
void MDCommandBuffer::_render_set_dirty_state() {