summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/alsa/audio_driver_alsa.cpp2
-rw-r--r--drivers/alsamidi/midi_driver_alsamidi.cpp2
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.cpp8
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp43
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.h15
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp4
-rw-r--r--drivers/gles3/rasterizer_gles3.h9
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp1110
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h429
-rw-r--r--drivers/gles3/shader_gles3.cpp8
-rw-r--r--drivers/gles3/storage/decal_atlas_storage.cpp75
-rw-r--r--drivers/gles3/storage/decal_atlas_storage.h67
-rw-r--r--drivers/gles3/storage/material_storage.cpp913
-rw-r--r--drivers/gles3/storage/material_storage.h338
-rw-r--r--drivers/gles3/storage/mesh_storage.cpp257
-rw-r--r--drivers/gles3/storage/mesh_storage.h204
-rw-r--r--drivers/gles3/storage/texture_storage.h10
-rw-r--r--drivers/gles3/texture_loader_gles3.cpp2
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.cpp12
-rw-r--r--drivers/unix/dir_access_unix.h2
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp223
-rw-r--r--drivers/vulkan/rendering_device_vulkan.h2
-rw-r--r--drivers/vulkan/vulkan_context.cpp2
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp2
-rw-r--r--drivers/xaudio2/audio_driver_xaudio2.cpp2
25 files changed, 2079 insertions, 1662 deletions
diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp
index 7884269103..f86c4d82ef 100644
--- a/drivers/alsa/audio_driver_alsa.cpp
+++ b/drivers/alsa/audio_driver_alsa.cpp
@@ -181,7 +181,7 @@ Error AudioDriverALSA::init() {
}
void AudioDriverALSA::thread_func(void *p_udata) {
- AudioDriverALSA *ad = (AudioDriverALSA *)p_udata;
+ AudioDriverALSA *ad = static_cast<AudioDriverALSA *>(p_udata);
while (!ad->exit_thread) {
ad->lock();
diff --git a/drivers/alsamidi/midi_driver_alsamidi.cpp b/drivers/alsamidi/midi_driver_alsamidi.cpp
index 0674c90cd6..c334146dd2 100644
--- a/drivers/alsamidi/midi_driver_alsamidi.cpp
+++ b/drivers/alsamidi/midi_driver_alsamidi.cpp
@@ -73,7 +73,7 @@ static int get_message_size(uint8_t message) {
}
void MIDIDriverALSAMidi::thread_func(void *p_udata) {
- MIDIDriverALSAMidi *md = (MIDIDriverALSAMidi *)p_udata;
+ MIDIDriverALSAMidi *md = static_cast<MIDIDriverALSAMidi *>(p_udata);
uint64_t timestamp = 0;
uint8_t buffer[256];
int expected_size = 255;
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp
index e2b195350f..276e69e470 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.cpp
+++ b/drivers/coreaudio/audio_driver_coreaudio.cpp
@@ -42,7 +42,7 @@
OSStatus AudioDriverCoreAudio::input_device_address_cb(AudioObjectID inObjectID,
UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses,
void *inClientData) {
- AudioDriverCoreAudio *driver = (AudioDriverCoreAudio *)inClientData;
+ AudioDriverCoreAudio *driver = static_cast<AudioDriverCoreAudio *>(inClientData);
// If our selected device is the Default call set_device to update the
// kAudioOutputUnitProperty_CurrentDevice property
@@ -56,7 +56,7 @@ OSStatus AudioDriverCoreAudio::input_device_address_cb(AudioObjectID inObjectID,
OSStatus AudioDriverCoreAudio::output_device_address_cb(AudioObjectID inObjectID,
UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses,
void *inClientData) {
- AudioDriverCoreAudio *driver = (AudioDriverCoreAudio *)inClientData;
+ AudioDriverCoreAudio *driver = static_cast<AudioDriverCoreAudio *>(inClientData);
// If our selected device is the Default call set_device to update the
// kAudioOutputUnitProperty_CurrentDevice property
@@ -168,7 +168,7 @@ OSStatus AudioDriverCoreAudio::output_callback(void *inRefCon,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList *ioData) {
- AudioDriverCoreAudio *ad = (AudioDriverCoreAudio *)inRefCon;
+ AudioDriverCoreAudio *ad = static_cast<AudioDriverCoreAudio *>(inRefCon);
if (!ad->active || !ad->try_lock()) {
for (unsigned int i = 0; i < ioData->mNumberBuffers; i++) {
@@ -209,7 +209,7 @@ OSStatus AudioDriverCoreAudio::input_callback(void *inRefCon,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList *ioData) {
- AudioDriverCoreAudio *ad = (AudioDriverCoreAudio *)inRefCon;
+ AudioDriverCoreAudio *ad = static_cast<AudioDriverCoreAudio *>(inRefCon);
if (!ad->active) {
return 0;
}
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index b47d2e08f1..1ddaf3d6a7 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -40,6 +40,7 @@
#include "servers/rendering/rendering_server_default.h"
#include "storage/canvas_texture_storage.h"
#include "storage/config.h"
+#include "storage/material_storage.h"
#ifndef GLES_OVER_GL
#define glClearDepth glClearDepthf
@@ -212,6 +213,8 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
}
void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer) {
+ GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
+ GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
Item *current_clip = nullptr;
Transform2D canvas_transform_inverse = p_canvas_transform_inverse;
@@ -228,14 +231,14 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
Item *ci = items[i];
RID material = ci->material_owner == nullptr ? ci->material : ci->material_owner->material;
- RasterizerStorageGLES3::Material *material_ptr = storage->material_owner.get_or_null(material);
+ GLES3::Material *material_ptr = material_storage->get_material(material);
if (material.is_null() && ci->canvas_group != nullptr) {
material = default_canvas_group_material;
}
if (material != prev_material) {
- RasterizerStorageGLES3::Shader *shader_ptr = nullptr;
+ GLES3::Shader *shader_ptr = nullptr;
if (material_ptr) {
shader_ptr = material_ptr->shader;
@@ -360,7 +363,6 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item
state.instance_data_array[r_index].dst_rect[i] = 0.0;
state.instance_data_array[r_index].lights[i] = uint32_t(0);
}
- state.instance_data_array[r_index].flags = base_flags;
state.instance_data_array[r_index].color_texture_pixel_size[0] = 0.0;
state.instance_data_array[r_index].color_texture_pixel_size[1] = 0.0;
@@ -906,6 +908,8 @@ void RasterizerCanvasGLES3::canvas_end() {
}
void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, uint32_t &r_index, RID &r_last_texture, Size2 &r_texpixel_size) {
+ GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
+
if (p_texture == RID()) {
p_texture = default_canvas_texture;
}
@@ -1251,9 +1255,8 @@ void RasterizerCanvasGLES3::_allocate_instance_data_buffer() {
}
void RasterizerCanvasGLES3::initialize() {
- // !BAS! shouldn't we be obtaining storage here as well?
- canvas_texture_storage = GLES3::CanvasTextureStorage::get_singleton();
- texture_storage = GLES3::TextureStorage::get_singleton();
+ GLES3::CanvasTextureStorage *canvas_texture_storage = GLES3::CanvasTextureStorage::get_singleton();
+ GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
// quad buffer
{
@@ -1423,10 +1426,10 @@ void RasterizerCanvasGLES3::initialize() {
//state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_PIXEL_SNAP, GLOBAL_DEF("rendering/quality/2d/use_pixel_snap", false));
{
- default_canvas_group_shader = storage->shader_allocate();
- storage->shader_initialize(default_canvas_group_shader);
+ default_canvas_group_shader = material_storage->shader_allocate();
+ material_storage->shader_initialize(default_canvas_group_shader);
- storage->shader_set_code(default_canvas_group_shader, R"(
+ material_storage->shader_set_code(default_canvas_group_shader, R"(
// Default CanvasGroup shader.
shader_type canvas_item;
@@ -1441,10 +1444,10 @@ void fragment() {
COLOR *= c;
}
)");
- default_canvas_group_material = storage->material_allocate();
- storage->material_initialize(default_canvas_group_material);
+ default_canvas_group_material = material_storage->material_allocate();
+ material_storage->material_initialize(default_canvas_group_material);
- storage->material_set_shader(default_canvas_group_material, default_canvas_group_shader);
+ material_storage->material_set_shader(default_canvas_group_material, default_canvas_group_shader);
}
default_canvas_texture = canvas_texture_storage->canvas_texture_allocate();
@@ -1456,13 +1459,25 @@ void fragment() {
state.current_shader_version = state.canvas_shader_default_version;
}
+RasterizerCanvasGLES3 *RasterizerCanvasGLES3::singleton = nullptr;
+
+RasterizerCanvasGLES3 *RasterizerCanvasGLES3::get_singleton() {
+ return singleton;
+}
+
RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
+ singleton = this;
}
+
RasterizerCanvasGLES3::~RasterizerCanvasGLES3() {
+ GLES3::CanvasTextureStorage *canvas_texture_storage = GLES3::CanvasTextureStorage::get_singleton();
+ GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
+
state.canvas_shader.version_free(state.canvas_shader_default_version);
- storage->free(default_canvas_group_material);
- storage->free(default_canvas_group_shader);
+ material_storage->material_free(default_canvas_group_material);
+ material_storage->shader_free(default_canvas_group_shader);
canvas_texture_storage->canvas_texture_free(default_canvas_texture);
+ singleton = nullptr;
}
void RasterizerCanvasGLES3::finalize() {
diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h
index 1f57c2b5ea..70066c5e2a 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.h
+++ b/drivers/gles3/rasterizer_canvas_gles3.h
@@ -38,6 +38,7 @@
#include "servers/rendering/renderer_canvas_render.h"
#include "servers/rendering/renderer_compositor.h"
#include "storage/canvas_texture_storage.h"
+#include "storage/material_storage.h"
#include "storage/texture_storage.h"
#include "shaders/canvas.glsl.gen.h"
@@ -45,6 +46,8 @@
class RasterizerSceneGLES3;
class RasterizerCanvasGLES3 : public RendererCanvasRender {
+ static RasterizerCanvasGLES3 *singleton;
+
_FORCE_INLINE_ void _update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4);
_FORCE_INLINE_ void _update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3);
@@ -166,7 +169,7 @@ public:
LocalVector<GLsync> fences;
uint32_t current_buffer = 0;
- InstanceData *instance_data_array;
+ InstanceData *instance_data_array = nullptr;
bool canvas_texscreen_used;
CanvasShaderGLES3 canvas_shader;
RID canvas_shader_current_version;
@@ -195,7 +198,7 @@ public:
bool end_batch = false;
Transform3D vp;
- Light *using_light;
+ Light *using_light = nullptr;
bool using_shadow;
bool using_transparent_rt;
@@ -217,11 +220,9 @@ public:
typedef void Texture;
- RasterizerSceneGLES3 *scene_render;
+ RasterizerSceneGLES3 *scene_render = nullptr;
- GLES3::CanvasTextureStorage *canvas_texture_storage;
- GLES3::TextureStorage *texture_storage;
- RasterizerStorageGLES3 *storage;
+ RasterizerStorageGLES3 *storage = nullptr;
void _set_uniforms();
@@ -277,6 +278,8 @@ public:
void initialize();
void finalize();
+
+ static RasterizerCanvasGLES3 *get_singleton();
RasterizerCanvasGLES3();
~RasterizerCanvasGLES3();
};
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index faadb2a4ed..61aefc1192 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -260,9 +260,9 @@ void RasterizerGLES3::initialize() {
RasterizerGLES3::RasterizerGLES3() {
canvas.storage = &storage;
canvas.scene_render = &scene;
- storage.canvas = &canvas;
+ //storage.canvas = &canvas;
//scene.storage = &storage;
- storage.scene = &scene;
+ //storage.scene = &scene;
}
void RasterizerGLES3::prepare_for_blitting_render_targets() {
diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h
index 93c58a8d9d..2279a502a2 100644
--- a/drivers/gles3/rasterizer_gles3.h
+++ b/drivers/gles3/rasterizer_gles3.h
@@ -39,6 +39,9 @@
#include "servers/rendering/renderer_compositor.h"
#include "storage/canvas_texture_storage.h"
#include "storage/config.h"
+#include "storage/decal_atlas_storage.h"
+#include "storage/material_storage.h"
+#include "storage/mesh_storage.h"
#include "storage/render_target_storage.h"
#include "storage/texture_storage.h"
@@ -53,6 +56,9 @@ protected:
GLES3::Config config;
GLES3::CanvasTextureStorage canvas_texture_storage;
GLES3::TextureStorage texture_storage;
+ GLES3::DecalAtlasStorage decal_atlas_storage;
+ GLES3::MaterialStorage material_storage;
+ GLES3::MeshStorage mesh_storage;
RasterizerStorageGLES3 storage;
RasterizerCanvasGLES3 canvas;
RasterizerSceneGLES3 scene;
@@ -61,7 +67,10 @@ protected:
public:
RendererCanvasTextureStorage *get_canvas_texture_storage() { return &canvas_texture_storage; }
+ RendererMaterialStorage *get_material_storage() { return &material_storage; }
+ RendererMeshStorage *get_mesh_storage() { return &mesh_storage; }
RendererTextureStorage *get_texture_storage() { return &texture_storage; }
+ RendererDecalAtlasStorage *get_decal_atlas_storage() { return &decal_atlas_storage; }
RendererStorage *get_storage() { return &storage; }
RendererCanvasRender *get_canvas() { return &canvas; }
RendererSceneRender *get_scene() { return &scene; }
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 158b96ef27..3517d985f0 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -34,7 +34,7 @@
#include "core/config/project_settings.h"
#include "core/math/transform_3d.h"
-#include "rasterizer_canvas_gles3.h"
+// #include "rasterizer_canvas_gles3.h"
#include "rasterizer_scene_gles3.h"
#include "servers/rendering/shader_language.h"
@@ -58,951 +58,6 @@ RID RasterizerStorageGLES3::sky_create() {
void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_radiance_size) {
}
-/* SHADER API */
-
-RID RasterizerStorageGLES3::shader_allocate() {
- Shader *shader = memnew(Shader);
- shader->mode = RS::SHADER_CANVAS_ITEM;
- //shader->shader = &scene->state.scene_shader;
- RID rid = shader_owner.make_rid(shader);
- _shader_make_dirty(shader);
- shader->self = rid;
-
- return rid;
-}
-
-void RasterizerStorageGLES3::shader_initialize(RID p_rid) {
- // noop
-}
-
-//RID RasterizerStorageGLES3::shader_create() {
-// Shader *shader = memnew(Shader);
-// shader->mode = RS::SHADER_SPATIAL;
-// shader->shader = &scene->state.scene_shader;
-// RID rid = shader_owner.make_rid(shader);
-// _shader_make_dirty(shader);
-// shader->self = rid;
-
-// return rid;
-//}
-
-void RasterizerStorageGLES3::_shader_make_dirty(Shader *p_shader) {
- if (p_shader->dirty_list.in_list()) {
- return;
- }
-
- _shader_dirty_list.add(&p_shader->dirty_list);
-}
-
-void RasterizerStorageGLES3::shader_set_code(RID p_shader, const String &p_code) {
- Shader *shader = shader_owner.get_or_null(p_shader);
- ERR_FAIL_COND(!shader);
-
- shader->code = p_code;
-
- String mode_string = ShaderLanguage::get_shader_type(p_code);
- RS::ShaderMode mode;
-
- if (mode_string == "canvas_item") {
- mode = RS::SHADER_CANVAS_ITEM;
- } else if (mode_string == "particles") {
- mode = RS::SHADER_PARTICLES;
- } else if (mode_string == "sky") {
- mode = RS::SHADER_SKY;
- } else if (mode_string == "spatial") {
- mode = RS::SHADER_SPATIAL;
- } else {
- mode = RS::SHADER_MAX;
- ERR_PRINT("shader type " + mode_string + " not supported in OpenGL renderer");
- }
-
- if (shader->version.is_valid() && mode != shader->mode) {
- shader->shader->version_free(shader->version);
- shader->version = RID();
- }
-
- shader->mode = mode;
-
- // TODO handle all shader types
- if (mode == RS::SHADER_CANVAS_ITEM) {
- shader->shader = &canvas->state.canvas_shader;
-
- } else if (mode == RS::SHADER_SPATIAL) {
- //shader->shader = &scene->state.scene_shader;
- } else if (mode == RS::SHADER_PARTICLES) {
- } else if (mode == RS::SHADER_SKY) {
- } else {
- return;
- }
-
- if (shader->version.is_null() && shader->shader) {
- shader->version = shader->shader->version_create();
- }
-
- _shader_make_dirty(shader);
-}
-
-String RasterizerStorageGLES3::shader_get_code(RID p_shader) const {
- const Shader *shader = shader_owner.get_or_null(p_shader);
- ERR_FAIL_COND_V(!shader, "");
-
- return shader->code;
-}
-
-void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
- _shader_dirty_list.remove(&p_shader->dirty_list);
-
- p_shader->valid = false;
-
- p_shader->uniforms.clear();
-
- if (p_shader->code.is_empty()) {
- return; //just invalid, but no error
- }
-
- ShaderCompiler::GeneratedCode gen_code;
- ShaderCompiler::IdentifierActions *actions = nullptr;
-
- switch (p_shader->mode) {
- case RS::SHADER_CANVAS_ITEM: {
- p_shader->canvas_item.light_mode = Shader::CanvasItem::LIGHT_MODE_NORMAL;
- p_shader->canvas_item.blend_mode = Shader::CanvasItem::BLEND_MODE_MIX;
-
- p_shader->canvas_item.uses_screen_texture = false;
- p_shader->canvas_item.uses_screen_uv = false;
- p_shader->canvas_item.uses_time = false;
- p_shader->canvas_item.uses_modulate = false;
- p_shader->canvas_item.uses_color = false;
- p_shader->canvas_item.uses_vertex = false;
-
- p_shader->canvas_item.uses_model_matrix = false;
- p_shader->canvas_item.uses_extra_matrix = false;
- p_shader->canvas_item.uses_projection_matrix = false;
- p_shader->canvas_item.uses_instance_custom = false;
-
- shaders.actions_canvas.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_ADD);
- shaders.actions_canvas.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MIX);
- shaders.actions_canvas.render_mode_values["blend_sub"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_SUB);
- shaders.actions_canvas.render_mode_values["blend_mul"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MUL);
- shaders.actions_canvas.render_mode_values["blend_premul_alpha"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_PMALPHA);
-
- shaders.actions_canvas.render_mode_values["unshaded"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, Shader::CanvasItem::LIGHT_MODE_UNSHADED);
- shaders.actions_canvas.render_mode_values["light_only"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, Shader::CanvasItem::LIGHT_MODE_LIGHT_ONLY);
-
- shaders.actions_canvas.usage_flag_pointers["SCREEN_UV"] = &p_shader->canvas_item.uses_screen_uv;
- shaders.actions_canvas.usage_flag_pointers["SCREEN_PIXEL_SIZE"] = &p_shader->canvas_item.uses_screen_uv;
- shaders.actions_canvas.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->canvas_item.uses_screen_texture;
- shaders.actions_canvas.usage_flag_pointers["TIME"] = &p_shader->canvas_item.uses_time;
- shaders.actions_canvas.usage_flag_pointers["MODULATE"] = &p_shader->canvas_item.uses_modulate;
- shaders.actions_canvas.usage_flag_pointers["COLOR"] = &p_shader->canvas_item.uses_color;
-
- shaders.actions_canvas.usage_flag_pointers["VERTEX"] = &p_shader->canvas_item.uses_vertex;
-
- shaders.actions_canvas.usage_flag_pointers["MODEL_MATRIX"] = &p_shader->canvas_item.uses_model_matrix;
- shaders.actions_canvas.usage_flag_pointers["EXTRA_MATRIX"] = &p_shader->canvas_item.uses_extra_matrix;
- shaders.actions_canvas.usage_flag_pointers["PROJECTION_MATRIX"] = &p_shader->canvas_item.uses_projection_matrix;
- shaders.actions_canvas.usage_flag_pointers["INSTANCE_CUSTOM"] = &p_shader->canvas_item.uses_instance_custom;
-
- actions = &shaders.actions_canvas;
- actions->uniforms = &p_shader->uniforms;
- } break;
-
- case RS::SHADER_SPATIAL: {
- // TODO remove once 3D is added back
- return;
- p_shader->spatial.blend_mode = Shader::Spatial::BLEND_MODE_MIX;
- p_shader->spatial.depth_draw_mode = Shader::Spatial::DEPTH_DRAW_OPAQUE;
- p_shader->spatial.cull_mode = Shader::Spatial::CULL_MODE_BACK;
- p_shader->spatial.uses_alpha = false;
- p_shader->spatial.uses_alpha_scissor = false;
- p_shader->spatial.uses_discard = false;
- p_shader->spatial.unshaded = false;
- p_shader->spatial.no_depth_test = false;
- p_shader->spatial.uses_sss = false;
- p_shader->spatial.uses_time = false;
- p_shader->spatial.uses_vertex_lighting = false;
- p_shader->spatial.uses_screen_texture = false;
- p_shader->spatial.uses_depth_texture = false;
- p_shader->spatial.uses_vertex = false;
- p_shader->spatial.uses_tangent = false;
- p_shader->spatial.uses_ensure_correct_normals = false;
- p_shader->spatial.writes_modelview_or_projection = false;
- p_shader->spatial.uses_world_coordinates = false;
-
- shaders.actions_scene.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_ADD);
- shaders.actions_scene.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_MIX);
- shaders.actions_scene.render_mode_values["blend_sub"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_SUB);
- shaders.actions_scene.render_mode_values["blend_mul"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_MUL);
-
- shaders.actions_scene.render_mode_values["depth_draw_opaque"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_OPAQUE);
- shaders.actions_scene.render_mode_values["depth_draw_always"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_ALWAYS);
- shaders.actions_scene.render_mode_values["depth_draw_never"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_NEVER);
- shaders.actions_scene.render_mode_values["depth_draw_alpha_prepass"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS);
-
- shaders.actions_scene.render_mode_values["cull_front"] = Pair<int *, int>(&p_shader->spatial.cull_mode, Shader::Spatial::CULL_MODE_FRONT);
- shaders.actions_scene.render_mode_values["cull_back"] = Pair<int *, int>(&p_shader->spatial.cull_mode, Shader::Spatial::CULL_MODE_BACK);
- shaders.actions_scene.render_mode_values["cull_disabled"] = Pair<int *, int>(&p_shader->spatial.cull_mode, Shader::Spatial::CULL_MODE_DISABLED);
-
- shaders.actions_scene.render_mode_flags["unshaded"] = &p_shader->spatial.unshaded;
- shaders.actions_scene.render_mode_flags["depth_test_disable"] = &p_shader->spatial.no_depth_test;
-
- shaders.actions_scene.render_mode_flags["vertex_lighting"] = &p_shader->spatial.uses_vertex_lighting;
-
- shaders.actions_scene.render_mode_flags["world_vertex_coords"] = &p_shader->spatial.uses_world_coordinates;
-
- shaders.actions_scene.render_mode_flags["ensure_correct_normals"] = &p_shader->spatial.uses_ensure_correct_normals;
-
- shaders.actions_scene.usage_flag_pointers["ALPHA"] = &p_shader->spatial.uses_alpha;
- shaders.actions_scene.usage_flag_pointers["ALPHA_SCISSOR"] = &p_shader->spatial.uses_alpha_scissor;
-
- shaders.actions_scene.usage_flag_pointers["SSS_STRENGTH"] = &p_shader->spatial.uses_sss;
- shaders.actions_scene.usage_flag_pointers["DISCARD"] = &p_shader->spatial.uses_discard;
- shaders.actions_scene.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->spatial.uses_screen_texture;
- shaders.actions_scene.usage_flag_pointers["DEPTH_TEXTURE"] = &p_shader->spatial.uses_depth_texture;
- shaders.actions_scene.usage_flag_pointers["TIME"] = &p_shader->spatial.uses_time;
-
- // Use of any of these BUILTINS indicate the need for transformed tangents.
- // This is needed to know when to transform tangents in software skinning.
- shaders.actions_scene.usage_flag_pointers["TANGENT"] = &p_shader->spatial.uses_tangent;
- shaders.actions_scene.usage_flag_pointers["NORMALMAP"] = &p_shader->spatial.uses_tangent;
-
- shaders.actions_scene.write_flag_pointers["MODELVIEW_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
- shaders.actions_scene.write_flag_pointers["PROJECTION_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
- shaders.actions_scene.write_flag_pointers["VERTEX"] = &p_shader->spatial.uses_vertex;
-
- actions = &shaders.actions_scene;
- actions->uniforms = &p_shader->uniforms;
- } break;
-
- default: {
- return;
- } break;
- }
-
- Error err = shaders.compiler.compile(p_shader->mode, p_shader->code, actions, p_shader->path, gen_code);
- if (err != OK) {
- return;
- }
-
- Vector<StringName> texture_uniform_names;
- for (int i = 0; i < gen_code.texture_uniforms.size(); i++) {
- texture_uniform_names.push_back(gen_code.texture_uniforms[i].name);
- }
-
- p_shader->shader->version_set_code(p_shader->version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_names);
-
- p_shader->texture_uniforms = gen_code.texture_uniforms;
-
- p_shader->uses_vertex_time = gen_code.uses_vertex_time;
- p_shader->uses_fragment_time = gen_code.uses_fragment_time;
-
- for (SelfList<Material> *E = p_shader->materials.first(); E; E = E->next()) {
- _material_make_dirty(E->self());
- }
-
- p_shader->valid = true;
-}
-
-void RasterizerStorageGLES3::update_dirty_shaders() {
- while (_shader_dirty_list.first()) {
- _update_shader(_shader_dirty_list.first()->self());
- }
-}
-
-void RasterizerStorageGLES3::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const {
- Shader *shader = shader_owner.get_or_null(p_shader);
- ERR_FAIL_COND(!shader);
-
- if (shader->dirty_list.in_list()) {
- _update_shader(shader);
- }
-
- Map<int, StringName> order;
-
- for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) {
- if (E->get().texture_order >= 0) {
- order[E->get().texture_order + 100000] = E->key();
- } else {
- order[E->get().order] = E->key();
- }
- }
-
- for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) {
- PropertyInfo pi;
- ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[E->get()];
-
- pi.name = E->get();
-
- switch (u.type) {
- case ShaderLanguage::TYPE_VOID: {
- pi.type = Variant::NIL;
- } break;
-
- case ShaderLanguage::TYPE_BOOL: {
- pi.type = Variant::BOOL;
- } break;
-
- // bool vectors
- case ShaderLanguage::TYPE_BVEC2: {
- pi.type = Variant::INT;
- pi.hint = PROPERTY_HINT_FLAGS;
- pi.hint_string = "x,y";
- } break;
- case ShaderLanguage::TYPE_BVEC3: {
- pi.type = Variant::INT;
- pi.hint = PROPERTY_HINT_FLAGS;
- pi.hint_string = "x,y,z";
- } break;
- case ShaderLanguage::TYPE_BVEC4: {
- pi.type = Variant::INT;
- pi.hint = PROPERTY_HINT_FLAGS;
- pi.hint_string = "x,y,z,w";
- } break;
-
- // int stuff
- case ShaderLanguage::TYPE_UINT:
- case ShaderLanguage::TYPE_INT: {
- pi.type = Variant::INT;
-
- if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
- pi.hint = PROPERTY_HINT_RANGE;
- pi.hint_string = rtos(u.hint_range[0]) + "," + rtos(u.hint_range[1]) + "," + rtos(u.hint_range[2]);
- }
- } break;
-
- case ShaderLanguage::TYPE_IVEC2:
- case ShaderLanguage::TYPE_UVEC2:
- case ShaderLanguage::TYPE_IVEC3:
- case ShaderLanguage::TYPE_UVEC3:
- case ShaderLanguage::TYPE_IVEC4:
- case ShaderLanguage::TYPE_UVEC4: {
- // not sure what this should be in godot 4
- // pi.type = Variant::POOL_INT_ARRAY;
- pi.type = Variant::PACKED_INT32_ARRAY;
- } break;
-
- case ShaderLanguage::TYPE_FLOAT: {
- pi.type = Variant::FLOAT;
- if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
- pi.hint = PROPERTY_HINT_RANGE;
- pi.hint_string = rtos(u.hint_range[0]) + "," + rtos(u.hint_range[1]) + "," + rtos(u.hint_range[2]);
- }
- } break;
-
- case ShaderLanguage::TYPE_VEC2: {
- pi.type = Variant::VECTOR2;
- } break;
- case ShaderLanguage::TYPE_VEC3: {
- pi.type = Variant::VECTOR3;
- } break;
-
- case ShaderLanguage::TYPE_VEC4: {
- if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
- pi.type = Variant::COLOR;
- } else {
- pi.type = Variant::PLANE;
- }
- } break;
-
- case ShaderLanguage::TYPE_MAT2: {
- pi.type = Variant::TRANSFORM2D;
- } break;
-
- case ShaderLanguage::TYPE_MAT3: {
- pi.type = Variant::BASIS;
- } break;
-
- case ShaderLanguage::TYPE_MAT4: {
- pi.type = Variant::TRANSFORM3D;
- } break;
-
- case ShaderLanguage::TYPE_SAMPLER2D:
- // case ShaderLanguage::TYPE_SAMPLEREXT:
- case ShaderLanguage::TYPE_ISAMPLER2D:
- case ShaderLanguage::TYPE_USAMPLER2D: {
- pi.type = Variant::OBJECT;
- pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
- pi.hint_string = "Texture";
- } break;
-
- case ShaderLanguage::TYPE_SAMPLERCUBE: {
- pi.type = Variant::OBJECT;
- pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
- pi.hint_string = "CubeMap";
- } break;
-
- case ShaderLanguage::TYPE_SAMPLER2DARRAY:
- case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
- case ShaderLanguage::TYPE_USAMPLER2DARRAY:
- case ShaderLanguage::TYPE_SAMPLER3D:
- case ShaderLanguage::TYPE_ISAMPLER3D:
- case ShaderLanguage::TYPE_USAMPLER3D: {
- // Not implemented in OpenGL
- } break;
- // new for godot 4
- case ShaderLanguage::TYPE_SAMPLERCUBEARRAY:
- case ShaderLanguage::TYPE_STRUCT:
- case ShaderLanguage::TYPE_MAX: {
- } break;
- }
-
- p_param_list->push_back(pi);
- }
-}
-
-void RasterizerStorageGLES3::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) {
- Shader *shader = shader_owner.get_or_null(p_shader);
- ERR_FAIL_COND(!shader);
- ERR_FAIL_COND(p_texture.is_valid() && !GLES3::TextureStorage::get_singleton()->owns_texture(p_texture));
-
- if (!p_texture.is_valid()) {
- if (shader->default_textures.has(p_name) && shader->default_textures[p_name].has(p_index)) {
- shader->default_textures[p_name].erase(p_index);
-
- if (shader->default_textures[p_name].is_empty()) {
- shader->default_textures.erase(p_name);
- }
- }
- } else {
- if (!shader->default_textures.has(p_name)) {
- shader->default_textures[p_name] = Map<int, RID>();
- }
- shader->default_textures[p_name][p_index] = p_texture;
- }
-
- _shader_make_dirty(shader);
-}
-
-RID RasterizerStorageGLES3::shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const {
- const Shader *shader = shader_owner.get_or_null(p_shader);
- ERR_FAIL_COND_V(!shader, RID());
-
- if (shader->default_textures.has(p_name) && shader->default_textures[p_name].has(p_index)) {
- return shader->default_textures[p_name][p_index];
- }
-
- return RID();
-}
-
-/* COMMON MATERIAL API */
-
-void RasterizerStorageGLES3::_material_make_dirty(Material *p_material) const {
- if (p_material->dirty_list.in_list()) {
- return;
- }
-
- _material_dirty_list.add(&p_material->dirty_list);
-}
-
-RID RasterizerStorageGLES3::material_allocate() {
- Material *material = memnew(Material);
- return material_owner.make_rid(material);
-}
-
-void RasterizerStorageGLES3::material_initialize(RID p_rid) {
-}
-
-//RID RasterizerStorageGLES3::material_create() {
-// Material *material = memnew(Material);
-
-// return material_owner.make_rid(material);
-//}
-
-void RasterizerStorageGLES3::material_set_shader(RID p_material, RID p_shader) {
- Material *material = material_owner.get_or_null(p_material);
- ERR_FAIL_COND(!material);
-
- Shader *shader = shader_owner.get_or_null(p_shader);
-
- if (material->shader) {
- // if a shader is present, remove the old shader
- material->shader->materials.remove(&material->list);
- }
-
- material->shader = shader;
-
- if (shader) {
- shader->materials.add(&material->list);
- }
-
- _material_make_dirty(material);
-}
-
-RID RasterizerStorageGLES3::material_get_shader(RID p_material) const {
- const Material *material = material_owner.get_or_null(p_material);
- ERR_FAIL_COND_V(!material, RID());
-
- if (material->shader) {
- return material->shader->self;
- }
-
- return RID();
-}
-
-void RasterizerStorageGLES3::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) {
- Material *material = material_owner.get_or_null(p_material);
- ERR_FAIL_COND(!material);
-
- if (p_value.get_type() == Variant::NIL) {
- material->params.erase(p_param);
- } else {
- material->params[p_param] = p_value;
- }
-
- _material_make_dirty(material);
-}
-
-Variant RasterizerStorageGLES3::material_get_param(RID p_material, const StringName &p_param) const {
- const Material *material = material_owner.get_or_null(p_material);
- ERR_FAIL_COND_V(!material, RID());
-
- if (material->params.has(p_param)) {
- return material->params[p_param];
- }
-
- return material_get_param_default(p_material, p_param);
-}
-
-Variant RasterizerStorageGLES3::material_get_param_default(RID p_material, const StringName &p_param) const {
- const Material *material = material_owner.get_or_null(p_material);
- ERR_FAIL_COND_V(!material, Variant());
-
- if (material->shader) {
- if (material->shader->uniforms.has(p_param)) {
- ShaderLanguage::ShaderNode::Uniform uniform = material->shader->uniforms[p_param];
- Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
- return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.hint);
- }
- }
- return Variant();
-}
-
-void RasterizerStorageGLES3::material_set_line_width(RID p_material, float p_width) {
- Material *material = material_owner.get_or_null(p_material);
- ERR_FAIL_COND(!material);
-
- material->line_width = p_width;
-}
-
-void RasterizerStorageGLES3::material_set_next_pass(RID p_material, RID p_next_material) {
- Material *material = material_owner.get_or_null(p_material);
- ERR_FAIL_COND(!material);
-
- material->next_pass = p_next_material;
-}
-
-bool RasterizerStorageGLES3::material_is_animated(RID p_material) {
- Material *material = material_owner.get_or_null(p_material);
- ERR_FAIL_COND_V(!material, false);
- if (material->dirty_list.in_list()) {
- _update_material(material);
- }
-
- bool animated = material->is_animated_cache;
- if (!animated && material->next_pass.is_valid()) {
- animated = material_is_animated(material->next_pass);
- }
- return animated;
-}
-
-bool RasterizerStorageGLES3::material_casts_shadows(RID p_material) {
- Material *material = material_owner.get_or_null(p_material);
- ERR_FAIL_COND_V(!material, false);
- if (material->dirty_list.in_list()) {
- _update_material(material);
- }
-
- bool casts_shadows = material->can_cast_shadow_cache;
-
- if (!casts_shadows && material->next_pass.is_valid()) {
- casts_shadows = material_casts_shadows(material->next_pass);
- }
-
- return casts_shadows;
-}
-
-bool RasterizerStorageGLES3::material_uses_tangents(RID p_material) {
- Material *material = material_owner.get_or_null(p_material);
- ERR_FAIL_COND_V(!material, false);
-
- if (!material->shader) {
- return false;
- }
-
- if (material->shader->dirty_list.in_list()) {
- _update_shader(material->shader);
- }
-
- return material->shader->spatial.uses_tangent;
-}
-
-bool RasterizerStorageGLES3::material_uses_ensure_correct_normals(RID p_material) {
- Material *material = material_owner.get_or_null(p_material);
- ERR_FAIL_COND_V(!material, false);
-
- if (!material->shader) {
- return false;
- }
-
- if (material->shader->dirty_list.in_list()) {
- _update_shader(material->shader);
- }
-
- return material->shader->spatial.uses_ensure_correct_normals;
-}
-
-void RasterizerStorageGLES3::material_add_instance_owner(RID p_material, DependencyTracker *p_instance) {
- /*
- Material *material = material_owner.get_or_null(p_material);
- ERR_FAIL_COND(!material);
-
- Map<InstanceBaseDependency *, int>::Element *E = material->instance_owners.find(p_instance);
- if (E) {
- E->get()++;
- } else {
- material->instance_owners[p_instance] = 1;
- }
-*/
-}
-
-void RasterizerStorageGLES3::material_remove_instance_owner(RID p_material, DependencyTracker *p_instance) {
- /*
- Material *material = material_owner.get_or_null(p_material);
- ERR_FAIL_COND(!material);
-
- Map<InstanceBaseDependency *, int>::Element *E = material->instance_owners.find(p_instance);
- ERR_FAIL_COND(!E);
-
- E->get()--;
-
- if (E->get() == 0) {
- material->instance_owners.erase(E);
- }
-*/
-}
-
-void RasterizerStorageGLES3::material_set_render_priority(RID p_material, int priority) {
- ERR_FAIL_COND(priority < RS::MATERIAL_RENDER_PRIORITY_MIN);
- ERR_FAIL_COND(priority > RS::MATERIAL_RENDER_PRIORITY_MAX);
-
- Material *material = material_owner.get_or_null(p_material);
- ERR_FAIL_COND(!material);
-
- material->render_priority = priority;
-}
-
-void RasterizerStorageGLES3::_update_material(Material *p_material) {
- if (p_material->dirty_list.in_list()) {
- _material_dirty_list.remove(&p_material->dirty_list);
- }
-
- if (p_material->shader && p_material->shader->dirty_list.in_list()) {
- _update_shader(p_material->shader);
- }
-
- if (p_material->shader && !p_material->shader->valid) {
- return;
- }
-
- {
- bool can_cast_shadow = false;
- bool is_animated = false;
-
- if (p_material->shader && p_material->shader->mode == RS::SHADER_SPATIAL) {
- if (p_material->shader->spatial.blend_mode == Shader::Spatial::BLEND_MODE_MIX &&
- (!p_material->shader->spatial.uses_alpha || p_material->shader->spatial.depth_draw_mode == Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS)) {
- can_cast_shadow = true;
- }
-
- if (p_material->shader->spatial.uses_discard && p_material->shader->uses_fragment_time) {
- is_animated = true;
- }
-
- if (p_material->shader->spatial.uses_vertex && p_material->shader->uses_vertex_time) {
- is_animated = true;
- }
-
- if (can_cast_shadow != p_material->can_cast_shadow_cache || is_animated != p_material->is_animated_cache) {
- p_material->can_cast_shadow_cache = can_cast_shadow;
- p_material->is_animated_cache = is_animated;
-
- /*
- for (Map<Geometry *, int>::Element *E = p_material->geometry_owners.front(); E; E = E->next()) {
- E->key()->material_changed_notify();
- }
-
- for (Map<InstanceBaseDependency *, int>::Element *E = p_material->instance_owners.front(); E; E = E->next()) {
- E->key()->base_changed(false, true);
- }
- */
- }
- }
- }
-
- // uniforms and other things will be set in the use_material method in ShaderGLES3
-
- if (p_material->shader && p_material->shader->texture_uniforms.size() > 0) {
- p_material->textures.resize(p_material->shader->texture_uniforms.size());
-
- for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_material->shader->uniforms.front(); E; E = E->next()) {
- if (E->get().texture_order < 0) {
- continue; // not a texture, does not go here
- }
-
- RID texture;
-
- Map<StringName, Variant>::Element *V = p_material->params.find(E->key());
-
- if (V) {
- texture = V->get();
- }
-
- if (!texture.is_valid()) {
- Map<StringName, Map<int, RID>>::Element *W = p_material->shader->default_textures.find(E->key());
-
- // TODO: make texture uniform array properly works with GLES3
- if (W && W->get().has(0)) {
- texture = W->get()[0];
- }
- }
-
- p_material->textures.write[E->get().texture_order] = Pair<StringName, RID>(E->key(), texture);
- }
- } else {
- p_material->textures.clear();
- }
-}
-/*
-void RasterizerStorageGLES3::_material_add_geometry(RID p_material, Geometry *p_geometry) {
- Material *material = material_owner.get_or_null(p_material);
- ERR_FAIL_COND(!material);
-
- Map<Geometry *, int>::Element *I = material->geometry_owners.find(p_geometry);
-
- if (I) {
- I->get()++;
- } else {
- material->geometry_owners[p_geometry] = 1;
- }
-}
-
-void RasterizerStorageGLES3::_material_remove_geometry(RID p_material, Geometry *p_geometry) {
- Material *material = material_owner.get_or_null(p_material);
- ERR_FAIL_COND(!material);
-
- Map<Geometry *, int>::Element *I = material->geometry_owners.find(p_geometry);
- ERR_FAIL_COND(!I);
-
- I->get()--;
-
- if (I->get() == 0) {
- material->geometry_owners.erase(I);
- }
-}
-*/
-void RasterizerStorageGLES3::update_dirty_materials() {
- while (_material_dirty_list.first()) {
- Material *material = _material_dirty_list.first()->self();
- _update_material(material);
- }
-}
-
-/* MESH API */
-
-RID RasterizerStorageGLES3::mesh_allocate() {
- return RID();
-}
-
-void RasterizerStorageGLES3::mesh_initialize(RID p_rid) {
-}
-
-void RasterizerStorageGLES3::mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) {
-}
-
-bool RasterizerStorageGLES3::mesh_needs_instance(RID p_mesh, bool p_has_skeleton) {
- return false;
-}
-
-RID RasterizerStorageGLES3::mesh_instance_create(RID p_base) {
- return RID();
-}
-
-void RasterizerStorageGLES3::mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) {
-}
-
-void RasterizerStorageGLES3::mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) {
-}
-
-void RasterizerStorageGLES3::mesh_instance_check_for_update(RID p_mesh_instance) {
-}
-
-void RasterizerStorageGLES3::update_mesh_instances() {
-}
-
-void RasterizerStorageGLES3::reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) {
-}
-
-float RasterizerStorageGLES3::reflection_probe_get_mesh_lod_threshold(RID p_probe) const {
- return 0.0;
-}
-
-void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) {
-}
-
-int RasterizerStorageGLES3::mesh_get_blend_shape_count(RID p_mesh) const {
- return 0;
-}
-
-void RasterizerStorageGLES3::mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) {
-}
-
-RS::BlendShapeMode RasterizerStorageGLES3::mesh_get_blend_shape_mode(RID p_mesh) const {
- return RS::BLEND_SHAPE_MODE_NORMALIZED;
-}
-
-void RasterizerStorageGLES3::mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
-}
-
-void RasterizerStorageGLES3::mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
-}
-
-void RasterizerStorageGLES3::mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
-}
-
-void RasterizerStorageGLES3::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) {
-}
-
-RID RasterizerStorageGLES3::mesh_surface_get_material(RID p_mesh, int p_surface) const {
- return RID();
-}
-
-RS::SurfaceData RasterizerStorageGLES3::mesh_get_surface(RID p_mesh, int p_surface) const {
- return RS::SurfaceData();
-}
-
-int RasterizerStorageGLES3::mesh_get_surface_count(RID p_mesh) const {
- return 1;
-}
-
-void RasterizerStorageGLES3::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) {
-}
-
-AABB RasterizerStorageGLES3::mesh_get_custom_aabb(RID p_mesh) const {
- return AABB();
-}
-
-AABB RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) {
- return AABB();
-}
-
-void RasterizerStorageGLES3::mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) {
-}
-
-void RasterizerStorageGLES3::mesh_clear(RID p_mesh) {
-}
-
-/* MULTIMESH API */
-
-RID RasterizerStorageGLES3::multimesh_allocate() {
- return RID();
-}
-
-void RasterizerStorageGLES3::multimesh_initialize(RID p_rid) {
-}
-
-void RasterizerStorageGLES3::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) {
-}
-
-int RasterizerStorageGLES3::multimesh_get_instance_count(RID p_multimesh) const {
- return 0;
-}
-
-void RasterizerStorageGLES3::multimesh_set_mesh(RID p_multimesh, RID p_mesh) {
-}
-
-void RasterizerStorageGLES3::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform) {
-}
-
-void RasterizerStorageGLES3::multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) {
-}
-
-void RasterizerStorageGLES3::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) {
-}
-
-void RasterizerStorageGLES3::multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) {
-}
-
-RID RasterizerStorageGLES3::multimesh_get_mesh(RID p_multimesh) const {
- return RID();
-}
-
-AABB RasterizerStorageGLES3::multimesh_get_aabb(RID p_multimesh) const {
- return AABB();
-}
-
-Transform3D RasterizerStorageGLES3::multimesh_instance_get_transform(RID p_multimesh, int p_index) const {
- return Transform3D();
-}
-
-Transform2D RasterizerStorageGLES3::multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const {
- return Transform2D();
-}
-
-Color RasterizerStorageGLES3::multimesh_instance_get_color(RID p_multimesh, int p_index) const {
- return Color();
-}
-
-Color RasterizerStorageGLES3::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const {
- return Color();
-}
-
-void RasterizerStorageGLES3::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) {
-}
-
-Vector<float> RasterizerStorageGLES3::multimesh_get_buffer(RID p_multimesh) const {
- return Vector<float>();
-}
-
-void RasterizerStorageGLES3::multimesh_set_visible_instances(RID p_multimesh, int p_visible) {
-}
-
-int RasterizerStorageGLES3::multimesh_get_visible_instances(RID p_multimesh) const {
- return 0;
-}
-
-/* SKELETON API */
-
-RID RasterizerStorageGLES3::skeleton_allocate() {
- return RID();
-}
-
-void RasterizerStorageGLES3::skeleton_initialize(RID p_rid) {
-}
-
-void RasterizerStorageGLES3::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton) {
-}
-
-void RasterizerStorageGLES3::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) {
-}
-
-int RasterizerStorageGLES3::skeleton_get_bone_count(RID p_skeleton) const {
- return 0;
-}
-
-void RasterizerStorageGLES3::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) {
-}
-
-Transform3D RasterizerStorageGLES3::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const {
- return Transform3D();
-}
-
-void RasterizerStorageGLES3::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) {
-}
-
-Transform2D RasterizerStorageGLES3::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const {
- return Transform2D();
-}
-
/* Light API */
RID RasterizerStorageGLES3::directional_light_allocate() {
@@ -1199,47 +254,11 @@ bool RasterizerStorageGLES3::reflection_probe_renders_shadows(RID p_probe) const
void RasterizerStorageGLES3::base_update_dependency(RID p_base, DependencyTracker *p_instance) {
}
-void RasterizerStorageGLES3::skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) {
-}
-
-/* DECAL API */
-
-RID RasterizerStorageGLES3::decal_allocate() {
- return RID();
-}
-
-void RasterizerStorageGLES3::decal_initialize(RID p_rid) {
-}
-
-void RasterizerStorageGLES3::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
-}
-
-void RasterizerStorageGLES3::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
-}
-
-void RasterizerStorageGLES3::decal_set_emission_energy(RID p_decal, float p_energy) {
-}
-
-void RasterizerStorageGLES3::decal_set_albedo_mix(RID p_decal, float p_mix) {
-}
-
-void RasterizerStorageGLES3::decal_set_modulate(RID p_decal, const Color &p_modulate) {
-}
-
-void RasterizerStorageGLES3::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
-}
-
-void RasterizerStorageGLES3::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
-}
-
-void RasterizerStorageGLES3::decal_set_fade(RID p_decal, float p_above, float p_below) {
-}
-
-void RasterizerStorageGLES3::decal_set_normal_fade(RID p_decal, float p_fade) {
+void RasterizerStorageGLES3::reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) {
}
-AABB RasterizerStorageGLES3::decal_get_aabb(RID p_decal) const {
- return AABB();
+float RasterizerStorageGLES3::reflection_probe_get_mesh_lod_threshold(RID p_probe) const {
+ return 0.0;
}
/* VOXEL GI API */
@@ -1529,6 +548,10 @@ void RasterizerStorageGLES3::particles_set_canvas_sdf_collision(RID p_particles,
void RasterizerStorageGLES3::update_particles() {
}
+bool RasterizerStorageGLES3::particles_is_inactive(RID p_particles) const {
+ return false;
+}
+
/* PARTICLES COLLISION */
RID RasterizerStorageGLES3::particles_collision_allocate() {
@@ -1635,52 +658,6 @@ AABB RasterizerStorageGLES3::visibility_notifier_get_aabb(RID p_notifier) const
void RasterizerStorageGLES3::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) {
}
-/* GLOBAL VARIABLES */
-
-void RasterizerStorageGLES3::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) {
-}
-
-void RasterizerStorageGLES3::global_variable_remove(const StringName &p_name) {
-}
-
-Vector<StringName> RasterizerStorageGLES3::global_variable_get_list() const {
- return Vector<StringName>();
-}
-
-void RasterizerStorageGLES3::global_variable_set(const StringName &p_name, const Variant &p_value) {
-}
-
-void RasterizerStorageGLES3::global_variable_set_override(const StringName &p_name, const Variant &p_value) {
-}
-
-Variant RasterizerStorageGLES3::global_variable_get(const StringName &p_name) const {
- return Variant();
-}
-
-RS::GlobalVariableType RasterizerStorageGLES3::global_variable_get_type(const StringName &p_name) const {
- return RS::GLOBAL_VAR_TYPE_MAX;
-}
-
-void RasterizerStorageGLES3::global_variables_load_settings(bool p_load_textures) {
-}
-
-void RasterizerStorageGLES3::global_variables_clear() {
-}
-
-int32_t RasterizerStorageGLES3::global_variables_instance_allocate(RID p_instance) {
- return 0;
-}
-
-void RasterizerStorageGLES3::global_variables_instance_free(RID p_instance) {
-}
-
-void RasterizerStorageGLES3::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) {
-}
-
-bool RasterizerStorageGLES3::particles_is_inactive(RID p_particles) const {
- return false;
-}
-
/* RENDER TARGET */
void RasterizerStorageGLES3::_set_current_render_target(RID p_render_target) {
@@ -2634,63 +1611,12 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
memdelete(sky);
return true;
- } else if (shader_owner.owns(p_rid)) {
- Shader *shader = shader_owner.get_or_null(p_rid);
-
- if (shader->shader && shader->version.is_valid()) {
- shader->shader->version_free(shader->version);
- }
-
- if (shader->dirty_list.in_list()) {
- _shader_dirty_list.remove(&shader->dirty_list);
- }
-
- while (shader->materials.first()) {
- Material *m = shader->materials.first()->self();
-
- m->shader = nullptr;
- _material_make_dirty(m);
-
- shader->materials.remove(shader->materials.first());
- }
-
- shader_owner.free(p_rid);
- memdelete(shader);
-
+ } else if (GLES3::MaterialStorage::get_singleton()->owns_shader(p_rid)) {
+ GLES3::MaterialStorage::get_singleton()->shader_free(p_rid);
return true;
- } else if (material_owner.owns(p_rid)) {
- Material *m = material_owner.get_or_null(p_rid);
-
- if (m->shader) {
- m->shader->materials.remove(&m->list);
- }
-
- /*
- for (Map<Geometry *, int>::Element *E = m->geometry_owners.front(); E; E = E->next()) {
- Geometry *g = E->key();
- g->material = RID();
- }
-
- for (Map<InstanceBaseDependency *, int>::Element *E = m->instance_owners.front(); E; E = E->next()) {
- InstanceBaseDependency *ins = E->key();
-
- if (ins->material_override == p_rid) {
- ins->material_override = RID();
- }
-
- for (int i = 0; i < ins->materials.size(); i++) {
- if (ins->materials[i] == p_rid) {
- ins->materials.write[i] = RID();
- }
- }
- }
-*/
-
- material_owner.free(p_rid);
- memdelete(m);
-
+ } else if (GLES3::MaterialStorage::get_singleton()->owns_material(p_rid)) {
+ GLES3::MaterialStorage::get_singleton()->material_free(p_rid);
return true;
-
} else {
return false;
}
@@ -3015,13 +1941,6 @@ void RasterizerStorageGLES3::initialize() {
// OR max_vertex_texture_image_units is zero
config->use_skeleton_software = (config->float_texture_supported == false) || (config->max_vertex_texture_image_units == 0);
- shaders.copy.initialize();
- shaders.copy_version = shaders.copy.version_create(); //TODO
- shaders.copy.version_bind_shader(shaders.copy_version, CopyShaderGLES3::MODE_COPY_SECTION);
- //shaders.cubemap_filter.init();
- //bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx");
- //shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::LOW_QUALITY, !ggx_hq);
-
{
// quad for copying stuff
@@ -3179,8 +2098,8 @@ uint64_t RasterizerStorageGLES3::get_rendering_info(RS::RenderingInfo p_info) {
}
void RasterizerStorageGLES3::update_dirty_resources() {
- update_dirty_shaders();
- update_dirty_materials();
+ GLES3::MaterialStorage::get_singleton()->update_dirty_shaders();
+ GLES3::MaterialStorage::get_singleton()->update_dirty_materials();
// update_dirty_skeletons();
// update_dirty_multimeshes();
}
@@ -3190,7 +2109,6 @@ RasterizerStorageGLES3::RasterizerStorageGLES3() {
}
RasterizerStorageGLES3::~RasterizerStorageGLES3() {
- shaders.copy.version_free(shaders.copy_version);
}
#endif // GLES3_ENABLED
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 83b81293c4..105529ee3d 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -42,18 +42,17 @@
#include "servers/rendering/shader_language.h"
#include "storage/canvas_texture_storage.h"
#include "storage/config.h"
+#include "storage/material_storage.h"
#include "storage/render_target_storage.h"
#include "storage/texture_storage.h"
-#include "shaders/copy.glsl.gen.h"
-
-class RasterizerCanvasGLES3;
-class RasterizerSceneGLES3;
+// class RasterizerCanvasGLES3;
+// class RasterizerSceneGLES3;
class RasterizerStorageGLES3 : public RendererStorage {
public:
- RasterizerCanvasGLES3 *canvas;
- RasterizerSceneGLES3 *scene;
+ // RasterizerCanvasGLES3 *canvas;
+ // RasterizerSceneGLES3 *scene;
static GLuint system_fbo;
@@ -79,19 +78,6 @@ public:
} resources;
- mutable struct Shaders {
- ShaderCompiler compiler;
-
- CopyShaderGLES3 copy;
- RID copy_version;
- //CubemapFilterShaderGLES3 cubemap_filter;
-
- ShaderCompiler::IdentifierActions actions_canvas;
- ShaderCompiler::IdentifierActions actions_scene;
- ShaderCompiler::IdentifierActions actions_particles;
-
- } shaders;
-
struct Info {
uint64_t texture_mem = 0;
uint64_t vertex_mem = 0;
@@ -146,368 +132,6 @@ public:
RID sky_create();
void sky_set_texture(RID p_sky, RID p_panorama, int p_radiance_size);
- // SHADER API
-
- struct Material;
-
- struct Shader {
- RID self;
-
- RS::ShaderMode mode;
- ShaderGLES3 *shader;
- String code;
- SelfList<Material>::List materials;
-
- Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
-
- RID version;
-
- SelfList<Shader> dirty_list;
-
- Map<StringName, Map<int, RID>> default_textures;
-
- Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
-
- bool valid;
-
- String path;
-
- uint32_t index;
- uint64_t last_pass;
-
- struct CanvasItem {
- enum BlendMode {
- BLEND_MODE_MIX,
- BLEND_MODE_ADD,
- BLEND_MODE_SUB,
- BLEND_MODE_MUL,
- BLEND_MODE_PMALPHA,
- };
-
- int blend_mode;
-
- enum LightMode {
- LIGHT_MODE_NORMAL,
- LIGHT_MODE_UNSHADED,
- LIGHT_MODE_LIGHT_ONLY
- };
-
- int light_mode;
-
- bool uses_screen_texture;
- bool uses_screen_uv;
- bool uses_time;
- bool uses_modulate;
- bool uses_color;
- bool uses_vertex;
-
- // all these should disable item joining if used in a custom shader
- bool uses_model_matrix;
- bool uses_extra_matrix;
- bool uses_projection_matrix;
- bool uses_instance_custom;
-
- } canvas_item;
-
- struct Spatial {
- enum BlendMode {
- BLEND_MODE_MIX,
- BLEND_MODE_ADD,
- BLEND_MODE_SUB,
- BLEND_MODE_MUL,
- };
-
- int blend_mode;
-
- enum DepthDrawMode {
- DEPTH_DRAW_OPAQUE,
- DEPTH_DRAW_ALWAYS,
- DEPTH_DRAW_NEVER,
- DEPTH_DRAW_ALPHA_PREPASS,
- };
-
- int depth_draw_mode;
-
- enum CullMode {
- CULL_MODE_FRONT,
- CULL_MODE_BACK,
- CULL_MODE_DISABLED,
- };
-
- int cull_mode;
-
- bool uses_alpha;
- bool uses_alpha_scissor;
- bool unshaded;
- bool no_depth_test;
- bool uses_vertex;
- bool uses_discard;
- bool uses_sss;
- bool uses_screen_texture;
- bool uses_depth_texture;
- bool uses_time;
- bool uses_tangent;
- bool uses_ensure_correct_normals;
- bool writes_modelview_or_projection;
- bool uses_vertex_lighting;
- bool uses_world_coordinates;
-
- } spatial;
-
- struct Particles {
- } particles;
-
- bool uses_vertex_time;
- bool uses_fragment_time;
-
- Shader() :
- dirty_list(this) {
- shader = nullptr;
- valid = false;
- version = RID();
- last_pass = 0;
- }
- };
-
- mutable RID_PtrOwner<Shader> shader_owner;
- mutable SelfList<Shader>::List _shader_dirty_list;
-
- void _shader_make_dirty(Shader *p_shader);
-
- RID shader_allocate() override;
- void shader_initialize(RID p_rid) override;
-
- //RID shader_create() override;
-
- void shader_set_code(RID p_shader, const String &p_code) override;
- String shader_get_code(RID p_shader) const override;
- void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override;
-
- void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override;
- RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const override;
-
- RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override { return RS::ShaderNativeSourceCode(); };
-
- void _update_shader(Shader *p_shader) const;
- void update_dirty_shaders();
-
- // new
- Variant shader_get_param_default(RID p_material, const StringName &p_param) const override { return Variant(); }
-
- // COMMON MATERIAL API
-
- struct Material {
- RID self;
- Shader *shader;
- Map<StringName, Variant> params;
- SelfList<Material> list;
- SelfList<Material> dirty_list;
- Vector<Pair<StringName, RID>> textures;
- float line_width;
- int render_priority;
-
- RID next_pass;
-
- uint32_t index;
- uint64_t last_pass;
-
- // Map<Geometry *, int> geometry_owners;
- // Map<InstanceBaseDependency *, int> instance_owners;
-
- bool can_cast_shadow_cache;
- bool is_animated_cache;
-
- Material() :
- list(this),
- dirty_list(this) {
- can_cast_shadow_cache = false;
- is_animated_cache = false;
- shader = nullptr;
- line_width = 1.0;
- last_pass = 0;
- render_priority = 0;
- }
- };
-
- mutable SelfList<Material>::List _material_dirty_list;
- void _material_make_dirty(Material *p_material) const;
-
- // void _material_add_geometry(RID p_material, Geometry *p_geometry);
- // void _material_remove_geometry(RID p_material, Geometry *p_geometry);
-
- void _update_material(Material *p_material);
-
- mutable RID_PtrOwner<Material> material_owner;
-
- // new
- void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override {}
- void material_update_dependency(RID p_material, DependencyTracker *p_instance) override {}
-
- // old
- RID material_allocate() override;
- void material_initialize(RID p_rid) override;
-
- //RID material_create() override;
-
- void material_set_shader(RID p_material, RID p_shader) override;
- RID material_get_shader(RID p_material) const;
-
- void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) override;
- Variant material_get_param(RID p_material, const StringName &p_param) const override;
- Variant material_get_param_default(RID p_material, const StringName &p_param) const;
-
- void material_set_line_width(RID p_material, float p_width);
- void material_set_next_pass(RID p_material, RID p_next_material) override;
-
- bool material_is_animated(RID p_material) override;
- bool material_casts_shadows(RID p_material) override;
- bool material_uses_tangents(RID p_material);
- bool material_uses_ensure_correct_normals(RID p_material);
-
- void material_add_instance_owner(RID p_material, DependencyTracker *p_instance);
- void material_remove_instance_owner(RID p_material, DependencyTracker *p_instance);
-
- void material_set_render_priority(RID p_material, int priority) override;
-
- void update_dirty_materials();
-
- /* MESH API */
-
- RID mesh_allocate() override;
- void mesh_initialize(RID p_rid) override;
- void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) override;
- bool mesh_needs_instance(RID p_mesh, bool p_has_skeleton) override;
- RID mesh_instance_create(RID p_base) override;
- void mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) override;
- void mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) override;
- void mesh_instance_check_for_update(RID p_mesh_instance) override;
- void update_mesh_instances() override;
- void reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) override;
- float reflection_probe_get_mesh_lod_threshold(RID p_probe) const override;
-
- void mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) override;
-
- int mesh_get_blend_shape_count(RID p_mesh) const override;
-
- void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) override;
- RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const override;
-
- void mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override;
- void mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override;
- void mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override;
-
- void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) override;
- RID mesh_surface_get_material(RID p_mesh, int p_surface) const override;
-
- RS::SurfaceData mesh_get_surface(RID p_mesh, int p_surface) const override;
- int mesh_get_surface_count(RID p_mesh) const override;
-
- void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) override;
- AABB mesh_get_custom_aabb(RID p_mesh) const override;
-
- AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) override;
- void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) override;
- void mesh_clear(RID p_mesh) override;
-
- /* MULTIMESH API */
-
- struct MultiMesh {
- RID mesh;
- int instances = 0;
- RS::MultimeshTransformFormat xform_format = RS::MULTIMESH_TRANSFORM_3D;
- bool uses_colors = false;
- bool uses_custom_data = false;
- int visible_instances = -1;
- AABB aabb;
- bool aabb_dirty = false;
- bool buffer_set = false;
- uint32_t stride_cache = 0;
- uint32_t color_offset_cache = 0;
- uint32_t custom_data_offset_cache = 0;
-
- Vector<float> data_cache; //used if individual setting is used
- bool *data_cache_dirty_regions = nullptr;
- uint32_t data_cache_used_dirty_regions = 0;
-
- RID buffer; //storage buffer
- RID uniform_set_3d;
- RID uniform_set_2d;
-
- bool dirty = false;
- MultiMesh *dirty_list = nullptr;
-
- Dependency dependency;
- };
-
- mutable RID_Owner<MultiMesh, true> multimesh_owner;
-
- MultiMesh *multimesh_dirty_list = nullptr;
-
- _FORCE_INLINE_ void _multimesh_make_local(MultiMesh *multimesh) const;
- _FORCE_INLINE_ void _multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb);
- _FORCE_INLINE_ void _multimesh_mark_all_dirty(MultiMesh *multimesh, bool p_data, bool p_aabb);
- _FORCE_INLINE_ void _multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances);
- void _update_dirty_multimeshes();
-
- RID multimesh_allocate() override;
- void multimesh_initialize(RID p_rid) override;
- void multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) override;
- int multimesh_get_instance_count(RID p_multimesh) const override;
-
- void multimesh_set_mesh(RID p_multimesh, RID p_mesh) override;
- void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform) override;
- void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) override;
- void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) override;
- void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) override;
-
- RID multimesh_get_mesh(RID p_multimesh) const override;
- AABB multimesh_get_aabb(RID p_multimesh) const override;
-
- Transform3D multimesh_instance_get_transform(RID p_multimesh, int p_index) const override;
- Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const override;
- Color multimesh_instance_get_color(RID p_multimesh, int p_index) const override;
- Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const override;
- void multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) override;
- Vector<float> multimesh_get_buffer(RID p_multimesh) const override;
-
- void multimesh_set_visible_instances(RID p_multimesh, int p_visible) override;
- int multimesh_get_visible_instances(RID p_multimesh) const override;
-
- _FORCE_INLINE_ RS::MultimeshTransformFormat multimesh_get_transform_format(RID p_multimesh) const {
- MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
- return multimesh->xform_format;
- }
-
- _FORCE_INLINE_ bool multimesh_uses_colors(RID p_multimesh) const {
- MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
- return multimesh->uses_colors;
- }
-
- _FORCE_INLINE_ bool multimesh_uses_custom_data(RID p_multimesh) const {
- MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
- return multimesh->uses_custom_data;
- }
-
- _FORCE_INLINE_ uint32_t multimesh_get_instances_to_draw(RID p_multimesh) const {
- MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
- if (multimesh->visible_instances >= 0) {
- return multimesh->visible_instances;
- }
- return multimesh->instances;
- }
-
- /* SKELETON API */
-
- RID skeleton_allocate() override;
- void skeleton_initialize(RID p_rid) override;
- void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) override;
- void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) override;
- int skeleton_get_bone_count(RID p_skeleton) const override;
- void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) override;
- Transform3D skeleton_bone_get_transform(RID p_skeleton, int p_bone) const override;
- void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) override;
- Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const override;
-
/* Light API */
RID directional_light_allocate() override;
@@ -567,6 +191,8 @@ public:
void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) override;
void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) override;
void reflection_probe_set_resolution(RID p_probe, int p_resolution) override;
+ void reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) override;
+ float reflection_probe_get_mesh_lod_threshold(RID p_probe) const override;
AABB reflection_probe_get_aabb(RID p_probe) const override;
RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const override;
@@ -577,26 +203,6 @@ public:
bool reflection_probe_renders_shadows(RID p_probe) const override;
void base_update_dependency(RID p_base, DependencyTracker *p_instance) override;
- void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) override;
-
- /* DECAL API */
-
- RID decal_allocate() override;
- void decal_initialize(RID p_rid) override;
- void decal_set_extents(RID p_decal, const Vector3 &p_extents) override;
- void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override;
- void decal_set_emission_energy(RID p_decal, float p_energy) override;
- void decal_set_albedo_mix(RID p_decal, float p_mix) override;
- void decal_set_modulate(RID p_decal, const Color &p_modulate) override;
- void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override;
- void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override;
- void decal_set_fade(RID p_decal, float p_above, float p_below) override;
- void decal_set_normal_fade(RID p_decal, float p_fade) override;
-
- AABB decal_get_aabb(RID p_decal) const override;
-
- void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
- void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
/* VOXEL GI API */
@@ -713,6 +319,7 @@ public:
void particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, RID p_texture) override;
void update_particles() override;
+ bool particles_is_inactive(RID p_particles) const override;
/* PARTICLES COLLISION */
@@ -756,26 +363,6 @@ public:
AABB visibility_notifier_get_aabb(RID p_notifier) const override;
void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) override;
- /* GLOBAL VARIABLES */
-
- void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) override;
- void global_variable_remove(const StringName &p_name) override;
- Vector<StringName> global_variable_get_list() const override;
-
- void global_variable_set(const StringName &p_name, const Variant &p_value) override;
- void global_variable_set_override(const StringName &p_name, const Variant &p_value) override;
- Variant global_variable_get(const StringName &p_name) const override;
- RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const override;
-
- void global_variables_load_settings(bool p_load_textures = true) override;
- void global_variables_clear() override;
-
- int32_t global_variables_instance_allocate(RID p_instance) override;
- void global_variables_instance_free(RID p_instance) override;
- void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) override;
-
- bool particles_is_inactive(RID p_particles) const override;
-
// RENDER TARGET
mutable RID_PtrOwner<GLES3::RenderTarget> render_target_owner;
diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp
index 9349722625..4b0986cca1 100644
--- a/drivers/gles3/shader_gles3.cpp
+++ b/drivers/gles3/shader_gles3.cpp
@@ -554,11 +554,9 @@ void ShaderGLES3::_clear_version(Version *p_version) {
for (int i = 0; i < variant_count; i++) {
for (OAHashMap<uint64_t, Version::Specialization>::Iterator it = p_version->variants[i].iter(); it.valid; it = p_version->variants[i].next_iter(it)) {
- if (it.valid) {
- glDeleteShader(it.value->vert_id);
- glDeleteShader(it.value->frag_id);
- glDeleteProgram(it.value->id);
- }
+ glDeleteShader(it.value->vert_id);
+ glDeleteShader(it.value->frag_id);
+ glDeleteProgram(it.value->id);
}
}
diff --git a/drivers/gles3/storage/decal_atlas_storage.cpp b/drivers/gles3/storage/decal_atlas_storage.cpp
new file mode 100644
index 0000000000..7bac34ea19
--- /dev/null
+++ b/drivers/gles3/storage/decal_atlas_storage.cpp
@@ -0,0 +1,75 @@
+/*************************************************************************/
+/* decal_atlas_storage.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifdef GLES3_ENABLED
+
+#include "decal_atlas_storage.h"
+
+using namespace GLES3;
+
+RID DecalAtlasStorage::decal_allocate() {
+ return RID();
+}
+
+void DecalAtlasStorage::decal_initialize(RID p_rid) {
+}
+
+void DecalAtlasStorage::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
+}
+
+void DecalAtlasStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
+}
+
+void DecalAtlasStorage::decal_set_emission_energy(RID p_decal, float p_energy) {
+}
+
+void DecalAtlasStorage::decal_set_albedo_mix(RID p_decal, float p_mix) {
+}
+
+void DecalAtlasStorage::decal_set_modulate(RID p_decal, const Color &p_modulate) {
+}
+
+void DecalAtlasStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
+}
+
+void DecalAtlasStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
+}
+
+void DecalAtlasStorage::decal_set_fade(RID p_decal, float p_above, float p_below) {
+}
+
+void DecalAtlasStorage::decal_set_normal_fade(RID p_decal, float p_fade) {
+}
+
+AABB DecalAtlasStorage::decal_get_aabb(RID p_decal) const {
+ return AABB();
+}
+
+#endif // !GLES3_ENABLED
diff --git a/drivers/gles3/storage/decal_atlas_storage.h b/drivers/gles3/storage/decal_atlas_storage.h
new file mode 100644
index 0000000000..f5dc36b1fb
--- /dev/null
+++ b/drivers/gles3/storage/decal_atlas_storage.h
@@ -0,0 +1,67 @@
+/*************************************************************************/
+/* decal_atlas_storage.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef DECAL_ATLAS_STORAGE_GLES3_H
+#define DECAL_ATLAS_STORAGE_GLES3_H
+
+#ifdef GLES3_ENABLED
+
+#include "core/templates/rid_owner.h"
+#include "servers/rendering/storage/decal_atlas_storage.h"
+
+namespace GLES3 {
+
+class DecalAtlasStorage : public RendererDecalAtlasStorage {
+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_set_extents(RID p_decal, const Vector3 &p_extents) override;
+ virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override;
+ virtual void decal_set_emission_energy(RID p_decal, float p_energy) override;
+ virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override;
+ virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override;
+ virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override;
+ virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override;
+ virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override;
+ virtual void decal_set_normal_fade(RID p_decal, float p_fade) override;
+
+ virtual AABB decal_get_aabb(RID p_decal) const override;
+
+ virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
+ virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
+};
+
+} // namespace GLES3
+
+#endif // !GLES3_ENABLED
+
+#endif // !DECAL_ATLAS_STORAGE_GLES3_H
diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp
new file mode 100644
index 0000000000..e519c428d2
--- /dev/null
+++ b/drivers/gles3/storage/material_storage.cpp
@@ -0,0 +1,913 @@
+/*************************************************************************/
+/* material_storage.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifdef GLES3_ENABLED
+
+#include "material_storage.h"
+#include "config.h"
+#include "texture_storage.h"
+
+#include "drivers/gles3/rasterizer_canvas_gles3.h"
+
+using namespace GLES3;
+
+MaterialStorage *MaterialStorage::singleton = nullptr;
+
+MaterialStorage *MaterialStorage::get_singleton() {
+ return singleton;
+}
+
+MaterialStorage::MaterialStorage() {
+ singleton = this;
+
+ shaders.copy.initialize();
+ shaders.copy_version = shaders.copy.version_create(); //TODO
+ shaders.copy.version_bind_shader(shaders.copy_version, CopyShaderGLES3::MODE_COPY_SECTION);
+ //shaders.cubemap_filter.init();
+ //bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx");
+ //shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::LOW_QUALITY, !ggx_hq);
+}
+
+MaterialStorage::~MaterialStorage() {
+ shaders.copy.version_free(shaders.copy_version);
+
+ singleton = nullptr;
+}
+
+/* GLOBAL VARIABLE API */
+
+void MaterialStorage::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) {
+}
+
+void MaterialStorage::global_variable_remove(const StringName &p_name) {
+}
+
+Vector<StringName> MaterialStorage::global_variable_get_list() const {
+ return Vector<StringName>();
+}
+
+void MaterialStorage::global_variable_set(const StringName &p_name, const Variant &p_value) {
+}
+
+void MaterialStorage::global_variable_set_override(const StringName &p_name, const Variant &p_value) {
+}
+
+Variant MaterialStorage::global_variable_get(const StringName &p_name) const {
+ return Variant();
+}
+
+RS::GlobalVariableType MaterialStorage::global_variable_get_type(const StringName &p_name) const {
+ return RS::GLOBAL_VAR_TYPE_MAX;
+}
+
+void MaterialStorage::global_variables_load_settings(bool p_load_textures) {
+}
+
+void MaterialStorage::global_variables_clear() {
+}
+
+int32_t MaterialStorage::global_variables_instance_allocate(RID p_instance) {
+ return 0;
+}
+
+void MaterialStorage::global_variables_instance_free(RID p_instance) {
+}
+
+void MaterialStorage::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) {
+}
+
+/* SHADER API */
+
+void MaterialStorage::_shader_make_dirty(Shader *p_shader) {
+ if (p_shader->dirty_list.in_list()) {
+ return;
+ }
+
+ _shader_dirty_list.add(&p_shader->dirty_list);
+}
+
+RID MaterialStorage::shader_allocate() {
+ Shader *shader = memnew(Shader);
+ shader->mode = RS::SHADER_CANVAS_ITEM;
+ //shader->shader = &scene->state.scene_shader;
+ RID rid = shader_owner.make_rid(shader);
+ _shader_make_dirty(shader);
+ shader->self = rid;
+
+ return rid;
+}
+
+void MaterialStorage::shader_initialize(RID p_rid) {
+ // noop
+}
+
+//RID MaterialStorage::shader_create() {
+// Shader *shader = memnew(Shader);
+// shader->mode = RS::SHADER_SPATIAL;
+// shader->shader = &scene->state.scene_shader;
+// RID rid = shader_owner.make_rid(shader);
+// _shader_make_dirty(shader);
+// shader->self = rid;
+
+// return rid;
+//}
+
+void MaterialStorage::shader_free(RID p_rid) {
+ Shader *shader = shader_owner.get_or_null(p_rid);
+
+ if (shader->shader && shader->version.is_valid()) {
+ shader->shader->version_free(shader->version);
+ }
+
+ if (shader->dirty_list.in_list()) {
+ _shader_dirty_list.remove(&shader->dirty_list);
+ }
+
+ while (shader->materials.first()) {
+ Material *m = shader->materials.first()->self();
+
+ m->shader = nullptr;
+ _material_make_dirty(m);
+
+ shader->materials.remove(shader->materials.first());
+ }
+
+ shader_owner.free(p_rid);
+ memdelete(shader);
+}
+
+void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) {
+ Shader *shader = shader_owner.get_or_null(p_shader);
+ ERR_FAIL_COND(!shader);
+
+ shader->code = p_code;
+
+ String mode_string = ShaderLanguage::get_shader_type(p_code);
+ RS::ShaderMode mode;
+
+ if (mode_string == "canvas_item") {
+ mode = RS::SHADER_CANVAS_ITEM;
+ } else if (mode_string == "particles") {
+ mode = RS::SHADER_PARTICLES;
+ } else if (mode_string == "sky") {
+ mode = RS::SHADER_SKY;
+ } else if (mode_string == "spatial") {
+ mode = RS::SHADER_SPATIAL;
+ } else {
+ mode = RS::SHADER_MAX;
+ ERR_PRINT("shader type " + mode_string + " not supported in OpenGL renderer");
+ }
+
+ if (shader->version.is_valid() && mode != shader->mode) {
+ shader->shader->version_free(shader->version);
+ shader->version = RID();
+ }
+
+ shader->mode = mode;
+
+ // TODO handle all shader types
+ if (mode == RS::SHADER_CANVAS_ITEM) {
+ shader->shader = &RasterizerCanvasGLES3::get_singleton()->state.canvas_shader;
+ } else if (mode == RS::SHADER_SPATIAL) {
+ //shader->shader = &scene->state.scene_shader;
+ } else if (mode == RS::SHADER_PARTICLES) {
+ } else if (mode == RS::SHADER_SKY) {
+ } else {
+ return;
+ }
+
+ if (shader->version.is_null() && shader->shader) {
+ shader->version = shader->shader->version_create();
+ }
+
+ _shader_make_dirty(shader);
+}
+
+String MaterialStorage::shader_get_code(RID p_shader) const {
+ const Shader *shader = shader_owner.get_or_null(p_shader);
+ ERR_FAIL_COND_V(!shader, "");
+
+ return shader->code;
+}
+
+void MaterialStorage::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const {
+ Shader *shader = shader_owner.get_or_null(p_shader);
+ ERR_FAIL_COND(!shader);
+
+ if (shader->dirty_list.in_list()) {
+ _update_shader(shader);
+ }
+
+ Map<int, StringName> order;
+
+ for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) {
+ if (E->get().texture_order >= 0) {
+ order[E->get().texture_order + 100000] = E->key();
+ } else {
+ order[E->get().order] = E->key();
+ }
+ }
+
+ for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) {
+ PropertyInfo pi;
+ ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[E->get()];
+
+ pi.name = E->get();
+
+ switch (u.type) {
+ case ShaderLanguage::TYPE_VOID: {
+ pi.type = Variant::NIL;
+ } break;
+
+ case ShaderLanguage::TYPE_BOOL: {
+ pi.type = Variant::BOOL;
+ } break;
+
+ // bool vectors
+ case ShaderLanguage::TYPE_BVEC2: {
+ pi.type = Variant::INT;
+ pi.hint = PROPERTY_HINT_FLAGS;
+ pi.hint_string = "x,y";
+ } break;
+ case ShaderLanguage::TYPE_BVEC3: {
+ pi.type = Variant::INT;
+ pi.hint = PROPERTY_HINT_FLAGS;
+ pi.hint_string = "x,y,z";
+ } break;
+ case ShaderLanguage::TYPE_BVEC4: {
+ pi.type = Variant::INT;
+ pi.hint = PROPERTY_HINT_FLAGS;
+ pi.hint_string = "x,y,z,w";
+ } break;
+
+ // int stuff
+ case ShaderLanguage::TYPE_UINT:
+ case ShaderLanguage::TYPE_INT: {
+ pi.type = Variant::INT;
+
+ if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
+ pi.hint = PROPERTY_HINT_RANGE;
+ pi.hint_string = rtos(u.hint_range[0]) + "," + rtos(u.hint_range[1]) + "," + rtos(u.hint_range[2]);
+ }
+ } break;
+
+ case ShaderLanguage::TYPE_IVEC2:
+ case ShaderLanguage::TYPE_UVEC2:
+ case ShaderLanguage::TYPE_IVEC3:
+ case ShaderLanguage::TYPE_UVEC3:
+ case ShaderLanguage::TYPE_IVEC4:
+ case ShaderLanguage::TYPE_UVEC4: {
+ // not sure what this should be in godot 4
+ // pi.type = Variant::POOL_INT_ARRAY;
+ pi.type = Variant::PACKED_INT32_ARRAY;
+ } break;
+
+ case ShaderLanguage::TYPE_FLOAT: {
+ pi.type = Variant::FLOAT;
+ if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
+ pi.hint = PROPERTY_HINT_RANGE;
+ pi.hint_string = rtos(u.hint_range[0]) + "," + rtos(u.hint_range[1]) + "," + rtos(u.hint_range[2]);
+ }
+ } break;
+
+ case ShaderLanguage::TYPE_VEC2: {
+ pi.type = Variant::VECTOR2;
+ } break;
+ case ShaderLanguage::TYPE_VEC3: {
+ pi.type = Variant::VECTOR3;
+ } break;
+
+ case ShaderLanguage::TYPE_VEC4: {
+ if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
+ pi.type = Variant::COLOR;
+ } else {
+ pi.type = Variant::PLANE;
+ }
+ } break;
+
+ case ShaderLanguage::TYPE_MAT2: {
+ pi.type = Variant::TRANSFORM2D;
+ } break;
+
+ case ShaderLanguage::TYPE_MAT3: {
+ pi.type = Variant::BASIS;
+ } break;
+
+ case ShaderLanguage::TYPE_MAT4: {
+ pi.type = Variant::TRANSFORM3D;
+ } break;
+
+ case ShaderLanguage::TYPE_SAMPLER2D:
+ // case ShaderLanguage::TYPE_SAMPLEREXT:
+ case ShaderLanguage::TYPE_ISAMPLER2D:
+ case ShaderLanguage::TYPE_USAMPLER2D: {
+ pi.type = Variant::OBJECT;
+ pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ pi.hint_string = "Texture";
+ } break;
+
+ case ShaderLanguage::TYPE_SAMPLERCUBE: {
+ pi.type = Variant::OBJECT;
+ pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ pi.hint_string = "CubeMap";
+ } break;
+
+ case ShaderLanguage::TYPE_SAMPLER2DARRAY:
+ case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
+ case ShaderLanguage::TYPE_USAMPLER2DARRAY:
+ case ShaderLanguage::TYPE_SAMPLER3D:
+ case ShaderLanguage::TYPE_ISAMPLER3D:
+ case ShaderLanguage::TYPE_USAMPLER3D: {
+ // Not implemented in OpenGL
+ } break;
+ // new for godot 4
+ case ShaderLanguage::TYPE_SAMPLERCUBEARRAY:
+ case ShaderLanguage::TYPE_STRUCT:
+ case ShaderLanguage::TYPE_MAX: {
+ } break;
+ }
+
+ p_param_list->push_back(pi);
+ }
+}
+
+void MaterialStorage::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) {
+ Shader *shader = shader_owner.get_or_null(p_shader);
+ ERR_FAIL_COND(!shader);
+ ERR_FAIL_COND(p_texture.is_valid() && !TextureStorage::get_singleton()->owns_texture(p_texture));
+
+ if (!p_texture.is_valid()) {
+ if (shader->default_textures.has(p_name) && shader->default_textures[p_name].has(p_index)) {
+ shader->default_textures[p_name].erase(p_index);
+
+ if (shader->default_textures[p_name].is_empty()) {
+ shader->default_textures.erase(p_name);
+ }
+ }
+ } else {
+ if (!shader->default_textures.has(p_name)) {
+ shader->default_textures[p_name] = Map<int, RID>();
+ }
+ shader->default_textures[p_name][p_index] = p_texture;
+ }
+
+ _shader_make_dirty(shader);
+}
+
+RID MaterialStorage::shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const {
+ const Shader *shader = shader_owner.get_or_null(p_shader);
+ ERR_FAIL_COND_V(!shader, RID());
+
+ if (shader->default_textures.has(p_name) && shader->default_textures[p_name].has(p_index)) {
+ return shader->default_textures[p_name][p_index];
+ }
+
+ return RID();
+}
+
+void MaterialStorage::_update_shader(Shader *p_shader) const {
+ _shader_dirty_list.remove(&p_shader->dirty_list);
+
+ p_shader->valid = false;
+
+ p_shader->uniforms.clear();
+
+ if (p_shader->code.is_empty()) {
+ return; //just invalid, but no error
+ }
+
+ ShaderCompiler::GeneratedCode gen_code;
+ ShaderCompiler::IdentifierActions *actions = nullptr;
+
+ switch (p_shader->mode) {
+ case RS::SHADER_CANVAS_ITEM: {
+ p_shader->canvas_item.light_mode = Shader::CanvasItem::LIGHT_MODE_NORMAL;
+ p_shader->canvas_item.blend_mode = Shader::CanvasItem::BLEND_MODE_MIX;
+
+ p_shader->canvas_item.uses_screen_texture = false;
+ p_shader->canvas_item.uses_screen_uv = false;
+ p_shader->canvas_item.uses_time = false;
+ p_shader->canvas_item.uses_modulate = false;
+ p_shader->canvas_item.uses_color = false;
+ p_shader->canvas_item.uses_vertex = false;
+
+ p_shader->canvas_item.uses_model_matrix = false;
+ p_shader->canvas_item.uses_extra_matrix = false;
+ p_shader->canvas_item.uses_projection_matrix = false;
+ p_shader->canvas_item.uses_instance_custom = false;
+
+ shaders.actions_canvas.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_ADD);
+ shaders.actions_canvas.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MIX);
+ shaders.actions_canvas.render_mode_values["blend_sub"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_SUB);
+ shaders.actions_canvas.render_mode_values["blend_mul"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MUL);
+ shaders.actions_canvas.render_mode_values["blend_premul_alpha"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_PMALPHA);
+
+ shaders.actions_canvas.render_mode_values["unshaded"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, Shader::CanvasItem::LIGHT_MODE_UNSHADED);
+ shaders.actions_canvas.render_mode_values["light_only"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, Shader::CanvasItem::LIGHT_MODE_LIGHT_ONLY);
+
+ shaders.actions_canvas.usage_flag_pointers["SCREEN_UV"] = &p_shader->canvas_item.uses_screen_uv;
+ shaders.actions_canvas.usage_flag_pointers["SCREEN_PIXEL_SIZE"] = &p_shader->canvas_item.uses_screen_uv;
+ shaders.actions_canvas.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->canvas_item.uses_screen_texture;
+ shaders.actions_canvas.usage_flag_pointers["TIME"] = &p_shader->canvas_item.uses_time;
+ shaders.actions_canvas.usage_flag_pointers["MODULATE"] = &p_shader->canvas_item.uses_modulate;
+ shaders.actions_canvas.usage_flag_pointers["COLOR"] = &p_shader->canvas_item.uses_color;
+
+ shaders.actions_canvas.usage_flag_pointers["VERTEX"] = &p_shader->canvas_item.uses_vertex;
+
+ shaders.actions_canvas.usage_flag_pointers["MODEL_MATRIX"] = &p_shader->canvas_item.uses_model_matrix;
+ shaders.actions_canvas.usage_flag_pointers["EXTRA_MATRIX"] = &p_shader->canvas_item.uses_extra_matrix;
+ shaders.actions_canvas.usage_flag_pointers["PROJECTION_MATRIX"] = &p_shader->canvas_item.uses_projection_matrix;
+ shaders.actions_canvas.usage_flag_pointers["INSTANCE_CUSTOM"] = &p_shader->canvas_item.uses_instance_custom;
+
+ actions = &shaders.actions_canvas;
+ actions->uniforms = &p_shader->uniforms;
+ } break;
+
+ case RS::SHADER_SPATIAL: {
+ // TODO remove once 3D is added back
+ return;
+ p_shader->spatial.blend_mode = Shader::Spatial::BLEND_MODE_MIX;
+ p_shader->spatial.depth_draw_mode = Shader::Spatial::DEPTH_DRAW_OPAQUE;
+ p_shader->spatial.cull_mode = Shader::Spatial::CULL_MODE_BACK;
+ p_shader->spatial.uses_alpha = false;
+ p_shader->spatial.uses_alpha_scissor = false;
+ p_shader->spatial.uses_discard = false;
+ p_shader->spatial.unshaded = false;
+ p_shader->spatial.no_depth_test = false;
+ p_shader->spatial.uses_sss = false;
+ p_shader->spatial.uses_time = false;
+ p_shader->spatial.uses_vertex_lighting = false;
+ p_shader->spatial.uses_screen_texture = false;
+ p_shader->spatial.uses_depth_texture = false;
+ p_shader->spatial.uses_vertex = false;
+ p_shader->spatial.uses_tangent = false;
+ p_shader->spatial.uses_ensure_correct_normals = false;
+ p_shader->spatial.writes_modelview_or_projection = false;
+ p_shader->spatial.uses_world_coordinates = false;
+
+ shaders.actions_scene.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_ADD);
+ shaders.actions_scene.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_MIX);
+ shaders.actions_scene.render_mode_values["blend_sub"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_SUB);
+ shaders.actions_scene.render_mode_values["blend_mul"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_MUL);
+
+ shaders.actions_scene.render_mode_values["depth_draw_opaque"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_OPAQUE);
+ shaders.actions_scene.render_mode_values["depth_draw_always"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_ALWAYS);
+ shaders.actions_scene.render_mode_values["depth_draw_never"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_NEVER);
+ shaders.actions_scene.render_mode_values["depth_draw_alpha_prepass"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS);
+
+ shaders.actions_scene.render_mode_values["cull_front"] = Pair<int *, int>(&p_shader->spatial.cull_mode, Shader::Spatial::CULL_MODE_FRONT);
+ shaders.actions_scene.render_mode_values["cull_back"] = Pair<int *, int>(&p_shader->spatial.cull_mode, Shader::Spatial::CULL_MODE_BACK);
+ shaders.actions_scene.render_mode_values["cull_disabled"] = Pair<int *, int>(&p_shader->spatial.cull_mode, Shader::Spatial::CULL_MODE_DISABLED);
+
+ shaders.actions_scene.render_mode_flags["unshaded"] = &p_shader->spatial.unshaded;
+ shaders.actions_scene.render_mode_flags["depth_test_disable"] = &p_shader->spatial.no_depth_test;
+
+ shaders.actions_scene.render_mode_flags["vertex_lighting"] = &p_shader->spatial.uses_vertex_lighting;
+
+ shaders.actions_scene.render_mode_flags["world_vertex_coords"] = &p_shader->spatial.uses_world_coordinates;
+
+ shaders.actions_scene.render_mode_flags["ensure_correct_normals"] = &p_shader->spatial.uses_ensure_correct_normals;
+
+ shaders.actions_scene.usage_flag_pointers["ALPHA"] = &p_shader->spatial.uses_alpha;
+ shaders.actions_scene.usage_flag_pointers["ALPHA_SCISSOR"] = &p_shader->spatial.uses_alpha_scissor;
+
+ shaders.actions_scene.usage_flag_pointers["SSS_STRENGTH"] = &p_shader->spatial.uses_sss;
+ shaders.actions_scene.usage_flag_pointers["DISCARD"] = &p_shader->spatial.uses_discard;
+ shaders.actions_scene.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->spatial.uses_screen_texture;
+ shaders.actions_scene.usage_flag_pointers["DEPTH_TEXTURE"] = &p_shader->spatial.uses_depth_texture;
+ shaders.actions_scene.usage_flag_pointers["TIME"] = &p_shader->spatial.uses_time;
+
+ // Use of any of these BUILTINS indicate the need for transformed tangents.
+ // This is needed to know when to transform tangents in software skinning.
+ shaders.actions_scene.usage_flag_pointers["TANGENT"] = &p_shader->spatial.uses_tangent;
+ shaders.actions_scene.usage_flag_pointers["NORMALMAP"] = &p_shader->spatial.uses_tangent;
+
+ shaders.actions_scene.write_flag_pointers["MODELVIEW_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
+ shaders.actions_scene.write_flag_pointers["PROJECTION_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
+ shaders.actions_scene.write_flag_pointers["VERTEX"] = &p_shader->spatial.uses_vertex;
+
+ actions = &shaders.actions_scene;
+ actions->uniforms = &p_shader->uniforms;
+ } break;
+
+ default: {
+ return;
+ } break;
+ }
+
+ Error err = shaders.compiler.compile(p_shader->mode, p_shader->code, actions, p_shader->path, gen_code);
+ if (err != OK) {
+ return;
+ }
+
+ Vector<StringName> texture_uniform_names;
+ for (int i = 0; i < gen_code.texture_uniforms.size(); i++) {
+ texture_uniform_names.push_back(gen_code.texture_uniforms[i].name);
+ }
+
+ p_shader->shader->version_set_code(p_shader->version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_names);
+
+ p_shader->texture_uniforms = gen_code.texture_uniforms;
+
+ p_shader->uses_vertex_time = gen_code.uses_vertex_time;
+ p_shader->uses_fragment_time = gen_code.uses_fragment_time;
+
+ for (SelfList<Material> *E = p_shader->materials.first(); E; E = E->next()) {
+ _material_make_dirty(E->self());
+ }
+
+ p_shader->valid = true;
+}
+
+void MaterialStorage::update_dirty_shaders() {
+ while (_shader_dirty_list.first()) {
+ _update_shader(_shader_dirty_list.first()->self());
+ }
+}
+
+/* MATERIAL API */
+
+void MaterialStorage::_material_make_dirty(Material *p_material) const {
+ if (p_material->dirty_list.in_list()) {
+ return;
+ }
+
+ _material_dirty_list.add(&p_material->dirty_list);
+}
+
+void MaterialStorage::_update_material(Material *p_material) {
+ if (p_material->dirty_list.in_list()) {
+ _material_dirty_list.remove(&p_material->dirty_list);
+ }
+
+ if (p_material->shader && p_material->shader->dirty_list.in_list()) {
+ _update_shader(p_material->shader);
+ }
+
+ if (p_material->shader && !p_material->shader->valid) {
+ return;
+ }
+
+ {
+ if (p_material->shader && p_material->shader->mode == RS::SHADER_SPATIAL) {
+ bool can_cast_shadow = false;
+ bool is_animated = false;
+
+ if (p_material->shader->spatial.blend_mode == Shader::Spatial::BLEND_MODE_MIX &&
+ (!p_material->shader->spatial.uses_alpha || p_material->shader->spatial.depth_draw_mode == Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS)) {
+ can_cast_shadow = true;
+ }
+
+ if (p_material->shader->spatial.uses_discard && p_material->shader->uses_fragment_time) {
+ is_animated = true;
+ }
+
+ if (p_material->shader->spatial.uses_vertex && p_material->shader->uses_vertex_time) {
+ is_animated = true;
+ }
+
+ if (can_cast_shadow != p_material->can_cast_shadow_cache || is_animated != p_material->is_animated_cache) {
+ p_material->can_cast_shadow_cache = can_cast_shadow;
+ p_material->is_animated_cache = is_animated;
+
+ /*
+ for (Map<Geometry *, int>::Element *E = p_material->geometry_owners.front(); E; E = E->next()) {
+ E->key()->material_changed_notify();
+ }
+
+ for (Map<InstanceBaseDependency *, int>::Element *E = p_material->instance_owners.front(); E; E = E->next()) {
+ E->key()->base_changed(false, true);
+ }
+ */
+ }
+ }
+ }
+
+ // uniforms and other things will be set in the use_material method in ShaderGLES3
+
+ if (p_material->shader && p_material->shader->texture_uniforms.size() > 0) {
+ p_material->textures.resize(p_material->shader->texture_uniforms.size());
+
+ for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_material->shader->uniforms.front(); E; E = E->next()) {
+ if (E->get().texture_order < 0) {
+ continue; // not a texture, does not go here
+ }
+
+ RID texture;
+
+ Map<StringName, Variant>::Element *V = p_material->params.find(E->key());
+
+ if (V) {
+ texture = V->get();
+ }
+
+ if (!texture.is_valid()) {
+ Map<StringName, Map<int, RID>>::Element *W = p_material->shader->default_textures.find(E->key());
+
+ // TODO: make texture uniform array properly works with GLES3
+ if (W && W->get().has(0)) {
+ texture = W->get()[0];
+ }
+ }
+
+ p_material->textures.write[E->get().texture_order] = Pair<StringName, RID>(E->key(), texture);
+ }
+ } else {
+ p_material->textures.clear();
+ }
+}
+
+RID MaterialStorage::material_allocate() {
+ Material *material = memnew(Material);
+ return material_owner.make_rid(material);
+}
+
+void MaterialStorage::material_initialize(RID p_rid) {
+}
+
+//RID MaterialStorage::material_create() {
+// Material *material = memnew(Material);
+
+// return material_owner.make_rid(material);
+//}
+
+void MaterialStorage::material_free(RID p_rid) {
+ Material *m = material_owner.get_or_null(p_rid);
+
+ if (m->shader) {
+ m->shader->materials.remove(&m->list);
+ }
+
+ /*
+ for (Map<Geometry *, int>::Element *E = m->geometry_owners.front(); E; E = E->next()) {
+ Geometry *g = E->key();
+ g->material = RID();
+ }
+
+ for (Map<InstanceBaseDependency *, int>::Element *E = m->instance_owners.front(); E; E = E->next()) {
+ InstanceBaseDependency *ins = E->key();
+
+ if (ins->material_override == p_rid) {
+ ins->material_override = RID();
+ }
+
+ for (int i = 0; i < ins->materials.size(); i++) {
+ if (ins->materials[i] == p_rid) {
+ ins->materials.write[i] = RID();
+ }
+ }
+ }
+*/
+
+ material_owner.free(p_rid);
+ memdelete(m);
+}
+
+void MaterialStorage::material_set_shader(RID p_material, RID p_shader) {
+ Material *material = material_owner.get_or_null(p_material);
+ ERR_FAIL_COND(!material);
+
+ Shader *shader = get_shader(p_shader);
+
+ if (material->shader) {
+ // if a shader is present, remove the old shader
+ material->shader->materials.remove(&material->list);
+ }
+
+ material->shader = shader;
+
+ if (shader) {
+ shader->materials.add(&material->list);
+ }
+
+ _material_make_dirty(material);
+}
+
+void MaterialStorage::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) {
+ Material *material = material_owner.get_or_null(p_material);
+ ERR_FAIL_COND(!material);
+
+ if (p_value.get_type() == Variant::NIL) {
+ material->params.erase(p_param);
+ } else {
+ material->params[p_param] = p_value;
+ }
+
+ _material_make_dirty(material);
+}
+
+Variant MaterialStorage::material_get_param(RID p_material, const StringName &p_param) const {
+ const Material *material = material_owner.get_or_null(p_material);
+ ERR_FAIL_COND_V(!material, RID());
+
+ if (material->params.has(p_param)) {
+ return material->params[p_param];
+ }
+
+ return material_get_param_default(p_material, p_param);
+}
+
+void MaterialStorage::material_set_next_pass(RID p_material, RID p_next_material) {
+ Material *material = material_owner.get_or_null(p_material);
+ ERR_FAIL_COND(!material);
+
+ material->next_pass = p_next_material;
+}
+
+void MaterialStorage::material_set_render_priority(RID p_material, int priority) {
+ ERR_FAIL_COND(priority < RS::MATERIAL_RENDER_PRIORITY_MIN);
+ ERR_FAIL_COND(priority > RS::MATERIAL_RENDER_PRIORITY_MAX);
+
+ Material *material = material_owner.get_or_null(p_material);
+ ERR_FAIL_COND(!material);
+
+ material->render_priority = priority;
+}
+
+bool MaterialStorage::material_is_animated(RID p_material) {
+ Material *material = material_owner.get_or_null(p_material);
+ ERR_FAIL_COND_V(!material, false);
+ if (material->dirty_list.in_list()) {
+ _update_material(material);
+ }
+
+ bool animated = material->is_animated_cache;
+ if (!animated && material->next_pass.is_valid()) {
+ animated = material_is_animated(material->next_pass);
+ }
+ return animated;
+}
+
+bool MaterialStorage::material_casts_shadows(RID p_material) {
+ Material *material = material_owner.get_or_null(p_material);
+ ERR_FAIL_COND_V(!material, false);
+ if (material->dirty_list.in_list()) {
+ _update_material(material);
+ }
+
+ bool casts_shadows = material->can_cast_shadow_cache;
+
+ if (!casts_shadows && material->next_pass.is_valid()) {
+ casts_shadows = material_casts_shadows(material->next_pass);
+ }
+
+ return casts_shadows;
+}
+
+Variant MaterialStorage::material_get_param_default(RID p_material, const StringName &p_param) const {
+ const Material *material = material_owner.get_or_null(p_material);
+ ERR_FAIL_COND_V(!material, Variant());
+
+ if (material->shader) {
+ if (material->shader->uniforms.has(p_param)) {
+ ShaderLanguage::ShaderNode::Uniform uniform = material->shader->uniforms[p_param];
+ Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
+ return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.hint);
+ }
+ }
+ return Variant();
+}
+
+void MaterialStorage::update_dirty_materials() {
+ while (_material_dirty_list.first()) {
+ Material *material = _material_dirty_list.first()->self();
+ _update_material(material);
+ }
+}
+
+/* are these still used? */
+RID MaterialStorage::material_get_shader(RID p_material) const {
+ const Material *material = material_owner.get_or_null(p_material);
+ ERR_FAIL_COND_V(!material, RID());
+
+ if (material->shader) {
+ return material->shader->self;
+ }
+
+ return RID();
+}
+
+void MaterialStorage::material_set_line_width(RID p_material, float p_width) {
+ Material *material = material_owner.get_or_null(p_material);
+ ERR_FAIL_COND(!material);
+
+ material->line_width = p_width;
+}
+
+bool MaterialStorage::material_uses_tangents(RID p_material) {
+ Material *material = material_owner.get_or_null(p_material);
+ ERR_FAIL_COND_V(!material, false);
+
+ if (!material->shader) {
+ return false;
+ }
+
+ if (material->shader->dirty_list.in_list()) {
+ _update_shader(material->shader);
+ }
+
+ return material->shader->spatial.uses_tangent;
+}
+
+bool MaterialStorage::material_uses_ensure_correct_normals(RID p_material) {
+ Material *material = material_owner.get_or_null(p_material);
+ ERR_FAIL_COND_V(!material, false);
+
+ if (!material->shader) {
+ return false;
+ }
+
+ if (material->shader->dirty_list.in_list()) {
+ _update_shader(material->shader);
+ }
+
+ return material->shader->spatial.uses_ensure_correct_normals;
+}
+
+void MaterialStorage::material_add_instance_owner(RID p_material, RendererStorage::DependencyTracker *p_instance) {
+ /*
+ Material *material = material_owner.get_or_null(p_material);
+ ERR_FAIL_COND(!material);
+
+ Map<InstanceBaseDependency *, int>::Element *E = material->instance_owners.find(p_instance);
+ if (E) {
+ E->get()++;
+ } else {
+ material->instance_owners[p_instance] = 1;
+ }
+*/
+}
+
+void MaterialStorage::material_remove_instance_owner(RID p_material, RendererStorage::DependencyTracker *p_instance) {
+ /*
+ Material *material = material_owner.get_or_null(p_material);
+ ERR_FAIL_COND(!material);
+
+ Map<InstanceBaseDependency *, int>::Element *E = material->instance_owners.find(p_instance);
+ ERR_FAIL_COND(!E);
+
+ E->get()--;
+
+ if (E->get() == 0) {
+ material->instance_owners.erase(E);
+ }
+*/
+}
+
+/*
+void MaterialStorage::_material_add_geometry(RID p_material, Geometry *p_geometry) {
+ Material *material = material_owner.get_or_null(p_material);
+ ERR_FAIL_COND(!material);
+
+ Map<Geometry *, int>::Element *I = material->geometry_owners.find(p_geometry);
+
+ if (I) {
+ I->get()++;
+ } else {
+ material->geometry_owners[p_geometry] = 1;
+ }
+}
+
+void MaterialStorage::_material_remove_geometry(RID p_material, Geometry *p_geometry) {
+ Material *material = material_owner.get_or_null(p_material);
+ ERR_FAIL_COND(!material);
+
+ Map<Geometry *, int>::Element *I = material->geometry_owners.find(p_geometry);
+ ERR_FAIL_COND(!I);
+
+ I->get()--;
+
+ if (I->get() == 0) {
+ material->geometry_owners.erase(I);
+ }
+}
+*/
+
+#endif // !GLES3_ENABLED
diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h
new file mode 100644
index 0000000000..450ee7191f
--- /dev/null
+++ b/drivers/gles3/storage/material_storage.h
@@ -0,0 +1,338 @@
+/*************************************************************************/
+/* material_storage.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef MATERIAL_STORAGE_GLES3_H
+#define MATERIAL_STORAGE_GLES3_H
+
+#ifdef GLES3_ENABLED
+
+#include "core/templates/local_vector.h"
+#include "core/templates/rid_owner.h"
+#include "core/templates/self_list.h"
+#include "servers/rendering/renderer_compositor.h"
+#include "servers/rendering/renderer_storage.h"
+#include "servers/rendering/shader_compiler.h"
+#include "servers/rendering/shader_language.h"
+#include "servers/rendering/storage/material_storage.h"
+
+#include "drivers/gles3/shaders/copy.glsl.gen.h"
+
+namespace GLES3 {
+
+/* SHADER Structs */
+
+struct Shaders {
+ ShaderCompiler compiler;
+
+ CopyShaderGLES3 copy;
+ RID copy_version;
+ //CubemapFilterShaderGLES3 cubemap_filter;
+
+ ShaderCompiler::IdentifierActions actions_canvas;
+ ShaderCompiler::IdentifierActions actions_scene;
+ ShaderCompiler::IdentifierActions actions_particles;
+};
+
+struct Material;
+
+struct Shader {
+ RID self;
+
+ RS::ShaderMode mode;
+ ShaderGLES3 *shader = nullptr;
+ String code;
+ SelfList<Material>::List materials;
+
+ Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
+
+ RID version;
+
+ SelfList<Shader> dirty_list;
+
+ Map<StringName, Map<int, RID>> default_textures;
+
+ Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
+
+ bool valid;
+
+ String path;
+
+ uint32_t index;
+ uint64_t last_pass;
+
+ struct CanvasItem {
+ enum BlendMode {
+ BLEND_MODE_MIX,
+ BLEND_MODE_ADD,
+ BLEND_MODE_SUB,
+ BLEND_MODE_MUL,
+ BLEND_MODE_PMALPHA,
+ };
+
+ int blend_mode;
+
+ enum LightMode {
+ LIGHT_MODE_NORMAL,
+ LIGHT_MODE_UNSHADED,
+ LIGHT_MODE_LIGHT_ONLY
+ };
+
+ int light_mode;
+
+ bool uses_screen_texture;
+ bool uses_screen_uv;
+ bool uses_time;
+ bool uses_modulate;
+ bool uses_color;
+ bool uses_vertex;
+
+ // all these should disable item joining if used in a custom shader
+ bool uses_model_matrix;
+ bool uses_extra_matrix;
+ bool uses_projection_matrix;
+ bool uses_instance_custom;
+
+ } canvas_item;
+
+ struct Spatial {
+ enum BlendMode {
+ BLEND_MODE_MIX,
+ BLEND_MODE_ADD,
+ BLEND_MODE_SUB,
+ BLEND_MODE_MUL,
+ };
+
+ int blend_mode;
+
+ enum DepthDrawMode {
+ DEPTH_DRAW_OPAQUE,
+ DEPTH_DRAW_ALWAYS,
+ DEPTH_DRAW_NEVER,
+ DEPTH_DRAW_ALPHA_PREPASS,
+ };
+
+ int depth_draw_mode;
+
+ enum CullMode {
+ CULL_MODE_FRONT,
+ CULL_MODE_BACK,
+ CULL_MODE_DISABLED,
+ };
+
+ int cull_mode;
+
+ bool uses_alpha;
+ bool uses_alpha_scissor;
+ bool unshaded;
+ bool no_depth_test;
+ bool uses_vertex;
+ bool uses_discard;
+ bool uses_sss;
+ bool uses_screen_texture;
+ bool uses_depth_texture;
+ bool uses_time;
+ bool uses_tangent;
+ bool uses_ensure_correct_normals;
+ bool writes_modelview_or_projection;
+ bool uses_vertex_lighting;
+ bool uses_world_coordinates;
+
+ } spatial;
+
+ struct Particles {
+ } particles;
+
+ bool uses_vertex_time;
+ bool uses_fragment_time;
+
+ Shader() :
+ dirty_list(this) {
+ shader = nullptr;
+ valid = false;
+ version = RID();
+ last_pass = 0;
+ }
+};
+
+/* MATERIAL Structs */
+
+struct Material {
+ RID self;
+ Shader *shader = nullptr;
+ Map<StringName, Variant> params;
+ SelfList<Material> list;
+ SelfList<Material> dirty_list;
+ Vector<Pair<StringName, RID>> textures;
+ float line_width;
+ int render_priority;
+
+ RID next_pass;
+
+ uint32_t index;
+ uint64_t last_pass;
+
+ // Map<Geometry *, int> geometry_owners;
+ // Map<InstanceBaseDependency *, int> instance_owners;
+
+ bool can_cast_shadow_cache;
+ bool is_animated_cache;
+
+ Material() :
+ list(this),
+ dirty_list(this) {
+ can_cast_shadow_cache = false;
+ is_animated_cache = false;
+ shader = nullptr;
+ line_width = 1.0;
+ last_pass = 0;
+ render_priority = 0;
+ }
+};
+
+class MaterialStorage : public RendererMaterialStorage {
+private:
+ static MaterialStorage *singleton;
+
+ /* SHADER API */
+
+ mutable Shaders shaders;
+
+ mutable RID_PtrOwner<Shader> shader_owner;
+ mutable SelfList<Shader>::List _shader_dirty_list;
+
+ /* MATERIAL API */
+
+ mutable SelfList<Material>::List _material_dirty_list;
+ mutable RID_PtrOwner<Material> material_owner;
+
+public:
+ static MaterialStorage *get_singleton();
+
+ MaterialStorage();
+ virtual ~MaterialStorage();
+
+ /* GLOBAL VARIABLE API */
+
+ virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) override;
+ virtual void global_variable_remove(const StringName &p_name) override;
+ virtual Vector<StringName> global_variable_get_list() const override;
+
+ virtual void global_variable_set(const StringName &p_name, const Variant &p_value) override;
+ virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) override;
+ virtual Variant global_variable_get(const StringName &p_name) const override;
+ virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const override;
+
+ virtual void global_variables_load_settings(bool p_load_textures = true) override;
+ virtual void global_variables_clear() override;
+
+ virtual int32_t global_variables_instance_allocate(RID p_instance) override;
+ virtual void global_variables_instance_free(RID p_instance) override;
+ virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) override;
+
+ /* SHADER API */
+
+ Shader *get_shader(RID p_rid) { return shader_owner.get_or_null(p_rid); };
+ bool owns_shader(RID p_rid) { return shader_owner.owns(p_rid); };
+
+ void _shader_make_dirty(Shader *p_shader);
+
+ virtual RID shader_allocate() override;
+ virtual void shader_initialize(RID p_rid) override;
+ virtual void shader_free(RID p_rid) override;
+
+ //RID shader_create() override;
+
+ virtual void shader_set_code(RID p_shader, const String &p_code) override;
+ virtual String shader_get_code(RID p_shader) const override;
+ virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override;
+
+ virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override;
+ virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const override;
+
+ virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override { return RS::ShaderNativeSourceCode(); };
+
+ void _update_shader(Shader *p_shader) const;
+ void update_dirty_shaders();
+
+ // new
+ Variant shader_get_param_default(RID p_material, const StringName &p_param) const override { return Variant(); }
+
+ /* MATERIAL API */
+
+ Material *get_material(RID p_rid) { return material_owner.get_or_null(p_rid); };
+ bool owns_material(RID p_rid) { return material_owner.owns(p_rid); };
+
+ void _material_make_dirty(Material *p_material) const;
+
+ // void _material_add_geometry(RID p_material, Geometry *p_geometry);
+ // void _material_remove_geometry(RID p_material, Geometry *p_geometry);
+
+ void _update_material(Material *p_material);
+
+ // new
+ virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override {}
+ virtual void material_update_dependency(RID p_material, RendererStorage::DependencyTracker *p_instance) override {}
+
+ // old
+ virtual RID material_allocate() override;
+ virtual void material_initialize(RID p_rid) override;
+
+ virtual void material_free(RID p_rid) override;
+
+ //RID material_create() override;
+
+ virtual void material_set_shader(RID p_material, RID p_shader) override;
+ virtual RID material_get_shader(RID p_material) const;
+
+ virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) override;
+ virtual Variant material_get_param(RID p_material, const StringName &p_param) const override;
+ virtual Variant material_get_param_default(RID p_material, const StringName &p_param) const;
+
+ void material_set_line_width(RID p_material, float p_width);
+ virtual void material_set_next_pass(RID p_material, RID p_next_material) override;
+
+ virtual bool material_is_animated(RID p_material) override;
+ virtual bool material_casts_shadows(RID p_material) override;
+ bool material_uses_tangents(RID p_material);
+ bool material_uses_ensure_correct_normals(RID p_material);
+
+ void material_add_instance_owner(RID p_material, RendererStorage::DependencyTracker *p_instance);
+ void material_remove_instance_owner(RID p_material, RendererStorage::DependencyTracker *p_instance);
+
+ void material_set_render_priority(RID p_material, int priority) override;
+
+ void update_dirty_materials();
+};
+
+} // namespace GLES3
+
+#endif // GLES3_ENABLED
+
+#endif // !MATERIAL_STORAGE_GLES3_H
diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp
new file mode 100644
index 0000000000..c2a431aff1
--- /dev/null
+++ b/drivers/gles3/storage/mesh_storage.cpp
@@ -0,0 +1,257 @@
+/*************************************************************************/
+/* mesh_storage.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifdef GLES3_ENABLED
+
+#include "mesh_storage.h"
+
+using namespace GLES3;
+
+MeshStorage *MeshStorage::singleton = nullptr;
+
+MeshStorage *MeshStorage::get_singleton() {
+ return singleton;
+}
+
+MeshStorage::MeshStorage() {
+ singleton = this;
+}
+
+MeshStorage::~MeshStorage() {
+ singleton = nullptr;
+}
+
+/* MESH API */
+
+RID MeshStorage::mesh_allocate() {
+ return RID();
+}
+
+void MeshStorage::mesh_initialize(RID p_rid) {
+}
+
+void MeshStorage::mesh_free(RID p_rid) {
+}
+
+void MeshStorage::mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) {
+}
+
+bool MeshStorage::mesh_needs_instance(RID p_mesh, bool p_has_skeleton) {
+ return false;
+}
+
+void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) {
+}
+
+int MeshStorage::mesh_get_blend_shape_count(RID p_mesh) const {
+ return 0;
+}
+
+void MeshStorage::mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) {
+}
+
+RS::BlendShapeMode MeshStorage::mesh_get_blend_shape_mode(RID p_mesh) const {
+ return RS::BLEND_SHAPE_MODE_NORMALIZED;
+}
+
+void MeshStorage::mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
+}
+
+void MeshStorage::mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
+}
+
+void MeshStorage::mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
+}
+
+void MeshStorage::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) {
+}
+
+RID MeshStorage::mesh_surface_get_material(RID p_mesh, int p_surface) const {
+ return RID();
+}
+
+RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const {
+ return RS::SurfaceData();
+}
+
+int MeshStorage::mesh_get_surface_count(RID p_mesh) const {
+ return 1;
+}
+
+void MeshStorage::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) {
+}
+
+AABB MeshStorage::mesh_get_custom_aabb(RID p_mesh) const {
+ return AABB();
+}
+
+AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) {
+ return AABB();
+}
+
+void MeshStorage::mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) {
+}
+
+void MeshStorage::mesh_clear(RID p_mesh) {
+}
+
+/* MESH INSTANCE API */
+
+RID MeshStorage::mesh_instance_create(RID p_base) {
+ return RID();
+}
+
+void MeshStorage::mesh_instance_free(RID p_rid) {
+}
+
+void MeshStorage::mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) {
+}
+
+void MeshStorage::mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) {
+}
+
+void MeshStorage::mesh_instance_check_for_update(RID p_mesh_instance) {
+}
+
+void MeshStorage::update_mesh_instances() {
+}
+
+/* MULTIMESH API */
+
+RID MeshStorage::multimesh_allocate() {
+ return RID();
+}
+
+void MeshStorage::multimesh_initialize(RID p_rid) {
+}
+
+void MeshStorage::multimesh_free(RID p_rid) {
+}
+
+void MeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) {
+}
+
+int MeshStorage::multimesh_get_instance_count(RID p_multimesh) const {
+ return 0;
+}
+
+void MeshStorage::multimesh_set_mesh(RID p_multimesh, RID p_mesh) {
+}
+
+void MeshStorage::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform) {
+}
+
+void MeshStorage::multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) {
+}
+
+void MeshStorage::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) {
+}
+
+void MeshStorage::multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) {
+}
+
+RID MeshStorage::multimesh_get_mesh(RID p_multimesh) const {
+ return RID();
+}
+
+AABB MeshStorage::multimesh_get_aabb(RID p_multimesh) const {
+ return AABB();
+}
+
+Transform3D MeshStorage::multimesh_instance_get_transform(RID p_multimesh, int p_index) const {
+ return Transform3D();
+}
+
+Transform2D MeshStorage::multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const {
+ return Transform2D();
+}
+
+Color MeshStorage::multimesh_instance_get_color(RID p_multimesh, int p_index) const {
+ return Color();
+}
+
+Color MeshStorage::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const {
+ return Color();
+}
+
+void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) {
+}
+
+Vector<float> MeshStorage::multimesh_get_buffer(RID p_multimesh) const {
+ return Vector<float>();
+}
+
+void MeshStorage::multimesh_set_visible_instances(RID p_multimesh, int p_visible) {
+}
+
+int MeshStorage::multimesh_get_visible_instances(RID p_multimesh) const {
+ return 0;
+}
+
+/* SKELETON API */
+
+RID MeshStorage::skeleton_allocate() {
+ return RID();
+}
+
+void MeshStorage::skeleton_initialize(RID p_rid) {
+}
+
+void MeshStorage::skeleton_free(RID p_rid) {
+}
+
+void MeshStorage::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton) {
+}
+
+void MeshStorage::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) {
+}
+
+int MeshStorage::skeleton_get_bone_count(RID p_skeleton) const {
+ return 0;
+}
+
+void MeshStorage::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) {
+}
+
+Transform3D MeshStorage::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const {
+ return Transform3D();
+}
+
+void MeshStorage::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) {
+}
+
+Transform2D MeshStorage::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const {
+ return Transform2D();
+}
+
+void MeshStorage::skeleton_update_dependency(RID p_base, RendererStorage::DependencyTracker *p_instance) {
+}
+
+#endif // GLES3_ENABLED
diff --git a/drivers/gles3/storage/mesh_storage.h b/drivers/gles3/storage/mesh_storage.h
new file mode 100644
index 0000000000..3f44908049
--- /dev/null
+++ b/drivers/gles3/storage/mesh_storage.h
@@ -0,0 +1,204 @@
+/*************************************************************************/
+/* mesh_storage.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef MESH_STORAGE_GLES3_H
+#define MESH_STORAGE_GLES3_H
+
+#ifdef GLES3_ENABLED
+
+#include "core/templates/local_vector.h"
+#include "core/templates/rid_owner.h"
+#include "core/templates/self_list.h"
+#include "servers/rendering/storage/mesh_storage.h"
+
+namespace GLES3 {
+
+class MeshStorage : public RendererMeshStorage {
+private:
+ static MeshStorage *singleton;
+
+public:
+ static MeshStorage *get_singleton();
+
+ MeshStorage();
+ virtual ~MeshStorage();
+
+ /* MESH API */
+
+ virtual RID mesh_allocate() override;
+ virtual void mesh_initialize(RID p_rid) override;
+ virtual void mesh_free(RID p_rid) override;
+
+ virtual void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) override;
+ virtual bool mesh_needs_instance(RID p_mesh, bool p_has_skeleton) override;
+
+ virtual void mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) override;
+
+ virtual int mesh_get_blend_shape_count(RID p_mesh) const override;
+
+ virtual void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) override;
+ virtual RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const override;
+
+ virtual void mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override;
+ virtual void mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override;
+ virtual void mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override;
+
+ virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) override;
+ virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const override;
+
+ virtual RS::SurfaceData mesh_get_surface(RID p_mesh, int p_surface) const override;
+ virtual int mesh_get_surface_count(RID p_mesh) const override;
+
+ virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) override;
+ virtual AABB mesh_get_custom_aabb(RID p_mesh) const override;
+
+ virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) override;
+ virtual void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) override;
+ virtual void mesh_clear(RID p_mesh) override;
+
+ /* MESH INSTANCE API */
+
+ virtual RID mesh_instance_create(RID p_base) override;
+ virtual void mesh_instance_free(RID p_rid) override;
+ virtual void mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) override;
+ virtual void mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) override;
+ virtual void mesh_instance_check_for_update(RID p_mesh_instance) override;
+ virtual void update_mesh_instances() override;
+
+ /* MULTIMESH API */
+
+ struct MultiMesh {
+ RID mesh;
+ int instances = 0;
+ RS::MultimeshTransformFormat xform_format = RS::MULTIMESH_TRANSFORM_3D;
+ bool uses_colors = false;
+ bool uses_custom_data = false;
+ int visible_instances = -1;
+ AABB aabb;
+ bool aabb_dirty = false;
+ bool buffer_set = false;
+ uint32_t stride_cache = 0;
+ uint32_t color_offset_cache = 0;
+ uint32_t custom_data_offset_cache = 0;
+
+ Vector<float> data_cache; //used if individual setting is used
+ bool *data_cache_dirty_regions = nullptr;
+ uint32_t data_cache_used_dirty_regions = 0;
+
+ RID buffer; //storage buffer
+ RID uniform_set_3d;
+ RID uniform_set_2d;
+
+ bool dirty = false;
+ MultiMesh *dirty_list = nullptr;
+
+ RendererStorage::Dependency dependency;
+ };
+
+ mutable RID_Owner<MultiMesh, true> multimesh_owner;
+
+ MultiMesh *multimesh_dirty_list = nullptr;
+
+ _FORCE_INLINE_ void _multimesh_make_local(MultiMesh *multimesh) const;
+ _FORCE_INLINE_ void _multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb);
+ _FORCE_INLINE_ void _multimesh_mark_all_dirty(MultiMesh *multimesh, bool p_data, bool p_aabb);
+ _FORCE_INLINE_ void _multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances);
+ void _update_dirty_multimeshes();
+
+ virtual RID multimesh_allocate() override;
+ virtual void multimesh_initialize(RID p_rid) override;
+ virtual void multimesh_free(RID p_rid) override;
+ virtual void multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) override;
+ virtual int multimesh_get_instance_count(RID p_multimesh) const override;
+
+ virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh) override;
+ virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform) override;
+ virtual void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) override;
+ virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) override;
+ virtual void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) override;
+
+ virtual RID multimesh_get_mesh(RID p_multimesh) const override;
+ virtual AABB multimesh_get_aabb(RID p_multimesh) const override;
+
+ virtual Transform3D multimesh_instance_get_transform(RID p_multimesh, int p_index) const override;
+ virtual Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const override;
+ virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const override;
+ virtual Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const override;
+ virtual void multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) override;
+ virtual Vector<float> multimesh_get_buffer(RID p_multimesh) const override;
+
+ virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible) override;
+ virtual int multimesh_get_visible_instances(RID p_multimesh) const override;
+
+ _FORCE_INLINE_ RS::MultimeshTransformFormat multimesh_get_transform_format(RID p_multimesh) const {
+ MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
+ return multimesh->xform_format;
+ }
+
+ _FORCE_INLINE_ bool multimesh_uses_colors(RID p_multimesh) const {
+ MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
+ return multimesh->uses_colors;
+ }
+
+ _FORCE_INLINE_ bool multimesh_uses_custom_data(RID p_multimesh) const {
+ MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
+ return multimesh->uses_custom_data;
+ }
+
+ _FORCE_INLINE_ uint32_t multimesh_get_instances_to_draw(RID p_multimesh) const {
+ MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
+ if (multimesh->visible_instances >= 0) {
+ return multimesh->visible_instances;
+ }
+ return multimesh->instances;
+ }
+
+ /* SKELETON API */
+
+ virtual RID skeleton_allocate() override;
+ virtual void skeleton_initialize(RID p_rid) override;
+ virtual void skeleton_free(RID p_rid) override;
+
+ virtual void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) override;
+ virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) override;
+ virtual int skeleton_get_bone_count(RID p_skeleton) const override;
+ virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) override;
+ virtual Transform3D skeleton_bone_get_transform(RID p_skeleton, int p_bone) const override;
+ virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) override;
+ virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const override;
+
+ virtual void skeleton_update_dependency(RID p_base, RendererStorage::DependencyTracker *p_instance) override;
+};
+
+} // namespace GLES3
+
+#endif // GLES3_ENABLED
+
+#endif // !MESH_STORAGE_GLES3_H
diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h
index 8a921fbe10..7656cdf67e 100644
--- a/drivers/gles3/storage/texture_storage.h
+++ b/drivers/gles3/storage/texture_storage.h
@@ -93,7 +93,7 @@ enum OpenGLTextureFlags {
struct Texture {
RID self;
- Texture *proxy;
+ Texture *proxy = nullptr;
Set<Texture *> proxy_owners;
String path;
@@ -125,20 +125,20 @@ struct Texture {
uint16_t stored_cube_sides;
- RenderTarget *render_target;
+ RenderTarget *render_target = nullptr;
Vector<Ref<Image>> images;
bool redraw_if_visible;
RS::TextureDetectCallback detect_3d;
- void *detect_3d_ud;
+ void *detect_3d_ud = nullptr;
RS::TextureDetectCallback detect_srgb;
- void *detect_srgb_ud;
+ void *detect_srgb_ud = nullptr;
RS::TextureDetectCallback detect_normal;
- void *detect_normal_ud;
+ void *detect_normal_ud = nullptr;
CanvasTexture *canvas_texture = nullptr;
diff --git a/drivers/gles3/texture_loader_gles3.cpp b/drivers/gles3/texture_loader_gles3.cpp
index f8d4cfdc61..8c8724686d 100644
--- a/drivers/gles3/texture_loader_gles3.cpp
+++ b/drivers/gles3/texture_loader_gles3.cpp
@@ -52,7 +52,7 @@ RES ResourceFormatGLES2Texture::load(const String &p_path, const String &p_origi
uint8_t **row_p = memnew_arr(uint8_t *, height);
for (unsigned int i = 0; i < height; i++) {
- row_p[i] = 0; //No colors any more, I want them to turn black
+ row_p[i] = nullptr; // No colors any more, I want them to turn black.
}
memdelete_arr(row_p);
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
index ef9bbc3483..0c27b76ed8 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
@@ -41,7 +41,7 @@
#endif
void AudioDriverPulseAudio::pa_state_cb(pa_context *c, void *userdata) {
- AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata;
+ AudioDriverPulseAudio *ad = static_cast<AudioDriverPulseAudio *>(userdata);
switch (pa_context_get_state(c)) {
case PA_CONTEXT_TERMINATED:
@@ -65,7 +65,7 @@ void AudioDriverPulseAudio::pa_state_cb(pa_context *c, void *userdata) {
}
void AudioDriverPulseAudio::pa_sink_info_cb(pa_context *c, const pa_sink_info *l, int eol, void *userdata) {
- AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata;
+ AudioDriverPulseAudio *ad = static_cast<AudioDriverPulseAudio *>(userdata);
// If eol is set to a positive number, you're at the end of the list
if (eol > 0) {
@@ -84,7 +84,7 @@ void AudioDriverPulseAudio::pa_sink_info_cb(pa_context *c, const pa_sink_info *l
}
void AudioDriverPulseAudio::pa_source_info_cb(pa_context *c, const pa_source_info *l, int eol, void *userdata) {
- AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata;
+ AudioDriverPulseAudio *ad = static_cast<AudioDriverPulseAudio *>(userdata);
// If eol is set to a positive number, you're at the end of the list
if (eol > 0) {
@@ -104,7 +104,7 @@ void AudioDriverPulseAudio::pa_source_info_cb(pa_context *c, const pa_source_inf
void AudioDriverPulseAudio::pa_server_info_cb(pa_context *c, const pa_server_info *i, void *userdata) {
ERR_FAIL_COND_MSG(!i, "PulseAudio server info is null.");
- AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata;
+ AudioDriverPulseAudio *ad = static_cast<AudioDriverPulseAudio *>(userdata);
ad->capture_default_device = i->default_source_name;
ad->default_device = i->default_sink_name;
@@ -588,7 +588,7 @@ AudioDriver::SpeakerMode AudioDriverPulseAudio::get_speaker_mode() const {
}
void AudioDriverPulseAudio::pa_sinklist_cb(pa_context *c, const pa_sink_info *l, int eol, void *userdata) {
- AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata;
+ AudioDriverPulseAudio *ad = static_cast<AudioDriverPulseAudio *>(userdata);
// If eol is set to a positive number, you're at the end of the list
if (eol > 0) {
@@ -771,7 +771,7 @@ void AudioDriverPulseAudio::capture_set_device(const String &p_name) {
}
void AudioDriverPulseAudio::pa_sourcelist_cb(pa_context *c, const pa_source_info *l, int eol, void *userdata) {
- AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata;
+ AudioDriverPulseAudio *ad = static_cast<AudioDriverPulseAudio *>(userdata);
// If eol is set to a positive number, you're at the end of the list
if (eol > 0) {
diff --git a/drivers/unix/dir_access_unix.h b/drivers/unix/dir_access_unix.h
index f90f55605c..b4dc012db2 100644
--- a/drivers/unix/dir_access_unix.h
+++ b/drivers/unix/dir_access_unix.h
@@ -41,7 +41,7 @@
#include <unistd.h>
class DirAccessUnix : public DirAccess {
- DIR *dir_stream;
+ DIR *dir_stream = nullptr;
static DirAccess *create_fs();
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 62de01e8bb..260f7dd08b 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -1318,7 +1318,7 @@ const VkImageType RenderingDeviceVulkan::vulkan_image_type[RenderingDevice::TEXT
/**** BUFFER MANAGEMENT ****/
/***************************/
-Error RenderingDeviceVulkan::_buffer_allocate(Buffer *p_buffer, uint32_t p_size, uint32_t p_usage, VmaMemoryUsage p_mapping) {
+Error RenderingDeviceVulkan::_buffer_allocate(Buffer *p_buffer, uint32_t p_size, uint32_t p_usage, VmaMemoryUsage p_mem_usage, VmaAllocationCreateFlags p_mem_flags) {
VkBufferCreateInfo bufferInfo;
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.pNext = nullptr;
@@ -1330,8 +1330,8 @@ Error RenderingDeviceVulkan::_buffer_allocate(Buffer *p_buffer, uint32_t p_size,
bufferInfo.pQueueFamilyIndices = nullptr;
VmaAllocationCreateInfo allocInfo;
- allocInfo.flags = 0;
- allocInfo.usage = p_mapping;
+ allocInfo.flags = p_mem_flags;
+ allocInfo.usage = p_mem_usage;
allocInfo.requiredFlags = 0;
allocInfo.preferredFlags = 0;
allocInfo.memoryTypeBits = 0;
@@ -1380,8 +1380,8 @@ Error RenderingDeviceVulkan::_insert_staging_block() {
bufferInfo.pQueueFamilyIndices = nullptr;
VmaAllocationCreateInfo allocInfo;
- allocInfo.flags = 0;
- allocInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;
+ allocInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
+ allocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_HOST;
allocInfo.requiredFlags = 0;
allocInfo.preferredFlags = 0;
allocInfo.memoryTypeBits = 0;
@@ -1484,7 +1484,7 @@ Error RenderingDeviceVulkan::_staging_buffer_allocate(uint32_t p_amount, uint32_
//this is an old block, which was already processed, let's reuse
staging_buffer_blocks.write[staging_buffer_current].frame_used = frames_drawn;
staging_buffer_blocks.write[staging_buffer_current].fill_amount = 0;
- } else if (staging_buffer_blocks[staging_buffer_current].frame_used > frames_drawn - frame_count) {
+ } else {
//this block may still be in use, let's not touch it unless we have to, so.. can we create a new one?
if ((uint64_t)staging_buffer_blocks.size() * staging_buffer_block_size < staging_buffer_max_size) {
//we are still allowed to create a new block, so let's do that and insert it for current pos
@@ -1847,9 +1847,9 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
uint32_t image_size = get_image_format_required_size(p_format.format, p_format.width, p_format.height, p_format.depth, p_format.mipmaps, &width, &height);
VmaAllocationCreateInfo allocInfo;
- allocInfo.flags = 0;
+ allocInfo.flags = (p_format.usage_bits & TEXTURE_USAGE_CPU_READ_BIT) ? VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT : 0;
allocInfo.pool = nullptr;
- allocInfo.usage = p_format.usage_bits & TEXTURE_USAGE_CPU_READ_BIT ? VMA_MEMORY_USAGE_CPU_ONLY : VMA_MEMORY_USAGE_GPU_ONLY;
+ allocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
allocInfo.requiredFlags = 0;
allocInfo.preferredFlags = 0;
allocInfo.memoryTypeBits = 0;
@@ -2703,7 +2703,7 @@ Vector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint32_t
//allocate buffer
VkCommandBuffer command_buffer = frames[frame].draw_command_buffer; //makes more sense to retrieve
Buffer tmp_buffer;
- _buffer_allocate(&tmp_buffer, buffer_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_CPU_ONLY);
+ _buffer_allocate(&tmp_buffer, buffer_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_HOST, VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT);
{ //Source image barrier
VkImageMemoryBarrier image_memory_barrier;
@@ -3364,8 +3364,14 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
attachment_last_pass.resize(p_attachments.size());
Vector<VkAttachmentDescription> attachments;
+ Vector<int> attachment_remap;
for (int i = 0; i < p_attachments.size(); i++) {
+ if (p_attachments[i].usage_flags == AttachmentFormat::UNUSED_ATTACHMENT) {
+ attachment_remap.push_back(VK_ATTACHMENT_UNUSED);
+ continue;
+ }
+
ERR_FAIL_INDEX_V(p_attachments[i].format, DATA_FORMAT_MAX, VK_NULL_HANDLE);
ERR_FAIL_INDEX_V(p_attachments[i].samples, TEXTURE_SAMPLES_MAX, VK_NULL_HANDLE);
ERR_FAIL_COND_V_MSG(!(p_attachments[i].usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_INPUT_ATTACHMENT_BIT)),
@@ -3567,7 +3573,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
}
attachment_last_pass[i] = -1;
-
+ attachment_remap.push_back(attachments.size());
attachments.push_back(description);
}
@@ -3612,7 +3618,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
} else {
ERR_FAIL_COND_V_MSG(texture_samples != p_attachments[attachment].samples, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), if an attachment is marked as multisample, all of them should be multisample and use the same number of samples.");
}
- reference.attachment = attachment;
+ reference.attachment = attachment_remap[attachment];
reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachment_last_pass[attachment] = i;
}
@@ -3631,7 +3637,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), input attachment (" + itos(j) + ").");
ERR_FAIL_COND_V_MSG(!(p_attachments[attachment].usage_flags & TEXTURE_USAGE_INPUT_ATTACHMENT_BIT), VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it isn't marked as an input texture.");
ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass.");
- reference.attachment = attachment;
+ reference.attachment = attachment_remap[attachment];
reference.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
attachment_last_pass[attachment] = i;
}
@@ -3657,7 +3663,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass.");
bool multisample = p_attachments[attachment].samples > TEXTURE_SAMPLES_1;
ERR_FAIL_COND_V_MSG(multisample, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), resolve attachments can't be multisample.");
- reference.attachment = attachment;
+ reference.attachment = attachment_remap[attachment];
reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
attachment_last_pass[attachment] = i;
}
@@ -3671,7 +3677,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), VK_NULL_HANDLE, "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), depth attachment.");
ERR_FAIL_COND_V_MSG(!(p_attachments[attachment].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT), VK_NULL_HANDLE, "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it's marked as depth, but it's not a depth attachment.");
ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass.");
- depth_stencil_reference.attachment = attachment;
+ depth_stencil_reference.attachment = attachment_remap[attachment];
depth_stencil_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
attachment_last_pass[attachment] = i;
@@ -3958,14 +3964,13 @@ RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attac
for (int i = 0; i < p_texture_attachments.size(); i++) {
Texture *texture = texture_owner.get_or_null(p_texture_attachments[i]);
- ERR_FAIL_COND_V_MSG(!texture, RID(), "Texture index supplied for framebuffer (" + itos(i) + ") is not a valid texture.");
- ERR_FAIL_COND_V_MSG(texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer");
+ ERR_FAIL_COND_V_MSG(texture && texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer");
- if (texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ if (texture && texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
pass.depth_attachment = i;
} else {
- pass.color_attachments.push_back(i);
+ pass.color_attachments.push_back(texture ? i : FramebufferPass::ATTACHMENT_UNUSED);
}
}
@@ -3979,29 +3984,35 @@ RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_tex
_THREAD_SAFE_METHOD_
Vector<AttachmentFormat> attachments;
+ attachments.resize(p_texture_attachments.size());
Size2i size;
-
+ bool size_set = false;
for (int i = 0; i < p_texture_attachments.size(); i++) {
+ AttachmentFormat af;
Texture *texture = texture_owner.get_or_null(p_texture_attachments[i]);
- ERR_FAIL_COND_V_MSG(!texture, RID(), "Texture index supplied for framebuffer (" + itos(i) + ") is not a valid texture.");
+ if (!texture) {
+ af.usage_flags = AttachmentFormat::UNUSED_ATTACHMENT;
+ } else {
+ ERR_FAIL_COND_V_MSG(texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer");
- ERR_FAIL_COND_V_MSG(texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer");
+ if (!size_set) {
+ size.width = texture->width;
+ size.height = texture->height;
+ size_set = true;
+ } else {
+ ERR_FAIL_COND_V_MSG((uint32_t)size.width != texture->width || (uint32_t)size.height != texture->height, RID(),
+ "All textures in a framebuffer should be the same size.");
+ }
- if (i == 0) {
- size.width = texture->width;
- size.height = texture->height;
- } else {
- ERR_FAIL_COND_V_MSG((uint32_t)size.width != texture->width || (uint32_t)size.height != texture->height, RID(),
- "All textures in a framebuffer should be the same size.");
+ af.format = texture->format;
+ af.samples = texture->samples;
+ af.usage_flags = texture->usage_flags;
}
-
- AttachmentFormat af;
- af.format = texture->format;
- af.samples = texture->samples;
- af.usage_flags = texture->usage_flags;
- attachments.push_back(af);
+ attachments.write[i] = af;
}
+ ERR_FAIL_COND_V_MSG(!size_set, RID(), "All attachments unused.");
+
FramebufferFormatID format_id = framebuffer_format_create_multipass(attachments, p_passes, p_view_count);
if (format_id == INVALID_ID) {
return RID();
@@ -4019,7 +4030,9 @@ RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_tex
RID id = framebuffer_owner.make_rid(framebuffer);
for (int i = 0; i < p_texture_attachments.size(); i++) {
- _add_dependency(id, p_texture_attachments[i]);
+ if (p_texture_attachments[i].is_valid()) {
+ _add_dependency(id, p_texture_attachments[i]);
+ }
}
return id;
@@ -4097,7 +4110,7 @@ RID RenderingDeviceVulkan::vertex_buffer_create(uint32_t p_size_bytes, const Vec
usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
}
Buffer buffer;
- _buffer_allocate(&buffer, p_size_bytes, usage, VMA_MEMORY_USAGE_GPU_ONLY);
+ _buffer_allocate(&buffer, p_size_bytes, usage, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0);
if (p_data.size()) {
uint64_t data_size = p_data.size();
const uint8_t *r = p_data.ptr();
@@ -4259,7 +4272,7 @@ RID RenderingDeviceVulkan::index_buffer_create(uint32_t p_index_count, IndexBuff
#else
index_buffer.max_index = 0xFFFFFFFF;
#endif
- _buffer_allocate(&index_buffer, size_bytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY);
+ _buffer_allocate(&index_buffer, size_bytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0);
if (p_data.size()) {
uint64_t data_size = p_data.size();
const uint8_t *r = p_data.ptr();
@@ -4952,8 +4965,8 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve
Vector<uint8_t> ret;
ret.resize(total_size);
- uint32_t offset = 0;
{
+ uint32_t offset = 0;
uint8_t *binptr = ret.ptrw();
binptr[0] = 'G';
binptr[1] = 'V';
@@ -5026,7 +5039,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_
uint32_t bin_data_size = decode_uint32(binptr + 8);
- const RenderingDeviceVulkanShaderBinaryData &binary_data = *(const RenderingDeviceVulkanShaderBinaryData *)(binptr + 12);
+ const RenderingDeviceVulkanShaderBinaryData &binary_data = *(reinterpret_cast<const RenderingDeviceVulkanShaderBinaryData *>(binptr + 12));
Shader::PushConstant push_constant;
push_constant.push_constant_size = binary_data.push_constant_size;
@@ -5038,7 +5051,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_
bool is_compute = binary_data.is_compute;
- uint32_t compute_local_size[3] = { binary_data.compute_local_size[0], binary_data.compute_local_size[1], binary_data.compute_local_size[2] };
+ const uint32_t compute_local_size[3] = { binary_data.compute_local_size[0], binary_data.compute_local_size[1], binary_data.compute_local_size[2] };
read_offset += sizeof(uint32_t) * 3 + bin_data_size;
@@ -5062,7 +5075,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_
ERR_FAIL_COND_V(read_offset + sizeof(uint32_t) >= binsize, RID());
uint32_t set_count = decode_uint32(binptr + read_offset);
read_offset += sizeof(uint32_t);
- const RenderingDeviceVulkanShaderBinaryDataBinding *set_ptr = (const RenderingDeviceVulkanShaderBinaryDataBinding *)(binptr + read_offset);
+ const RenderingDeviceVulkanShaderBinaryDataBinding *set_ptr = reinterpret_cast<const RenderingDeviceVulkanShaderBinaryDataBinding *>(binptr + read_offset);
uint32_t set_size = set_count * sizeof(RenderingDeviceVulkanShaderBinaryDataBinding);
ERR_FAIL_COND_V(read_offset + set_size >= binsize, RID());
@@ -5134,7 +5147,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_
Vector<Shader::SpecializationConstant> specialization_constants;
for (uint32_t i = 0; i < binary_data.specialization_constant_count; i++) {
- const RenderingDeviceVulkanShaderBinarySpecializationConstant &src_sc = *(const RenderingDeviceVulkanShaderBinarySpecializationConstant *)(binptr + read_offset);
+ const RenderingDeviceVulkanShaderBinarySpecializationConstant &src_sc = *(reinterpret_cast<const RenderingDeviceVulkanShaderBinarySpecializationConstant *>(binptr + read_offset));
Shader::SpecializationConstant sc;
sc.constant.int_value = src_sc.int_value;
sc.constant.type = PipelineSpecializationConstantType(src_sc.type);
@@ -5371,7 +5384,7 @@ RID RenderingDeviceVulkan::uniform_buffer_create(uint32_t p_size_bytes, const Ve
"Creating buffers with data is forbidden during creation of a draw list");
Buffer buffer;
- Error err = _buffer_allocate(&buffer, p_size_bytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY);
+ Error err = _buffer_allocate(&buffer, p_size_bytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0);
ERR_FAIL_COND_V(err != OK, RID());
if (p_data.size()) {
uint64_t data_size = p_data.size();
@@ -5397,7 +5410,7 @@ RID RenderingDeviceVulkan::storage_buffer_create(uint32_t p_size_bytes, const Ve
if (p_usage & STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT) {
flags |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
}
- Error err = _buffer_allocate(&buffer, p_size_bytes, flags, VMA_MEMORY_USAGE_GPU_ONLY);
+ Error err = _buffer_allocate(&buffer, p_size_bytes, flags, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0);
ERR_FAIL_COND_V(err != OK, RID());
if (p_data.size()) {
@@ -5423,7 +5436,7 @@ RID RenderingDeviceVulkan::texture_buffer_create(uint32_t p_size_elements, DataF
ERR_FAIL_COND_V(p_data.size() && (uint32_t)p_data.size() != size_bytes, RID());
TextureBuffer texture_buffer;
- Error err = _buffer_allocate(&texture_buffer.buffer, size_bytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY);
+ Error err = _buffer_allocate(&texture_buffer.buffer, size_bytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0);
ERR_FAIL_COND_V(err != OK, RID());
if (p_data.size()) {
@@ -6170,7 +6183,7 @@ Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) {
VkCommandBuffer command_buffer = frames[frame].setup_command_buffer;
Buffer tmp_buffer;
- _buffer_allocate(&tmp_buffer, buffer->size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_CPU_ONLY);
+ _buffer_allocate(&tmp_buffer, buffer->size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_HOST, VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT);
VkBufferCopy region;
region.srcOffset = 0;
region.dstOffset = 0;
@@ -6321,7 +6334,7 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma
rasterization_state_create_info.depthClampEnable = p_rasterization_state.enable_depth_clamp;
rasterization_state_create_info.rasterizerDiscardEnable = p_rasterization_state.discard_primitives;
rasterization_state_create_info.polygonMode = (p_rasterization_state.wireframe ? VK_POLYGON_MODE_LINE : VK_POLYGON_MODE_FILL);
- static VkCullModeFlags cull_mode[3] = {
+ static const VkCullModeFlags cull_mode[3] = {
VK_CULL_MODE_NONE,
VK_CULL_MODE_FRONT_BIT,
VK_CULL_MODE_BACK_BIT
@@ -6348,7 +6361,7 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma
Vector<VkSampleMask> sample_mask;
if (p_multisample_state.sample_mask.size()) {
//use sample mask
- int rasterization_sample_mask_expected_size[TEXTURE_SAMPLES_MAX] = {
+ const int rasterization_sample_mask_expected_size[TEXTURE_SAMPLES_MAX] = {
1, 2, 4, 8, 16, 32, 64
};
ERR_FAIL_COND_V(rasterization_sample_mask_expected_size[p_multisample_state.sample_count] != p_multisample_state.sample_mask.size(), RID());
@@ -6417,49 +6430,55 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma
Vector<VkPipelineColorBlendAttachmentState> attachment_states;
{
const FramebufferPass &pass = fb_format.E->key().passes[p_for_render_pass];
-
+ attachment_states.resize(pass.color_attachments.size());
+ ERR_FAIL_COND_V(p_blend_state.attachments.size() < pass.color_attachments.size(), RID());
for (int i = 0; i < pass.color_attachments.size(); i++) {
- if (pass.color_attachments[i] != FramebufferPass::ATTACHMENT_UNUSED) {
- int idx = attachment_states.size();
-
- ERR_FAIL_INDEX_V(idx, p_blend_state.attachments.size(), RID());
- VkPipelineColorBlendAttachmentState state;
- state.blendEnable = p_blend_state.attachments[idx].enable_blend;
-
- ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].src_color_blend_factor, BLEND_FACTOR_MAX, RID());
- state.srcColorBlendFactor = blend_factors[p_blend_state.attachments[idx].src_color_blend_factor];
- ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].dst_color_blend_factor, BLEND_FACTOR_MAX, RID());
- state.dstColorBlendFactor = blend_factors[p_blend_state.attachments[idx].dst_color_blend_factor];
- ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].color_blend_op, BLEND_OP_MAX, RID());
- state.colorBlendOp = blend_operations[p_blend_state.attachments[idx].color_blend_op];
-
- ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].src_alpha_blend_factor, BLEND_FACTOR_MAX, RID());
- state.srcAlphaBlendFactor = blend_factors[p_blend_state.attachments[idx].src_alpha_blend_factor];
- ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].dst_alpha_blend_factor, BLEND_FACTOR_MAX, RID());
- state.dstAlphaBlendFactor = blend_factors[p_blend_state.attachments[idx].dst_alpha_blend_factor];
- ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].alpha_blend_op, BLEND_OP_MAX, RID());
- state.alphaBlendOp = blend_operations[p_blend_state.attachments[idx].alpha_blend_op];
+ VkPipelineColorBlendAttachmentState state;
+ if (pass.color_attachments[i] == FramebufferPass::ATTACHMENT_UNUSED) {
+ state.blendEnable = false;
+
+ state.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO;
+ state.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
+ state.colorBlendOp = VK_BLEND_OP_ADD;
+
+ state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
+ state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
+ state.alphaBlendOp = VK_BLEND_OP_ADD;
+
+ state.colorWriteMask = 0;
+ } else {
+ state.blendEnable = p_blend_state.attachments[i].enable_blend;
+
+ ERR_FAIL_INDEX_V(p_blend_state.attachments[i].src_color_blend_factor, BLEND_FACTOR_MAX, RID());
+ state.srcColorBlendFactor = blend_factors[p_blend_state.attachments[i].src_color_blend_factor];
+ ERR_FAIL_INDEX_V(p_blend_state.attachments[i].dst_color_blend_factor, BLEND_FACTOR_MAX, RID());
+ state.dstColorBlendFactor = blend_factors[p_blend_state.attachments[i].dst_color_blend_factor];
+ ERR_FAIL_INDEX_V(p_blend_state.attachments[i].color_blend_op, BLEND_OP_MAX, RID());
+ state.colorBlendOp = blend_operations[p_blend_state.attachments[i].color_blend_op];
+
+ ERR_FAIL_INDEX_V(p_blend_state.attachments[i].src_alpha_blend_factor, BLEND_FACTOR_MAX, RID());
+ state.srcAlphaBlendFactor = blend_factors[p_blend_state.attachments[i].src_alpha_blend_factor];
+ ERR_FAIL_INDEX_V(p_blend_state.attachments[i].dst_alpha_blend_factor, BLEND_FACTOR_MAX, RID());
+ state.dstAlphaBlendFactor = blend_factors[p_blend_state.attachments[i].dst_alpha_blend_factor];
+ ERR_FAIL_INDEX_V(p_blend_state.attachments[i].alpha_blend_op, BLEND_OP_MAX, RID());
+ state.alphaBlendOp = blend_operations[p_blend_state.attachments[i].alpha_blend_op];
state.colorWriteMask = 0;
- if (p_blend_state.attachments[idx].write_r) {
+ if (p_blend_state.attachments[i].write_r) {
state.colorWriteMask |= VK_COLOR_COMPONENT_R_BIT;
}
- if (p_blend_state.attachments[idx].write_g) {
+ if (p_blend_state.attachments[i].write_g) {
state.colorWriteMask |= VK_COLOR_COMPONENT_G_BIT;
}
- if (p_blend_state.attachments[idx].write_b) {
+ if (p_blend_state.attachments[i].write_b) {
state.colorWriteMask |= VK_COLOR_COMPONENT_B_BIT;
}
- if (p_blend_state.attachments[idx].write_a) {
+ if (p_blend_state.attachments[i].write_a) {
state.colorWriteMask |= VK_COLOR_COMPONENT_A_BIT;
}
-
- attachment_states.push_back(state);
- idx++;
}
+ attachment_states.write[i] = state;
}
-
- ERR_FAIL_COND_V(attachment_states.size() != p_blend_state.attachments.size(), RID());
}
color_blend_state_create_info.attachmentCount = attachment_states.size();
@@ -6863,10 +6882,11 @@ Error RenderingDeviceVulkan::_draw_list_setup_framebuffer(Framebuffer *p_framebu
Vector<VkImageView> attachments;
for (int i = 0; i < p_framebuffer->texture_ids.size(); i++) {
Texture *texture = texture_owner.get_or_null(p_framebuffer->texture_ids[i]);
- ERR_FAIL_COND_V(!texture, ERR_BUG);
- attachments.push_back(texture->view);
- ERR_FAIL_COND_V(texture->width != p_framebuffer->size.width, ERR_BUG);
- ERR_FAIL_COND_V(texture->height != p_framebuffer->size.height, ERR_BUG);
+ if (texture) {
+ attachments.push_back(texture->view);
+ ERR_FAIL_COND_V(texture->width != p_framebuffer->size.width, ERR_BUG);
+ ERR_FAIL_COND_V(texture->height != p_framebuffer->size.height, ERR_BUG);
+ }
}
framebuffer_create_info.attachmentCount = attachments.size();
framebuffer_create_info.pAttachments = attachments.ptr();
@@ -6910,13 +6930,18 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
Vector<VkClearValue> clear_values;
clear_values.resize(framebuffer->texture_ids.size());
-
+ int clear_values_count = 0;
{
int color_index = 0;
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
- Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
VkClearValue clear_value;
+ Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
+ if (!texture) {
+ color_index++;
+ continue;
+ }
+
if (color_index < p_clear_colors.size() && texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
ERR_FAIL_INDEX_V(color_index, p_clear_colors.size(), ERR_BUG); //a bug
Color clear_color = p_clear_colors[color_index];
@@ -6934,15 +6959,18 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
clear_value.color.float32[2] = 0;
clear_value.color.float32[3] = 0;
}
- clear_values.write[i] = clear_value;
+ clear_values.write[clear_values_count++] = clear_value;
}
}
- render_pass_begin.clearValueCount = clear_values.size();
+ render_pass_begin.clearValueCount = clear_values_count;
render_pass_begin.pClearValues = clear_values.ptr();
for (int i = 0; i < p_storage_textures.size(); i++) {
Texture *texture = texture_owner.get_or_null(p_storage_textures[i]);
+ if (!texture) {
+ continue;
+ }
ERR_CONTINUE_MSG(!(texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT), "Supplied storage texture " + itos(i) + " for draw list is not set to be used for storage.");
if (texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT) {
@@ -6981,6 +7009,9 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
+ if (!texture) {
+ continue;
+ }
texture->bound = true;
draw_list_bound_textures.push_back(framebuffer->texture_ids[i]);
}
@@ -6989,15 +7020,21 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
}
void RenderingDeviceVulkan::_draw_list_insert_clear_region(DrawList *draw_list, Framebuffer *framebuffer, Point2i viewport_offset, Point2i viewport_size, bool p_clear_color, const Vector<Color> &p_clear_colors, bool p_clear_depth, float p_depth, uint32_t p_stencil) {
+ ERR_FAIL_COND_MSG(p_clear_color && p_clear_colors.size() != framebuffer->texture_ids.size(), "Clear color values supplied (" + itos(p_clear_colors.size()) + ") differ from the amount required for framebuffer color attachments (" + itos(framebuffer->texture_ids.size()) + ").");
Vector<VkClearAttachment> clear_attachments;
int color_index = 0;
+ int texture_index = 0;
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
- VkClearAttachment clear_at = {};
+ if (!texture) {
+ texture_index++;
+ continue;
+ }
+
+ VkClearAttachment clear_at = {};
if (p_clear_color && texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- ERR_FAIL_INDEX(color_index, p_clear_colors.size()); //a bug
- Color clear_color = p_clear_colors[color_index];
+ Color clear_color = p_clear_colors[texture_index++];
clear_at.clearValue.color.float32[0] = clear_color.r;
clear_at.clearValue.color.float32[1] = clear_color.g;
clear_at.clearValue.color.float32[2] = clear_color.b;
@@ -7073,18 +7110,14 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
}
if (p_initial_color_action == INITIAL_ACTION_CLEAR) { //check clear values
-
int color_count = 0;
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
-
- if (texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ if (!texture || !(texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
color_count++;
}
}
-
- ERR_FAIL_COND_V_MSG(p_clear_color_values.size() != color_count, INVALID_ID,
- "Clear color values supplied (" + itos(p_clear_color_values.size()) + ") differ from the amount required for framebuffer color attachments (" + itos(color_count) + ").");
+ ERR_FAIL_COND_V_MSG(p_clear_color_values.size() != color_count, INVALID_ID, "Clear color values supplied (" + itos(p_clear_color_values.size()) + ") differ from the amount required for framebuffer color attachments (" + itos(color_count) + ").");
}
VkFramebuffer vkframebuffer;
@@ -7176,7 +7209,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
- if (texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ if (!texture || !(texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
color_count++;
}
}
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index a4d5af91a4..7d9bd19309 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -219,7 +219,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
}
};
- Error _buffer_allocate(Buffer *p_buffer, uint32_t p_size, uint32_t p_usage, VmaMemoryUsage p_mapping);
+ Error _buffer_allocate(Buffer *p_buffer, uint32_t p_size, uint32_t p_usage, VmaMemoryUsage p_mem_usage, VmaAllocationCreateFlags p_mem_flags);
Error _buffer_free(Buffer *p_buffer);
Error _buffer_update(Buffer *p_buffer, size_t p_offset, const uint8_t *p_data, size_t p_data_size, bool p_use_draw_command_buffer = false, uint32_t p_required_align = 32);
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index 3551b5d6c4..a09a757842 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -900,7 +900,7 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
free(device_queue_props);
print_verbose(" #" + itos(i) + ": " + vendor + " " + name + " - " + (present_supported ? "Supported" : "Unsupported") + ", " + dev_type);
- if (present_supported) { // Select first supported device of preffered type: Discrete > Integrated > Virtual > CPU > Other.
+ if (present_supported) { // Select first supported device of preferred type: Discrete > Integrated > Virtual > CPU > Other.
switch (props.deviceType) {
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: {
if (type_selected < 4) {
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp
index c9609b469a..3a62850339 100644
--- a/drivers/wasapi/audio_driver_wasapi.cpp
+++ b/drivers/wasapi/audio_driver_wasapi.cpp
@@ -680,7 +680,7 @@ void AudioDriverWASAPI::write_sample(WORD format_tag, int bits_per_sample, BYTE
}
void AudioDriverWASAPI::thread_func(void *p_udata) {
- AudioDriverWASAPI *ad = (AudioDriverWASAPI *)p_udata;
+ AudioDriverWASAPI *ad = static_cast<AudioDriverWASAPI *>(p_udata);
uint32_t avail_frames = 0;
uint32_t write_ofs = 0;
diff --git a/drivers/xaudio2/audio_driver_xaudio2.cpp b/drivers/xaudio2/audio_driver_xaudio2.cpp
index 03fdfda23d..c32c7cf1e5 100644
--- a/drivers/xaudio2/audio_driver_xaudio2.cpp
+++ b/drivers/xaudio2/audio_driver_xaudio2.cpp
@@ -84,7 +84,7 @@ Error AudioDriverXAudio2::init() {
}
void AudioDriverXAudio2::thread_func(void *p_udata) {
- AudioDriverXAudio2 *ad = (AudioDriverXAudio2 *)p_udata;
+ AudioDriverXAudio2 *ad = static_cast<AudioDriverXAudio2 *>(p_udata);
while (!ad->exit_thread) {
if (!ad->active) {