diff options
Diffstat (limited to 'servers')
146 files changed, 2611 insertions, 2356 deletions
diff --git a/servers/audio/audio_effect.cpp b/servers/audio/audio_effect.cpp index f38d0adfb2..870a77806b 100644 --- a/servers/audio/audio_effect.cpp +++ b/servers/audio/audio_effect.cpp @@ -31,16 +31,12 @@ #include "audio_effect.h" void AudioEffectInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - if (GDVIRTUAL_REQUIRED_CALL(_process, p_src_frames, p_dst_frames, p_frame_count)) { - return; - } + GDVIRTUAL_REQUIRED_CALL(_process, p_src_frames, p_dst_frames, p_frame_count); } bool AudioEffectInstance::process_silence() const { - bool ret; - if (GDVIRTUAL_CALL(_process_silence, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_process_silence, ret); + return ret; } void AudioEffectInstance::_bind_methods() { @@ -52,10 +48,8 @@ void AudioEffectInstance::_bind_methods() { Ref<AudioEffectInstance> AudioEffect::instantiate() { Ref<AudioEffectInstance> ret; - if (GDVIRTUAL_REQUIRED_CALL(_instantiate, ret)) { - return ret; - } - return Ref<AudioEffectInstance>(); + GDVIRTUAL_REQUIRED_CALL(_instantiate, ret); + return ret; } void AudioEffect::_bind_methods() { GDVIRTUAL_BIND(_instantiate); diff --git a/servers/audio/audio_effect.h b/servers/audio/audio_effect.h index 653d04595e..93f10c156a 100644 --- a/servers/audio/audio_effect.h +++ b/servers/audio/audio_effect.h @@ -41,7 +41,7 @@ class AudioEffectInstance : public RefCounted { GDCLASS(AudioEffectInstance, RefCounted); protected: - GDVIRTUAL3(_process, GDNativeConstPtr<AudioFrame>, GDNativePtr<AudioFrame>, int) + GDVIRTUAL3(_process, GDExtensionConstPtr<AudioFrame>, GDExtensionPtr<AudioFrame>, int) GDVIRTUAL0RC(bool, _process_silence) static void _bind_methods(); diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp index 1bfe6a3eb5..113e728106 100644 --- a/servers/audio/audio_stream.cpp +++ b/servers/audio/audio_stream.cpp @@ -54,11 +54,9 @@ bool AudioStreamPlayback::is_playing() const { } int AudioStreamPlayback::get_loop_count() const { - int ret; - if (GDVIRTUAL_CALL(_get_loop_count, ret)) { - return ret; - } - return 0; + int ret = 0; + GDVIRTUAL_CALL(_get_loop_count, ret); + return ret; } double AudioStreamPlayback::get_playback_position() const { @@ -69,18 +67,13 @@ double AudioStreamPlayback::get_playback_position() const { ERR_FAIL_V_MSG(0, "AudioStreamPlayback::get_playback_position unimplemented!"); } void AudioStreamPlayback::seek(double p_time) { - if (GDVIRTUAL_CALL(_seek, p_time)) { - return; - } + GDVIRTUAL_CALL(_seek, p_time); } int AudioStreamPlayback::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) { - int ret; - if (GDVIRTUAL_REQUIRED_CALL(_mix, p_buffer, p_rate_scale, p_frames, ret)) { - return ret; - } - - return 0; + int ret = 0; + GDVIRTUAL_REQUIRED_CALL(_mix, p_buffer, p_rate_scale, p_frames, ret); + return ret; } void AudioStreamPlayback::tag_used_streams() { @@ -111,20 +104,14 @@ void AudioStreamPlaybackResampled::begin_resample() { } int AudioStreamPlaybackResampled::_mix_internal(AudioFrame *p_buffer, int p_frames) { - int ret; - if (GDVIRTUAL_REQUIRED_CALL(_mix_resampled, p_buffer, p_frames, ret)) { - return ret; - } - - return 0; + int ret = 0; + GDVIRTUAL_REQUIRED_CALL(_mix_resampled, p_buffer, p_frames, ret); + return ret; } float AudioStreamPlaybackResampled::get_stream_sampling_rate() { - float ret; - if (GDVIRTUAL_REQUIRED_CALL(_get_stream_sampling_rate, ret)) { - return ret; - } - - return 0; + float ret = 0; + GDVIRTUAL_REQUIRED_CALL(_get_stream_sampling_rate, ret); + return ret; } void AudioStreamPlaybackResampled::_bind_methods() { @@ -201,58 +188,44 @@ Ref<AudioStreamPlayback> AudioStream::instantiate_playback() { } String AudioStream::get_stream_name() const { String ret; - if (GDVIRTUAL_CALL(_get_stream_name, ret)) { - return ret; - } - return String(); + GDVIRTUAL_CALL(_get_stream_name, ret); + return ret; } double AudioStream::get_length() const { - double ret; - if (GDVIRTUAL_CALL(_get_length, ret)) { - return ret; - } - return 0; + double ret = 0; + GDVIRTUAL_CALL(_get_length, ret); + return ret; } bool AudioStream::is_monophonic() const { - bool ret; - if (GDVIRTUAL_CALL(_is_monophonic, ret)) { - return ret; - } - return true; + bool ret = true; + GDVIRTUAL_CALL(_is_monophonic, ret); + return ret; } double AudioStream::get_bpm() const { double ret = 0; - if (GDVIRTUAL_CALL(_get_bpm, ret)) { - return ret; - } - return 0; + GDVIRTUAL_CALL(_get_bpm, ret); + return ret; } bool AudioStream::has_loop() const { bool ret = 0; - if (GDVIRTUAL_CALL(_has_loop, ret)) { - return ret; - } - return 0; + GDVIRTUAL_CALL(_has_loop, ret); + return ret; } int AudioStream::get_bar_beats() const { int ret = 0; - if (GDVIRTUAL_CALL(_get_bar_beats, ret)) { - return ret; - } - return 0; + GDVIRTUAL_CALL(_get_bar_beats, ret); + return ret; } int AudioStream::get_beat_count() const { int ret = 0; - if (GDVIRTUAL_CALL(_get_beat_count, ret)) { - return ret; - } - return 0; + GDVIRTUAL_CALL(_get_beat_count, ret); + return ret; } void AudioStream::tag_used(float p_offset) { @@ -582,8 +555,9 @@ Ref<AudioStreamPlayback> AudioStreamRandomizer::instance_playback_no_repeats() { } } if (local_pool.is_empty()) { + // There is only one sound to choose from. + // Always play a random sound while allowing repeats (which always plays the same sound). playback = instance_playback_random(); - WARN_PRINT("Playback stream pool is too small to prevent repeats."); return playback; } diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h index c41475010c..c6ae6817e7 100644 --- a/servers/audio/audio_stream.h +++ b/servers/audio/audio_stream.h @@ -53,7 +53,7 @@ protected: GDVIRTUAL0RC(int, _get_loop_count) GDVIRTUAL0RC(double, _get_playback_position) GDVIRTUAL1(_seek, double) - GDVIRTUAL3R(int, _mix, GDNativePtr<AudioFrame>, float, int) + GDVIRTUAL3R(int, _mix, GDExtensionPtr<AudioFrame>, float, int) GDVIRTUAL0(_tag_used_streams) public: virtual void start(double p_from_pos = 0.0); @@ -91,7 +91,7 @@ protected: virtual int _mix_internal(AudioFrame *p_buffer, int p_frames); virtual float get_stream_sampling_rate(); - GDVIRTUAL2R(int, _mix_resampled, GDNativePtr<AudioFrame>, int) + GDVIRTUAL2R(int, _mix_resampled, GDExtensionPtr<AudioFrame>, int) GDVIRTUAL0RC(float, _get_stream_sampling_rate) static void _bind_methods(); diff --git a/servers/audio/effects/audio_effect_delay.cpp b/servers/audio/effects/audio_effect_delay.cpp index f71ff05b23..69c62e3a13 100644 --- a/servers/audio/effects/audio_effect_delay.cpp +++ b/servers/audio/effects/audio_effect_delay.cpp @@ -94,7 +94,7 @@ void AudioEffectDelayInstance::_process_chunk(const AudioFrame *p_src_frames, Au //apply lowpass and feedback gain AudioFrame fb_in = out * feedback_level_f * lpf_ic + h * lpf_c; - fb_in.undenormalise(); //avoid denormals + fb_in.undenormalize(); //avoid denormals h = fb_in; fb_buf[feedback_buffer_pos] = fb_in; diff --git a/servers/audio/effects/audio_effect_distortion.cpp b/servers/audio/effects/audio_effect_distortion.cpp index 5987ed7bb2..25ca0cfdfe 100644 --- a/servers/audio/effects/audio_effect_distortion.cpp +++ b/servers/audio/effects/audio_effect_distortion.cpp @@ -50,7 +50,7 @@ void AudioEffectDistortionInstance::process(const AudioFrame *p_src_frames, Audi float lofi_mult = powf(2.0, 2.0 + (1.0 - drive_f) * 14); //goes from 16 to 2 bits for (int i = 0; i < p_frame_count * 2; i++) { - float out = undenormalise(src[i] * lpf_ic + lpf_c * h[i & 1]); + float out = undenormalize(src[i] * lpf_ic + lpf_c * h[i & 1]); h[i & 1] = out; float a = out; float ha = src[i] - out; //high freqs @@ -160,10 +160,10 @@ void AudioEffectDistortion::_bind_methods() { ClassDB::bind_method(D_METHOD("get_post_gain"), &AudioEffectDistortion::get_post_gain); ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Clip,ATan,LoFi,Overdrive,Wave Shape"), "set_mode", "get_mode"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pre_gain", PROPERTY_HINT_RANGE, "-60,60,0.01"), "set_pre_gain", "get_pre_gain"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pre_gain", PROPERTY_HINT_RANGE, "-60,60,0.01,suffix:dB"), "set_pre_gain", "get_pre_gain"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "keep_hf_hz", PROPERTY_HINT_RANGE, "1,20500,1,suffix:Hz"), "set_keep_hf_hz", "get_keep_hf_hz"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "drive", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drive", "get_drive"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "post_gain", PROPERTY_HINT_RANGE, "-80,24,0.01"), "set_post_gain", "get_post_gain"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "post_gain", PROPERTY_HINT_RANGE, "-80,24,0.01,suffix:dB"), "set_post_gain", "get_post_gain"); BIND_ENUM_CONSTANT(MODE_CLIP); BIND_ENUM_CONSTANT(MODE_ATAN); diff --git a/servers/audio/effects/reverb_filter.cpp b/servers/audio/effects/reverb_filter.cpp index 0363706714..2b60b73b7e 100644 --- a/servers/audio/effects/reverb_filter.cpp +++ b/servers/audio/effects/reverb_filter.cpp @@ -77,7 +77,7 @@ void Reverb::process(float *p_src, float *p_dst, int p_frames) { read_pos += echo_buffer_size; } - float in = undenormalise(echo_buffer[read_pos] * params.predelay_fb + p_src[i]); + float in = undenormalize(echo_buffer[read_pos] * params.predelay_fb + p_src[i]); echo_buffer[echo_buffer_pos] = in; @@ -111,7 +111,7 @@ void Reverb::process(float *p_src, float *p_dst, int p_frames) { c.pos = 0; } - float out = undenormalise(c.buffer[c.pos] * c.feedback); + float out = undenormalize(c.buffer[c.pos] * c.feedback); out = out * (1.0 - c.damp) + c.damp_h * c.damp; //lowpass c.damp_h = out; c.buffer[c.pos] = input_buffer[j] + out; @@ -138,7 +138,7 @@ void Reverb::process(float *p_src, float *p_dst, int p_frames) { ap=&allpass[m_ap]; \ if (ap->pos>=ap_size_limit[m_ap]) \ ap->pos=0; \ - aux=undenormalise(ap->buffer[ap->pos]); \ + aux=undenormalize(ap->buffer[ap->pos]); \ in=sample; \ sample=-in+aux; \ ap->pos++; @@ -163,7 +163,7 @@ void Reverb::process(float *p_src, float *p_dst, int p_frames) { } float aux = a.buffer[a.pos]; - a.buffer[a.pos] = undenormalise(allpass_feedback * aux + p_dst[j]); + a.buffer[a.pos] = undenormalize(allpass_feedback * aux + p_dst[j]); p_dst[j] = aux - allpass_feedback * a.buffer[a.pos]; a.pos++; } diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 1254a6740a..e657570f9b 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -1454,7 +1454,7 @@ void AudioServer::update() { } void AudioServer::load_default_bus_layout() { - String layout_path = ProjectSettings::get_singleton()->get("audio/buses/default_bus_layout"); + String layout_path = GLOBAL_GET("audio/buses/default_bus_layout"); if (ResourceLoader::exists(layout_path)) { Ref<AudioBusLayout> default_layout = ResourceLoader::load(layout_path); diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 4b97bede56..523cc714f0 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -302,19 +302,12 @@ void DisplayServer::tts_post_utterance_event(TTSUtteranceEvent p_event, int p_id case DisplayServer::TTS_UTTERANCE_ENDED: case DisplayServer::TTS_UTTERANCE_CANCELED: { if (utterance_callback[p_event].is_valid()) { - Variant args[1]; - args[0] = p_id; - const Variant *argp[] = { &args[0] }; - utterance_callback[p_event].call_deferredp(argp, 1); // Should be deferred, on some platforms utterance events can be called from different threads in a rapid succession. + utterance_callback[p_event].call_deferred(p_id); // Should be deferred, on some platforms utterance events can be called from different threads in a rapid succession. } } break; case DisplayServer::TTS_UTTERANCE_BOUNDARY: { if (utterance_callback[p_event].is_valid()) { - Variant args[2]; - args[0] = p_pos; - args[1] = p_id; - const Variant *argp[] = { &args[0], &args[1] }; - utterance_callback[p_event].call_deferredp(argp, 2); // Should be deferred, on some platforms utterance events can be called from different threads in a rapid succession. + utterance_callback[p_event].call_deferred(p_pos, p_id); // Should be deferred, on some platforms utterance events can be called from different threads in a rapid succession. } } break; default: @@ -374,8 +367,7 @@ float DisplayServer::screen_get_scale(int p_screen) const { return 1.0f; }; -bool DisplayServer::screen_is_touchscreen(int p_screen) const { - //return false; +bool DisplayServer::is_touchscreen_available() const { return Input::get_singleton() && Input::get_singleton()->is_emulating_touch_from_mouse(); } @@ -581,6 +573,8 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("global_menu_set_item_icon", "menu_root", "idx", "icon"), &DisplayServer::global_menu_set_item_icon); ClassDB::bind_method(D_METHOD("global_menu_set_item_indentation_level", "menu_root", "idx", "level"), &DisplayServer::global_menu_set_item_indentation_level); + ClassDB::bind_method(D_METHOD("global_menu_get_item_count", "menu_root"), &DisplayServer::global_menu_get_item_count); + ClassDB::bind_method(D_METHOD("global_menu_remove_item", "menu_root", "idx"), &DisplayServer::global_menu_remove_item); ClassDB::bind_method(D_METHOD("global_menu_clear", "menu_root"), &DisplayServer::global_menu_clear); @@ -623,7 +617,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("screen_get_usable_rect", "screen"), &DisplayServer::screen_get_usable_rect, DEFVAL(SCREEN_OF_MAIN_WINDOW)); ClassDB::bind_method(D_METHOD("screen_get_dpi", "screen"), &DisplayServer::screen_get_dpi, DEFVAL(SCREEN_OF_MAIN_WINDOW)); ClassDB::bind_method(D_METHOD("screen_get_scale", "screen"), &DisplayServer::screen_get_scale, DEFVAL(SCREEN_OF_MAIN_WINDOW)); - ClassDB::bind_method(D_METHOD("screen_is_touchscreen", "screen"), &DisplayServer::screen_is_touchscreen, DEFVAL(SCREEN_OF_MAIN_WINDOW)); + ClassDB::bind_method(D_METHOD("is_touchscreen_available"), &DisplayServer::is_touchscreen_available, DEFVAL(SCREEN_OF_MAIN_WINDOW)); ClassDB::bind_method(D_METHOD("screen_get_max_scale"), &DisplayServer::screen_get_max_scale); ClassDB::bind_method(D_METHOD("screen_get_refresh_rate", "screen"), &DisplayServer::screen_get_refresh_rate, DEFVAL(SCREEN_OF_MAIN_WINDOW)); @@ -636,9 +630,6 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_window_list"), &DisplayServer::get_window_list); ClassDB::bind_method(D_METHOD("get_window_at_screen_position", "position"), &DisplayServer::get_window_at_screen_position); - ClassDB::bind_method(D_METHOD("create_sub_window", "mode", "vsync_mode", "flags", "rect"), &DisplayServer::create_sub_window, DEFVAL(Rect2i())); - ClassDB::bind_method(D_METHOD("delete_sub_window", "window_id"), &DisplayServer::delete_sub_window); - ClassDB::bind_method(D_METHOD("window_get_native_handle", "handle_type", "window_id"), &DisplayServer::window_get_native_handle, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_get_active_popup"), &DisplayServer::window_get_active_popup); ClassDB::bind_method(D_METHOD("window_set_popup_safe_rect", "window", "rect"), &DisplayServer::window_set_popup_safe_rect); @@ -651,6 +642,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("window_set_current_screen", "screen", "window_id"), &DisplayServer::window_set_current_screen, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_get_position", "window_id"), &DisplayServer::window_get_position, DEFVAL(MAIN_WINDOW_ID)); + ClassDB::bind_method(D_METHOD("window_get_position_with_decorations", "window_id"), &DisplayServer::window_get_position_with_decorations, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_set_position", "position", "window_id"), &DisplayServer::window_set_position, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_get_size", "window_id"), &DisplayServer::window_get_size, DEFVAL(MAIN_WINDOW_ID)); @@ -661,7 +653,6 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("window_set_input_text_callback", "callback", "window_id"), &DisplayServer::window_set_input_text_callback, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_set_drop_files_callback", "callback", "window_id"), &DisplayServer::window_set_drop_files_callback, DEFVAL(MAIN_WINDOW_ID)); - ClassDB::bind_method(D_METHOD("window_attach_instance_id", "instance_id", "window_id"), &DisplayServer::window_attach_instance_id, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_get_attached_instance_id", "window_id"), &DisplayServer::window_get_attached_instance_id, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_get_max_size", "window_id"), &DisplayServer::window_get_max_size, DEFVAL(MAIN_WINDOW_ID)); @@ -670,7 +661,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("window_get_min_size", "window_id"), &DisplayServer::window_get_min_size, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_set_min_size", "min_size", "window_id"), &DisplayServer::window_set_min_size, DEFVAL(MAIN_WINDOW_ID)); - ClassDB::bind_method(D_METHOD("window_get_real_size", "window_id"), &DisplayServer::window_get_real_size, DEFVAL(MAIN_WINDOW_ID)); + ClassDB::bind_method(D_METHOD("window_get_size_with_decorations", "window_id"), &DisplayServer::window_get_size_with_decorations, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_get_mode", "window_id"), &DisplayServer::window_get_mode, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_set_mode", "mode", "window_id"), &DisplayServer::window_set_mode, DEFVAL(MAIN_WINDOW_ID)); @@ -695,6 +686,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("window_set_vsync_mode", "vsync_mode", "window_id"), &DisplayServer::window_set_vsync_mode, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_get_vsync_mode", "window_id"), &DisplayServer::window_get_vsync_mode, DEFVAL(MAIN_WINDOW_ID)); + ClassDB::bind_method(D_METHOD("window_is_maximize_allowed", "window_id"), &DisplayServer::window_is_maximize_allowed, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_maximize_on_title_dbl_click"), &DisplayServer::window_maximize_on_title_dbl_click); ClassDB::bind_method(D_METHOD("window_minimize_on_title_dbl_click"), &DisplayServer::window_minimize_on_title_dbl_click); @@ -834,6 +826,7 @@ void DisplayServer::_bind_methods() { BIND_ENUM_CONSTANT(DISPLAY_HANDLE); BIND_ENUM_CONSTANT(WINDOW_HANDLE); BIND_ENUM_CONSTANT(WINDOW_VIEW); + BIND_ENUM_CONSTANT(OPENGL_CONTEXT); BIND_ENUM_CONSTANT(TTS_UTTERANCE_STARTED); BIND_ENUM_CONSTANT(TTS_UTTERANCE_ENDED); @@ -865,9 +858,9 @@ Vector<String> DisplayServer::get_create_function_rendering_drivers(int p_index) return server_create_functions[p_index].get_rendering_drivers_function(); } -DisplayServer *DisplayServer::create(int p_index, const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { +DisplayServer *DisplayServer::create(int p_index, const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) { ERR_FAIL_INDEX_V(p_index, server_create_count, nullptr); - return server_create_functions[p_index].create_function(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error); + return server_create_functions[p_index].create_function(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error); } void DisplayServer::_input_set_mouse_mode(Input::MouseMode p_mode) { diff --git a/servers/display_server.h b/servers/display_server.h index 8eafccc040..4c36b0acb9 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -70,9 +70,10 @@ public: DISPLAY_HANDLE, WINDOW_HANDLE, WINDOW_VIEW, + OPENGL_CONTEXT, }; - typedef DisplayServer *(*CreateFunction)(const String &, WindowMode, VSyncMode, uint32_t, const Size2i &, Error &r_error); + typedef DisplayServer *(*CreateFunction)(const String &, WindowMode, VSyncMode, uint32_t, const Point2i *, const Size2i &, Error &r_error); typedef Vector<String> (*GetRenderingDriversFunction)(); private: @@ -261,7 +262,7 @@ public: return scale; } virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const = 0; - virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const; + virtual bool is_touchscreen_available() const; // Keep the ScreenOrientation enum values in sync with the `display/window/handheld/orientation` // project setting hint. @@ -352,6 +353,7 @@ public: virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID) = 0; virtual Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const = 0; + virtual Point2i window_get_position_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const = 0; virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID) = 0; virtual void window_set_transient(WindowID p_window, WindowID p_parent) = 0; @@ -365,7 +367,7 @@ public: virtual void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) = 0; virtual Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const = 0; - virtual Size2i window_get_real_size(WindowID p_window = MAIN_WINDOW_ID) const = 0; // FIXME: Find clearer name for this. + virtual Size2i window_get_size_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const = 0; virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID) = 0; virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const = 0; @@ -382,7 +384,7 @@ public: virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) = 0; virtual void window_set_window_buttons_offset(const Vector2i &p_offset, WindowID p_window = MAIN_WINDOW_ID) {} - virtual Vector2i window_get_safe_title_margins(WindowID p_window = MAIN_WINDOW_ID) const { return Vector2i(); } + virtual Vector3i window_get_safe_title_margins(WindowID p_window = MAIN_WINDOW_ID) const { return Vector3i(); } virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const = 0; @@ -483,7 +485,7 @@ public: static int get_create_function_count(); static const char *get_create_function_name(int p_index); static Vector<String> get_create_function_rendering_drivers(int p_index); - static DisplayServer *create(int p_index, const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error); + static DisplayServer *create(int p_index, const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error); DisplayServer(); ~DisplayServer(); diff --git a/servers/display_server_headless.h b/servers/display_server_headless.h index 3853ff4fdc..94b5f3c1e9 100644 --- a/servers/display_server_headless.h +++ b/servers/display_server_headless.h @@ -45,7 +45,7 @@ private: return drivers; } - static DisplayServer *create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { + static DisplayServer *create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) { r_error = OK; RasterizerDummy::make_current(); return memnew(DisplayServerHeadless()); @@ -90,6 +90,7 @@ public: void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID) override {} Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const override { return Point2i(); } + Point2i window_get_position_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const override { return Point2i(); } void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID) override {} void window_set_transient(WindowID p_window, WindowID p_parent) override {} @@ -102,7 +103,7 @@ public: void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override {} Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const override { return Size2i(); } - Size2i window_get_real_size(WindowID p_window = MAIN_WINDOW_ID) const override { return Size2i(); } + Size2i window_get_size_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const override { return Size2i(); } void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID) override {} WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const override { return WINDOW_MODE_MINIMIZED; } diff --git a/servers/extensions/physics_server_2d_extension.h b/servers/extensions/physics_server_2d_extension.h index 573b51ee12..7a7a3c5cba 100644 --- a/servers/extensions/physics_server_2d_extension.h +++ b/servers/extensions/physics_server_2d_extension.h @@ -126,12 +126,12 @@ protected: static void _bind_methods(); bool is_body_excluded_from_query(const RID &p_body) const; - GDVIRTUAL7R(bool, _intersect_ray, const Vector2 &, const Vector2 &, uint32_t, bool, bool, bool, GDNativePtr<PhysicsServer2DExtensionRayResult>) - GDVIRTUAL7R(int, _intersect_point, const Vector2 &, ObjectID, uint32_t, bool, bool, GDNativePtr<PhysicsServer2DExtensionShapeResult>, int) - GDVIRTUAL9R(int, _intersect_shape, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDNativePtr<PhysicsServer2DExtensionShapeResult>, int) - GDVIRTUAL9R(bool, _cast_motion, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDNativePtr<real_t>, GDNativePtr<real_t>) - GDVIRTUAL10R(bool, _collide_shape, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDNativePtr<Vector2>, int, GDNativePtr<int>) - GDVIRTUAL8R(bool, _rest_info, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDNativePtr<PhysicsServer2DExtensionShapeRestInfo>) + GDVIRTUAL7R(bool, _intersect_ray, const Vector2 &, const Vector2 &, uint32_t, bool, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionRayResult>) + GDVIRTUAL7R(int, _intersect_point, const Vector2 &, ObjectID, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionShapeResult>, int) + GDVIRTUAL9R(int, _intersect_shape, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionShapeResult>, int) + GDVIRTUAL9R(bool, _cast_motion, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<real_t>, GDExtensionPtr<real_t>) + GDVIRTUAL10R(bool, _collide_shape, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<Vector2>, int, GDExtensionPtr<int>) + GDVIRTUAL8R(bool, _rest_info, RID, const Transform2D &, const Vector2 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionShapeRestInfo>) public: virtual bool intersect_ray(const RayParameters &p_parameters, RayResult &r_result) override { @@ -190,9 +190,9 @@ class PhysicsServer2DExtension : public PhysicsServer2D { protected: static void _bind_methods(); - GDVIRTUAL9R(bool, _shape_collide, RID, const Transform2D &, const Vector2 &, RID, const Transform2D &, const Vector2 &, GDNativePtr<Vector2>, int, GDNativePtr<int>) + GDVIRTUAL9R(bool, _shape_collide, RID, const Transform2D &, const Vector2 &, RID, const Transform2D &, const Vector2 &, GDExtensionPtr<Vector2>, int, GDExtensionPtr<int>) - GDVIRTUAL8R(bool, _body_collide_shape, RID, int, RID, const Transform2D &, const Vector2 &, GDNativePtr<Vector2>, int, GDNativePtr<int>) + GDVIRTUAL8R(bool, _body_collide_shape, RID, int, RID, const Transform2D &, const Vector2 &, GDExtensionPtr<Vector2>, int, GDExtensionPtr<int>) public: // The warning is valid, but unavoidable. If the function is not overridden it will error anyway. @@ -385,7 +385,7 @@ public: EXBIND1R(PhysicsDirectBodyState2D *, body_get_direct_state, RID) - GDVIRTUAL7RC(bool, _body_test_motion, RID, const Transform2D &, const Vector2 &, real_t, bool, bool, GDNativePtr<PhysicsServer2DExtensionMotionResult>) + GDVIRTUAL7RC(bool, _body_test_motion, RID, const Transform2D &, const Vector2 &, real_t, bool, bool, GDExtensionPtr<PhysicsServer2DExtensionMotionResult>) thread_local static const HashSet<RID> *exclude_bodies; thread_local static const HashSet<ObjectID> *exclude_objects; diff --git a/servers/extensions/physics_server_3d_extension.h b/servers/extensions/physics_server_3d_extension.h index 57f2a2d790..a85df0683c 100644 --- a/servers/extensions/physics_server_3d_extension.h +++ b/servers/extensions/physics_server_3d_extension.h @@ -128,12 +128,12 @@ protected: static void _bind_methods(); bool is_body_excluded_from_query(const RID &p_body) const; - GDVIRTUAL8R(bool, _intersect_ray, const Vector3 &, const Vector3 &, uint32_t, bool, bool, bool, bool, GDNativePtr<PhysicsServer3DExtensionRayResult>) - GDVIRTUAL6R(int, _intersect_point, const Vector3 &, uint32_t, bool, bool, GDNativePtr<PhysicsServer3DExtensionShapeResult>, int) - GDVIRTUAL9R(int, _intersect_shape, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDNativePtr<PhysicsServer3DExtensionShapeResult>, int) - GDVIRTUAL10R(bool, _cast_motion, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDNativePtr<real_t>, GDNativePtr<real_t>, GDNativePtr<PhysicsServer3DExtensionShapeRestInfo>) - GDVIRTUAL10R(bool, _collide_shape, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDNativePtr<Vector3>, int, GDNativePtr<int>) - GDVIRTUAL8R(bool, _rest_info, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDNativePtr<PhysicsServer3DExtensionShapeRestInfo>) + GDVIRTUAL8R(bool, _intersect_ray, const Vector3 &, const Vector3 &, uint32_t, bool, bool, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionRayResult>) + GDVIRTUAL6R(int, _intersect_point, const Vector3 &, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionShapeResult>, int) + GDVIRTUAL9R(int, _intersect_shape, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionShapeResult>, int) + GDVIRTUAL10R(bool, _cast_motion, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<real_t>, GDExtensionPtr<real_t>, GDExtensionPtr<PhysicsServer3DExtensionShapeRestInfo>) + GDVIRTUAL10R(bool, _collide_shape, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<Vector3>, int, GDExtensionPtr<int>) + GDVIRTUAL8R(bool, _rest_info, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDExtensionPtr<PhysicsServer3DExtensionShapeRestInfo>) GDVIRTUAL2RC(Vector3, _get_closest_point_to_object_volume, RID, const Vector3 &) public: @@ -382,7 +382,7 @@ public: EXBIND2(body_set_ray_pickable, RID, bool) - GDVIRTUAL7RC(bool, _body_test_motion, RID, const Transform3D &, const Vector3 &, real_t, int, bool, GDNativePtr<PhysicsServer3DExtensionMotionResult>) + GDVIRTUAL7RC(bool, _body_test_motion, RID, const Transform3D &, const Vector3 &, real_t, int, bool, GDExtensionPtr<PhysicsServer3DExtensionMotionResult>) thread_local static const HashSet<RID> *exclude_bodies; thread_local static const HashSet<ObjectID> *exclude_objects; diff --git a/servers/movie_writer/movie_writer.cpp b/servers/movie_writer/movie_writer.cpp index 2164dca29e..419943f2d2 100644 --- a/servers/movie_writer/movie_writer.cpp +++ b/servers/movie_writer/movie_writer.cpp @@ -52,34 +52,26 @@ MovieWriter *MovieWriter::find_writer_for_file(const String &p_file) { } uint32_t MovieWriter::get_audio_mix_rate() const { - uint32_t ret = 0; - if (GDVIRTUAL_REQUIRED_CALL(_get_audio_mix_rate, ret)) { - return ret; - } - return 48000; + uint32_t ret = 48000; + GDVIRTUAL_REQUIRED_CALL(_get_audio_mix_rate, ret); + return ret; } AudioServer::SpeakerMode MovieWriter::get_audio_speaker_mode() const { AudioServer::SpeakerMode ret = AudioServer::SPEAKER_MODE_STEREO; - if (GDVIRTUAL_REQUIRED_CALL(_get_audio_speaker_mode, ret)) { - return ret; - } - return AudioServer::SPEAKER_MODE_STEREO; + GDVIRTUAL_REQUIRED_CALL(_get_audio_speaker_mode, ret); + return ret; } Error MovieWriter::write_begin(const Size2i &p_movie_size, uint32_t p_fps, const String &p_base_path) { - Error ret = OK; - if (GDVIRTUAL_REQUIRED_CALL(_write_begin, p_movie_size, p_fps, p_base_path, ret)) { - return ret; - } - return ERR_UNCONFIGURED; + Error ret = ERR_UNCONFIGURED; + GDVIRTUAL_REQUIRED_CALL(_write_begin, p_movie_size, p_fps, p_base_path, ret); + return ret; } Error MovieWriter::write_frame(const Ref<Image> &p_image, const int32_t *p_audio_data) { - Error ret = OK; - if (GDVIRTUAL_REQUIRED_CALL(_write_frame, p_image, p_audio_data, ret)) { - return ret; - } - return ERR_UNCONFIGURED; + Error ret = ERR_UNCONFIGURED; + GDVIRTUAL_REQUIRED_CALL(_write_frame, p_image, p_audio_data, ret); + return ret; } void MovieWriter::write_end() { @@ -88,23 +80,35 @@ void MovieWriter::write_end() { bool MovieWriter::handles_file(const String &p_path) const { bool ret = false; - if (GDVIRTUAL_REQUIRED_CALL(_handles_file, p_path, ret)) { - return ret; - } - return false; + GDVIRTUAL_REQUIRED_CALL(_handles_file, p_path, ret); + return ret; } void MovieWriter::get_supported_extensions(List<String> *r_extensions) const { Vector<String> exts; - if (GDVIRTUAL_REQUIRED_CALL(_get_supported_extensions, exts)) { - for (int i = 0; i < exts.size(); i++) { - r_extensions->push_back(exts[i]); - } + GDVIRTUAL_REQUIRED_CALL(_get_supported_extensions, exts); + for (int i = 0; i < exts.size(); i++) { + r_extensions->push_back(exts[i]); } } void MovieWriter::begin(const Size2i &p_movie_size, uint32_t p_fps, const String &p_base_path) { project_name = GLOBAL_GET("application/config/name"); + + print_line(vformat("Movie Maker mode enabled, recording movie at %d FPS...", p_fps)); + + // Check for available disk space and warn the user if needed. + Ref<DirAccess> dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + String path = p_base_path.get_basename(); + if (path.is_relative_path()) { + path = "res://" + path; + } + dir->open(path); + if (dir->get_space_left() < 10 * Math::pow(1024.0, 3.0)) { + // Less than 10 GiB available. + WARN_PRINT(vformat("Current available space on disk is low (%s). MovieWriter will fail during movie recording if the disk runs out of available space.", String::humanize_size(dir->get_space_left()))); + } + mix_rate = get_audio_mix_rate(); AudioDriverDummy::get_dummy_singleton()->set_mix_rate(mix_rate); AudioDriverDummy::get_dummy_singleton()->set_speaker_mode(AudioDriver::SpeakerMode(get_audio_speaker_mode())); diff --git a/servers/movie_writer/movie_writer.h b/servers/movie_writer/movie_writer.h index 7877a60715..fffc43459d 100644 --- a/servers/movie_writer/movie_writer.h +++ b/servers/movie_writer/movie_writer.h @@ -67,7 +67,7 @@ protected: GDVIRTUAL0RC(Vector<String>, _get_supported_extensions) GDVIRTUAL3R(Error, _write_begin, const Size2i &, uint32_t, const String &) - GDVIRTUAL2R(Error, _write_frame, const Ref<Image> &, GDNativeConstPtr<int32_t>) + GDVIRTUAL2R(Error, _write_frame, const Ref<Image> &, GDExtensionConstPtr<int32_t>) GDVIRTUAL0(_write_end) static void _bind_methods(); diff --git a/servers/navigation/navigation_utilities.h b/servers/navigation/navigation_utilities.h index bedcc16a67..e99c139528 100644 --- a/servers/navigation/navigation_utilities.h +++ b/servers/navigation/navigation_utilities.h @@ -48,8 +48,8 @@ struct PathQueryParameters { PathfindingAlgorithm pathfinding_algorithm = PATHFINDING_ALGORITHM_ASTAR; PathPostProcessing path_postprocessing = PATH_POSTPROCESSING_CORRIDORFUNNEL; RID map; - Vector3 start_position = Vector3(); - Vector3 target_position = Vector3(); + Vector3 start_position; + Vector3 target_position; uint32_t navigation_layers = 1; }; diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp index 04e5d2f6a1..1614b8e2f5 100644 --- a/servers/navigation_server_2d.cpp +++ b/servers/navigation_server_2d.cpp @@ -140,10 +140,6 @@ static Transform3D trf2_to_trf3(const Transform2D &d) { return Transform3D(b, o); } -static Object *obj_to_obj(Object *d) { - return d; -} - static StringName sn_to_sn(const StringName &d) { return d; } @@ -152,9 +148,13 @@ static Variant var_to_var(const Variant &d) { return d; } +static ObjectID id_to_id(const ObjectID &id) { + return id; +} + static Ref<NavigationMesh> poly_to_mesh(Ref<NavigationPolygon> d) { if (d.is_valid()) { - return d->get_mesh(); + return d->get_navigation_mesh(); } else { return Ref<NavigationMesh>(); } @@ -250,13 +250,15 @@ void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("region_get_enter_cost", "region"), &NavigationServer2D::region_get_enter_cost); ClassDB::bind_method(D_METHOD("region_set_travel_cost", "region", "travel_cost"), &NavigationServer2D::region_set_travel_cost); ClassDB::bind_method(D_METHOD("region_get_travel_cost", "region"), &NavigationServer2D::region_get_travel_cost); + ClassDB::bind_method(D_METHOD("region_set_owner_id", "region", "owner_id"), &NavigationServer2D::region_set_owner_id); + ClassDB::bind_method(D_METHOD("region_get_owner_id", "region"), &NavigationServer2D::region_get_owner_id); ClassDB::bind_method(D_METHOD("region_owns_point", "region", "point"), &NavigationServer2D::region_owns_point); ClassDB::bind_method(D_METHOD("region_set_map", "region", "map"), &NavigationServer2D::region_set_map); ClassDB::bind_method(D_METHOD("region_get_map", "region"), &NavigationServer2D::region_get_map); ClassDB::bind_method(D_METHOD("region_set_navigation_layers", "region", "navigation_layers"), &NavigationServer2D::region_set_navigation_layers); ClassDB::bind_method(D_METHOD("region_get_navigation_layers", "region"), &NavigationServer2D::region_get_navigation_layers); ClassDB::bind_method(D_METHOD("region_set_transform", "region", "transform"), &NavigationServer2D::region_set_transform); - ClassDB::bind_method(D_METHOD("region_set_navpoly", "region", "nav_poly"), &NavigationServer2D::region_set_navpoly); + ClassDB::bind_method(D_METHOD("region_set_navigation_polygon", "region", "navigation_polygon"), &NavigationServer2D::region_set_navigation_polygon); ClassDB::bind_method(D_METHOD("region_get_connections_count", "region"), &NavigationServer2D::region_get_connections_count); ClassDB::bind_method(D_METHOD("region_get_connection_pathway_start", "region", "connection"), &NavigationServer2D::region_get_connection_pathway_start); ClassDB::bind_method(D_METHOD("region_get_connection_pathway_end", "region", "connection"), &NavigationServer2D::region_get_connection_pathway_end); @@ -276,6 +278,8 @@ void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("link_get_enter_cost", "link"), &NavigationServer2D::link_get_enter_cost); ClassDB::bind_method(D_METHOD("link_set_travel_cost", "link", "travel_cost"), &NavigationServer2D::link_set_travel_cost); ClassDB::bind_method(D_METHOD("link_get_travel_cost", "link"), &NavigationServer2D::link_get_travel_cost); + ClassDB::bind_method(D_METHOD("link_set_owner_id", "link", "owner_id"), &NavigationServer2D::link_set_owner_id); + ClassDB::bind_method(D_METHOD("link_get_owner_id", "link"), &NavigationServer2D::link_get_owner_id); ClassDB::bind_method(D_METHOD("agent_create"), &NavigationServer2D::agent_create); ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &NavigationServer2D::agent_set_map); @@ -289,7 +293,7 @@ void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("agent_set_target_velocity", "agent", "target_velocity"), &NavigationServer2D::agent_set_target_velocity); ClassDB::bind_method(D_METHOD("agent_set_position", "agent", "position"), &NavigationServer2D::agent_set_position); ClassDB::bind_method(D_METHOD("agent_is_map_changed", "agent"), &NavigationServer2D::agent_is_map_changed); - ClassDB::bind_method(D_METHOD("agent_set_callback", "agent", "receiver", "method", "userdata"), &NavigationServer2D::agent_set_callback, DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("agent_set_callback", "agent", "object_id", "method", "userdata"), &NavigationServer2D::agent_set_callback, DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("free_rid", "rid"), &NavigationServer2D::free); @@ -348,6 +352,8 @@ void FORWARD_2_C(region_set_enter_cost, RID, p_region, real_t, p_enter_cost, rid real_t FORWARD_1_C(region_get_enter_cost, RID, p_region, rid_to_rid); void FORWARD_2_C(region_set_travel_cost, RID, p_region, real_t, p_travel_cost, rid_to_rid, real_to_real); real_t FORWARD_1_C(region_get_travel_cost, RID, p_region, rid_to_rid); +void FORWARD_2_C(region_set_owner_id, RID, p_region, ObjectID, p_owner_id, rid_to_rid, id_to_id); +ObjectID FORWARD_1_C(region_get_owner_id, RID, p_region, rid_to_rid); bool FORWARD_2_C(region_owns_point, RID, p_region, const Vector2 &, p_point, rid_to_rid, v2_to_v3); void FORWARD_2_C(region_set_map, RID, p_region, RID, p_map, rid_to_rid, rid_to_rid); @@ -355,8 +361,8 @@ void FORWARD_2_C(region_set_navigation_layers, RID, p_region, uint32_t, p_naviga uint32_t FORWARD_1_C(region_get_navigation_layers, RID, p_region, rid_to_rid); void FORWARD_2_C(region_set_transform, RID, p_region, Transform2D, p_transform, rid_to_rid, trf2_to_trf3); -void NavigationServer2D::region_set_navpoly(RID p_region, Ref<NavigationPolygon> p_nav_mesh) const { - NavigationServer3D::get_singleton()->region_set_navmesh(p_region, poly_to_mesh(p_nav_mesh)); +void NavigationServer2D::region_set_navigation_polygon(RID p_region, Ref<NavigationPolygon> p_navigation_polygon) const { + NavigationServer3D::get_singleton()->region_set_navigation_mesh(p_region, poly_to_mesh(p_navigation_polygon)); } int FORWARD_1_C(region_get_connections_count, RID, p_region, rid_to_rid); @@ -379,6 +385,8 @@ void FORWARD_2_C(link_set_enter_cost, RID, p_link, real_t, p_enter_cost, rid_to_ real_t FORWARD_1_C(link_get_enter_cost, RID, p_link, rid_to_rid); void FORWARD_2_C(link_set_travel_cost, RID, p_link, real_t, p_travel_cost, rid_to_rid, real_to_real); real_t FORWARD_1_C(link_get_travel_cost, RID, p_link, rid_to_rid); +void FORWARD_2_C(link_set_owner_id, RID, p_link, ObjectID, p_owner_id, rid_to_rid, id_to_id); +ObjectID FORWARD_1_C(link_get_owner_id, RID, p_link, rid_to_rid); RID NavigationServer2D::agent_create() const { RID agent = NavigationServer3D::get_singleton()->agent_create(); @@ -408,7 +416,7 @@ void FORWARD_2_C(agent_set_ignore_y, RID, p_agent, bool, p_ignore, rid_to_rid, b bool FORWARD_1_C(agent_is_map_changed, RID, p_agent, rid_to_rid); -void FORWARD_4_C(agent_set_callback, RID, p_agent, Object *, p_receiver, StringName, p_method, Variant, p_udata, rid_to_rid, obj_to_obj, sn_to_sn, var_to_var); +void FORWARD_4_C(agent_set_callback, RID, p_agent, ObjectID, p_object_id, StringName, p_method, Variant, p_udata, rid_to_rid, id_to_id, sn_to_sn, var_to_var); void FORWARD_1_C(free, RID, p_object, rid_to_rid); diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h index 54cfc6b14e..9b921969c0 100644 --- a/servers/navigation_server_2d.h +++ b/servers/navigation_server_2d.h @@ -34,7 +34,7 @@ #include "core/object/class_db.h" #include "core/templates/rid.h" -#include "scene/2d/navigation_region_2d.h" +#include "scene/resources/navigation_polygon.h" #include "servers/navigation/navigation_path_query_parameters_2d.h" #include "servers/navigation/navigation_path_query_result_2d.h" @@ -108,6 +108,10 @@ public: virtual void region_set_travel_cost(RID p_region, real_t p_travel_cost) const; virtual real_t region_get_travel_cost(RID p_region) const; + /// Set the node which manages this region. + virtual void region_set_owner_id(RID p_region, ObjectID p_owner_id) const; + virtual ObjectID region_get_owner_id(RID p_region) const; + virtual bool region_owns_point(RID p_region, const Vector2 &p_point) const; /// Set the map of this region. @@ -122,7 +126,7 @@ public: virtual void region_set_transform(RID p_region, Transform2D p_transform) const; /// Set the navigation poly of this region. - virtual void region_set_navpoly(RID p_region, Ref<NavigationPolygon> p_nav_mesh) const; + virtual void region_set_navigation_polygon(RID p_region, Ref<NavigationPolygon> p_navigation_polygon) const; /// Get a list of a region's connection to other regions. virtual int region_get_connections_count(RID p_region) const; @@ -160,6 +164,10 @@ public: virtual void link_set_travel_cost(RID p_link, real_t p_travel_cost) const; virtual real_t link_get_travel_cost(RID p_link) const; + /// Set the node which manages this link. + virtual void link_set_owner_id(RID p_link, ObjectID p_owner_id) const; + virtual ObjectID link_get_owner_id(RID p_link) const; + /// Creates the agent. virtual RID agent_create() const; @@ -218,7 +226,7 @@ public: virtual bool agent_is_map_changed(RID p_agent) const; /// Callback called at the end of the RVO process - virtual void agent_set_callback(RID p_agent, Object *p_receiver, StringName p_method, Variant p_udata = Variant()) const; + virtual void agent_set_callback(RID p_agent, ObjectID p_object_id, StringName p_method, Variant p_udata = Variant()) const; virtual void query_path(const Ref<NavigationPathQueryParameters2D> &p_query_parameters, Ref<NavigationPathQueryResult2D> p_query_result) const; diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp index cab8816747..cbefe48633 100644 --- a/servers/navigation_server_3d.cpp +++ b/servers/navigation_server_3d.cpp @@ -69,14 +69,16 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("region_get_enter_cost", "region"), &NavigationServer3D::region_get_enter_cost); ClassDB::bind_method(D_METHOD("region_set_travel_cost", "region", "travel_cost"), &NavigationServer3D::region_set_travel_cost); ClassDB::bind_method(D_METHOD("region_get_travel_cost", "region"), &NavigationServer3D::region_get_travel_cost); + ClassDB::bind_method(D_METHOD("region_set_owner_id", "region", "owner_id"), &NavigationServer3D::region_set_owner_id); + ClassDB::bind_method(D_METHOD("region_get_owner_id", "region"), &NavigationServer3D::region_get_owner_id); ClassDB::bind_method(D_METHOD("region_owns_point", "region", "point"), &NavigationServer3D::region_owns_point); ClassDB::bind_method(D_METHOD("region_set_map", "region", "map"), &NavigationServer3D::region_set_map); ClassDB::bind_method(D_METHOD("region_get_map", "region"), &NavigationServer3D::region_get_map); ClassDB::bind_method(D_METHOD("region_set_navigation_layers", "region", "navigation_layers"), &NavigationServer3D::region_set_navigation_layers); ClassDB::bind_method(D_METHOD("region_get_navigation_layers", "region"), &NavigationServer3D::region_get_navigation_layers); ClassDB::bind_method(D_METHOD("region_set_transform", "region", "transform"), &NavigationServer3D::region_set_transform); - ClassDB::bind_method(D_METHOD("region_set_navmesh", "region", "nav_mesh"), &NavigationServer3D::region_set_navmesh); - ClassDB::bind_method(D_METHOD("region_bake_navmesh", "mesh", "node"), &NavigationServer3D::region_bake_navmesh); + ClassDB::bind_method(D_METHOD("region_set_navigation_mesh", "region", "navigation_mesh"), &NavigationServer3D::region_set_navigation_mesh); + ClassDB::bind_method(D_METHOD("region_bake_navigation_mesh", "navigation_mesh", "root_node"), &NavigationServer3D::region_bake_navigation_mesh); ClassDB::bind_method(D_METHOD("region_get_connections_count", "region"), &NavigationServer3D::region_get_connections_count); ClassDB::bind_method(D_METHOD("region_get_connection_pathway_start", "region", "connection"), &NavigationServer3D::region_get_connection_pathway_start); ClassDB::bind_method(D_METHOD("region_get_connection_pathway_end", "region", "connection"), &NavigationServer3D::region_get_connection_pathway_end); @@ -96,6 +98,8 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("link_get_enter_cost", "link"), &NavigationServer3D::link_get_enter_cost); ClassDB::bind_method(D_METHOD("link_set_travel_cost", "link", "travel_cost"), &NavigationServer3D::link_set_travel_cost); ClassDB::bind_method(D_METHOD("link_get_travel_cost", "link"), &NavigationServer3D::link_get_travel_cost); + ClassDB::bind_method(D_METHOD("link_set_owner_id", "link", "owner_id"), &NavigationServer3D::link_set_owner_id); + ClassDB::bind_method(D_METHOD("link_get_owner_id", "link"), &NavigationServer3D::link_get_owner_id); ClassDB::bind_method(D_METHOD("agent_create"), &NavigationServer3D::agent_create); ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &NavigationServer3D::agent_set_map); @@ -109,7 +113,7 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("agent_set_target_velocity", "agent", "target_velocity"), &NavigationServer3D::agent_set_target_velocity); ClassDB::bind_method(D_METHOD("agent_set_position", "agent", "position"), &NavigationServer3D::agent_set_position); ClassDB::bind_method(D_METHOD("agent_is_map_changed", "agent"), &NavigationServer3D::agent_is_map_changed); - ClassDB::bind_method(D_METHOD("agent_set_callback", "agent", "receiver", "method", "userdata"), &NavigationServer3D::agent_set_callback, DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("agent_set_callback", "agent", "object_id", "method", "userdata"), &NavigationServer3D::agent_set_callback, DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("free_rid", "rid"), &NavigationServer3D::free); @@ -151,7 +155,7 @@ NavigationServer3D::NavigationServer3D() { debug_navigation_enable_link_connections_xray = GLOBAL_DEF("debug/shapes/navigation/enable_link_connections_xray", true); if (Engine::get_singleton()->is_editor_hint()) { - // enable NavigationServer3D when in Editor or else navmesh edge connections are invisible + // enable NavigationServer3D when in Editor or else navigation mesh edge connections are invisible // on runtime tests SceneTree has "Visible Navigation" set and main iteration takes care of this set_debug_enabled(true); } diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h index 0f537383a2..65d6d19073 100644 --- a/servers/navigation_server_3d.h +++ b/servers/navigation_server_3d.h @@ -120,6 +120,10 @@ public: virtual void region_set_travel_cost(RID p_region, real_t p_travel_cost) const = 0; virtual real_t region_get_travel_cost(RID p_region) const = 0; + /// Set the node which manages this region. + virtual void region_set_owner_id(RID p_region, ObjectID p_owner_id) const = 0; + virtual ObjectID region_get_owner_id(RID p_region) const = 0; + virtual bool region_owns_point(RID p_region, const Vector3 &p_point) const = 0; /// Set the map of this region. @@ -134,10 +138,10 @@ public: virtual void region_set_transform(RID p_region, Transform3D p_transform) const = 0; /// Set the navigation mesh of this region. - virtual void region_set_navmesh(RID p_region, Ref<NavigationMesh> p_nav_mesh) const = 0; + virtual void region_set_navigation_mesh(RID p_region, Ref<NavigationMesh> p_navigation_mesh) const = 0; /// Bake the navigation mesh. - virtual void region_bake_navmesh(Ref<NavigationMesh> r_mesh, Node *p_node) const = 0; + virtual void region_bake_navigation_mesh(Ref<NavigationMesh> p_navigation_mesh, Node *p_root_node) const = 0; /// Get a list of a region's connection to other regions. virtual int region_get_connections_count(RID p_region) const = 0; @@ -175,6 +179,10 @@ public: virtual void link_set_travel_cost(RID p_link, real_t p_travel_cost) const = 0; virtual real_t link_get_travel_cost(RID p_link) const = 0; + /// Set the node which manages this link. + virtual void link_set_owner_id(RID p_link, ObjectID p_owner_id) const = 0; + virtual ObjectID link_get_owner_id(RID p_link) const = 0; + /// Creates the agent. virtual RID agent_create() const = 0; @@ -233,7 +241,7 @@ public: virtual bool agent_is_map_changed(RID p_agent) const = 0; /// Callback called at the end of the RVO process - virtual void agent_set_callback(RID p_agent, Object *p_receiver, StringName p_method, Variant p_udata = Variant()) const = 0; + virtual void agent_set_callback(RID p_agent, ObjectID p_object_id, StringName p_method, Variant p_udata = Variant()) const = 0; /// Destroy the `RID` virtual void free(RID p_object) const = 0; diff --git a/servers/physics_2d/godot_body_pair_2d.cpp b/servers/physics_2d/godot_body_pair_2d.cpp index 7b7c67bbc2..1684835e76 100644 --- a/servers/physics_2d/godot_body_pair_2d.cpp +++ b/servers/physics_2d/godot_body_pair_2d.cpp @@ -161,6 +161,11 @@ void GodotBodyPair2D::_validate_contacts() { } } +// _test_ccd prevents tunneling by slowing down a high velocity body that is about to collide so that next frame it will be at an appropriate location to collide (i.e. slight overlap) +// Warning: the way velocity is adjusted down to cause a collision means the momentum will be weaker than it should for a bounce! +// Process: only proceed if body A's motion is high relative to its size. +// cast forward along motion vector to see if A is going to enter/pass B's collider next frame, only proceed if it does. +// adjust the velocity of A down so that it will just slightly intersect the collider instead of blowing right past it. bool GodotBodyPair2D::_test_ccd(real_t p_step, GodotBody2D *p_A, int p_shape_A, const Transform2D &p_xform_A, GodotBody2D *p_B, int p_shape_B, const Transform2D &p_xform_B) { Vector2 motion = p_A->get_linear_velocity() * p_step; real_t mlen = motion.length(); @@ -180,24 +185,32 @@ bool GodotBodyPair2D::_test_ccd(real_t p_step, GodotBody2D *p_A, int p_shape_A, return false; } - // Going too fast in that direction. + // A is moving fast enough that tunneling might occur. See if it's really about to collide. // Cast a segment from support in motion normal, in the same direction of motion by motion length. - // Support is the worst case collision point, so real collision happened before. + // Support point will the farthest forward collision point along the movement vector. + // i.e. the point that should hit B first if any collision does occur. + + // convert mnormal into body A's local xform because get_support requires (and returns) local coordinates. int a; Vector2 s[2]; - p_A->get_shape(p_shape_A)->get_supports(p_xform_A.basis_xform(mnormal).normalized(), s, a); + p_A->get_shape(p_shape_A)->get_supports(p_xform_A.basis_xform_inv(mnormal).normalized(), s, a); Vector2 from = p_xform_A.xform(s[0]); + // Back up 10% of the per-frame motion behind the support point and use that as the beginning of our cast. + // This should ensure the calculated new velocity will really cause a bit of overlap instead of just getting us very close. Vector2 to = from + motion; Transform2D from_inv = p_xform_B.affine_inverse(); - // Start from a little inside the bounding box. - Vector2 local_from = from_inv.xform(from - mnormal * mlen * 0.1); + // Back up 10% of the per-frame motion behind the support point and use that as the beginning of our cast. + // At high speeds, this may mean we're actually casting from well behind the body instead of inside it, which is odd. But it still works out. + Vector2 local_from = from_inv.xform(from - motion * 0.1); Vector2 local_to = from_inv.xform(to); Vector2 rpos, rnorm; if (!p_B->get_shape(p_shape_B)->intersect_segment(local_from, local_to, rpos, rnorm)) { + // there was no hit. Since the segment is the length of per-frame motion, this means the bodies will not + // actually collide yet on next frame. We'll probably check again next frame once they're closer. return false; } @@ -215,7 +228,7 @@ bool GodotBodyPair2D::_test_ccd(real_t p_step, GodotBody2D *p_A, int p_shape_A, // next frame will hit softly or soft enough. Vector2 hitpos = p_xform_B.xform(rpos); - real_t newlen = hitpos.distance_to(from) - (max - min) * 0.01; + real_t newlen = hitpos.distance_to(from) + (max - min) * 0.01; // adding 1% of body length to the distance between collision and support point should cause body A's support point to arrive just within B's collider next frame. p_A->set_linear_velocity(mnormal * (newlen / p_step)); return true; diff --git a/servers/physics_2d/godot_shape_2d.cpp b/servers/physics_2d/godot_shape_2d.cpp index da414ae233..6823cb32c1 100644 --- a/servers/physics_2d/godot_shape_2d.cpp +++ b/servers/physics_2d/godot_shape_2d.cpp @@ -369,8 +369,9 @@ void GodotCapsuleShape2D::get_supports(const Vector2 &p_normal, Vector2 *r_suppo Vector2 n = p_normal; real_t d = n.y; + real_t h = height * 0.5 - radius; // half-height of the rectangle part - if (Math::abs(d) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)) { + if (h > 0 && Math::abs(d) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)) { // make it flat n.y = 0.0; n.normalize(); @@ -378,13 +379,10 @@ void GodotCapsuleShape2D::get_supports(const Vector2 &p_normal, Vector2 *r_suppo r_amount = 2; r_supports[0] = n; - r_supports[0].y += height * 0.5 - radius; + r_supports[0].y += h; r_supports[1] = n; - r_supports[1].y -= height * 0.5 - radius; - + r_supports[1].y -= h; } else { - real_t h = height * 0.5 - radius; - n *= radius; n.y += (d > 0) ? h : -h; r_amount = 1; diff --git a/servers/physics_2d/godot_space_2d.cpp b/servers/physics_2d/godot_space_2d.cpp index a82d7dbbc4..89afb0e2a0 100644 --- a/servers/physics_2d/godot_space_2d.cpp +++ b/servers/physics_2d/godot_space_2d.cpp @@ -1225,7 +1225,7 @@ GodotSpace2D::GodotSpace2D() { ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/solver/solver_iterations", PropertyInfo(Variant::INT, "physics/2d/solver/solver_iterations", PROPERTY_HINT_RANGE, "1,32,1,or_greater")); contact_recycle_radius = GLOBAL_DEF("physics/2d/solver/contact_recycle_radius", 1.0); - ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/solver/contact_recycle_radius", PropertyInfo(Variant::FLOAT, "physics/2d/solver/contact_max_separation", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater")); + ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/solver/contact_recycle_radius", PropertyInfo(Variant::FLOAT, "physics/2d/solver/contact_recycle_radius", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater")); contact_max_separation = GLOBAL_DEF("physics/2d/solver/contact_max_separation", 1.5); ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/solver/contact_max_separation", PropertyInfo(Variant::FLOAT, "physics/2d/solver/contact_max_separation", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater")); diff --git a/servers/physics_2d/godot_step_2d.cpp b/servers/physics_2d/godot_step_2d.cpp index 46718c8819..b7d79bc0e3 100644 --- a/servers/physics_2d/godot_step_2d.cpp +++ b/servers/physics_2d/godot_step_2d.cpp @@ -71,7 +71,7 @@ void GodotStep2D::_populate_island(GodotBody2D *p_body, LocalVector<GodotBody2D } } -void GodotStep2D::_setup_contraint(uint32_t p_constraint_index, void *p_userdata) { +void GodotStep2D::_setup_constraint(uint32_t p_constraint_index, void *p_userdata) { GodotConstraint2D *constraint = all_constraints[p_constraint_index]; constraint->setup(delta); } @@ -238,8 +238,8 @@ void GodotStep2D::step(GodotSpace2D *p_space, real_t p_delta) { /* SETUP CONSTRAINTS / PROCESS COLLISIONS */ - uint32_t total_contraint_count = all_constraints.size(); - WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &GodotStep2D::_setup_contraint, nullptr, total_contraint_count, -1, true, SNAME("Physics2DConstraintSetup")); + uint32_t total_constraint_count = all_constraints.size(); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &GodotStep2D::_setup_constraint, nullptr, total_constraint_count, -1, true, SNAME("Physics2DConstraintSetup")); WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); { //profile diff --git a/servers/physics_2d/godot_step_2d.h b/servers/physics_2d/godot_step_2d.h index 9f8fdd6ce3..4b3b6fc966 100644 --- a/servers/physics_2d/godot_step_2d.h +++ b/servers/physics_2d/godot_step_2d.h @@ -47,7 +47,7 @@ class GodotStep2D { LocalVector<GodotConstraint2D *> all_constraints; void _populate_island(GodotBody2D *p_body, LocalVector<GodotBody2D *> &p_body_island, LocalVector<GodotConstraint2D *> &p_constraint_island); - void _setup_contraint(uint32_t p_constraint_index, void *p_userdata = nullptr); + void _setup_constraint(uint32_t p_constraint_index, void *p_userdata = nullptr); void _pre_solve_island(LocalVector<GodotConstraint2D *> &p_constraint_island) const; void _solve_island(uint32_t p_island_index, void *p_userdata = nullptr) const; void _check_suspend(LocalVector<GodotBody2D *> &p_body_island) const; diff --git a/servers/physics_3d/godot_body_3d.cpp b/servers/physics_3d/godot_body_3d.cpp index cec233d95b..53f4ab86f9 100644 --- a/servers/physics_3d/godot_body_3d.cpp +++ b/servers/physics_3d/godot_body_3d.cpp @@ -118,7 +118,7 @@ void GodotBody3D::update_mass_properties() { shape_inertia_tensor = shape_basis * shape_inertia_tensor * shape_basis.transposed(); Vector3 shape_origin = shape_transform.origin - center_of_mass_local; - inertia_tensor += shape_inertia_tensor + (Basis() * shape_origin.dot(shape_origin) - shape_origin.outer(shape_origin)) * mass; + inertia_tensor += shape_inertia_tensor + (Basis() * shape_origin.dot(shape_origin) - shape_origin.outer(shape_origin)) * mass_new; } // Set the inertia to a valid value when there are no valid shapes. diff --git a/servers/physics_3d/godot_body_pair_3d.cpp b/servers/physics_3d/godot_body_pair_3d.cpp index 7e6cc6f834..00b7941292 100644 --- a/servers/physics_3d/godot_body_pair_3d.cpp +++ b/servers/physics_3d/godot_body_pair_3d.cpp @@ -161,6 +161,11 @@ void GodotBodyPair3D::validate_contacts() { } } +// _test_ccd prevents tunneling by slowing down a high velocity body that is about to collide so that next frame it will be at an appropriate location to collide (i.e. slight overlap) +// Warning: the way velocity is adjusted down to cause a collision means the momentum will be weaker than it should for a bounce! +// Process: only proceed if body A's motion is high relative to its size. +// cast forward along motion vector to see if A is going to enter/pass B's collider next frame, only proceed if it does. +// adjust the velocity of A down so that it will just slightly intersect the collider instead of blowing right past it. bool GodotBodyPair3D::_test_ccd(real_t p_step, GodotBody3D *p_A, int p_shape_A, const Transform3D &p_xform_A, GodotBody3D *p_B, int p_shape_B, const Transform3D &p_xform_B) { Vector3 motion = p_A->get_linear_velocity() * p_step; real_t mlen = motion.length(); @@ -177,33 +182,39 @@ bool GodotBodyPair3D::_test_ccd(real_t p_step, GodotBody3D *p_A, int p_shape_A, // Let's say it should move more than 1/3 the size of the object in that axis. bool fast_object = mlen > (max - min) * 0.3; if (!fast_object) { - return false; + return false; // moving slow enough that there's no chance of tunneling. } - // Going too fast in that direction. + // A is moving fast enough that tunneling might occur. See if it's really about to collide. // Cast a segment from support in motion normal, in the same direction of motion by motion length. - // Support is the worst case collision point, so real collision happened before. - Vector3 s = p_A->get_shape(p_shape_A)->get_support(p_xform_A.basis.xform(mnormal).normalized()); + // Support point will the farthest forward collision point along the movement vector. + // i.e. the point that should hit B first if any collision does occur. + + // convert mnormal into body A's local xform because get_support requires (and returns) local coordinates. + Vector3 s = p_A->get_shape(p_shape_A)->get_support(p_xform_A.basis.xform_inv(mnormal).normalized()); Vector3 from = p_xform_A.xform(s); Vector3 to = from + motion; Transform3D from_inv = p_xform_B.affine_inverse(); - // Start from a little inside the bounding box. - Vector3 local_from = from_inv.xform(from - mnormal * mlen * 0.1); + // Back up 10% of the per-frame motion behind the support point and use that as the beginning of our cast. + // At high speeds, this may mean we're actually casting from well behind the body instead of inside it, which is odd. But it still works out. + Vector3 local_from = from_inv.xform(from - motion * 0.1); Vector3 local_to = from_inv.xform(to); Vector3 rpos, rnorm; if (!p_B->get_shape(p_shape_B)->intersect_segment(local_from, local_to, rpos, rnorm, true)) { + // there was no hit. Since the segment is the length of per-frame motion, this means the bodies will not + // actually collide yet on next frame. We'll probably check again next frame once they're closer. return false; } - // Shorten the linear velocity so it does not hit, but gets close enough, - // next frame will hit softly or soft enough. + // Shorten the linear velocity so it will collide next frame. Vector3 hitpos = p_xform_B.xform(rpos); - real_t newlen = hitpos.distance_to(from) - (max - min) * 0.01; + real_t newlen = hitpos.distance_to(from) + (max - min) * 0.01; // adding 1% of body length to the distance between collision and support point should cause body A's support point to arrive just within B's collider next frame. + p_A->set_linear_velocity((mnormal * newlen) / p_step); return true; diff --git a/servers/physics_3d/godot_collision_solver_3d_sat.cpp b/servers/physics_3d/godot_collision_solver_3d_sat.cpp index 933a5e28df..8c78957789 100644 --- a/servers/physics_3d/godot_collision_solver_3d_sat.cpp +++ b/servers/physics_3d/godot_collision_solver_3d_sat.cpp @@ -964,8 +964,8 @@ static void _collision_sphere_convex_polygon(const GodotShape3D *p_a, const Tran // edges of B for (int i = 0; i < edge_count; i++) { - Vector3 v1 = p_transform_b.xform(vertices[edges[i].a]); - Vector3 v2 = p_transform_b.xform(vertices[edges[i].b]); + Vector3 v1 = p_transform_b.xform(vertices[edges[i].vertex_a]); + Vector3 v2 = p_transform_b.xform(vertices[edges[i].vertex_b]); Vector3 v3 = p_transform_a.origin; Vector3 n1 = v2 - v1; @@ -1404,7 +1404,7 @@ static void _collision_box_convex_polygon(const GodotShape3D *p_a, const Transfo Vector3 e1 = p_transform_a.basis.get_column(i); for (int j = 0; j < edge_count; j++) { - Vector3 e2 = p_transform_b.basis.xform(vertices[edges[j].a]) - p_transform_b.basis.xform(vertices[edges[j].b]); + Vector3 e2 = p_transform_b.basis.xform(vertices[edges[j].vertex_a]) - p_transform_b.basis.xform(vertices[edges[j].vertex_b]); Vector3 axis = e1.cross(e2).normalized(); @@ -1460,8 +1460,8 @@ static void _collision_box_convex_polygon(const GodotShape3D *p_a, const Transfo } for (int e = 0; e < edge_count; e++) { - Vector3 p1 = p_transform_b.xform(vertices[edges[e].a]); - Vector3 p2 = p_transform_b.xform(vertices[edges[e].b]); + Vector3 p1 = p_transform_b.xform(vertices[edges[e].vertex_a]); + Vector3 p2 = p_transform_b.xform(vertices[edges[e].vertex_b]); Vector3 n = (p2 - p1); if (!separator.test_axis((point - p2).cross(n).cross(n).normalized())) { @@ -1771,7 +1771,7 @@ static void _collision_capsule_convex_polygon(const GodotShape3D *p_a, const Tra for (int i = 0; i < edge_count; i++) { // cylinder - Vector3 edge_axis = p_transform_b.basis.xform(vertices[edges[i].a]) - p_transform_b.basis.xform(vertices[edges[i].b]); + Vector3 edge_axis = p_transform_b.basis.xform(vertices[edges[i].vertex_a]) - p_transform_b.basis.xform(vertices[edges[i].vertex_b]); Vector3 axis = edge_axis.cross(p_transform_a.basis.get_column(1)).normalized(); if (!separator.test_axis(axis)) { @@ -1789,8 +1789,8 @@ static void _collision_capsule_convex_polygon(const GodotShape3D *p_a, const Tra Vector3 sphere_pos = p_transform_a.origin + ((i == 0) ? capsule_axis : -capsule_axis); for (int j = 0; j < edge_count; j++) { - Vector3 n1 = sphere_pos - p_transform_b.xform(vertices[edges[j].a]); - Vector3 n2 = p_transform_b.basis.xform(vertices[edges[j].a]) - p_transform_b.basis.xform(vertices[edges[j].b]); + Vector3 n1 = sphere_pos - p_transform_b.xform(vertices[edges[j].vertex_a]); + Vector3 n2 = p_transform_b.basis.xform(vertices[edges[j].vertex_a]) - p_transform_b.basis.xform(vertices[edges[j].vertex_b]); Vector3 axis = n1.cross(n2).cross(n2).normalized(); @@ -1908,7 +1908,7 @@ static void _collision_cylinder_cylinder(const GodotShape3D *p_a, const Transfor } // Cylinder B end caps. - if (!separator.test_axis(cylinder_A_axis.normalized())) { + if (!separator.test_axis(cylinder_B_axis.normalized())) { return; } @@ -2075,6 +2075,16 @@ static void _collision_cylinder_face(const GodotShape3D *p_a, const Transform3D separator.generate_contacts(); } +static _FORCE_INLINE_ bool is_minkowski_face(const Vector3 &A, const Vector3 &B, const Vector3 &B_x_A, const Vector3 &C, const Vector3 &D, const Vector3 &D_x_C) { + // Test if arcs AB and CD intersect on the unit sphere + real_t CBA = C.dot(B_x_A); + real_t DBA = D.dot(B_x_A); + real_t ADC = A.dot(D_x_C); + real_t BDC = B.dot(D_x_C); + + return (CBA * DBA < 0.0f) && (ADC * BDC < 0.0f) && (CBA * BDC > 0.0f); +} + template <bool withMargin> static void _collision_convex_polygon_convex_polygon(const GodotShape3D *p_a, const Transform3D &p_transform_a, const GodotShape3D *p_b, const Transform3D &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { const GodotConvexPolygonShape3D *convex_polygon_A = static_cast<const GodotConvexPolygonShape3D *>(p_a); @@ -2129,16 +2139,27 @@ static void _collision_convex_polygon_convex_polygon(const GodotShape3D *p_a, co } // A<->B edges + for (int i = 0; i < edge_count_A; i++) { - Vector3 e1 = p_transform_a.basis.xform(vertices_A[edges_A[i].a]) - p_transform_a.basis.xform(vertices_A[edges_A[i].b]); + Vector3 p1 = p_transform_a.xform(vertices_A[edges_A[i].vertex_a]); + Vector3 q1 = p_transform_a.xform(vertices_A[edges_A[i].vertex_b]); + Vector3 e1 = q1 - p1; + Vector3 u1 = p_transform_a.basis.xform(faces_A[edges_A[i].face_a].plane.normal).normalized(); + Vector3 v1 = p_transform_a.basis.xform(faces_A[edges_A[i].face_b].plane.normal).normalized(); for (int j = 0; j < edge_count_B; j++) { - Vector3 e2 = p_transform_b.basis.xform(vertices_B[edges_B[j].a]) - p_transform_b.basis.xform(vertices_B[edges_B[j].b]); + Vector3 p2 = p_transform_b.xform(vertices_B[edges_B[j].vertex_a]); + Vector3 q2 = p_transform_b.xform(vertices_B[edges_B[j].vertex_b]); + Vector3 e2 = q2 - p2; + Vector3 u2 = p_transform_b.basis.xform(faces_B[edges_B[j].face_a].plane.normal).normalized(); + Vector3 v2 = p_transform_b.basis.xform(faces_B[edges_B[j].face_b].plane.normal).normalized(); - Vector3 axis = e1.cross(e2).normalized(); + if (is_minkowski_face(u1, v1, -e1, -u2, -v2, -e2)) { + Vector3 axis = e1.cross(e2).normalized(); - if (!separator.test_axis(axis)) { - return; + if (!separator.test_axis(axis)) { + return; + } } } } @@ -2157,8 +2178,8 @@ static void _collision_convex_polygon_convex_polygon(const GodotShape3D *p_a, co //edge-vertex (shell) for (int i = 0; i < edge_count_A; i++) { - Vector3 e1 = p_transform_a.basis.xform(vertices_A[edges_A[i].a]); - Vector3 e2 = p_transform_a.basis.xform(vertices_A[edges_A[i].b]); + Vector3 e1 = p_transform_a.basis.xform(vertices_A[edges_A[i].vertex_a]); + Vector3 e2 = p_transform_a.basis.xform(vertices_A[edges_A[i].vertex_b]); Vector3 n = (e2 - e1); for (int j = 0; j < vertex_count_B; j++) { @@ -2171,8 +2192,8 @@ static void _collision_convex_polygon_convex_polygon(const GodotShape3D *p_a, co } for (int i = 0; i < edge_count_B; i++) { - Vector3 e1 = p_transform_b.basis.xform(vertices_B[edges_B[i].a]); - Vector3 e2 = p_transform_b.basis.xform(vertices_B[edges_B[i].b]); + Vector3 e1 = p_transform_b.basis.xform(vertices_B[edges_B[i].vertex_a]); + Vector3 e2 = p_transform_b.basis.xform(vertices_B[edges_B[i].vertex_b]); Vector3 n = (e2 - e1); for (int j = 0; j < vertex_count_A; j++) { @@ -2231,7 +2252,7 @@ static void _collision_convex_polygon_face(const GodotShape3D *p_a, const Transf // A<->B edges for (int i = 0; i < edge_count; i++) { - Vector3 e1 = p_transform_a.xform(vertices[edges[i].a]) - p_transform_a.xform(vertices[edges[i].b]); + Vector3 e1 = p_transform_a.xform(vertices[edges[i].vertex_a]) - p_transform_a.xform(vertices[edges[i].vertex_b]); for (int j = 0; j < 3; j++) { Vector3 e2 = vertex[j] - vertex[(j + 1) % 3]; @@ -2266,8 +2287,8 @@ static void _collision_convex_polygon_face(const GodotShape3D *p_a, const Transf //edge-vertex (shell) for (int i = 0; i < edge_count; i++) { - Vector3 e1 = p_transform_a.basis.xform(vertices[edges[i].a]); - Vector3 e2 = p_transform_a.basis.xform(vertices[edges[i].b]); + Vector3 e1 = p_transform_a.basis.xform(vertices[edges[i].vertex_a]); + Vector3 e2 = p_transform_a.basis.xform(vertices[edges[i].vertex_b]); Vector3 n = (e2 - e1); for (int j = 0; j < 3; j++) { diff --git a/servers/physics_3d/godot_shape_3d.cpp b/servers/physics_3d/godot_shape_3d.cpp index e051c688fa..1a016fbc72 100644 --- a/servers/physics_3d/godot_shape_3d.cpp +++ b/servers/physics_3d/godot_shape_3d.cpp @@ -521,8 +521,9 @@ void GodotCapsuleShape3D::get_supports(const Vector3 &p_normal, int p_max, Vecto Vector3 n = p_normal; real_t d = n.y; + real_t h = height * 0.5 - radius; // half-height of the cylinder part - if (Math::abs(d) < edge_support_threshold) { + if (h > 0 && Math::abs(d) < edge_support_threshold) { // make it flat n.y = 0.0; n.normalize(); @@ -531,13 +532,10 @@ void GodotCapsuleShape3D::get_supports(const Vector3 &p_normal, int p_max, Vecto r_amount = 2; r_type = FEATURE_EDGE; r_supports[0] = n; - r_supports[0].y += height * 0.5 - radius; + r_supports[0].y += h; r_supports[1] = n; - r_supports[1].y -= height * 0.5 - radius; - + r_supports[1].y -= h; } else { - real_t h = height * 0.5 - radius; - n *= radius; n.y += (d > 0) ? h : -h; r_amount = 1; @@ -817,48 +815,78 @@ GodotCylinderShape3D::GodotCylinderShape3D() {} /********** CONVEX POLYGON *************/ void GodotConvexPolygonShape3D::project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const { - int vertex_count = mesh.vertices.size(); + uint32_t vertex_count = mesh.vertices.size(); if (vertex_count == 0) { return; } const Vector3 *vrts = &mesh.vertices[0]; - for (int i = 0; i < vertex_count; i++) { - real_t d = p_normal.dot(p_transform.xform(vrts[i])); + if (vertex_count > 3 * extreme_vertices.size()) { + // For a large mesh, two calls to get_support() is faster than a full + // scan over all vertices. - if (i == 0 || d > r_max) { - r_max = d; - } - if (i == 0 || d < r_min) { - r_min = d; + Vector3 n = p_transform.basis.xform_inv(p_normal).normalized(); + r_min = p_normal.dot(p_transform.xform(get_support(-n))); + r_max = p_normal.dot(p_transform.xform(get_support(n))); + } else { + for (uint32_t i = 0; i < vertex_count; i++) { + real_t d = p_normal.dot(p_transform.xform(vrts[i])); + + if (i == 0 || d > r_max) { + r_max = d; + } + if (i == 0 || d < r_min) { + r_min = d; + } } } } Vector3 GodotConvexPolygonShape3D::get_support(const Vector3 &p_normal) const { - Vector3 n = p_normal; - - int vert_support_idx = -1; - real_t support_max = 0; - - int vertex_count = mesh.vertices.size(); - if (vertex_count == 0) { + if (mesh.vertices.size() == 0) { return Vector3(); } - const Vector3 *vrts = &mesh.vertices[0]; - - for (int i = 0; i < vertex_count; i++) { - real_t d = n.dot(vrts[i]); + // Find an initial guess for the support vertex by checking the ones we + // found in _setup(). - if (i == 0 || d > support_max) { - support_max = d; - vert_support_idx = i; + int best_vertex = -1; + real_t max_support = 0.0; + for (uint32_t i = 0; i < extreme_vertices.size(); i++) { + real_t s = p_normal.dot(mesh.vertices[extreme_vertices[i]]); + if (best_vertex == -1 || s > max_support) { + best_vertex = extreme_vertices[i]; + max_support = s; } } + if (extreme_vertices.size() == mesh.vertices.size()) { + // We've already checked every vertex, so we can return now. + return mesh.vertices[best_vertex]; + } + + // Move along the surface until we reach the true support vertex. - return vrts[vert_support_idx]; + int last_vertex = -1; + while (true) { + int next_vertex = -1; + for (uint32_t i = 0; i < vertex_neighbors[best_vertex].size(); i++) { + int vert = vertex_neighbors[best_vertex][i]; + if (vert != last_vertex) { + real_t s = p_normal.dot(mesh.vertices[vert]); + if (s > max_support) { + next_vertex = vert; + max_support = s; + break; + } + } + } + if (next_vertex == -1) { + return mesh.vertices[best_vertex]; + } + last_vertex = best_vertex; + best_vertex = next_vertex; + } } void GodotConvexPolygonShape3D::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { @@ -915,13 +943,13 @@ void GodotConvexPolygonShape3D::get_supports(const Vector3 &p_normal, int p_max, } for (int i = 0; i < ec; i++) { - real_t dot = (vertices[edges[i].a] - vertices[edges[i].b]).normalized().dot(p_normal); + real_t dot = (vertices[edges[i].vertex_a] - vertices[edges[i].vertex_b]).normalized().dot(p_normal); dot = ABS(dot); - if (dot < edge_support_threshold && (edges[i].a == vtx || edges[i].b == vtx)) { + if (dot < edge_support_threshold && (edges[i].vertex_a == vtx || edges[i].vertex_b == vtx)) { r_amount = 2; r_type = FEATURE_EDGE; - r_supports[0] = vertices[edges[i].a]; - r_supports[1] = vertices[edges[i].b]; + r_supports[0] = vertices[edges[i].vertex_a]; + r_supports[1] = vertices[edges[i].vertex_b]; return; } } @@ -1025,8 +1053,8 @@ Vector3 GodotConvexPolygonShape3D::get_closest_point_to(const Vector3 &p_point) int ec = mesh.edges.size(); for (int i = 0; i < ec; i++) { Vector3 s[2] = { - vertices[edges[i].a], - vertices[edges[i].b] + vertices[edges[i].vertex_a], + vertices[edges[i].vertex_b] }; Vector3 closest = Geometry3D::get_closest_point_to_segment(p_point, s); @@ -1058,7 +1086,7 @@ void GodotConvexPolygonShape3D::_setup(const Vector<Vector3> &p_vertices) { AABB _aabb; - for (int i = 0; i < mesh.vertices.size(); i++) { + for (uint32_t i = 0; i < mesh.vertices.size(); i++) { if (i == 0) { _aabb.position = mesh.vertices[i]; } else { @@ -1067,6 +1095,43 @@ void GodotConvexPolygonShape3D::_setup(const Vector<Vector3> &p_vertices) { } configure(_aabb); + + // Pre-compute the extreme vertices in 26 directions. This will be used + // to speed up get_support() by letting us quickly get a good guess for + // the support vertex. + + for (int x = -1; x < 2; x++) { + for (int y = -1; y < 2; y++) { + for (int z = -1; z < 2; z++) { + if (x != 0 || y != 0 || z != 0) { + Vector3 dir(x, y, z); + dir.normalize(); + real_t max_support = 0.0; + int best_vertex = -1; + for (uint32_t i = 0; i < mesh.vertices.size(); i++) { + real_t s = dir.dot(mesh.vertices[i]); + if (best_vertex == -1 || s > max_support) { + best_vertex = i; + max_support = s; + } + } + if (extreme_vertices.find(best_vertex) == -1) + extreme_vertices.push_back(best_vertex); + } + } + } + } + + // Record all the neighbors of each vertex. This is used in get_support(). + + if (extreme_vertices.size() < mesh.vertices.size()) { + vertex_neighbors.resize(mesh.vertices.size()); + for (uint32_t i = 0; i < mesh.edges.size(); i++) { + Geometry3D::MeshData::Edge &edge = mesh.edges[i]; + vertex_neighbors[edge.vertex_a].push_back(edge.vertex_b); + vertex_neighbors[edge.vertex_b].push_back(edge.vertex_a); + } + } } void GodotConvexPolygonShape3D::set_data(const Variant &p_data) { @@ -1074,7 +1139,12 @@ void GodotConvexPolygonShape3D::set_data(const Variant &p_data) { } Variant GodotConvexPolygonShape3D::get_data() const { - return mesh.vertices; + Vector<Vector3> vertices; + vertices.resize(mesh.vertices.size()); + for (uint32_t i = 0; i < mesh.vertices.size(); i++) { + vertices.write[i] = mesh.vertices[i]; + } + return vertices; } GodotConvexPolygonShape3D::GodotConvexPolygonShape3D() { @@ -1926,7 +1996,7 @@ void GodotHeightMapShape3D::_get_cell(const Vector3 &p_point, int &r_x, int &r_y Vector3 clamped_point(p_point); clamped_point.x = CLAMP(p_point.x, pos_local.x, pos_local.x + shape_aabb.size.x); clamped_point.y = CLAMP(p_point.y, pos_local.y, pos_local.y + shape_aabb.size.y); - clamped_point.z = CLAMP(p_point.z, pos_local.z, pos_local.x + shape_aabb.size.z); + clamped_point.z = CLAMP(p_point.z, pos_local.z, pos_local.z + shape_aabb.size.z); r_x = (clamped_point.x < 0.0) ? (clamped_point.x - 0.5) : (clamped_point.x + 0.5); r_y = (clamped_point.y < 0.0) ? (clamped_point.y - 0.5) : (clamped_point.y + 0.5); diff --git a/servers/physics_3d/godot_shape_3d.h b/servers/physics_3d/godot_shape_3d.h index 1fc8f7c711..dc8e34e2bc 100644 --- a/servers/physics_3d/godot_shape_3d.h +++ b/servers/physics_3d/godot_shape_3d.h @@ -277,6 +277,8 @@ public: struct GodotConvexPolygonShape3D : public GodotShape3D { Geometry3D::MeshData mesh; + LocalVector<int> extreme_vertices; + LocalVector<LocalVector<int>> vertex_neighbors; void _setup(const Vector<Vector3> &p_vertices); diff --git a/servers/physics_3d/godot_soft_body_3d.cpp b/servers/physics_3d/godot_soft_body_3d.cpp index 173843072a..31b6b9e12f 100644 --- a/servers/physics_3d/godot_soft_body_3d.cpp +++ b/servers/physics_3d/godot_soft_body_3d.cpp @@ -722,7 +722,14 @@ void GodotSoftBody3D::reoptimize_link_order() { const int reop_not_dependent = -1; const int reop_node_complete = -2; - uint32_t i, link_count = links.size(), node_count = nodes.size(); + uint32_t link_count = links.size(); + uint32_t node_count = nodes.size(); + + if (link_count < 1 || node_count < 2) { + return; + } + + uint32_t i; Link *lr; int ar, br; Node *node0 = &(nodes[0]); @@ -1004,7 +1011,6 @@ void GodotSoftBody3D::predict_motion(real_t p_delta) { } break; case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE: case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE_COMBINE: { - gravity = Vector3(0, 0, 0); gravity = area_gravity; gravity_done = area_gravity_mode == PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE; } break; diff --git a/servers/physics_3d/godot_space_3d.cpp b/servers/physics_3d/godot_space_3d.cpp index c23485279d..c98409e2c4 100644 --- a/servers/physics_3d/godot_space_3d.cpp +++ b/servers/physics_3d/godot_space_3d.cpp @@ -1258,7 +1258,7 @@ GodotSpace3D::GodotSpace3D() { ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/solver/solver_iterations", PropertyInfo(Variant::INT, "physics/3d/solver/solver_iterations", PROPERTY_HINT_RANGE, "1,32,1,or_greater")); contact_recycle_radius = GLOBAL_DEF("physics/3d/solver/contact_recycle_radius", 0.01); - ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/solver/contact_recycle_radius", PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_max_separation", PROPERTY_HINT_RANGE, "0,0.1,0.01,or_greater")); + ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/solver/contact_recycle_radius", PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_recycle_radius", PROPERTY_HINT_RANGE, "0,0.1,0.01,or_greater")); contact_max_separation = GLOBAL_DEF("physics/3d/solver/contact_max_separation", 0.05); ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/solver/contact_max_separation", PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_max_separation", PROPERTY_HINT_RANGE, "0,0.1,0.01,or_greater")); diff --git a/servers/physics_3d/godot_step_3d.cpp b/servers/physics_3d/godot_step_3d.cpp index bfedcd29c0..634523d0b9 100644 --- a/servers/physics_3d/godot_step_3d.cpp +++ b/servers/physics_3d/godot_step_3d.cpp @@ -111,7 +111,7 @@ void GodotStep3D::_populate_island_soft_body(GodotSoftBody3D *p_soft_body, Local } } -void GodotStep3D::_setup_contraint(uint32_t p_constraint_index, void *p_userdata) { +void GodotStep3D::_setup_constraint(uint32_t p_constraint_index, void *p_userdata) { GodotConstraint3D *constraint = all_constraints[p_constraint_index]; constraint->setup(delta); } @@ -342,8 +342,8 @@ void GodotStep3D::step(GodotSpace3D *p_space, real_t p_delta) { /* SETUP CONSTRAINTS / PROCESS COLLISIONS */ - uint32_t total_contraint_count = all_constraints.size(); - WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &GodotStep3D::_setup_contraint, nullptr, total_contraint_count, -1, true, SNAME("Physics3DConstraintSetup")); + uint32_t total_constraint_count = all_constraints.size(); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &GodotStep3D::_setup_constraint, nullptr, total_constraint_count, -1, true, SNAME("Physics3DConstraintSetup")); WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); { //profile diff --git a/servers/physics_3d/godot_step_3d.h b/servers/physics_3d/godot_step_3d.h index 189487757f..a0854a720c 100644 --- a/servers/physics_3d/godot_step_3d.h +++ b/servers/physics_3d/godot_step_3d.h @@ -48,7 +48,7 @@ class GodotStep3D { void _populate_island(GodotBody3D *p_body, LocalVector<GodotBody3D *> &p_body_island, LocalVector<GodotConstraint3D *> &p_constraint_island); void _populate_island_soft_body(GodotSoftBody3D *p_soft_body, LocalVector<GodotBody3D *> &p_body_island, LocalVector<GodotConstraint3D *> &p_constraint_island); - void _setup_contraint(uint32_t p_constraint_index, void *p_userdata = nullptr); + void _setup_constraint(uint32_t p_constraint_index, void *p_userdata = nullptr); void _pre_solve_island(LocalVector<GodotConstraint3D *> &p_constraint_island) const; void _solve_island(uint32_t p_island_index, void *p_userdata = nullptr); void _check_suspend(const LocalVector<GodotBody3D *> &p_body_island) const; diff --git a/servers/physics_3d/joints/godot_generic_6dof_joint_3d.cpp b/servers/physics_3d/joints/godot_generic_6dof_joint_3d.cpp index e0fa940104..dfe2bfa4d3 100644 --- a/servers/physics_3d/joints/godot_generic_6dof_joint_3d.cpp +++ b/servers/physics_3d/joints/godot_generic_6dof_joint_3d.cpp @@ -232,7 +232,7 @@ GodotGeneric6DOFJoint3D::GodotGeneric6DOFJoint3D(GodotBody3D *rbA, GodotBody3D * void GodotGeneric6DOFJoint3D::calculateAngleInfo() { Basis relative_frame = m_calculatedTransformB.basis.inverse() * m_calculatedTransformA.basis; - m_calculatedAxisAngleDiff = relative_frame.get_euler(Basis::EULER_ORDER_XYZ); + m_calculatedAxisAngleDiff = relative_frame.get_euler(EulerOrder::XYZ); // in euler angle mode we do not actually constrain the angular velocity // along the axes axis[0] and axis[2] (although we do use axis[1]) : diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index 21be311637..c5a93cc390 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -479,8 +479,8 @@ void PhysicsTestMotionParameters2D::set_exclude_bodies(const TypedArray<RID> &p_ } } -Array PhysicsTestMotionParameters2D::get_exclude_objects() const { - Array exclude; +TypedArray<uint64_t> PhysicsTestMotionParameters2D::get_exclude_objects() const { + TypedArray<uint64_t> exclude; exclude.resize(parameters.exclude_objects.size()); int object_index = 0; @@ -491,7 +491,7 @@ Array PhysicsTestMotionParameters2D::get_exclude_objects() const { return exclude; } -void PhysicsTestMotionParameters2D::set_exclude_objects(const Array &p_exclude) { +void PhysicsTestMotionParameters2D::set_exclude_objects(const TypedArray<uint64_t> &p_exclude) { for (int i = 0; i < p_exclude.size(); ++i) { ObjectID object_id = p_exclude[i]; ERR_CONTINUE(object_id.is_null()); diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index 95425e72e8..8b4b5ae4de 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -732,8 +732,8 @@ public: TypedArray<RID> get_exclude_bodies() const; void set_exclude_bodies(const TypedArray<RID> &p_exclude); - Array get_exclude_objects() const; - void set_exclude_objects(const Array &p_exclude); + TypedArray<uint64_t> get_exclude_objects() const; + void set_exclude_objects(const TypedArray<uint64_t> &p_exclude); bool is_recovery_as_collision_enabled() const { return parameters.recovery_as_collision; } void set_recovery_as_collision_enabled(bool p_enabled) { parameters.recovery_as_collision = p_enabled; } diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index db21e1db06..aecb687d5f 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -169,25 +169,25 @@ PhysicsDirectBodyState3D::PhysicsDirectBodyState3D() {} /////////////////////////////////////////////////////// -void PhysicsRayQueryParameters3D::set_exclude(const Vector<RID> &p_exclude) { +void PhysicsRayQueryParameters3D::set_exclude(const TypedArray<RID> &p_exclude) { parameters.exclude.clear(); for (int i = 0; i < p_exclude.size(); i++) { parameters.exclude.insert(p_exclude[i]); } } -Vector<RID> PhysicsRayQueryParameters3D::get_exclude() const { - Vector<RID> ret; +TypedArray<RID> PhysicsRayQueryParameters3D::get_exclude() const { + TypedArray<RID> ret; ret.resize(parameters.exclude.size()); int idx = 0; for (const RID &E : parameters.exclude) { - ret.write[idx++] = E; + ret[idx++] = E; } return ret; } void PhysicsRayQueryParameters3D::_bind_methods() { - ClassDB::bind_static_method("PhysicsRayQueryParameters3D", D_METHOD("create", "from", "to", "collision_mask", "exclude"), &PhysicsRayQueryParameters3D::create, DEFVAL(UINT32_MAX), DEFVAL(Vector<RID>())); + ClassDB::bind_static_method("PhysicsRayQueryParameters3D", D_METHOD("create", "from", "to", "collision_mask", "exclude"), &PhysicsRayQueryParameters3D::create, DEFVAL(UINT32_MAX), DEFVAL(TypedArray<RID>())); ClassDB::bind_method(D_METHOD("set_from", "from"), &PhysicsRayQueryParameters3D::set_from); ClassDB::bind_method(D_METHOD("get_from"), &PhysicsRayQueryParameters3D::get_from); @@ -225,7 +225,7 @@ void PhysicsRayQueryParameters3D::_bind_methods() { /////////////////////////////////////////////////////// -Ref<PhysicsRayQueryParameters3D> PhysicsRayQueryParameters3D::create(Vector3 p_from, Vector3 p_to, uint32_t p_mask, const Vector<RID> &p_exclude) { +Ref<PhysicsRayQueryParameters3D> PhysicsRayQueryParameters3D::create(Vector3 p_from, Vector3 p_to, uint32_t p_mask, const TypedArray<RID> &p_exclude) { Ref<PhysicsRayQueryParameters3D> params; params.instantiate(); params->set_from(p_from); @@ -235,19 +235,19 @@ Ref<PhysicsRayQueryParameters3D> PhysicsRayQueryParameters3D::create(Vector3 p_f return params; } -void PhysicsPointQueryParameters3D::set_exclude(const Vector<RID> &p_exclude) { +void PhysicsPointQueryParameters3D::set_exclude(const TypedArray<RID> &p_exclude) { parameters.exclude.clear(); for (int i = 0; i < p_exclude.size(); i++) { parameters.exclude.insert(p_exclude[i]); } } -Vector<RID> PhysicsPointQueryParameters3D::get_exclude() const { - Vector<RID> ret; +TypedArray<RID> PhysicsPointQueryParameters3D::get_exclude() const { + TypedArray<RID> ret; ret.resize(parameters.exclude.size()); int idx = 0; for (const RID &E : parameters.exclude) { - ret.write[idx++] = E; + ret[idx++] = E; } return ret; } @@ -290,19 +290,19 @@ void PhysicsShapeQueryParameters3D::set_shape_rid(const RID &p_shape) { } } -void PhysicsShapeQueryParameters3D::set_exclude(const Vector<RID> &p_exclude) { +void PhysicsShapeQueryParameters3D::set_exclude(const TypedArray<RID> &p_exclude) { parameters.exclude.clear(); for (int i = 0; i < p_exclude.size(); i++) { parameters.exclude.insert(p_exclude[i]); } } -Vector<RID> PhysicsShapeQueryParameters3D::get_exclude() const { - Vector<RID> ret; +TypedArray<RID> PhysicsShapeQueryParameters3D::get_exclude() const { + TypedArray<RID> ret; ret.resize(parameters.exclude.size()); int idx = 0; for (const RID &E : parameters.exclude) { - ret.write[idx++] = E; + ret[idx++] = E; } return ret; } @@ -482,37 +482,37 @@ void PhysicsDirectSpaceState3D::_bind_methods() { /////////////////////////////// -Vector<RID> PhysicsTestMotionParameters3D::get_exclude_bodies() const { - Vector<RID> exclude; +TypedArray<RID> PhysicsTestMotionParameters3D::get_exclude_bodies() const { + TypedArray<RID> exclude; exclude.resize(parameters.exclude_bodies.size()); int body_index = 0; - for (RID body : parameters.exclude_bodies) { - exclude.write[body_index++] = body; + for (const RID &body : parameters.exclude_bodies) { + exclude[body_index++] = body; } return exclude; } -void PhysicsTestMotionParameters3D::set_exclude_bodies(const Vector<RID> &p_exclude) { - for (RID body : p_exclude) { - parameters.exclude_bodies.insert(body); +void PhysicsTestMotionParameters3D::set_exclude_bodies(const TypedArray<RID> &p_exclude) { + for (int i = 0; i < p_exclude.size(); i++) { + parameters.exclude_bodies.insert(p_exclude[i]); } } -Array PhysicsTestMotionParameters3D::get_exclude_objects() const { - Array exclude; +TypedArray<uint64_t> PhysicsTestMotionParameters3D::get_exclude_objects() const { + TypedArray<uint64_t> exclude; exclude.resize(parameters.exclude_objects.size()); int object_index = 0; - for (ObjectID object_id : parameters.exclude_objects) { + for (const ObjectID &object_id : parameters.exclude_objects) { exclude[object_index++] = object_id; } return exclude; } -void PhysicsTestMotionParameters3D::set_exclude_objects(const Array &p_exclude) { +void PhysicsTestMotionParameters3D::set_exclude_objects(const TypedArray<uint64_t> &p_exclude) { for (int i = 0; i < p_exclude.size(); ++i) { ObjectID object_id = p_exclude[i]; ERR_CONTINUE(object_id.is_null()); diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index 87877ad52d..ca1ff57c99 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -210,8 +210,8 @@ public: class PhysicsServer3DRenderingServerHandler : public Object { GDCLASS(PhysicsServer3DRenderingServerHandler, Object) protected: - GDVIRTUAL2(_set_vertex, int, GDNativeConstPtr<void>) - GDVIRTUAL2(_set_normal, int, GDNativeConstPtr<void>) + GDVIRTUAL2(_set_vertex, int, GDExtensionConstPtr<void>) + GDVIRTUAL2(_set_normal, int, GDExtensionConstPtr<void>) GDVIRTUAL1(_set_aabb, const AABB &) static void _bind_methods(); @@ -822,7 +822,7 @@ protected: static void _bind_methods(); public: - static Ref<PhysicsRayQueryParameters3D> create(Vector3 p_from, Vector3 p_to, uint32_t p_mask, const Vector<RID> &p_exclude); + static Ref<PhysicsRayQueryParameters3D> create(Vector3 p_from, Vector3 p_to, uint32_t p_mask, const TypedArray<RID> &p_exclude); const PhysicsDirectSpaceState3D::RayParameters &get_parameters() const { return parameters; } void set_from(const Vector3 &p_from) { parameters.from = p_from; } @@ -846,8 +846,8 @@ public: void set_hit_back_faces(bool p_enable) { parameters.hit_back_faces = p_enable; } bool is_hit_back_faces_enabled() const { return parameters.hit_back_faces; } - void set_exclude(const Vector<RID> &p_exclude); - Vector<RID> get_exclude() const; + void set_exclude(const TypedArray<RID> &p_exclude); + TypedArray<RID> get_exclude() const; }; class PhysicsPointQueryParameters3D : public RefCounted { @@ -873,8 +873,8 @@ public: void set_collide_with_areas(bool p_enable) { parameters.collide_with_areas = p_enable; } bool is_collide_with_areas_enabled() const { return parameters.collide_with_areas; } - void set_exclude(const Vector<RID> &p_exclude); - Vector<RID> get_exclude() const; + void set_exclude(const TypedArray<RID> &p_exclude); + TypedArray<RID> get_exclude() const; }; class PhysicsShapeQueryParameters3D : public RefCounted { @@ -914,8 +914,8 @@ public: void set_collide_with_areas(bool p_enable) { parameters.collide_with_areas = p_enable; } bool is_collide_with_areas_enabled() const { return parameters.collide_with_areas; } - void set_exclude(const Vector<RID> &p_exclude); - Vector<RID> get_exclude() const; + void set_exclude(const TypedArray<RID> &p_exclude); + TypedArray<RID> get_exclude() const; }; class PhysicsTestMotionParameters3D : public RefCounted { @@ -944,11 +944,11 @@ public: bool is_collide_separation_ray_enabled() const { return parameters.collide_separation_ray; } void set_collide_separation_ray_enabled(bool p_enabled) { parameters.collide_separation_ray = p_enabled; } - Vector<RID> get_exclude_bodies() const; - void set_exclude_bodies(const Vector<RID> &p_exclude); + TypedArray<RID> get_exclude_bodies() const; + void set_exclude_bodies(const TypedArray<RID> &p_exclude); - Array get_exclude_objects() const; - void set_exclude_objects(const Array &p_exclude); + TypedArray<uint64_t> get_exclude_objects() const; + void set_exclude_objects(const TypedArray<uint64_t> &p_exclude); bool is_recovery_as_collision_enabled() const { return parameters.recovery_as_collision; } void set_recovery_as_collision_enabled(bool p_enabled) { parameters.recovery_as_collision = p_enabled; } diff --git a/servers/rendering/dummy/rasterizer_canvas_dummy.h b/servers/rendering/dummy/rasterizer_canvas_dummy.h index 64c4cf5024..65c64e8115 100644 --- a/servers/rendering/dummy/rasterizer_canvas_dummy.h +++ b/servers/rendering/dummy/rasterizer_canvas_dummy.h @@ -39,7 +39,6 @@ public: void free_polygon(PolygonID p_polygon) override {} void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) override {} - void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) override {} RID light_create() override { return RID(); } void light_set_texture(RID p_rid, RID p_texture) override {} diff --git a/servers/rendering/dummy/rasterizer_scene_dummy.h b/servers/rendering/dummy/rasterizer_scene_dummy.h index bc8f7c523b..3937362920 100644 --- a/servers/rendering/dummy/rasterizer_scene_dummy.h +++ b/servers/rendering/dummy/rasterizer_scene_dummy.h @@ -112,7 +112,6 @@ public: /* ENVIRONMENT API */ void environment_glow_set_use_bicubic_upscale(bool p_enable) override {} - void environment_glow_set_use_high_quality(bool p_enable) override {} void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override {} diff --git a/servers/rendering/dummy/storage/material_storage.h b/servers/rendering/dummy/storage/material_storage.h index ed8fefc558..b4e0a21ee1 100644 --- a/servers/rendering/dummy/storage/material_storage.h +++ b/servers/rendering/dummy/storage/material_storage.h @@ -54,7 +54,7 @@ public: virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override { return 0; } virtual void global_shader_parameters_instance_free(RID p_instance) override {} - virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) override {} + virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0) override {} /* SHADER API */ diff --git a/servers/rendering/dummy/storage/mesh_storage.cpp b/servers/rendering/dummy/storage/mesh_storage.cpp index adf736eee3..52de998835 100644 --- a/servers/rendering/dummy/storage/mesh_storage.cpp +++ b/servers/rendering/dummy/storage/mesh_storage.cpp @@ -56,3 +56,10 @@ void MeshStorage::mesh_free(RID p_rid) { mesh_owner.free(p_rid); } + +void MeshStorage::mesh_clear(RID p_mesh) { + DummyMesh *m = mesh_owner.get_or_null(p_mesh); + ERR_FAIL_COND(!m); + + m->surfaces.clear(); +} diff --git a/servers/rendering/dummy/storage/mesh_storage.h b/servers/rendering/dummy/storage/mesh_storage.h index b0914e70e4..28fe8cb80d 100644 --- a/servers/rendering/dummy/storage/mesh_storage.h +++ b/servers/rendering/dummy/storage/mesh_storage.h @@ -81,6 +81,7 @@ public: s->vertex_count = p_surface.vertex_count; s->index_data = p_surface.index_data; s->index_count = p_surface.index_count; + s->aabb = p_surface.aabb; s->skin_data = p_surface.skin_data; } @@ -115,7 +116,7 @@ public: virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) override { return AABB(); } virtual void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) override {} - virtual void mesh_clear(RID p_mesh) override {} + virtual void mesh_clear(RID p_mesh) override; /* MESH INSTANCE */ diff --git a/servers/rendering/dummy/storage/particles_storage.h b/servers/rendering/dummy/storage/particles_storage.h index 7cee55922d..beedff0a76 100644 --- a/servers/rendering/dummy/storage/particles_storage.h +++ b/servers/rendering/dummy/storage/particles_storage.h @@ -89,8 +89,6 @@ public: virtual void particles_add_collision(RID p_particles, RID p_instance) override {} virtual void particles_remove_collision(RID p_particles, RID p_instance) override {} - virtual 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 {} - virtual void update_particles() override {} /* PARTICLES COLLISION */ @@ -111,7 +109,6 @@ public: virtual void particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) override {} virtual AABB particles_collision_get_aabb(RID p_particles_collision) const override { return AABB(); } virtual bool particles_collision_is_heightfield(RID p_particles_collision) const override { return false; } - virtual RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const override { return RID(); } virtual RID particles_collision_instance_create(RID p_collision) override { return RID(); } virtual void particles_collision_instance_free(RID p_rid) override {} diff --git a/servers/rendering/dummy/storage/texture_storage.h b/servers/rendering/dummy/storage/texture_storage.h index 98acd5ad74..dd89504f38 100644 --- a/servers/rendering/dummy/storage/texture_storage.h +++ b/servers/rendering/dummy/storage/texture_storage.h @@ -80,6 +80,7 @@ public: virtual void texture_free(RID p_rid) override { // delete the texture DummyTexture *texture = texture_owner.get_or_null(p_rid); + ERR_FAIL_COND(!texture); texture_owner.free(p_rid); memdelete(texture); }; @@ -126,6 +127,8 @@ public: virtual Size2 texture_size_with_proxy(RID p_proxy) override { return Size2(); }; + virtual RID texture_get_rd_texture_rid(RID p_texture, bool p_srgb = false) const override { return RID(); }; + /* DECAL API */ virtual RID decal_allocate() override { return RID(); } virtual void decal_initialize(RID p_rid) override {} @@ -184,11 +187,9 @@ public: virtual void render_target_set_vrs_texture(RID p_render_target, RID p_texture) override {} virtual RID render_target_get_vrs_texture(RID p_render_target) const override { return RID(); } - virtual void render_target_set_override_color(RID p_render_target, RID p_texture) override {} + virtual void render_target_set_override(RID p_render_target, RID p_color_texture, RID p_depth_texture, RID p_velocity_texture) override {} virtual RID render_target_get_override_color(RID p_render_target) const override { return RID(); } - virtual void render_target_set_override_depth(RID p_render_target, RID p_texture) override {} virtual RID render_target_get_override_depth(RID p_render_target) const override { return RID(); } - virtual void render_target_set_override_velocity(RID p_render_target, RID p_texture) override {} virtual RID render_target_get_override_velocity(RID p_render_target) const override { return RID(); } virtual RID render_target_get_texture(RID p_render_target) override { return RID(); } diff --git a/servers/rendering/dummy/storage/utilities.h b/servers/rendering/dummy/storage/utilities.h index cb7b2a2b63..a42ab0d814 100644 --- a/servers/rendering/dummy/storage/utilities.h +++ b/servers/rendering/dummy/storage/utilities.h @@ -109,6 +109,8 @@ public: virtual String get_video_adapter_vendor() const override { return String(); } virtual RenderingDevice::DeviceType get_video_adapter_type() const override { return RenderingDevice::DeviceType::DEVICE_TYPE_OTHER; } virtual String get_video_adapter_api_version() const override { return String(); } + + virtual Size2i get_maximum_viewport_size() const override { return Size2i(); }; }; } // namespace RendererDummy diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index ffd8f695c6..33f1f38bf5 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -38,17 +38,17 @@ static const int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1; -void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel) { +void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask) { RENDER_TIMESTAMP("Cull CanvasItem Tree"); memset(z_list, 0, z_range * sizeof(RendererCanvasRender::Item *)); memset(z_last_list, 0, z_range * sizeof(RendererCanvasRender::Item *)); for (int i = 0; i < p_child_item_count; i++) { - _cull_canvas_item(p_child_items[i].item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr, true); + _cull_canvas_item(p_child_items[i].item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr, true, canvas_cull_mask); } if (p_canvas_item) { - _cull_canvas_item(p_canvas_item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr, true); + _cull_canvas_item(p_canvas_item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr, true, canvas_cull_mask); } RendererCanvasRender::Item *list = nullptr; @@ -223,13 +223,17 @@ void RendererCanvasCull::_attach_canvas_item_for_draw(RendererCanvasCull::Item * } } -void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool allow_y_sort) { +void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool allow_y_sort, uint32_t canvas_cull_mask) { Item *ci = p_canvas_item; if (!ci->visible) { return; } + if (!(ci->visibility_layer & canvas_cull_mask)) { + return; + } + if (ci->children_order_dirty) { ci->child_items.sort_custom<ItemIndexSort>(); ci->children_order_dirty = false; @@ -271,12 +275,12 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2 if (ci->clip) { if (p_canvas_clip != nullptr) { ci->final_clip_rect = p_canvas_clip->final_clip_rect.intersection(global_rect); - if (ci->final_clip_rect == Rect2()) { - // Clip rects do not intersect, so don't draw this item. - return; - } } else { - ci->final_clip_rect = global_rect; + ci->final_clip_rect = p_clip_rect.intersection(global_rect); + } + if (ci->final_clip_rect.size.width < 0.5 || ci->final_clip_rect.size.height < 0.5) { + // The clip rect area is 0, so don't draw the item. + return; } ci->final_clip_rect.position = ci->final_clip_rect.position.round(); ci->final_clip_rect.size = ci->final_clip_rect.size.round(); @@ -313,7 +317,7 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2 sorter.sort(child_items, child_item_count); for (i = 0; i < child_item_count; i++) { - _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, child_items[i]->ysort_parent_abs_z_index, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner, false); + _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, child_items[i]->ysort_parent_abs_z_index, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner, false, canvas_cull_mask); } } else { RendererCanvasRender::Item *canvas_group_from = nullptr; @@ -337,19 +341,19 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2 if (!child_items[i]->behind && !use_canvas_group) { continue; } - _cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, p_material_owner, true); + _cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, p_material_owner, true, canvas_cull_mask); } _attach_canvas_item_for_draw(ci, p_canvas_clip, r_z_list, r_z_last_list, xform, p_clip_rect, global_rect, modulate, p_z, p_material_owner, use_canvas_group, canvas_group_from, xform); for (int i = 0; i < child_item_count; i++) { if (child_items[i]->behind || use_canvas_group) { continue; } - _cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, p_material_owner, true); + _cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, r_z_list, r_z_last_list, (Item *)ci->final_clip_owner, p_material_owner, true, canvas_cull_mask); } } } -void RendererCanvasCull::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel) { +void RendererCanvasCull::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask) { RENDER_TIMESTAMP("> Render Canvas"); sdf_used = false; @@ -372,26 +376,26 @@ void RendererCanvasCull::render_canvas(RID p_render_target, Canvas *p_canvas, co } if (!has_mirror) { - _render_canvas_item_tree(p_render_target, ci, l, nullptr, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); + _render_canvas_item_tree(p_render_target, ci, l, nullptr, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel, canvas_cull_mask); } else { //used for parallaxlayer mirroring for (int i = 0; i < l; i++) { const Canvas::ChildItem &ci2 = p_canvas->child_items[i]; - _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); + _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel, canvas_cull_mask); //mirroring (useful for scrolling backgrounds) if (ci2.mirror.x != 0) { Transform2D xform2 = p_transform * Transform2D(0, Vector2(ci2.mirror.x, 0)); - _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); + _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel, canvas_cull_mask); } if (ci2.mirror.y != 0) { Transform2D xform2 = p_transform * Transform2D(0, Vector2(0, ci2.mirror.y)); - _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); + _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel, canvas_cull_mask); } if (ci2.mirror.y != 0 && ci2.mirror.x != 0) { Transform2D xform2 = p_transform * Transform2D(0, ci2.mirror); - _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel); + _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_directional_lights, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel, canvas_cull_mask); } } } @@ -513,6 +517,20 @@ void RendererCanvasCull::canvas_item_set_transform(RID p_item, const Transform2D canvas_item->xform = p_transform; } +void RendererCanvasCull::canvas_item_set_visibility_layer(RID p_item, uint32_t p_visibility_layer) { + Item *canvas_item = canvas_item_owner.get_or_null(p_item); + ERR_FAIL_COND(!canvas_item); + + canvas_item->visibility_layer = p_visibility_layer; +} + +uint32_t RendererCanvasCull::canvas_item_get_visibility_layer(RID p_item) { + Item *canvas_item = canvas_item_owner.get_or_null(p_item); + if (!canvas_item) + return 0; + return canvas_item->visibility_layer; +} + void RendererCanvasCull::canvas_item_set_clip(RID p_item, bool p_clip) { Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); @@ -1057,18 +1075,36 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point void RendererCanvasCull::canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) { ERR_FAIL_COND(p_points.size() < 2); - Item *canvas_item = canvas_item_owner.get_or_null(p_item); - ERR_FAIL_COND(!canvas_item); - - Item::CommandPolygon *pline = canvas_item->alloc_command<Item::CommandPolygon>(); - ERR_FAIL_COND(!pline); - if (true || p_width <= 1) { -#define TODO make thick lines possible + // TODO: `canvas_item_add_line`(`multiline`, `polyline`) share logic, should factor out. + if (p_width <= 1) { + Item *canvas_item = canvas_item_owner.get_or_null(p_item); + ERR_FAIL_COND(!canvas_item); + Item::CommandPolygon *pline = canvas_item->alloc_command<Item::CommandPolygon>(); + ERR_FAIL_COND(!pline); pline->primitive = RS::PRIMITIVE_LINES; pline->polygon.create(Vector<int>(), p_points, p_colors); } else { + if (p_colors.size() == 1) { + Color color = p_colors[0]; + for (int i = 0; i < p_points.size() >> 1; i++) { + Vector2 from = p_points[i * 2 + 0]; + Vector2 to = p_points[i * 2 + 1]; + + canvas_item_add_line(p_item, from, to, color, p_width); + } + } else if (p_colors.size() == p_points.size() >> 1) { + for (int i = 0; i < p_points.size() >> 1; i++) { + Color color = p_colors[i]; + Vector2 from = p_points[i * 2 + 0]; + Vector2 to = p_points[i * 2 + 1]; + + canvas_item_add_line(p_item, from, to, color, p_width); + } + } else { + ERR_FAIL_MSG("Length of p_colors is invalid."); + } } } @@ -1946,7 +1982,7 @@ void RendererCanvasCull::update_visibility_notifiers() { if (!visibility_notifier->enter_callable.is_null()) { if (RSG::threaded) { - visibility_notifier->enter_callable.call_deferredp(nullptr, 0); + visibility_notifier->enter_callable.call_deferred(); } else { Callable::CallError ce; Variant ret; @@ -1959,7 +1995,7 @@ void RendererCanvasCull::update_visibility_notifiers() { if (!visibility_notifier->exit_callable.is_null()) { if (RSG::threaded) { - visibility_notifier->exit_callable.call_deferredp(nullptr, 0); + visibility_notifier->exit_callable.call_deferred(); } else { Callable::CallError ce; Variant ret; diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h index 7a01fad9de..198e1020f0 100644 --- a/servers/rendering/renderer_canvas_cull.h +++ b/servers/rendering/renderer_canvas_cull.h @@ -54,6 +54,7 @@ public: Vector2 ysort_pos; int ysort_index; int ysort_parent_abs_z_index; // Absolute Z index of parent. Only populated and used when y-sorting. + uint32_t visibility_layer = 0xffffffff; Vector<Item *> child_items; @@ -179,14 +180,14 @@ public: _FORCE_INLINE_ void _attach_canvas_item_for_draw(Item *ci, Item *p_canvas_clip, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, const Transform2D &xform, const Rect2 &p_clip_rect, Rect2 global_rect, const Color &modulate, int p_z, RendererCanvasCull::Item *p_material_owner, bool p_use_canvas_group, RendererCanvasRender::Item *canvas_group_from, const Transform2D &p_xform); private: - void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel); - void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool allow_y_sort); + void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask); + void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool allow_y_sort, uint32_t canvas_cull_mask); RendererCanvasRender::Item **z_list; RendererCanvasRender::Item **z_last_list; public: - void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel); + void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask); bool was_sdf_used(); @@ -206,6 +207,9 @@ public: void canvas_item_set_visible(RID p_item, bool p_visible); void canvas_item_set_light_mask(RID p_item, int p_mask); + void canvas_item_set_visibility_layer(RID p_item, uint32_t p_layer); + uint32_t canvas_item_get_visibility_layer(RID p_item); + void canvas_item_set_transform(RID p_item, const Transform2D &p_transform); void canvas_item_set_clip(RID p_item, bool p_clip); void canvas_item_set_distance_field_mode(RID p_item, bool p_enable); diff --git a/servers/rendering/renderer_canvas_render.cpp b/servers/rendering/renderer_canvas_render.cpp index 623f0c647b..07394b49a3 100644 --- a/servers/rendering/renderer_canvas_render.cpp +++ b/servers/rendering/renderer_canvas_render.cpp @@ -32,7 +32,7 @@ #include "servers/rendering/rendering_server_globals.h" const Rect2 &RendererCanvasRender::Item::get_rect() const { - if (custom_rect || (!rect_dirty && !update_when_visible)) { + if (custom_rect || (!rect_dirty && !update_when_visible && skeleton == RID())) { return rect; } @@ -80,7 +80,7 @@ const Rect2 &RendererCanvasRender::Item::get_rect() const { } break; case Item::Command::TYPE_MESH: { const Item::CommandMesh *mesh = static_cast<const Item::CommandMesh *>(c); - AABB aabb = RSG::mesh_storage->mesh_get_aabb(mesh->mesh, RID()); + AABB aabb = RSG::mesh_storage->mesh_get_aabb(mesh->mesh, skeleton); r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y); diff --git a/servers/rendering/renderer_canvas_render.h b/servers/rendering/renderer_canvas_render.h index 6791ed9626..375358a5e8 100644 --- a/servers/rendering/renderer_canvas_render.h +++ b/servers/rendering/renderer_canvas_render.h @@ -476,7 +476,6 @@ public: }; virtual void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) = 0; - virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) = 0; struct LightOccluderInstance { bool enabled; diff --git a/servers/rendering/renderer_rd/SCsub b/servers/rendering/renderer_rd/SCsub index 10b83dca11..a27439e931 100644 --- a/servers/rendering/renderer_rd/SCsub +++ b/servers/rendering/renderer_rd/SCsub @@ -9,4 +9,5 @@ SConscript("environment/SCsub") SConscript("forward_clustered/SCsub") SConscript("forward_mobile/SCsub") SConscript("shaders/SCsub") +SConscript("spirv-reflect/SCsub") SConscript("storage_rd/SCsub") diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp index 53237c1dfb..9fda54a34d 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.cpp +++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp @@ -56,6 +56,7 @@ CopyEffects::CopyEffects(bool p_prefer_raster_effects) { blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n"); // BLUR_MODE_GAUSSIAN_GLOW blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n"); // BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE blur_modes.push_back("\n#define MODE_COPY\n"); // BLUR_MODE_COPY + blur_modes.push_back("\n#define MODE_SET_COLOR\n"); // BLUR_MODE_SET_COLOR blur_raster.shader.initialize(blur_modes); memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant)); @@ -105,6 +106,7 @@ CopyEffects::CopyEffects(bool p_prefer_raster_effects) { copy_modes.push_back("\n#define MODE_TWO_SOURCES\n"); // COPY_TO_FB_COPY2 copy_modes.push_back("\n#define MULTIVIEW\n"); // COPY_TO_FB_MULTIVIEW copy_modes.push_back("\n#define MULTIVIEW\n#define MODE_TWO_SOURCES\n"); // COPY_TO_FB_MULTIVIEW_WITH_DEPTH + copy_modes.push_back("\n#define MODE_SET_COLOR\n"); // COPY_TO_FB_SET_COLOR copy_to_fb.shader.initialize(copy_modes); @@ -357,8 +359,8 @@ void CopyEffects::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, cons copy.push_constant.flags |= COPY_FLAG_ALPHA_TO_ONE; } - copy.push_constant.section[0] = 0; - copy.push_constant.section[1] = 0; + copy.push_constant.section[0] = p_rect.position.x; + copy.push_constant.section[1] = p_rect.position.y; copy.push_constant.section[2] = p_rect.size.width; copy.push_constant.section[3] = p_rect.size.height; copy.push_constant.target[0] = p_rect.position.x; @@ -508,16 +510,18 @@ void CopyEffects::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuff memset(©_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant)); - copy_to_fb.push_constant.use_section = true; + copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_USE_SECTION; copy_to_fb.push_constant.section[0] = p_uv_rect.position.x; copy_to_fb.push_constant.section[1] = p_uv_rect.position.y; copy_to_fb.push_constant.section[2] = p_uv_rect.size.x; copy_to_fb.push_constant.section[3] = p_uv_rect.size.y; if (p_flip_y) { - copy_to_fb.push_constant.flip_y = true; + copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FLIP_Y; } + copy_to_fb.push_constant.luminance_multiplier = 1.0; + // setup our uniforms RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -535,25 +539,35 @@ void CopyEffects::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuff RD::get_singleton()->draw_list_draw(draw_list, true); } -void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary, bool p_multiview) { +void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary, bool p_multiview, bool p_alpha_to_one, bool p_linear) { UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); ERR_FAIL_NULL(uniform_set_cache); MaterialStorage *material_storage = MaterialStorage::get_singleton(); ERR_FAIL_NULL(material_storage); memset(©_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant)); + copy_to_fb.push_constant.luminance_multiplier = 1.0; if (p_flip_y) { - copy_to_fb.push_constant.flip_y = true; + copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FLIP_Y; } if (p_force_luminance) { - copy_to_fb.push_constant.force_luminance = true; + copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FORCE_LUMINANCE; } if (p_alpha_to_zero) { - copy_to_fb.push_constant.alpha_to_zero = true; + copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_ALPHA_TO_ZERO; } if (p_srgb) { - copy_to_fb.push_constant.srgb = true; + copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_SRGB; + } + if (p_alpha_to_one) { + copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_ALPHA_TO_ONE; + } + if (p_linear) { + // Used for copying to a linear buffer. In the mobile renderer we divide the contents of the linear buffer + // to allow for a wider effective range. + copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_LINEAR; + copy_to_fb.push_constant.luminance_multiplier = prefer_raster_effects ? 2.0 : 1.0; } // setup our uniforms @@ -608,15 +622,13 @@ void CopyEffects::copy_raster(RID p_source_texture, RID p_dest_framebuffer) { RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[BLUR_MODE_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_texture), 0); RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); - - memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant)); RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); RD::get_singleton()->draw_list_draw(draw_list, true); RD::get_singleton()->draw_list_end(); } -void CopyEffects::gaussian_blur(RID p_source_rd_texture, RID p_texture, const Rect2i &p_region, bool p_8bit_dst) { +void CopyEffects::gaussian_blur(RID p_source_rd_texture, RID p_texture, const Rect2i &p_region, const Size2i &p_size, bool p_8bit_dst) { ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute version of the gaussian blur with the mobile renderer."); UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); @@ -628,8 +640,10 @@ void CopyEffects::gaussian_blur(RID p_source_rd_texture, RID p_texture, const Re copy.push_constant.section[0] = p_region.position.x; copy.push_constant.section[1] = p_region.position.y; - copy.push_constant.section[2] = p_region.size.width; - copy.push_constant.section[3] = p_region.size.height; + copy.push_constant.target[0] = p_region.position.x; + copy.push_constant.target[1] = p_region.position.y; + copy.push_constant.section[2] = p_size.width; + copy.push_constant.section[3] = p_size.height; // setup our uniforms RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -641,7 +655,6 @@ void CopyEffects::gaussian_blur(RID p_source_rd_texture, RID p_texture, const Re RID shader = copy.shader.version_get_shader(copy.shader_version, mode); ERR_FAIL_COND(shader.is_null()); - //HORIZONTAL RD::DrawListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); @@ -654,7 +667,44 @@ void CopyEffects::gaussian_blur(RID p_source_rd_texture, RID p_texture, const Re RD::get_singleton()->compute_list_end(); } -void CopyEffects::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_high_quality, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_scale) { +void CopyEffects::gaussian_blur_raster(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_region, const Size2i &p_size) { + ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use the raster version of the gaussian blur with the clustered renderer."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + RID dest_framebuffer = FramebufferCacheRD::get_singleton()->get_cache(p_dest_texture); + + memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant)); + + BlurRasterMode blur_mode = BLUR_MODE_GAUSSIAN_BLUR; + + blur_raster.push_constant.pixel_size[0] = 1.0 / float(p_size.x); + blur_raster.push_constant.pixel_size[1] = 1.0 / float(p_size.y); + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture })); + + RID shader = blur_raster.shader.version_get_shader(blur_raster.shader_version, blur_mode); + ERR_FAIL_COND(shader.is_null()); + + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); + + RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); + + RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); +} + +void CopyEffects::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_scale) { ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute version of the gaussian glow with the mobile renderer."); UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); @@ -698,14 +748,14 @@ void CopyEffects::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, con RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_auto_exposure), 1); } - copy.push_constant.flags = base_flags | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0) | (p_high_quality ? COPY_FLAG_HIGH_QUALITY_GLOW : 0); + copy.push_constant.flags = base_flags | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.width, p_size.height, 1); RD::get_singleton()->compute_list_end(); } -void CopyEffects::gaussian_glow_raster(RID p_source_rd_texture, RID p_half_texture, RID p_dest_texture, float p_luminance_multiplier, const Size2i &p_size, float p_strength, bool p_high_quality, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_scale) { +void CopyEffects::gaussian_glow_raster(RID p_source_rd_texture, RID p_half_texture, RID p_dest_texture, float p_luminance_multiplier, const Size2i &p_size, float p_strength, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_scale) { ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use the raster version of the gaussian glow with the clustered renderer."); UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); @@ -882,6 +932,36 @@ void CopyEffects::set_color(RID p_dest_texture, const Color &p_color, const Rect RD::get_singleton()->compute_list_end(); } +void CopyEffects::set_color_raster(RID p_dest_texture, const Color &p_color, const Rect2i &p_region) { + ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use the raster version of the set_color shader with the clustered renderer."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + memset(©_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant)); + + copy_to_fb.push_constant.set_color[0] = p_color.r; + copy_to_fb.push_constant.set_color[1] = p_color.g; + copy_to_fb.push_constant.set_color[2] = p_color.b; + copy_to_fb.push_constant.set_color[3] = p_color.a; + + RID dest_framebuffer = FramebufferCacheRD::get_singleton()->get_cache(p_dest_texture); + + CopyToFBMode mode = COPY_TO_FB_SET_COLOR; + + RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, p_region); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer))); + RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); + RD::get_singleton()->draw_list_set_push_constant(draw_list, ©_to_fb.push_constant, sizeof(CopyToFbPushConstant)); + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); +} + void CopyEffects::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip) { UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); ERR_FAIL_NULL(uniform_set_cache); @@ -1075,7 +1155,8 @@ void CopyEffects::cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture, memset(&roughness.push_constant, 0, sizeof(CubemapRoughnessPushConstant)); roughness.push_constant.face_id = p_face_id > 9 ? 0 : p_face_id; - roughness.push_constant.roughness = p_roughness * p_roughness; // Shader expects roughness, not perceptual roughness, so multiply before passing in. + // Remap to perceptual-roughness^2 to create more detail in lower mips and match the mapping of cubemap_filter. + roughness.push_constant.roughness = p_roughness * p_roughness; roughness.push_constant.sample_count = p_sample_count; roughness.push_constant.use_direct_write = p_roughness == 0.0; roughness.push_constant.face_size = p_size; @@ -1122,8 +1203,8 @@ void CopyEffects::cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_f roughness.push_constant.use_direct_write = p_roughness == 0.0; roughness.push_constant.face_size = p_size; - // setup our uniforms - RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + // Setup our uniforms. + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture })); diff --git a/servers/rendering/renderer_rd/effects/copy_effects.h b/servers/rendering/renderer_rd/effects/copy_effects.h index 0ddb60ebef..a0904f0b8e 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.h +++ b/servers/rendering/renderer_rd/effects/copy_effects.h @@ -63,6 +63,8 @@ private: BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE, BLUR_MODE_COPY, + BLUR_MODE_SET_COLOR, + BLUR_MODE_MAX }; @@ -130,8 +132,7 @@ private: COPY_FLAG_FLIP_Y = (1 << 5), COPY_FLAG_FORCE_LUMINANCE = (1 << 6), COPY_FLAG_ALL_SOURCE = (1 << 7), - COPY_FLAG_HIGH_QUALITY_GLOW = (1 << 8), - COPY_FLAG_ALPHA_TO_ONE = (1 << 9), + COPY_FLAG_ALPHA_TO_ONE = (1 << 8), }; struct CopyPushConstant { @@ -174,19 +175,28 @@ private: COPY_TO_FB_MULTIVIEW, COPY_TO_FB_MULTIVIEW_WITH_DEPTH, + + COPY_TO_FB_SET_COLOR, COPY_TO_FB_MAX, }; + enum CopyToFBFlags { + COPY_TO_FB_FLAG_FLIP_Y = (1 << 0), + COPY_TO_FB_FLAG_USE_SECTION = (1 << 1), + COPY_TO_FB_FLAG_FORCE_LUMINANCE = (1 << 2), + COPY_TO_FB_FLAG_ALPHA_TO_ZERO = (1 << 3), + COPY_TO_FB_FLAG_SRGB = (1 << 4), + COPY_TO_FB_FLAG_ALPHA_TO_ONE = (1 << 5), + COPY_TO_FB_FLAG_LINEAR = (1 << 6), + }; + struct CopyToFbPushConstant { float section[4]; float pixel_size[2]; - uint32_t flip_y; - uint32_t use_section; + float luminance_multiplier; + uint32_t flags; - uint32_t force_luminance; - uint32_t alpha_to_zero; - uint32_t srgb; - uint32_t pad; + float set_color[4]; }; struct CopyToFb { @@ -316,18 +326,20 @@ public: void copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array); void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false); void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far); - void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false, bool p_srgb = false, RID p_secondary = RID(), bool p_multiview = false); + void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false, bool p_srgb = false, RID p_secondary = RID(), bool p_multiview = false, bool alpha_to_one = false, bool p_linear = false); void copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y = false, bool p_panorama = false); void copy_raster(RID p_source_texture, RID p_dest_framebuffer); - void gaussian_blur(RID p_source_rd_texture, RID p_texture, const Rect2i &p_region, bool p_8bit_dst = false); - void gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_threshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_scale = 1.0); - void gaussian_glow_raster(RID p_source_rd_texture, RID p_half_texture, RID p_dest_texture, float p_luminance_multiplier, const Size2i &p_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_threshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_scale = 1.0); + void gaussian_blur(RID p_source_rd_texture, RID p_texture, const Rect2i &p_region, const Size2i &p_size, bool p_8bit_dst = false); + void gaussian_blur_raster(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_region, const Size2i &p_size); + void gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_threshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_scale = 1.0); + void gaussian_glow_raster(RID p_source_rd_texture, RID p_half_texture, RID p_dest_texture, float p_luminance_multiplier, const Size2i &p_size, float p_strength = 1.0, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_threshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_scale = 1.0); void make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size); void make_mipmap_raster(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size); void set_color(RID p_dest_texture, const Color &p_color, const Rect2i &p_region, bool p_8bit_dst = false); + void set_color_raster(RID p_dest_texture, const Color &p_color, const Rect2i &p_region); void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip); void cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size); diff --git a/servers/rendering/renderer_rd/effects/resolve.h b/servers/rendering/renderer_rd/effects/resolve.h index 2a4cd06827..49fba921d5 100644 --- a/servers/rendering/renderer_rd/effects/resolve.h +++ b/servers/rendering/renderer_rd/effects/resolve.h @@ -65,8 +65,8 @@ public: Resolve(); ~Resolve(); - void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL); - void resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL); + void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS); + void resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS); }; } // namespace RendererRD diff --git a/servers/rendering/renderer_rd/effects/ss_effects.cpp b/servers/rendering/renderer_rd/effects/ss_effects.cpp index 9653382e96..8e43869b4d 100644 --- a/servers/rendering/renderer_rd/effects/ss_effects.cpp +++ b/servers/rendering/renderer_rd/effects/ss_effects.cpp @@ -1332,7 +1332,6 @@ void SSEffects::generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_bu for (int pass = 0; pass < blur_passes; pass++) { int blur_pipeline = SSAO_BLUR_PASS; if (ssao_quality > RS::ENV_SSAO_QUALITY_VERY_LOW) { - blur_pipeline = SSAO_BLUR_PASS_SMART; if (pass < blur_passes - 2) { blur_pipeline = SSAO_BLUR_PASS_WIDE; } else { diff --git a/servers/rendering/renderer_rd/effects/ss_effects.h b/servers/rendering/renderer_rd/effects/ss_effects.h index dfaf3881bb..a04dfc4a74 100644 --- a/servers/rendering/renderer_rd/effects/ss_effects.h +++ b/servers/rendering/renderer_rd/effects/ss_effects.h @@ -100,7 +100,7 @@ public: float sharpness = 0.98; float normal_rejection = 1.0; - Size2i full_screen_size = Size2i(); + Size2i full_screen_size; }; void ssil_allocate_buffers(SSILRenderBuffers &p_ssil_buffers, const SSILSettings &p_settings, RID p_linear_depth); @@ -137,7 +137,7 @@ public: float horizon = 0.06; float sharpness = 0.98; - Size2i full_screen_size = Size2i(); + Size2i full_screen_size; }; void ssao_allocate_buffers(SSAORenderBuffers &p_ssao_buffers, const SSAOSettings &p_settings, RID p_linear_depth); diff --git a/servers/rendering/renderer_rd/effects/vrs.cpp b/servers/rendering/renderer_rd/effects/vrs.cpp index 5ff00aa94c..701d53b41d 100644 --- a/servers/rendering/renderer_rd/effects/vrs.cpp +++ b/servers/rendering/renderer_rd/effects/vrs.cpp @@ -92,18 +92,15 @@ void VRS::copy_vrs(RID p_source_rd_texture, RID p_dest_framebuffer, bool p_multi } Size2i VRS::get_vrs_texture_size(const Size2i p_base_size) const { - // TODO we should find some way to store this properly, we're assuming 16x16 as this seems to be the standard but in our vrs_capacities we - // obtain a minimum and maximum size, and we should choose something within this range and then make sure that is consistently set when creating - // our frame buffer. Also it is important that we make the resulting size we calculate down below available to the end user so they know the size - // of the VRS buffer to supply. - Size2i texel_size = Size2i(16, 16); - - int width = p_base_size.x / texel_size.x; - if (p_base_size.x % texel_size.x != 0) { + int32_t texel_width = RD::get_singleton()->limit_get(RD::LIMIT_VRS_TEXEL_WIDTH); + int32_t texel_height = RD::get_singleton()->limit_get(RD::LIMIT_VRS_TEXEL_HEIGHT); + + int width = p_base_size.x / texel_width; + if (p_base_size.x % texel_width != 0) { width++; } - int height = p_base_size.y / texel_size.y; - if (p_base_size.y % texel_size.y != 0) { + int height = p_base_size.y / texel_height; + if (p_base_size.y % texel_height != 0) { height++; } return Size2i(width, height); diff --git a/servers/rendering/renderer_rd/environment/fog.cpp b/servers/rendering/renderer_rd/environment/fog.cpp index 74082906c4..38066b6613 100644 --- a/servers/rendering/renderer_rd/environment/fog.cpp +++ b/servers/rendering/renderer_rd/environment/fog.cpp @@ -319,10 +319,6 @@ void Fog::free_fog_shader() { material_storage->material_free(volumetric_fog.default_material); } -void Fog::FogShaderData::set_path_hint(const String &p_path) { - path = p_path; -} - void Fog::FogShaderData::set_code(const String &p_code) { //compile @@ -366,83 +362,6 @@ void Fog::FogShaderData::set_code(const String &p_code) { valid = true; } -void Fog::FogShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { - if (!p_texture.is_valid()) { - if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { - default_texture_params[p_name].erase(p_index); - - if (default_texture_params[p_name].is_empty()) { - default_texture_params.erase(p_name); - } - } - } else { - if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = HashMap<int, RID>(); - } - default_texture_params[p_name][p_index] = p_texture; - } -} - -void Fog::FogShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { - RBMap<int, StringName> order; - - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - if (E.value.texture_order >= 0) { - order[E.value.texture_order + 100000] = E.key; - } else { - order[E.value.order] = E.key; - } - } - - String last_group; - for (const KeyValue<int, StringName> &E : order) { - String group = uniforms[E.value].group; - if (!uniforms[E.value].subgroup.is_empty()) { - group += "::" + uniforms[E.value].subgroup; - } - - if (group != last_group) { - PropertyInfo pi; - pi.usage = PROPERTY_USAGE_GROUP; - pi.name = group; - p_param_list->push_back(pi); - - last_group = group; - } - - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); - pi.name = E.value; - p_param_list->push_back(pi); - } -} - -void Fog::FogShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - RendererMaterialStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E.value); - p.info.name = E.key; //supply name - p.index = E.value.instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); - p_param_list->push_back(p); - } -} - -bool Fog::FogShaderData::is_parameter_texture(const StringName &p_param) const { - if (!uniforms.has(p_param)) { - return false; - } - - return uniforms[p_param].texture_order >= 0; -} - bool Fog::FogShaderData::is_animated() const { return false; } @@ -451,15 +370,6 @@ bool Fog::FogShaderData::casts_shadows() const { return false; } -Variant Fog::FogShaderData::get_default_parameter(const StringName &p_parameter) const { - if (uniforms.has(p_parameter)) { - ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; - Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; - return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); - } - return Variant(); -} - RS::ShaderNativeSourceCode Fog::FogShaderData::get_native_source_code() const { Fog *fog_singleton = Fog::get_singleton(); @@ -727,9 +637,9 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P any_uses_time |= shader_data->uses_time; - Vector3i min = Vector3i(); - Vector3i max = Vector3i(); - Vector3i kernel_size = Vector3i(); + Vector3i min; + Vector3i max; + Vector3i kernel_size; Vector3 position = fog_volume_instance->transform.get_origin(); RS::FogVolumeShape volume_type = RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume); @@ -789,6 +699,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P RD::get_singleton()->compute_list_bind_uniform_set(compute_list, volumetric_fog.base_uniform_set, VolumetricFogShader::FogSet::FOG_SET_BASE); if (material->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(material->uniform_set)) { // Material may not have a uniform set. RD::get_singleton()->compute_list_bind_uniform_set(compute_list, material->uniform_set, VolumetricFogShader::FogSet::FOG_SET_MATERIAL); + material->set_as_used(); } RD::get_singleton()->compute_list_dispatch_threads(compute_list, kernel_size.x, kernel_size.y, kernel_size.z); diff --git a/servers/rendering/renderer_rd/environment/fog.h b/servers/rendering/renderer_rd/environment/fog.h index 0ade995758..a5f06a129d 100644 --- a/servers/rendering/renderer_rd/environment/fog.h +++ b/servers/rendering/renderer_rd/environment/fog.h @@ -188,27 +188,18 @@ private: RID version; RID pipeline; - HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size = 0; - String path; String code; - HashMap<StringName, HashMap<int, RID>> default_texture_params; bool uses_time = false; - virtual void set_path_hint(const String &p_hint); virtual void set_code(const String &p_Code); - virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); - virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; - virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; - virtual Variant get_default_parameter(const StringName &p_parameter) const; virtual RS::ShaderNativeSourceCode get_native_source_code() const; FogShaderData() {} diff --git a/servers/rendering/renderer_rd/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp index 9b6be0b422..61b7dd4504 100644 --- a/servers/rendering/renderer_rd/environment/gi.cpp +++ b/servers/rendering/renderer_rd/environment/gi.cpp @@ -2335,7 +2335,7 @@ void GI::SDFGI::render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_ img.instantiate(); for (uint32_t i = 0; i < cascade_size; i++) { Vector<uint8_t> subarr = data.slice(128 * 128 * i, 128 * 128 * (i + 1)); - img->create(cascade_size, cascade_size, false, Image::FORMAT_L8, subarr); + img->set_data(cascade_size, cascade_size, false, Image::FORMAT_L8, subarr); img->save_png("res://cascade_sdf_" + itos(cascade) + "_" + itos(i) + ".png"); } @@ -2866,7 +2866,8 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID { Transform3D to_cell = gi->voxel_gi_get_to_cell_xform(probe); - Transform3D to_probe_xform = (transform * to_cell.affine_inverse()).affine_inverse(); + Transform3D to_probe_xform = to_cell * transform.affine_inverse(); + //update lights for (uint32_t i = 0; i < light_count; i++) { @@ -3495,6 +3496,10 @@ void GI::init(SkyRD *p_sky) { { //calculate tables String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n"; + if (RendererSceneRenderRD::get_singleton()->is_vrs_supported()) { + defines += "\n#define USE_VRS\n"; + } + Vector<String> gi_modes; gi_modes.push_back("\n#define USE_VOXEL_GI_INSTANCES\n"); // MODE_VOXEL_GI @@ -4010,7 +4015,7 @@ void GI::process_gi(Ref<RenderSceneBuffersRD> p_render_buffers, const RID *p_nor u.append_id(rbgi->scene_data_ubo); uniforms.push_back(u); } - { + if (RendererSceneRenderRD::get_singleton()->is_vrs_supported()) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 19; diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index 4ff2a66975..40f68eb118 100644 --- a/servers/rendering/renderer_rd/environment/sky.cpp +++ b/servers/rendering/renderer_rd/environment/sky.cpp @@ -45,10 +45,6 @@ using namespace RendererRD; //////////////////////////////////////////////////////////////////////////////// // SKY SHADER -void SkyRD::SkyShaderData::set_path_hint(const String &p_path) { - path = p_path; -} - void SkyRD::SkyShaderData::set_code(const String &p_code) { //compile @@ -152,82 +148,6 @@ void SkyRD::SkyShaderData::set_code(const String &p_code) { valid = true; } -void SkyRD::SkyShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { - if (!p_texture.is_valid()) { - if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { - default_texture_params[p_name].erase(p_index); - - if (default_texture_params[p_name].is_empty()) { - default_texture_params.erase(p_name); - } - } - } else { - if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = HashMap<int, RID>(); - } - default_texture_params[p_name][p_index] = p_texture; - } -} - -void SkyRD::SkyShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { - HashMap<int, StringName> order; - - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - if (E.value.texture_order >= 0) { - order[E.value.texture_order + 100000] = E.key; - } else { - order[E.value.order] = E.key; - } - } - String last_group; - for (const KeyValue<int, StringName> &E : order) { - String group = uniforms[E.value].group; - if (!uniforms[E.value].subgroup.is_empty()) { - group += "::" + uniforms[E.value].subgroup; - } - - if (group != last_group) { - PropertyInfo pi; - pi.usage = PROPERTY_USAGE_GROUP; - pi.name = group; - p_param_list->push_back(pi); - - last_group = group; - } - - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); - pi.name = E.value; - p_param_list->push_back(pi); - } -} - -void SkyRD::SkyShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - RendererMaterialStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E.value); - p.info.name = E.key; //supply name - p.index = E.value.instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); - p_param_list->push_back(p); - } -} - -bool SkyRD::SkyShaderData::is_parameter_texture(const StringName &p_param) const { - if (!uniforms.has(p_param)) { - return false; - } - - return uniforms[p_param].texture_order >= 0; -} - bool SkyRD::SkyShaderData::is_animated() const { return false; } @@ -236,15 +156,6 @@ bool SkyRD::SkyShaderData::casts_shadows() const { return false; } -Variant SkyRD::SkyShaderData::get_default_parameter(const StringName &p_parameter) const { - if (uniforms.has(p_parameter)) { - ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; - Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; - return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); - } - return Variant(); -} - RS::ShaderNativeSourceCode SkyRD::SkyShaderData::get_native_source_code() const { RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); @@ -361,7 +272,7 @@ void SkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bo uint32_t w = p_size, h = p_size; EffectsRD *effects = RendererCompositorRD::singleton->get_effects(); - ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialised"); + ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialized"); bool prefer_raster_effects = effects->get_prefer_raster_effects(); if (p_use_array) { @@ -465,7 +376,7 @@ void SkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bo void SkyRD::ReflectionData::create_reflection_fast_filter(bool p_use_arrays) { RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); - ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised"); + ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialized"); bool prefer_raster_effects = copy_effects->get_prefer_raster_effects(); if (prefer_raster_effects) { @@ -523,7 +434,7 @@ void SkyRD::ReflectionData::create_reflection_fast_filter(bool p_use_arrays) { void SkyRD::ReflectionData::create_reflection_importance_sample(bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality) { RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); - ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised"); + ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialized"); bool prefer_raster_effects = copy_effects->get_prefer_raster_effects(); if (prefer_raster_effects) { @@ -592,7 +503,7 @@ void SkyRD::ReflectionData::create_reflection_importance_sample(bool p_use_array void SkyRD::ReflectionData::update_reflection_mipmaps(int p_start, int p_end) { RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); - ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised"); + ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialized"); bool prefer_raster_effects = copy_effects->get_prefer_raster_effects(); RD::get_singleton()->draw_command_begin_label("Update Radiance Cubemap Array Mipmaps"); @@ -772,9 +683,7 @@ Ref<Image> SkyRD::Sky::bake_panorama(float p_energy, int p_roughness_layers, con Vector<uint8_t> data = RD::get_singleton()->texture_get_data(rad_tex, 0); RD::get_singleton()->free(rad_tex); - Ref<Image> img; - img.instantiate(); - img->create(p_size.width, p_size.height, false, Image::FORMAT_RGBAF, data); + Ref<Image> img = Image::create_from_data(p_size.width, p_size.height, false, Image::FORMAT_RGBAF, data); for (int i = 0; i < p_size.width; i++) { for (int j = 0; j < p_size.height; j++) { Color c = img->get_pixel(i, j); @@ -1144,6 +1053,8 @@ void SkyRD::setup(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const P ERR_FAIL_COND(!shader_data); + material->set_as_used(); + // Invalidate supbass buffers if screen size changes if (sky->screen_size != p_screen_size) { sky->screen_size = p_screen_size; @@ -1544,6 +1455,8 @@ void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth ERR_FAIL_COND(!shader_data); + material->set_as_used(); + Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env); sky_transform.invert(); @@ -1641,6 +1554,8 @@ void SkyRD::update_res_buffers(RID p_env, uint32_t p_view_count, const Projectio ERR_FAIL_COND(!shader_data); + material->set_as_used(); + Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env); sky_transform.invert(); @@ -1663,7 +1578,7 @@ void SkyRD::update_res_buffers(RID p_env, uint32_t p_view_count, const Projectio projections = &camera; } - sky_transform = p_transform.basis * sky_transform; + sky_transform = sky_transform * p_transform.basis; if (shader_data->uses_quarter_res) { PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES]; @@ -1734,6 +1649,8 @@ void SkyRD::draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_vie ERR_FAIL_COND(!shader_data); + material->set_as_used(); + Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env); sky_transform.invert(); @@ -1756,7 +1673,7 @@ void SkyRD::draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_vie projections = &camera; } - sky_transform = p_transform.basis * sky_transform; + sky_transform = sky_transform * p_transform.basis; PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_BACKGROUND_MULTIVIEW : SKY_VERSION_BACKGROUND]; diff --git a/servers/rendering/renderer_rd/environment/sky.h b/servers/rendering/renderer_rd/environment/sky.h index 45c4f9bda7..607339b24e 100644 --- a/servers/rendering/renderer_rd/environment/sky.h +++ b/servers/rendering/renderer_rd/environment/sky.h @@ -112,15 +112,12 @@ private: RID version; PipelineCacheRD pipelines[SKY_VERSION_MAX]; - HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size = 0; - String path; String code; - HashMap<StringName, HashMap<int, RID>> default_texture_params; bool uses_time = false; bool uses_position = false; @@ -129,14 +126,8 @@ private: bool uses_light = false; virtual void set_code(const String &p_Code); - virtual void set_path_hint(const String &p_hint); - virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); - virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; - virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; - virtual Variant get_default_parameter(const StringName &p_parameter) const; virtual RS::ShaderNativeSourceCode get_native_source_code() const; SkyShaderData() {} diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 84d2ad328c..c853ae6c69 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -348,6 +348,7 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p #endif material_uniform_set = surf->material_uniform_set; shader = surf->shader; + surf->material->set_as_used(); #ifdef DEBUG_ENABLED } #endif @@ -754,7 +755,7 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, i bool cant_repeat = instance_data.flags & INSTANCE_DATA_FLAG_MULTIMESH || inst->mesh_instance.is_valid(); - if (prev_surface != nullptr && !cant_repeat && prev_surface->sort.sort_key1 == surface->sort.sort_key1 && prev_surface->sort.sort_key2 == surface->sort.sort_key2 && repeats < RenderElementInfo::MAX_REPEATS) { + if (prev_surface != nullptr && !cant_repeat && prev_surface->sort.sort_key1 == surface->sort.sort_key1 && prev_surface->sort.sort_key2 == surface->sort.sort_key2 && inst->mirror == prev_surface->owner->mirror && repeats < RenderElementInfo::MAX_REPEATS) { //this element is the same as the previous one, count repeats to draw it using instancing repeats++; } else { @@ -940,12 +941,13 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con // LOD if (p_render_data->scene_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) { - //lod - Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_render_data->scene_data->lod_camera_plane.normal); - Vector3 lod_support_max = inst->transformed_aabb.get_support(p_render_data->scene_data->lod_camera_plane.normal); + // Get the LOD support points on the mesh AABB. + Vector3 lod_support_min = inst->transformed_aabb.get_support(p_render_data->scene_data->cam_transform.basis.get_column(Vector3::AXIS_Z)); + Vector3 lod_support_max = inst->transformed_aabb.get_support(-p_render_data->scene_data->cam_transform.basis.get_column(Vector3::AXIS_Z)); - float distance_min = p_render_data->scene_data->lod_camera_plane.distance_to(lod_support_min); - float distance_max = p_render_data->scene_data->lod_camera_plane.distance_to(lod_support_max); + // Get the distances to those points on the AABB from the camera origin. + float distance_min = (float)p_render_data->scene_data->cam_transform.origin.distance_to(lod_support_min); + float distance_max = (float)p_render_data->scene_data->cam_transform.origin.distance_to(lod_support_max); float distance = 0.0; @@ -962,8 +964,8 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con distance = 1.0; } - uint32_t indices; - surf->sort.lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, &indices); + uint32_t indices = 0; + surf->sort.lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, indices); if (p_render_data->render_info) { indices = _indices_to_primitives(surf->primitive, indices); if (p_render_list == RENDER_LIST_OPAQUE) { //opaque @@ -1445,7 +1447,7 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo } //full barrier here, we need raster, transfer and compute and it depends from the previous work - RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL, RD::BARRIER_MASK_ALL); + RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL_BARRIERS, RD::BARRIER_MASK_ALL_BARRIERS); if (current_cluster_builder) { current_cluster_builder->begin(p_render_data->scene_data->cam_transform, p_render_data->scene_data->cam_projection, !p_render_data->reflection_probe.is_valid()); @@ -1621,7 +1623,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co bool using_ssr = false; bool using_sdfgi = false; bool using_voxelgi = false; - bool reverse_cull = false; + bool reverse_cull = p_render_data->scene_data->cam_transform.basis.determinant() < 0; bool using_ssil = p_render_data->environment.is_valid() && environment_get_ssil_enabled(p_render_data->environment); if (rb.is_valid()) { @@ -1764,6 +1766,10 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co draw_sky = true; } break; case RS::ENV_BG_CANVAS: { + if (rb.is_valid()) { + RID texture = RendererRD::TextureStorage::get_singleton()->render_target_get_rd_texture(rb->get_render_target()); + copy_effects->copy_to_fb_rect(texture, color_only_framebuffer, Rect2i(), false, false, false, false, RID(), false, false, true); + } keep_color = true; } break; case RS::ENV_BG_KEEP: { @@ -1830,7 +1836,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, RID()); bool finish_depth = using_ssao || using_sdfgi || using_voxelgi; - RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, 0, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_camera_plane, p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); + RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, 0, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); _render_list_with_threads(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear); RD::get_singleton()->draw_command_end_label(); @@ -1900,7 +1906,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co } } - RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, PASS_MODE_COLOR, color_pass_flags, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_camera_plane, p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); + RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, PASS_MODE_COLOR, color_pass_flags, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); _render_list_with_threads(&render_list_params, color_framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); if (will_continue_color && using_separate_specular) { // close the specular framebuffer, as it's no longer used @@ -2021,7 +2027,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co { uint32_t transparent_color_pass_flags = (color_pass_flags | COLOR_PASS_FLAG_TRANSPARENT) & ~(COLOR_PASS_FLAG_SEPARATE_SPECULAR); RID alpha_framebuffer = rb_data.is_valid() ? rb_data->get_color_pass_fb(transparent_color_pass_flags) : color_only_framebuffer; - RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR, transparent_color_pass_flags, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_camera_plane, p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); + RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR, transparent_color_pass_flags, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); _render_list_with_threads(&render_list_params, alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ); } @@ -2307,10 +2313,11 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page scene_data.view_projection[0] = p_projection; scene_data.z_far = p_zfar; scene_data.z_near = 0.0; - scene_data.lod_camera_plane = p_camera_plane; scene_data.lod_distance_multiplier = p_lod_distance_multiplier; scene_data.dual_paraboloid_side = p_use_dp_flip ? -1 : 1; scene_data.opaque_prepass_threshold = 0.1f; + scene_data.time = time; + scene_data.time_step = time_step; RenderDataRD render_data; render_data.scene_data = &scene_data; @@ -2378,7 +2385,7 @@ void RenderForwardClustered::_render_shadow_end(uint32_t p_barrier) { for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) { SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i]; - RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, 0, true, false, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER); + RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, 0, true, false, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER); _render_list_with_threads(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, shadow_pass.final_depth_action, Vector<Color>(), 1.0, 0, shadow_pass.rect); } @@ -2401,6 +2408,8 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con scene_data.z_far = p_cam_projection.get_z_far(); scene_data.dual_paraboloid_side = 0; scene_data.opaque_prepass_threshold = 0.0; + scene_data.time = time; + scene_data.time_step = time_step; RenderDataRD render_data; render_data.scene_data = &scene_data; @@ -2443,6 +2452,8 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform scene_data.material_uv2_mode = false; scene_data.opaque_prepass_threshold = 0.0f; scene_data.emissive_exposure_normalization = p_exposure_normalization; + scene_data.time = time; + scene_data.time_step = time_step; RenderDataRD render_data; render_data.scene_data = &scene_data; @@ -3083,7 +3094,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 19; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID vfog = RID(); + RID vfog; if (rb_data.is_valid() && rb->has_custom_data(RB_SCOPE_FOG)) { Ref<RendererRD::Fog::VolumetricFog> fog = rb->get_custom_data(RB_SCOPE_FOG); vfog = fog->fog_map; @@ -3349,7 +3360,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet SceneShaderForwardClustered::MaterialData *material_shadow = nullptr; void *surface_shadow = nullptr; - if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_position && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass && !p_material->shader_data->uses_alpha_clip && p_material->shader_data->cull_mode == SceneShaderForwardClustered::ShaderData::CULL_BACK) { + if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_position && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass && !p_material->shader_data->uses_alpha_clip && p_material->shader_data->cull_mode == SceneShaderForwardClustered::ShaderData::CULL_BACK && !p_material->shader_data->uses_point_size) { flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SHARED_SHADOW_MATERIAL; material_shadow = static_cast<SceneShaderForwardClustered::MaterialData *>(RendererRD::MaterialStorage::get_singleton()->material_get_data(scene_shader.default_material, RendererRD::MaterialStorage::SHADER_TYPE_3D)); @@ -3368,6 +3379,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet sdcache->flags = flags; sdcache->shader = p_material->shader_data; + sdcache->material = p_material; sdcache->material_uniform_set = p_material->uniform_set; sdcache->surface = mesh_storage->mesh_get_surface(p_mesh, p_surface); sdcache->primitive = mesh_storage->mesh_surface_get_primitive(sdcache->surface); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index 55f1ef01af..a5e8bb76d9 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -206,15 +206,14 @@ class RenderForwardClustered : public RendererSceneRenderRD { RID render_pass_uniform_set; bool force_wireframe = false; Vector2 uv_offset; - Plane lod_plane; float lod_distance_multiplier = 0.0; float screen_mesh_lod_threshold = 0.0; RD::FramebufferFormatID framebuffer_format = 0; uint32_t element_offset = 0; - uint32_t barrier = RD::BARRIER_MASK_ALL; + uint32_t barrier = RD::BARRIER_MASK_ALL_BARRIERS; bool use_directional_soft_shadow = false; - RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, uint32_t p_color_pass_flags, bool p_no_gi, bool p_use_directional_soft_shadows, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) { + RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, uint32_t p_color_pass_flags, bool p_no_gi, bool p_use_directional_soft_shadows, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS) { elements = p_elements; element_info = p_element_info; element_count = p_element_count; @@ -226,7 +225,6 @@ class RenderForwardClustered : public RendererSceneRenderRD { render_pass_uniform_set = p_render_pass_uniform_set; force_wireframe = p_force_wireframe; uv_offset = p_uv_offset; - lod_plane = p_lod_plane; lod_distance_multiplier = p_lod_distance_multiplier; screen_mesh_lod_threshold = p_screen_mesh_lod_threshold; element_offset = p_element_offset; @@ -443,6 +441,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { void *surface = nullptr; RID material_uniform_set; SceneShaderForwardClustered::ShaderData *shader = nullptr; + SceneShaderForwardClustered::MaterialData *material = nullptr; void *surface_shadow = nullptr; RID material_uniform_set_shadow; @@ -598,7 +597,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { void _render_shadow_begin(); void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr); void _render_shadow_process(); - void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL); + void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS); /* Render Scene */ void _process_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection); diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index c01919a606..6abf41a76f 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -37,10 +37,6 @@ using namespace RendererSceneRenderImplementation; -void SceneShaderForwardClustered::ShaderData::set_path_hint(const String &p_path) { - path = p_path; -} - void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { //compile @@ -115,6 +111,9 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { actions.usage_flag_pointers["ALPHA"] = &uses_alpha; actions.usage_flag_pointers["ALPHA_SCISSOR_THRESHOLD"] = &uses_alpha_clip; + // Use alpha clip pipeline for alpha hash/dither. + // This prevents sorting issues inherent to alpha blending and allows such materials to cast shadows. + actions.usage_flag_pointers["ALPHA_HASH_SCALE"] = &uses_alpha_clip; actions.render_mode_flags["depth_prepass_alpha"] = &uses_depth_pre_pass; actions.usage_flag_pointers["SSS_STRENGTH"] = &uses_sss; @@ -151,6 +150,8 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { depth_test = DepthTest(depth_testi); cull_mode = Cull(cull_modei); uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps; + uses_vertex_time = gen_code.uses_vertex_time; + uses_fragment_time = gen_code.uses_fragment_time; #if 0 print_line("**compiling shader:"); @@ -375,102 +376,16 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { valid = true; } -void SceneShaderForwardClustered::ShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { - if (!p_texture.is_valid()) { - if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { - default_texture_params[p_name].erase(p_index); - - if (default_texture_params[p_name].is_empty()) { - default_texture_params.erase(p_name); - } - } - } else { - if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = HashMap<int, RID>(); - } - default_texture_params[p_name][p_index] = p_texture; - } -} - -void SceneShaderForwardClustered::ShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { - HashMap<int, StringName> order; - - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL || - E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE || - E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE || - E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) { - // Don't expose any of these. - continue; - } - - if (E.value.texture_order >= 0) { - order[E.value.texture_order + 100000] = E.key; - } else { - order[E.value.order] = E.key; - } - } - - String last_group; - for (const KeyValue<int, StringName> &E : order) { - String group = uniforms[E.value].group; - if (!uniforms[E.value].subgroup.is_empty()) { - group += "::" + uniforms[E.value].subgroup; - } - - if (group != last_group) { - PropertyInfo pi; - pi.usage = PROPERTY_USAGE_GROUP; - pi.name = group; - p_param_list->push_back(pi); - - last_group = group; - } - - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); - pi.name = E.value; - p_param_list->push_back(pi); - } -} - -void SceneShaderForwardClustered::ShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - RendererMaterialStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E.value); - p.info.name = E.key; //supply name - p.index = E.value.instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); - p_param_list->push_back(p); - } -} - -bool SceneShaderForwardClustered::ShaderData::is_parameter_texture(const StringName &p_param) const { - if (!uniforms.has(p_param)) { - return false; - } - - return uniforms[p_param].texture_order >= 0; -} - bool SceneShaderForwardClustered::ShaderData::is_animated() const { - return false; + return (uses_fragment_time && uses_discard) || (uses_vertex_time && uses_vertex); } bool SceneShaderForwardClustered::ShaderData::casts_shadows() const { - return false; -} + bool has_read_screen_alpha = uses_screen_texture || uses_depth_texture || uses_normal_texture; + bool has_base_alpha = (uses_alpha && !uses_alpha_clip) || has_read_screen_alpha; + bool has_alpha = has_base_alpha || uses_blend_alpha; -Variant SceneShaderForwardClustered::ShaderData::get_default_parameter(const StringName &p_parameter) const { - if (uniforms.has(p_parameter)) { - ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; - Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; - return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); - } - return Variant(); + return !has_alpha || (uses_depth_pre_pass && !(depth_draw == DEPTH_DRAW_DISABLED || depth_test == DEPTH_TEST_DISABLED)); } RS::ShaderNativeSourceCode SceneShaderForwardClustered::ShaderData::get_native_source_code() const { @@ -697,10 +612,11 @@ void SceneShaderForwardClustered::init(const String p_defines) { actions.renames["CUSTOM3"] = "custom3_attrib"; actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB"; - actions.renames["NODE_POSITION_WORLD"] = "model_matrix[3].xyz"; + actions.renames["NODE_POSITION_WORLD"] = "read_model_matrix[3].xyz"; actions.renames["CAMERA_POSITION_WORLD"] = "scene_data.inv_view_matrix[3].xyz"; actions.renames["CAMERA_DIRECTION_WORLD"] = "scene_data.view_matrix[3].xyz"; - actions.renames["NODE_POSITION_VIEW"] = "(model_matrix * scene_data.view_matrix)[3].xyz"; + actions.renames["CAMERA_VISIBLE_LAYERS"] = "scene_data.camera_visible_layers"; + actions.renames["NODE_POSITION_VIEW"] = "(read_model_matrix * scene_data.view_matrix)[3].xyz"; actions.renames["VIEW_INDEX"] = "ViewIndex"; actions.renames["VIEW_MONO_LEFT"] = "0"; diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h index a9a9fa94de..51e4dd44d5 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h @@ -139,19 +139,15 @@ public: PipelineCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][PIPELINE_VERSION_MAX]; PipelineCacheRD color_pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][PIPELINE_COLOR_PASS_FLAG_COUNT]; - String path; - - HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size = 0; String code; - HashMap<StringName, HashMap<int, RID>> default_texture_params; - DepthDraw depth_draw; - DepthTest depth_test; + DepthDraw depth_draw = DEPTH_DRAW_OPAQUE; + DepthTest depth_test = DEPTH_TEST_ENABLED; bool uses_point_size = false; bool uses_alpha = false; @@ -172,6 +168,8 @@ public: bool uses_depth_texture = false; bool uses_normal_texture = false; bool uses_time = false; + bool uses_vertex_time = false; + bool uses_fragment_time = false; bool writes_modelview_or_projection = false; bool uses_world_coordinates = false; bool uses_screen_texture_mipmaps = false; @@ -181,15 +179,9 @@ public: uint32_t index = 0; virtual void set_code(const String &p_Code); - virtual void set_path_hint(const String &p_path); - virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); - virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; - void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; - virtual Variant get_default_parameter(const StringName &p_parameter) const; virtual RS::ShaderNativeSourceCode get_native_source_code() const; SelfList<ShaderData> shader_list_element; diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 2b2090f8ed..350a5eb0e4 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -70,17 +70,17 @@ void RenderForwardMobile::ForwardIDStorageMobile::map_forward_id(RendererRD::For void RenderForwardMobile::ForwardIDStorageMobile::fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, uint32_t &spec_constants, const GeometryInstanceForwardMobile *p_instance) { // first zero out our indices - p_push_constant->omni_lights[0] = 0xFFFF; - p_push_constant->omni_lights[1] = 0xFFFF; + p_push_constant->omni_lights[0] = 0xFFFFFFFF; + p_push_constant->omni_lights[1] = 0xFFFFFFFF; - p_push_constant->spot_lights[0] = 0xFFFF; - p_push_constant->spot_lights[1] = 0xFFFF; + p_push_constant->spot_lights[0] = 0xFFFFFFFF; + p_push_constant->spot_lights[1] = 0xFFFFFFFF; - p_push_constant->decals[0] = 0xFFFF; - p_push_constant->decals[1] = 0xFFFF; + p_push_constant->decals[0] = 0xFFFFFFFF; + p_push_constant->decals[1] = 0xFFFFFFFF; - p_push_constant->reflection_probes[0] = 0xFFFF; - p_push_constant->reflection_probes[1] = 0xFFFF; + p_push_constant->reflection_probes[0] = 0xFFFFFFFF; + p_push_constant->reflection_probes[1] = 0xFFFFFFFF; if (p_instance->omni_light_count == 0) { spec_constants |= 1 << SPEC_CONSTANT_DISABLE_OMNI_LIGHTS; @@ -612,7 +612,7 @@ void RenderForwardMobile::_pre_opaque_render(RenderDataRD *p_render_data) { } //full barrier here, we need raster, transfer and compute and it depends from the previous work - RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL, RD::BARRIER_MASK_ALL); + RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL_BARRIERS, RD::BARRIER_MASK_ALL_BARRIERS); bool using_shadows = true; @@ -673,7 +673,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color Size2i screen_size; RID framebuffer; - bool reverse_cull = false; + bool reverse_cull = p_render_data->scene_data->cam_transform.basis.determinant() < 0; bool using_subpass_transparent = true; bool using_subpass_post_process = true; @@ -796,6 +796,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color draw_sky = true; } break; case RS::ENV_BG_CANVAS: { + if (rb.is_valid()) { + RID dest_framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_ONE_PASS); + RID texture = RendererRD::TextureStorage::get_singleton()->render_target_get_rd_texture(rb->get_render_target()); + copy_effects->copy_to_fb_rect(texture, dest_framebuffer, Rect2i(), false, false, false, false, RID(), false, false, true); + } keep_color = true; } break; case RS::ENV_BG_KEEP: { @@ -916,7 +921,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color } RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer); - RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_camera_plane, p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); + RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); render_list_params.framebuffer_format = fb_format; if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time @@ -960,7 +965,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (!using_subpass_transparent) { // We're done with our subpasses so end our container pass - RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL); + RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL_BARRIERS); RD::get_singleton()->draw_command_end_label(); // Render 3D Pass / Render Reflection Probe Pass } @@ -983,7 +988,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (using_subpass_transparent) { RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer); - RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR_TRANSPARENT, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_camera_plane, p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); + RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR_TRANSPARENT, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); render_list_params.framebuffer_format = fb_format; if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time @@ -1012,7 +1017,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color RD::get_singleton()->draw_command_end_label(); // Render 3D Pass / Render Reflection Probe Pass - RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL); + RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL_BARRIERS); } else { RENDER_TIMESTAMP("Render Transparent"); @@ -1022,7 +1027,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color // _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false); RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer); - RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_camera_plane, p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); + RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); render_list_params.framebuffer_format = fb_format; if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time @@ -1032,12 +1037,12 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RenderForwardMobile::_render_list_thread_function, &render_list_params, thread_draw_lists.size(), -1, true, SNAME("ForwardMobileRenderSubpass")); WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); - RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL); + RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL_BARRIERS); } else { //single threaded RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ); _render_list(draw_list, fb_format, &render_list_params, 0, render_list_params.element_count); - RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL); + RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL_BARRIERS); } RD::get_singleton()->draw_command_end_label(); // Render Transparent Subpass @@ -1266,10 +1271,11 @@ void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedAr scene_data.view_projection[0] = p_projection; scene_data.z_near = 0.0; scene_data.z_far = p_zfar; - scene_data.lod_camera_plane = p_camera_plane; scene_data.lod_distance_multiplier = p_lod_distance_multiplier; scene_data.dual_paraboloid_side = p_use_dp_flip ? -1 : 1; scene_data.opaque_prepass_threshold = 0.1; + scene_data.time = time; + scene_data.time_step = time_step; RenderDataRD render_data; render_data.scene_data = &scene_data; @@ -1335,7 +1341,7 @@ void RenderForwardMobile::_render_shadow_end(uint32_t p_barrier) { for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) { SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i]; - RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, shadow_pass.rp_uniform_set, 0, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER); + RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, shadow_pass.rp_uniform_set, 0, false, Vector2(), shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER); _render_list_with_threads(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, shadow_pass.final_depth_action, Vector<Color>(), 1.0, 0, shadow_pass.rect); } @@ -1362,6 +1368,8 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c scene_data.material_uv2_mode = false; scene_data.opaque_prepass_threshold = 0.0f; scene_data.emissive_exposure_normalization = p_exposure_normalization; + scene_data.time = time; + scene_data.time_step = time_step; RenderDataRD render_data; render_data.scene_data = &scene_data; @@ -1485,6 +1493,8 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const scene_data.z_far = p_cam_projection.get_z_far(); scene_data.dual_paraboloid_side = 0; scene_data.opaque_prepass_threshold = 0.0; + scene_data.time = time; + scene_data.time_step = time_step; RenderDataRD render_data; render_data.scene_data = &scene_data; @@ -1808,12 +1818,13 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const // LOD if (p_render_data->scene_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) { - //lod - Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_render_data->scene_data->lod_camera_plane.normal); - Vector3 lod_support_max = inst->transformed_aabb.get_support(p_render_data->scene_data->lod_camera_plane.normal); + // Get the LOD support points on the mesh AABB. + Vector3 lod_support_min = inst->transformed_aabb.get_support(p_render_data->scene_data->cam_transform.basis.get_column(Vector3::AXIS_Z)); + Vector3 lod_support_max = inst->transformed_aabb.get_support(-p_render_data->scene_data->cam_transform.basis.get_column(Vector3::AXIS_Z)); - float distance_min = p_render_data->scene_data->lod_camera_plane.distance_to(lod_support_min); - float distance_max = p_render_data->scene_data->lod_camera_plane.distance_to(lod_support_max); + // Get the distances to those points on the AABB from the camera origin. + float distance_min = (float)p_render_data->scene_data->cam_transform.origin.distance_to(lod_support_min); + float distance_max = (float)p_render_data->scene_data->cam_transform.origin.distance_to(lod_support_max); float distance = 0.0; @@ -1830,8 +1841,8 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const distance = 1.0; } - uint32_t indices; - surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, &indices); + uint32_t indices = 0; + surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, indices); if (p_render_data->render_info) { indices = _indices_to_primitives(surf->primitive, indices); if (p_render_list == RENDER_LIST_OPAQUE) { //opaque @@ -2004,6 +2015,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr RID prev_index_array_rd; RID prev_pipeline_rd; RID prev_xforms_uniform_set; + bool should_request_redraw = false; bool shadow_pass = (p_params->pass_mode == PASS_MODE_SHADOW) || (p_params->pass_mode == PASS_MODE_SHADOW_DP); @@ -2080,6 +2092,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr #endif material_uniform_set = surf->material_uniform_set; shader = surf->shader; + surf->material->set_as_used(); #ifdef DEBUG_ENABLED } #endif @@ -2090,6 +2103,11 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr continue; } + //request a redraw if one of the shaders uses TIME + if (shader->uses_time) { + should_request_redraw = true; + } + //find cull variant SceneShaderForwardMobile::ShaderData::CullVariant cull_variant; @@ -2191,6 +2209,11 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instance_count); } + + // Make the actual redraw request + if (should_request_redraw) { + RenderingServerDefault::redraw_request(); + } } /* Geometry instance */ @@ -2385,6 +2408,7 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI sdcache->flags = flags; sdcache->shader = p_material->shader_data; + sdcache->material = p_material; sdcache->material_uniform_set = p_material->uniform_set; sdcache->surface = mesh_storage->mesh_get_surface(p_mesh, p_surface); sdcache->primitive = mesh_storage->mesh_surface_get_primitive(sdcache->surface); diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index 415bd79ad6..0f5a229d61 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -163,16 +163,15 @@ private: RID render_pass_uniform_set; bool force_wireframe = false; Vector2 uv_offset; - Plane lod_plane; uint32_t spec_constant_base_flags = 0; float lod_distance_multiplier = 0.0; float screen_mesh_lod_threshold = 0.0; RD::FramebufferFormatID framebuffer_format = 0; uint32_t element_offset = 0; - uint32_t barrier = RD::BARRIER_MASK_ALL; + uint32_t barrier = RD::BARRIER_MASK_ALL_BARRIERS; uint32_t subpass = 0; - RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, RID p_render_pass_uniform_set, uint32_t p_spec_constant_base_flags = 0, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) { + RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, RID p_render_pass_uniform_set, uint32_t p_spec_constant_base_flags = 0, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS) { elements = p_elements; element_info = p_element_info; element_count = p_element_count; @@ -183,7 +182,6 @@ private: render_pass_uniform_set = p_render_pass_uniform_set; force_wireframe = p_force_wireframe; uv_offset = p_uv_offset; - lod_plane = p_lod_plane; lod_distance_multiplier = p_lod_distance_multiplier; screen_mesh_lod_threshold = p_screen_mesh_lod_threshold; element_offset = p_element_offset; @@ -198,7 +196,7 @@ private: void _render_shadow_begin(); void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr); void _render_shadow_process(); - void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL); + void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS); /* Render Scene */ @@ -442,6 +440,7 @@ protected: void *surface = nullptr; RID material_uniform_set; SceneShaderForwardMobile::ShaderData *shader = nullptr; + SceneShaderForwardMobile::MaterialData *material = nullptr; void *surface_shadow = nullptr; RID material_uniform_set_shadow; diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index 71fb3ee4f5..224bb34189 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -39,10 +39,6 @@ using namespace RendererSceneRenderImplementation; /* ShaderData */ -void SceneShaderForwardMobile::ShaderData::set_path_hint(const String &p_path) { - path = p_path; -} - void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { //compile @@ -116,6 +112,9 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { actions.usage_flag_pointers["ALPHA"] = &uses_alpha; actions.usage_flag_pointers["ALPHA_SCISSOR_THRESHOLD"] = &uses_alpha_clip; + // Use alpha clip pipeline for alpha hash/dither. + // This prevents sorting issues inherent to alpha blending and allows such materials to cast shadows. + actions.usage_flag_pointers["ALPHA_HASH_SCALE"] = &uses_alpha_clip; actions.render_mode_flags["depth_prepass_alpha"] = &uses_depth_pre_pass; // actions.usage_flag_pointers["SSS_STRENGTH"] = &uses_sss; @@ -150,6 +149,8 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { depth_draw = DepthDraw(depth_drawi); depth_test = DepthTest(depth_testi); + uses_vertex_time = gen_code.uses_vertex_time; + uses_fragment_time = gen_code.uses_fragment_time; #if 0 print_line("**compiling shader:"); @@ -331,101 +332,16 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { valid = true; } -void SceneShaderForwardMobile::ShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { - if (!p_texture.is_valid()) { - if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { - default_texture_params[p_name].erase(p_index); - - if (default_texture_params[p_name].is_empty()) { - default_texture_params.erase(p_name); - } - } - } else { - if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = HashMap<int, RID>(); - } - default_texture_params[p_name][p_index] = p_texture; - } -} - -void SceneShaderForwardMobile::ShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { - HashMap<int, StringName> order; - - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL || - E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE || - E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE || - E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) { - continue; - } - - if (E.value.texture_order >= 0) { - order[E.value.texture_order + 100000] = E.key; - } else { - order[E.value.order] = E.key; - } - } - - String last_group; - for (const KeyValue<int, StringName> &E : order) { - String group = uniforms[E.value].group; - if (!uniforms[E.value].subgroup.is_empty()) { - group += "::" + uniforms[E.value].subgroup; - } - - if (group != last_group) { - PropertyInfo pi; - pi.usage = PROPERTY_USAGE_GROUP; - pi.name = group; - p_param_list->push_back(pi); - - last_group = group; - } - - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); - pi.name = E.value; - p_param_list->push_back(pi); - } -} - -void SceneShaderForwardMobile::ShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - RendererMaterialStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E.value); - p.info.name = E.key; //supply name - p.index = E.value.instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); - p_param_list->push_back(p); - } -} - -bool SceneShaderForwardMobile::ShaderData::is_parameter_texture(const StringName &p_param) const { - if (!uniforms.has(p_param)) { - return false; - } - - return uniforms[p_param].texture_order >= 0; -} - bool SceneShaderForwardMobile::ShaderData::is_animated() const { - return false; + return (uses_fragment_time && uses_discard) || (uses_vertex_time && uses_vertex); } bool SceneShaderForwardMobile::ShaderData::casts_shadows() const { - return false; -} + bool has_read_screen_alpha = uses_screen_texture || uses_depth_texture || uses_normal_texture; + bool has_base_alpha = (uses_alpha && !uses_alpha_clip) || has_read_screen_alpha; + bool has_alpha = has_base_alpha || uses_blend_alpha; -Variant SceneShaderForwardMobile::ShaderData::get_default_parameter(const StringName &p_parameter) const { - if (uniforms.has(p_parameter)) { - ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; - Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; - return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); - } - return Variant(); + return !has_alpha || (uses_depth_pre_pass && !(depth_draw == DEPTH_DRAW_DISABLED || depth_test == DEPTH_TEST_DISABLED)); } RS::ShaderNativeSourceCode SceneShaderForwardMobile::ShaderData::get_native_source_code() const { @@ -597,10 +513,11 @@ void SceneShaderForwardMobile::init(const String p_defines) { actions.renames["CUSTOM3"] = "custom3_attrib"; actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB"; - actions.renames["NODE_POSITION_WORLD"] = "model_matrix[3].xyz"; + actions.renames["NODE_POSITION_WORLD"] = "read_model_matrix[3].xyz"; actions.renames["CAMERA_POSITION_WORLD"] = "scene_data.inv_view_matrix[3].xyz"; actions.renames["CAMERA_DIRECTION_WORLD"] = "scene_data.view_matrix[3].xyz"; - actions.renames["NODE_POSITION_VIEW"] = "(model_matrix * scene_data.view_matrix)[3].xyz"; + actions.renames["CAMERA_VISIBLE_LAYERS"] = "scene_data.camera_visible_layers"; + actions.renames["NODE_POSITION_VIEW"] = "(read_model_matrix * scene_data.view_matrix)[3].xyz"; actions.renames["VIEW_INDEX"] = "ViewIndex"; actions.renames["VIEW_MONO_LEFT"] = "0"; diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h index f67665a02f..18a897a9e9 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h @@ -100,16 +100,12 @@ public: uint32_t vertex_input_mask = 0; PipelineCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][SHADER_VERSION_MAX]; - String path; - - HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size = 0; String code; - HashMap<StringName, HashMap<int, RID>> default_texture_params; DepthDraw depth_draw; DepthTest depth_test; @@ -132,6 +128,8 @@ public: bool uses_depth_texture = false; bool uses_normal_texture = false; bool uses_time = false; + bool uses_vertex_time = false; + bool uses_fragment_time = false; bool writes_modelview_or_projection = false; bool uses_world_coordinates = false; @@ -139,16 +137,8 @@ public: uint32_t index = 0; virtual void set_code(const String &p_Code); - virtual void set_path_hint(const String &p_path); - - virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); - virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; - void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - - virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; - virtual Variant get_default_parameter(const StringName &p_parameter) const; virtual RS::ShaderNativeSourceCode get_native_source_code() const; SelfList<ShaderData> shader_list_element; diff --git a/servers/rendering/renderer_rd/framebuffer_cache_rd.h b/servers/rendering/renderer_rd/framebuffer_cache_rd.h index f50d6baa30..8cf25cf44a 100644 --- a/servers/rendering/renderer_rd/framebuffer_cache_rd.h +++ b/servers/rendering/renderer_rd/framebuffer_cache_rd.h @@ -254,11 +254,11 @@ public: RID get_cache_multipass(const Vector<RID> &p_textures, const Vector<RD::FramebufferPass> &p_passes, uint32_t p_views = 1) { uint32_t h = hash_murmur3_one_32(p_views); - h = hash_murmur3_one_32(p_textures.size()); + h = hash_murmur3_one_32(p_textures.size(), h); for (int i = 0; i < p_textures.size(); i++) { h = hash_murmur3_one_64(p_textures[i].get_id(), h); } - h = hash_murmur3_one_32(p_passes.size()); + h = hash_murmur3_one_32(p_passes.size(), h); for (int i = 0; i < p_passes.size(); i++) { h = _hash_pass(p_passes[i], h); } diff --git a/servers/rendering/renderer_rd/pipeline_cache_rd.cpp b/servers/rendering/renderer_rd/pipeline_cache_rd.cpp index 9151c53823..7a2336970b 100644 --- a/servers/rendering/renderer_rd/pipeline_cache_rd.cpp +++ b/servers/rendering/renderer_rd/pipeline_cache_rd.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "pipeline_cache_rd.h" + #include "core/os/memory.h" RID PipelineCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe, uint32_t p_render_pass, uint32_t p_bool_specializations) { @@ -70,9 +71,7 @@ RID PipelineCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD } void PipelineCacheRD::_clear() { -#ifndef _MSC_VER -#warning Clear should probably recompile all the variants already compiled instead to avoid stalls? needs discussion -#endif + // TODO: Clear should probably recompile all the variants already compiled instead to avoid stalls? Needs discussion. if (versions) { for (uint32_t i = 0; i < version_count; i++) { //shader may be gone, so this may not be valid diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 4c14ef7b9e..f7302adbf6 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -398,7 +398,7 @@ void RendererCanvasRenderRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RI r_last_texture = p_texture; } -void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, PipelineVariants *p_pipeline_variants) { +void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, PipelineVariants *p_pipeline_variants, bool &r_sdf_used) { //create an empty push constant RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton(); @@ -706,7 +706,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend //bind textures - _bind_canvas_texture(p_draw_list, RID(), current_filter, current_repeat, last_texture, push_constant, texpixel_size); + _bind_canvas_texture(p_draw_list, primitive->texture, current_filter, current_repeat, last_texture, push_constant, texpixel_size); RD::get_singleton()->draw_list_bind_index_array(p_draw_list, primitive_arrays.index_array[MIN(3u, primitive->point_count) - 1]); @@ -796,7 +796,6 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend RenderingServerDefault::redraw_request(); // active particles means redraw request - bool local_coords = true; int dpc = particles_storage->particles_get_draw_passes(pt->particles); if (dpc == 0) { break; //nothing to draw @@ -818,12 +817,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend if (particles_storage->particles_has_collision(pt->particles) && texture_storage->render_target_is_sdf_enabled(p_render_target)) { //pass collision information - Transform2D xform; - if (local_coords) { - xform = p_item->final_transform; - } else { - xform = p_canvas_transform_inverse; - } + Transform2D xform = p_item->final_transform; RID sdf_texture = texture_storage->render_target_get_sdf_texture(p_render_target); @@ -839,6 +833,9 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend } else { particles_storage->particles_set_canvas_sdf_collision(pt->particles, false, Transform2D(), Rect2(), RID()); } + + // Signal that SDF texture needs to be updated. + r_sdf_used |= particles_storage->particles_has_collision(pt->particles); } if (mesh.is_null()) { @@ -1051,7 +1048,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo return uniform_set; } -void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer) { +void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); @@ -1075,10 +1072,7 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co clear_colors.push_back(texture_storage->render_target_get_clear_request_color(p_to_render_target)); texture_storage->render_target_disable_clear_request(p_to_render_target); } -#ifndef _MSC_VER -#warning TODO obtain from framebuffer format eventually when this is implemented -#endif - + // TODO: Obtain from framebuffer format eventually when this is implemented. fb_uniform_set = texture_storage->render_target_get_framebuffer_uniform_set(p_to_render_target); } @@ -1114,8 +1108,20 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co RID material = ci->material_owner == nullptr ? ci->material : ci->material_owner->material; - if (material.is_null() && ci->canvas_group != nullptr) { - material = default_canvas_group_material; + if (ci->canvas_group != nullptr) { + if (ci->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_AND_DRAW) { + if (!p_to_backbuffer) { + material = default_clip_children_material; + } + } else { + if (material.is_null()) { + if (ci->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_ONLY) { + material = default_clip_children_material; + } else { + material = default_canvas_group_material; + } + } + } } if (material != prev_material) { @@ -1130,6 +1136,7 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co // Update uniform set. if (material_data->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(material_data->uniform_set)) { // Material may not have a uniform set. RD::get_singleton()->draw_list_bind_uniform_set(draw_list, material_data->uniform_set, MATERIAL_UNIFORM_SET); + material_data->set_as_used(); } } else { pipeline_variants = &shader.pipeline_variants; @@ -1139,7 +1146,7 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co } } - _render_item(draw_list, p_to_render_target, ci, fb_format, canvas_transform_inverse, current_clip, p_lights, pipeline_variants); + _render_item(draw_list, p_to_render_target, ci, fb_format, canvas_transform_inverse, current_clip, p_lights, pipeline_variants, r_sdf_used); prev_material = material; } @@ -1437,13 +1444,15 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p update_skeletons = false; } - _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list); + _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used); item_count = 0; - Rect2i group_rect = ci->canvas_group_owner->global_rect_cache; - - if (ci->canvas_group_owner->canvas_group->mode == RS::CANVAS_GROUP_MODE_OPAQUE) { + if (ci->canvas_group_owner->canvas_group->mode != RS::CANVAS_GROUP_MODE_TRANSPARENT) { + Rect2i group_rect = ci->canvas_group_owner->global_rect_cache; texture_storage->render_target_copy_to_back_buffer(p_to_render_target, group_rect, false); + if (ci->canvas_group_owner->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_AND_DRAW) { + items[item_count++] = ci->canvas_group_owner; + } } else if (!backbuffer_cleared) { texture_storage->render_target_clear_back_buffer(p_to_render_target, Rect2i(), Color(0, 0, 0, 0)); backbuffer_cleared = true; @@ -1467,7 +1476,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p update_skeletons = false; } - _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, true); + _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, true); item_count = 0; if (ci->canvas_group->blur_mipmaps) { @@ -1475,6 +1484,8 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p } canvas_group_owner = nullptr; + // Backbuffer is dirty now and needs to be re-cleared if another CanvasGroup needs it. + backbuffer_cleared = false; } if (backbuffer_copy) { @@ -1484,7 +1495,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p update_skeletons = false; } - _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list); + _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used); item_count = 0; texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, backbuffer_gen_mipmaps); @@ -1510,7 +1521,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p update_skeletons = false; } - _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list); + _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, false); //then reset item_count = 0; } @@ -1621,7 +1632,7 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index, projection.set_frustum(xmin, xmax, ymin, ymax, nearp, farp); } - Vector3 cam_target = Basis(Vector3(0, 0, Math_TAU * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0)); + Vector3 cam_target = Basis::from_euler(Vector3(0, 0, Math_TAU * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0)); projection = projection * Projection(Transform3D().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse()); ShadowRenderPushConstant push_constant; @@ -1901,11 +1912,12 @@ void RendererCanvasRenderRD::occluder_polygon_set_shape(RID p_occluder, const Ve } } - //if same buffer len is being set, just use BufferSubData to avoid a pipeline flush + //if same buffer len is being set, just use buffer_update to avoid a pipeline flush if (oc->vertex_array.is_null()) { //create from scratch //vertices + // TODO: geometry is always of length lc * 6 * sizeof(float), so in doubles builds this will receive half the data it needs oc->vertex_buffer = RD::get_singleton()->vertex_buffer_create(lc * 6 * sizeof(real_t), geometry); Vector<RID> buffer; @@ -1990,10 +2002,6 @@ void RendererCanvasRenderRD::occluder_polygon_set_cull_mode(RID p_occluder, RS:: oc->cull_mode = p_mode; } -void RendererCanvasRenderRD::CanvasShaderData::set_path_hint(const String &p_path) { - path = p_path; -} - void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) { //compile @@ -2205,86 +2213,6 @@ void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) { valid = true; } -void RendererCanvasRenderRD::CanvasShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { - if (!p_texture.is_valid()) { - if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { - default_texture_params[p_name].erase(p_index); - - if (default_texture_params[p_name].is_empty()) { - default_texture_params.erase(p_name); - } - } - } else { - if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = HashMap<int, RID>(); - } - default_texture_params[p_name][p_index] = p_texture; - } -} - -void RendererCanvasRenderRD::CanvasShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { - HashMap<int, StringName> order; - - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL || - E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE || - E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE || - E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) { - // Don't expose any of these. - continue; - } - if (E.value.texture_order >= 0) { - order[E.value.texture_order + 100000] = E.key; - } else { - order[E.value.order] = E.key; - } - } - - String last_group; - for (const KeyValue<int, StringName> &E : order) { - String group = uniforms[E.value].group; - if (!uniforms[E.value].subgroup.is_empty()) { - group += "::" + uniforms[E.value].subgroup; - } - - if (group != last_group) { - PropertyInfo pi; - pi.usage = PROPERTY_USAGE_GROUP; - pi.name = group; - p_param_list->push_back(pi); - - last_group = group; - } - - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); - pi.name = E.value; - p_param_list->push_back(pi); - } -} - -void RendererCanvasRenderRD::CanvasShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - RendererMaterialStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E.value); - p.info.name = E.key; //supply name - p.index = E.value.instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); - p_param_list->push_back(p); - } -} - -bool RendererCanvasRenderRD::CanvasShaderData::is_parameter_texture(const StringName &p_param) const { - if (!uniforms.has(p_param)) { - return false; - } - - return uniforms[p_param].texture_order >= 0; -} - bool RendererCanvasRenderRD::CanvasShaderData::is_animated() const { return false; } @@ -2293,15 +2221,6 @@ bool RendererCanvasRenderRD::CanvasShaderData::casts_shadows() const { return false; } -Variant RendererCanvasRenderRD::CanvasShaderData::get_default_parameter(const StringName &p_parameter) const { - if (uniforms.has(p_parameter)) { - ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; - Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; - return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); - } - return Variant(); -} - RS::ShaderNativeSourceCode RendererCanvasRenderRD::CanvasShaderData::get_native_source_code() const { RendererCanvasRenderRD *canvas_singleton = static_cast<RendererCanvasRenderRD *>(RendererCanvasRender::singleton); return canvas_singleton->shader.canvas_shader.version_get_native_source_code(version); @@ -2667,16 +2586,6 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() { primitive_arrays.index_array[3] = shader.quad_index_array = RD::get_singleton()->index_array_create(shader.quad_index_buffer, 0, 6); } - { //default skeleton buffer - - shader.default_skeleton_uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SkeletonUniform)); - SkeletonUniform su; - _update_transform_2d_to_mat4(Transform2D(), su.skeleton_inverse); - _update_transform_2d_to_mat4(Transform2D(), su.skeleton_transform); - RD::get_singleton()->buffer_update(shader.default_skeleton_uniform_buffer, 0, sizeof(SkeletonUniform), &su); - - shader.default_skeleton_texture_buffer = RD::get_singleton()->texture_buffer_create(32, RD::DATA_FORMAT_R32G32B32A32_SFLOAT); - } { //default shadow texture to keep uniform set happy RD::TextureFormat tf; @@ -2739,6 +2648,26 @@ void fragment() { material_storage->material_set_shader(default_canvas_group_material, default_canvas_group_shader); } + { + default_clip_children_shader = material_storage->shader_allocate(); + material_storage->shader_initialize(default_clip_children_shader); + + material_storage->shader_set_code(default_clip_children_shader, R"( +// Default clip children shader. + +shader_type canvas_item; + +void fragment() { + vec4 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0); + COLOR.rgb = c.rgb; +} +)"); + default_clip_children_material = material_storage->material_allocate(); + material_storage->material_initialize(default_clip_children_material); + + material_storage->material_set_shader(default_clip_children_material, default_clip_children_shader); + } + static_assert(sizeof(PushConstant) == 128); } @@ -2790,6 +2719,9 @@ RendererCanvasRenderRD::~RendererCanvasRenderRD() { material_storage->material_free(default_canvas_group_material); material_storage->shader_free(default_canvas_group_shader); + material_storage->material_free(default_clip_children_material); + material_storage->shader_free(default_clip_children_shader); + { if (state.canvas_state_buffer.is_valid()) { RD::get_singleton()->free(state.canvas_state_buffer); @@ -2797,8 +2729,6 @@ RendererCanvasRenderRD::~RendererCanvasRenderRD() { memdelete_arr(state.light_uniforms); RD::get_singleton()->free(state.lights_uniform_buffer); - RD::get_singleton()->free(shader.default_skeleton_uniform_buffer); - RD::get_singleton()->free(shader.default_skeleton_texture_buffer); } //shadow rendering diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index 67db56d913..f809c7f046 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -144,10 +144,6 @@ class RendererCanvasRenderRD : public RendererCanvasRender { RID quad_index_array; PipelineVariants pipeline_variants; - // default_skeleton uniform set - RID default_skeleton_uniform_buffer; - RID default_skeleton_texture_buffer; - ShaderCompiler compiler; } shader; @@ -164,16 +160,13 @@ class RendererCanvasRenderRD : public RendererCanvasRender { bool valid = false; RID version; PipelineVariants pipeline_variants; - String path; - HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size = 0; String code; - HashMap<StringName, HashMap<int, RID>> default_texture_params; bool uses_screen_texture = false; bool uses_screen_texture_mipmaps = false; @@ -181,15 +174,8 @@ class RendererCanvasRenderRD : public RendererCanvasRender { bool uses_time = false; virtual void set_code(const String &p_Code); - virtual void set_path_hint(const String &p_path); - virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); - virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; - virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - - virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; - virtual Variant get_default_parameter(const StringName &p_parameter) const; virtual RS::ShaderNativeSourceCode get_native_source_code() const; CanvasShaderData() {} @@ -409,11 +395,6 @@ class RendererCanvasRenderRD : public RendererCanvasRender { uint32_t lights[4]; }; - struct SkeletonUniform { - float skeleton_transform[16]; - float skeleton_inverse[16]; - }; - Item *items[MAX_RENDER_ITEMS]; bool using_directional_lights = false; @@ -421,6 +402,8 @@ class RendererCanvasRenderRD : public RendererCanvasRender { RID default_canvas_group_shader; RID default_canvas_group_material; + RID default_clip_children_material; + RID default_clip_children_shader; RS::CanvasItemTextureFilter default_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR; RS::CanvasItemTextureRepeat default_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; @@ -428,8 +411,8 @@ class RendererCanvasRenderRD : public RendererCanvasRender { RID _create_base_uniform_set(RID p_to_render_target, bool p_backbuffer); inline void _bind_canvas_texture(RD::DrawListID p_draw_list, RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID &r_last_texture, PushConstant &push_constant, Size2 &r_texpixel_size); //recursive, so regular inline used instead. - void _render_item(RenderingDevice::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RenderingDevice::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, PipelineVariants *p_pipeline_variants); - void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer = false); + void _render_item(RenderingDevice::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RenderingDevice::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, PipelineVariants *p_pipeline_variants, bool &r_sdf_used); + void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer = false); _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); @@ -457,8 +440,6 @@ public: void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_light_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used); - void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) {} - virtual void set_shadow_texture_size(int p_size); void set_time(double p_time); diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp index dd3f62e509..f488fd63fe 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp @@ -102,10 +102,8 @@ void RendererCompositorRD::begin_frame(double frame_step) { } void RendererCompositorRD::end_frame(bool p_swap_buffers) { -#ifndef _MSC_VER -#warning TODO: likely pass a bool to swap buffers to avoid display? -#endif - RD::get_singleton()->swap_buffers(); //probably should pass some bool to avoid display? + // TODO: Likely pass a bool to swap buffers to avoid display? + RD::get_singleton()->swap_buffers(); } void RendererCompositorRD::initialize() { @@ -176,13 +174,19 @@ void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color texture_storage->texture_2d_initialize(texture, p_image); RID rd_texture = texture_storage->texture_get_rd_texture(texture); + RD::SamplerState sampler_state; + sampler_state.min_filter = p_use_filter ? RD::SAMPLER_FILTER_LINEAR : RD::SAMPLER_FILTER_NEAREST; + sampler_state.mag_filter = p_use_filter ? RD::SAMPLER_FILTER_LINEAR : RD::SAMPLER_FILTER_NEAREST; + sampler_state.max_lod = 0; + RID sampler = RD::get_singleton()->sampler_create(sampler_state); + RID uset; { Vector<RD::Uniform> uniforms; RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.append_id(blit.sampler); + u.append_id(sampler); u.append_id(rd_texture); uniforms.push_back(u); uset = RD::get_singleton()->uniform_set_create(uniforms, blit.shader.version_get_shader(blit.shader_version, BLIT_MODE_NORMAL), 0); @@ -243,6 +247,7 @@ void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color RD::get_singleton()->swap_buffers(); texture_storage->texture_free(texture); + RD::get_singleton()->free(sampler); } RendererCompositorRD *RendererCompositorRD::singleton = nullptr; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 061263ef76..3d84d47333 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -171,10 +171,6 @@ void RendererSceneRenderRD::environment_glow_set_use_bicubic_upscale(bool p_enab glow_bicubic_upscale = p_enable; } -void RendererSceneRenderRD::environment_glow_set_use_high_quality(bool p_enable) { - glow_high_quality = p_enable; -} - void RendererSceneRenderRD::environment_set_volumetric_fog_volume_size(int p_size, int p_depth) { volumetric_fog_size = p_size; volumetric_fog_depth = p_depth; @@ -250,9 +246,7 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba panorama_color = ambient_color.lerp(panorama_color, ambient_color_sky_mix); } - Ref<Image> panorama; - panorama.instantiate(); - panorama->create(p_size.width, p_size.height, false, Image::FORMAT_RGBAF); + Ref<Image> panorama = Image::create_empty(p_size.width, p_size.height, false, Image::FORMAT_RGBAF); panorama->fill(panorama_color); return panorama; } @@ -601,20 +595,20 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende RID source = rb->get_internal_texture(l); RID dest = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, l, i); if (can_use_storage) { - copy_effects->gaussian_glow(source, dest, vp_size, environment_get_glow_strength(p_render_data->environment), glow_high_quality, true, environment_get_glow_hdr_luminance_cap(p_render_data->environment), environment_get_exposure(p_render_data->environment), environment_get_glow_bloom(p_render_data->environment), environment_get_glow_hdr_bleed_threshold(p_render_data->environment), environment_get_glow_hdr_bleed_scale(p_render_data->environment), luminance_texture, auto_exposure_scale); + copy_effects->gaussian_glow(source, dest, vp_size, environment_get_glow_strength(p_render_data->environment), true, environment_get_glow_hdr_luminance_cap(p_render_data->environment), environment_get_exposure(p_render_data->environment), environment_get_glow_bloom(p_render_data->environment), environment_get_glow_hdr_bleed_threshold(p_render_data->environment), environment_get_glow_hdr_bleed_scale(p_render_data->environment), luminance_texture, auto_exposure_scale); } else { RID half = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_HALF_BLUR, 0, i); // we can reuse this for each view - copy_effects->gaussian_glow_raster(source, half, dest, luminance_multiplier, vp_size, environment_get_glow_strength(p_render_data->environment), glow_high_quality, true, environment_get_glow_hdr_luminance_cap(p_render_data->environment), environment_get_exposure(p_render_data->environment), environment_get_glow_bloom(p_render_data->environment), environment_get_glow_hdr_bleed_threshold(p_render_data->environment), environment_get_glow_hdr_bleed_scale(p_render_data->environment), luminance_texture, auto_exposure_scale); + copy_effects->gaussian_glow_raster(source, half, dest, luminance_multiplier, vp_size, environment_get_glow_strength(p_render_data->environment), true, environment_get_glow_hdr_luminance_cap(p_render_data->environment), environment_get_exposure(p_render_data->environment), environment_get_glow_bloom(p_render_data->environment), environment_get_glow_hdr_bleed_threshold(p_render_data->environment), environment_get_glow_hdr_bleed_scale(p_render_data->environment), luminance_texture, auto_exposure_scale); } } else { RID source = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, l, i - 1); RID dest = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, l, i); if (can_use_storage) { - copy_effects->gaussian_glow(source, dest, vp_size, environment_get_glow_strength(p_render_data->environment), glow_high_quality); + copy_effects->gaussian_glow(source, dest, vp_size, environment_get_glow_strength(p_render_data->environment)); } else { RID half = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_HALF_BLUR, 0, i); // we can reuse this for each view - copy_effects->gaussian_glow_raster(source, half, dest, luminance_multiplier, vp_size, environment_get_glow_strength(p_render_data->environment), glow_high_quality); + copy_effects->gaussian_glow_raster(source, half, dest, luminance_multiplier, vp_size, environment_get_glow_strength(p_render_data->environment)); } } } @@ -1080,6 +1074,7 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render scene_data.cam_transform = p_camera_data->main_transform; scene_data.cam_projection = p_camera_data->main_projection; scene_data.cam_orthogonal = p_camera_data->is_orthogonal; + scene_data.camera_visible_layers = p_camera_data->visible_layers; scene_data.taa_jitter = p_camera_data->taa_jitter; scene_data.view_count = p_camera_data->view_count; @@ -1101,7 +1096,6 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render // this should be the same for all cameras.. scene_data.lod_distance_multiplier = p_camera_data->main_projection.get_lod_multiplier(); - scene_data.lod_camera_plane = Plane(-p_camera_data->main_transform.basis.get_column(Vector3::AXIS_Z), p_camera_data->main_transform.get_origin()); if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) { scene_data.screen_mesh_lod_threshold = 0.0; @@ -1306,36 +1300,28 @@ TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Typed { PackedByteArray data = RD::get_singleton()->texture_get_data(albedo_alpha_tex, 0); - Ref<Image> img; - img.instantiate(); - img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data); + Ref<Image> img = Image::create_from_data(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data); RD::get_singleton()->free(albedo_alpha_tex); ret.push_back(img); } { PackedByteArray data = RD::get_singleton()->texture_get_data(normal_tex, 0); - Ref<Image> img; - img.instantiate(); - img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data); + Ref<Image> img = Image::create_from_data(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data); RD::get_singleton()->free(normal_tex); ret.push_back(img); } { PackedByteArray data = RD::get_singleton()->texture_get_data(orm_tex, 0); - Ref<Image> img; - img.instantiate(); - img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data); + Ref<Image> img = Image::create_from_data(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data); RD::get_singleton()->free(orm_tex); ret.push_back(img); } { PackedByteArray data = RD::get_singleton()->texture_get_data(emission_tex, 0); - Ref<Image> img; - img.instantiate(); - img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBAH, data); + Ref<Image> img = Image::create_from_data(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBAH, data); RD::get_singleton()->free(emission_tex); ret.push_back(img); } @@ -1411,7 +1397,6 @@ void RendererSceneRenderRD::init() { screen_space_roughness_limiter_amount = GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/amount"); screen_space_roughness_limiter_limit = GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/limit"); glow_bicubic_upscale = int(GLOBAL_GET("rendering/environment/glow/upscale_mode")) > 0; - glow_high_quality = GLOBAL_GET("rendering/environment/glow/use_high_quality"); directional_penumbra_shadow_kernel = memnew_arr(float, 128); directional_soft_shadow_kernel = memnew_arr(float, 128); @@ -1429,10 +1414,13 @@ void RendererSceneRenderRD::init() { cull_argument.set_page_pool(&cull_argument_pool); bool can_use_storage = _render_buffers_can_be_storage(); + bool can_use_vrs = is_vrs_supported(); bokeh_dof = memnew(RendererRD::BokehDOF(!can_use_storage)); copy_effects = memnew(RendererRD::CopyEffects(!can_use_storage)); tone_mapper = memnew(RendererRD::ToneMapper); - vrs = memnew(RendererRD::VRS); + if (can_use_vrs) { + vrs = memnew(RendererRD::VRS); + } if (can_use_storage) { fsr = memnew(RendererRD::FSR); } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 2312603829..d813d96f77 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -114,7 +114,6 @@ protected: /* ENVIRONMENT */ bool glow_bicubic_upscale = false; - bool glow_high_quality = false; bool use_physical_light_units = false; @@ -239,7 +238,6 @@ public: /* ENVIRONMENT API */ virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) override; - virtual void environment_glow_set_use_high_quality(bool p_enable) override; virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) override; virtual void environment_set_volumetric_fog_filter_active(bool p_enable) override; diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp index 0f2dea6fe9..5e9eadadd9 100644 --- a/servers/rendering/renderer_rd/shader_rd.cpp +++ b/servers/rendering/renderer_rd/shader_rd.cpp @@ -180,6 +180,7 @@ void ShaderRD::_build_variant_code(StringBuilder &builder, uint32_t p_variant, c #if defined(MACOS_ENABLED) || defined(IOS_ENABLED) builder.append("#define MOLTENVK_USED\n"); #endif + builder.append(String("#define RENDER_DRIVER_") + OS::get_singleton()->get_current_rendering_driver_name().to_upper() + "\n"); } break; case StageTemplate::Chunk::TYPE_MATERIAL_UNIFORMS: { builder.append(p_version->uniforms.get_data()); //uniforms (same for vertex and fragment) diff --git a/servers/rendering/renderer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl index 45dc63aa17..eb5f68849e 100644 --- a/servers/rendering/renderer_rd/shaders/canvas.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas.glsl @@ -191,48 +191,6 @@ void main() { uv += 1e-5; } -#ifdef USE_ATTRIBUTES -#if 0 - if (bool(draw_data.flags & FLAGS_USE_SKELETON) && bone_weights != vec4(0.0)) { //must be a valid bone - //skeleton transform - ivec4 bone_indicesi = ivec4(bone_indices); - - uvec2 tex_ofs = bone_indicesi.x * 2; - - mat2x4 m; - m = mat2x4( - texelFetch(skeleton_buffer, tex_ofs + 0), - texelFetch(skeleton_buffer, tex_ofs + 1)) * - bone_weights.x; - - tex_ofs = bone_indicesi.y * 2; - - m += mat2x4( - texelFetch(skeleton_buffer, tex_ofs + 0), - texelFetch(skeleton_buffer, tex_ofs + 1)) * - bone_weights.y; - - tex_ofs = bone_indicesi.z * 2; - - m += mat2x4( - texelFetch(skeleton_buffer, tex_ofs + 0), - texelFetch(skeleton_buffer, tex_ofs + 1)) * - bone_weights.z; - - tex_ofs = bone_indicesi.w * 2; - - m += mat2x4( - texelFetch(skeleton_buffer, tex_ofs + 0), - texelFetch(skeleton_buffer, tex_ofs + 1)) * - bone_weights.w; - - mat4 bone_matrix = skeleton_data.skeleton_transform * transpose(mat4(m[0], m[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))) * skeleton_data.skeleton_transform_inverse; - - //outvec = bone_matrix * outvec; - } -#endif -#endif - vertex = (canvas_data.canvas_transform * vec4(vertex, 0.0, 1.0)).xy; vertex_interp = vertex; @@ -598,13 +556,11 @@ void main() { normal = normalize((canvas_data.canvas_normal_transform * vec4(normal, 0.0)).xyz); } - vec3 base_color = color.rgb; + vec4 base_color = color; if (bool(draw_data.flags & FLAGS_USING_LIGHT_MASK)) { color = vec4(0.0); //invisible by default due to using light mask } - vec4 original_color = color; - #ifdef MODE_LIGHT_ONLY color = vec4(0.0); #elif !defined(MODE_UNSHADED) @@ -624,12 +580,14 @@ void main() { #ifdef LIGHT_CODE_USED vec4 shadow_modulate = vec4(1.0); - light_color = light_compute(light_vertex, vec3(direction, light_array.data[light_base].height), normal, light_color, light_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, true); + light_color = light_compute(light_vertex, vec3(direction, light_array.data[light_base].height), normal, light_color, light_color.a, specular_shininess, shadow_modulate, screen_uv, uv, base_color, true); #else if (normal_used) { vec3 light_vec = normalize(mix(vec3(direction, 0.0), vec3(0, 0, 1), light_array.data[light_base].height)); - light_color.rgb = light_normal_compute(light_vec, normal, base_color, light_color.rgb, specular_shininess, specular_shininess_used); + light_color.rgb = light_normal_compute(light_vec, normal, base_color.rgb, light_color.rgb, specular_shininess, specular_shininess_used); + } else { + light_color.rgb *= base_color.rgb; } #endif @@ -646,8 +604,6 @@ void main() { ); } - light_color.rgb *= original_color.rgb; - light_blend_compute(light_base, light_color, color.rgb); } @@ -657,20 +613,7 @@ void main() { if (i >= light_count) { break; } - uint light_base; - if (i < 8) { - if (i < 4) { - light_base = draw_data.lights[0]; - } else { - light_base = draw_data.lights[1]; - } - } else { - if (i < 12) { - light_base = draw_data.lights[2]; - } else { - light_base = draw_data.lights[3]; - } - } + uint light_base = draw_data.lights[i >> 2]; light_base >>= (i & 3) * 8; light_base &= 0xFF; @@ -685,7 +628,7 @@ void main() { vec3 light_position = vec3(light_array.data[light_base].position, light_array.data[light_base].height); light_color.rgb *= light_base_color.rgb; - light_color = light_compute(light_vertex, light_position, normal, light_color, light_base_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, false); + light_color = light_compute(light_vertex, light_position, normal, light_color, light_base_color.a, specular_shininess, shadow_modulate, screen_uv, uv, base_color, false); #else light_color.rgb *= light_base_color.rgb * light_base_color.a; @@ -695,7 +638,9 @@ void main() { vec3 pos = light_vertex; vec3 light_vec = normalize(light_pos - pos); - light_color.rgb = light_normal_compute(light_vec, normal, base_color, light_color.rgb, specular_shininess, specular_shininess_used); + light_color.rgb = light_normal_compute(light_vec, normal, base_color.rgb, light_color.rgb, specular_shininess, specular_shininess_used); + } else { + light_color.rgb *= base_color.rgb; } #endif if (any(lessThan(tex_uv, vec2(0.0, 0.0))) || any(greaterThanEqual(tex_uv, vec2(1.0, 1.0)))) { @@ -743,8 +688,6 @@ void main() { ); } - light_color.rgb *= original_color.rgb; - light_blend_compute(light_base, light_color, color.rgb); } #endif diff --git a/servers/rendering/renderer_rd/shaders/cluster_render.glsl b/servers/rendering/renderer_rd/shaders/cluster_render.glsl index 2fe230f0bf..8c26a67926 100644 --- a/servers/rendering/renderer_rd/shaders/cluster_render.glsl +++ b/servers/rendering/renderer_rd/shaders/cluster_render.glsl @@ -64,7 +64,7 @@ void main() { #version 450 #VERSION_DEFINES - +#ifndef MOLTENVK_USED // Metal will corrupt GPU state otherwise #if defined(has_GL_KHR_shader_subgroup_ballot) && defined(has_GL_KHR_shader_subgroup_arithmetic) && defined(has_GL_KHR_shader_subgroup_vote) #extension GL_KHR_shader_subgroup_ballot : enable @@ -73,6 +73,7 @@ void main() { #define USE_SUBGROUPS #endif +#endif layout(location = 0) in float depth_interp; layout(location = 1) in flat uint element_index; @@ -141,7 +142,11 @@ void main() { } } #else - if (!gl_HelperInvocation) { +// MoltenVK/Metal fails to compile shaders using gl_HelperInvocation for some GPUs +#ifndef MOLTENVK_USED + if (!gl_HelperInvocation) +#endif + { atomicOr(cluster_render.data[usage_write_offset], usage_write_bit); } #endif @@ -161,7 +166,11 @@ void main() { } } #else - if (!gl_HelperInvocation) { +// MoltenVK/Metal fails to compile shaders using gl_HelperInvocation for some GPUs +#ifndef MOLTENVK_USED + if (!gl_HelperInvocation) +#endif + { atomicOr(cluster_render.data[z_write_offset], z_write_bit); } #endif diff --git a/servers/rendering/renderer_rd/shaders/effects/blur_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/blur_raster.glsl index cb06250cf2..31aabbe9d2 100644 --- a/servers/rendering/renderer_rd/shaders/effects/blur_raster.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/blur_raster.glsl @@ -53,30 +53,31 @@ void main() { #ifdef MODE_GAUSSIAN_BLUR - // Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect - - // note, for blur blur.luminance_multiplier is irrelavant, we would be multiplying and then dividing by this amount. - - if (bool(blur.flags & FLAG_HORIZONTAL)) { - vec2 pix_size = blur.pixel_size; - pix_size *= 0.5; //reading from larger buffer, so use more samples - vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.214607; - color += texture(source_color, uv_interp + vec2(1.0, 0.0) * pix_size) * 0.189879; - color += texture(source_color, uv_interp + vec2(2.0, 0.0) * pix_size) * 0.131514; - color += texture(source_color, uv_interp + vec2(3.0, 0.0) * pix_size) * 0.071303; - color += texture(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size) * 0.189879; - color += texture(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size) * 0.131514; - color += texture(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size) * 0.071303; - frag_color = color; - } else { - vec2 pix_size = blur.pixel_size; - vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.38774; - color += texture(source_color, uv_interp + vec2(0.0, 1.0) * pix_size) * 0.24477; - color += texture(source_color, uv_interp + vec2(0.0, 2.0) * pix_size) * 0.06136; - color += texture(source_color, uv_interp + vec2(0.0, -1.0) * pix_size) * 0.24477; - color += texture(source_color, uv_interp + vec2(0.0, -2.0) * pix_size) * 0.06136; - frag_color = color; - } + // For Gaussian Blur we use 13 taps in a single pass instead of 12 taps over 2 passes. + // This minimizes the number of times we change framebuffers which is very important for mobile. + // Source: http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare + vec4 A = texture(source_color, uv_interp + blur.pixel_size * vec2(-1.0, -1.0)); + vec4 B = texture(source_color, uv_interp + blur.pixel_size * vec2(0.0, -1.0)); + vec4 C = texture(source_color, uv_interp + blur.pixel_size * vec2(1.0, -1.0)); + vec4 D = texture(source_color, uv_interp + blur.pixel_size * vec2(-0.5, -0.5)); + vec4 E = texture(source_color, uv_interp + blur.pixel_size * vec2(0.5, -0.5)); + vec4 F = texture(source_color, uv_interp + blur.pixel_size * vec2(-1.0, 0.0)); + vec4 G = texture(source_color, uv_interp); + vec4 H = texture(source_color, uv_interp + blur.pixel_size * vec2(1.0, 0.0)); + vec4 I = texture(source_color, uv_interp + blur.pixel_size * vec2(-0.5, 0.5)); + vec4 J = texture(source_color, uv_interp + blur.pixel_size * vec2(0.5, 0.5)); + vec4 K = texture(source_color, uv_interp + blur.pixel_size * vec2(-1.0, 1.0)); + vec4 L = texture(source_color, uv_interp + blur.pixel_size * vec2(0.0, 1.0)); + vec4 M = texture(source_color, uv_interp + blur.pixel_size * vec2(1.0, 1.0)); + + float base_weight = 0.5 / 4.0; + float lesser_weight = 0.125 / 4.0; + + frag_color = (D + E + I + J) * base_weight; + frag_color += (A + B + G + F) * lesser_weight; + frag_color += (B + C + H + G) * lesser_weight; + frag_color += (F + G + L + K) * lesser_weight; + frag_color += (G + H + M + L) * lesser_weight; #endif #ifdef MODE_GAUSSIAN_GLOW diff --git a/servers/rendering/renderer_rd/shaders/effects/copy.glsl b/servers/rendering/renderer_rd/shaders/effects/copy.glsl index bfe329b8ec..3a82861057 100644 --- a/servers/rendering/renderer_rd/shaders/effects/copy.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/copy.glsl @@ -14,8 +14,7 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; #define FLAG_FLIP_Y (1 << 5) #define FLAG_FORCE_LUMINANCE (1 << 6) #define FLAG_COPY_ALL_SOURCE (1 << 7) -#define FLAG_HIGH_QUALITY_GLOW (1 << 8) -#define FLAG_ALPHA_TO_ONE (1 << 9) +#define FLAG_ALPHA_TO_ONE (1 << 8) layout(push_constant, std430) uniform Params { ivec4 section; @@ -93,25 +92,14 @@ void main() { #ifdef MODE_GAUSSIAN_BLUR // First pass copy texture into 16x16 local memory for every 8x8 thread block - vec2 quad_center_uv = clamp(vec2(gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.5) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw)); + vec2 quad_center_uv = clamp(vec2(params.section.xy + gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.5) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw)); uint dest_index = gl_LocalInvocationID.x * 2 + gl_LocalInvocationID.y * 2 * 16; -#ifdef MODE_GLOW - if (bool(params.flags & FLAG_HIGH_QUALITY_GLOW)) { - vec2 quad_offset_uv = clamp((vec2(gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.0)) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw)); - - local_cache[dest_index] = (textureLod(source_color, quad_center_uv, 0) + textureLod(source_color, quad_offset_uv, 0)) * 0.5; - local_cache[dest_index + 1] = (textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0) + textureLod(source_color, quad_offset_uv + vec2(1.0 / params.section.z, 0.0), 0)) * 0.5; - local_cache[dest_index + 16] = (textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0) + textureLod(source_color, quad_offset_uv + vec2(0.0, 1.0 / params.section.w), 0)) * 0.5; - local_cache[dest_index + 16 + 1] = (textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0) + textureLod(source_color, quad_offset_uv + vec2(1.0 / params.section.zw), 0)) * 0.5; - } else -#endif - { - local_cache[dest_index] = textureLod(source_color, quad_center_uv, 0); - local_cache[dest_index + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0); - local_cache[dest_index + 16] = textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0); - local_cache[dest_index + 16 + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0); - } + local_cache[dest_index] = textureLod(source_color, quad_center_uv, 0); + local_cache[dest_index + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0); + local_cache[dest_index + 16] = textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0); + local_cache[dest_index + 16 + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0); + #ifdef MODE_GLOW if (bool(params.flags & FLAG_GLOW_FIRST_PASS)) { // Tonemap initial samples to reduce weight of fireflies: https://graphicrants.blogspot.com/2013/12/tone-mapping.html @@ -194,10 +182,10 @@ void main() { color = min(color * feedback, vec4(params.glow_luminance_cap)); } -#endif +#endif // MODE_GLOW imageStore(dest_buffer, pos + params.target, color); -#endif +#endif // MODE_GAUSSIAN_BLUR #ifdef MODE_SIMPLE_COPY @@ -227,7 +215,7 @@ void main() { imageStore(dest_buffer, pos + params.target, color); -#endif +#endif // MODE_SIMPLE_COPY #ifdef MODE_SIMPLE_COPY_DEPTH @@ -239,7 +227,7 @@ void main() { imageStore(dest_buffer, pos + params.target, vec4(color.r)); -#endif +#endif // MODE_SIMPLE_COPY_DEPTH #ifdef MODE_LINEARIZE_DEPTH_COPY @@ -253,7 +241,7 @@ void main() { } imageStore(dest_buffer, pos + params.target, color); -#endif +#endif // MODE_LINEARIZE_DEPTH_COPY #if defined(MODE_CUBEMAP_TO_PANORAMA) || defined(MODE_CUBEMAP_ARRAY_TO_PANORAMA) @@ -276,7 +264,7 @@ void main() { vec4 color = textureLod(source_color, vec4(normal, params.camera_z_far), 0.0); //the biggest the lod the least the acne #endif imageStore(dest_buffer, pos + params.target, color); -#endif +#endif // defined(MODE_CUBEMAP_TO_PANORAMA) || defined(MODE_CUBEMAP_ARRAY_TO_PANORAMA) #ifdef MODE_SET_COLOR imageStore(dest_buffer, pos + params.target, params.set_color); diff --git a/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl b/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl index 1c17eabb56..6137224162 100644 --- a/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl @@ -13,6 +13,14 @@ #endif // has_VK_KHR_multiview #endif //MULTIVIEW +#define FLAG_FLIP_Y (1 << 0) +#define FLAG_USE_SECTION (1 << 1) +#define FLAG_FORCE_LUMINANCE (1 << 2) +#define FLAG_ALPHA_TO_ZERO (1 << 3) +#define FLAG_SRGB (1 << 4) +#define FLAG_ALPHA_TO_ONE (1 << 5) +#define FLAG_LINEAR (1 << 6) + #ifdef MULTIVIEW layout(location = 0) out vec3 uv_interp; #else @@ -22,11 +30,10 @@ layout(location = 0) out vec2 uv_interp; layout(push_constant, std430) uniform Params { vec4 section; vec2 pixel_size; - bool flip_y; - bool use_section; + float luminance_multiplier; + uint flags; - bool force_luminance; - uint pad[3]; + vec4 color; } params; @@ -37,13 +44,13 @@ void main() { uv_interp.z = ViewIndex; #endif vec2 vpos = uv_interp.xy; - if (params.use_section) { + if (bool(params.flags & FLAG_USE_SECTION)) { vpos = params.section.xy + vpos * params.section.zw; } gl_Position = vec4(vpos * 2.0 - 1.0, 0.0, 1.0); - if (params.flip_y) { + if (bool(params.flags & FLAG_FLIP_Y)) { uv_interp.y = 1.0 - uv_interp.y; } } @@ -63,19 +70,25 @@ void main() { #endif // has_VK_KHR_multiview #endif //MULTIVIEW +#define FLAG_FLIP_Y (1 << 0) +#define FLAG_USE_SECTION (1 << 1) +#define FLAG_FORCE_LUMINANCE (1 << 2) +#define FLAG_ALPHA_TO_ZERO (1 << 3) +#define FLAG_SRGB (1 << 4) +#define FLAG_ALPHA_TO_ONE (1 << 5) +#define FLAG_LINEAR (1 << 6) + layout(push_constant, std430) uniform Params { vec4 section; vec2 pixel_size; - bool flip_y; - bool use_section; + float luminance_multiplier; + uint flags; - bool force_luminance; - bool alpha_to_zero; - bool srgb; - uint pad; + vec4 color; } params; +#ifndef MODE_SET_COLOR #ifdef MULTIVIEW layout(location = 0) in vec3 uv_interp; #else @@ -94,6 +107,7 @@ layout(set = 0, binding = 0) uniform sampler2D source_color; layout(set = 1, binding = 0) uniform sampler2D source_color2; #endif /* MODE_TWO_SOURCES */ #endif /* MULTIVIEW */ +#endif /* !SET_COLOR */ layout(location = 0) out vec4 frag_color; @@ -104,7 +118,15 @@ vec3 linear_to_srgb(vec3 color) { return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f))); } +vec3 srgb_to_linear(vec3 color) { + return mix(pow((color.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), color.rgb * (1.0 / 12.92), lessThan(color.rgb, vec3(0.04045))); +} + void main() { +#ifdef MODE_SET_COLOR + frag_color = params.color; +#else + #ifdef MULTIVIEW vec3 uv = uv_interp; #else @@ -155,15 +177,22 @@ void main() { #endif /* MODE_TWO_SOURCES */ #endif /* MULTIVIEW */ - if (params.force_luminance) { + if (bool(params.flags & FLAG_FORCE_LUMINANCE)) { color.rgb = vec3(max(max(color.r, color.g), color.b)); } - if (params.alpha_to_zero) { + if (bool(params.flags & FLAG_ALPHA_TO_ZERO)) { color.rgb *= color.a; } - if (params.srgb) { + if (bool(params.flags & FLAG_SRGB)) { color.rgb = linear_to_srgb(color.rgb); } + if (bool(params.flags & FLAG_ALPHA_TO_ONE)) { + color.a = 1.0; + } + if (bool(params.flags & FLAG_LINEAR)) { + color.rgb = srgb_to_linear(color.rgb); + } - frag_color = color; + frag_color = color / params.luminance_multiplier; +#endif // MODE_SET_COLOR } diff --git a/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl index 1bee428a6f..c0597fe3f3 100644 --- a/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl @@ -70,17 +70,6 @@ float DistributionGGX(float NdotH, float roughness4) { return roughness4 / denom; } -// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html -float GGX(float NdotV, float a) { - float k = a / 2.0; - return NdotV / (NdotV * (1.0 - k) + k); -} - -// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html -float G_Smith(float a, float nDotV, float nDotL) { - return GGX(nDotL, a * a) * GGX(nDotV, a * a); -} - float radicalInverse_VdC(uint bits) { bits = (bits << 16u) | (bits >> 16u); bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); diff --git a/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl index 9d8294a7da..631d1968b0 100644 --- a/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl @@ -66,6 +66,19 @@ void main() { vec4 normal_roughness = imageLoad(source_normal_roughness, ssC); vec3 normal = normal_roughness.xyz * 2.0 - 1.0; + float roughness = normal_roughness.w; + + // The roughness cutoff of 0.6 is chosen to match the roughness fadeout from GH-69828. + if (roughness > 0.6) { + // Do not compute SSR for rough materials to improve performance at the cost of + // subtle artifacting. +#ifdef MODE_ROUGH + imageStore(blur_radius_image, ssC, vec4(0.0)); +#endif + imageStore(ssr_image, ssC, vec4(0.0)); + return; + } + normal = normalize(normal); normal.y = -normal.y; //because this code reads flipped @@ -81,8 +94,6 @@ void main() { imageStore(ssr_image, ssC, vec4(0.0)); return; } - //ray_dir = normalize(view_dir - normal * dot(normal,view_dir) * 2.0); - //ray_dir = normalize(vec3(1.0, 1.0, -1.0)); //////////////// @@ -212,6 +223,9 @@ void main() { float grad = (steps_taken + 1.0) / float(params.num_steps); float initial_fade = params.curve_fade_in == 0.0 ? 1.0 : pow(clamp(grad, 0.0, 1.0), params.curve_fade_in); float fade = pow(clamp(1.0 - grad, 0.0, 1.0), params.distance_fade) * initial_fade; + // This is an ad-hoc term to fade out the SSR as roughness increases. Values used + // are meant to match the visual appearance of a ReflectionProbe. + float roughness_fade = smoothstep(0.4, 0.7, 1.0 - normal_roughness.w); final_pos = pos; vec4 final_color; @@ -220,7 +234,6 @@ void main() { // if roughness is enabled, do screen space cone tracing float blur_radius = 0.0; - float roughness = normal_roughness.w; if (roughness > 0.001) { float cone_angle = min(roughness, 0.999) * M_PI * 0.5; @@ -246,7 +259,7 @@ void main() { #endif // MODE_ROUGH - final_color = vec4(imageLoad(source_diffuse, ivec2(final_pos - 0.5)).rgb, fade * margin_blend); + final_color = vec4(imageLoad(source_diffuse, ivec2(final_pos - 0.5)).rgb, fade * margin_blend * roughness_fade); // Schlick term. float metallic = texelFetch(source_metallic, ssC << 1, 0).w; diff --git a/servers/rendering/renderer_rd/shaders/effects/taa_resolve.glsl b/servers/rendering/renderer_rd/shaders/effects/taa_resolve.glsl index b0a0839836..02566d8e35 100644 --- a/servers/rendering/renderer_rd/shaders/effects/taa_resolve.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/taa_resolve.glsl @@ -32,7 +32,9 @@ // Based on Spartan Engine's TAA implementation (without TAA upscale). // <https://github.com/PanosK92/SpartanEngine/blob/a8338d0609b85dc32f3732a5c27fb4463816a3b9/Data/shaders/temporal_antialiasing.hlsl> +#ifndef MOLTENVK_USED #define USE_SUBGROUPS +#endif // MOLTENVK_USED #define GROUP_SIZE 8 #define FLT_MIN 0.00000001 diff --git a/servers/rendering/renderer_rd/shaders/effects/vrs.glsl b/servers/rendering/renderer_rd/shaders/effects/vrs.glsl index 5ef83c0b44..b450bb9fe9 100644 --- a/servers/rendering/renderer_rd/shaders/effects/vrs.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/vrs.glsl @@ -63,10 +63,18 @@ void main() { #ifdef MULTIVIEW vec4 color = textureLod(source_color, uv, 0.0); + frag_color = uint(color.r * 255.0); #else /* MULTIVIEW */ vec4 color = textureLod(source_color, uv, 0.0); -#endif /* MULTIVIEW */ - // See if we can change the sampler to one that returns int... - frag_color = uint(color.r * 256.0); + // for user supplied VRS map we do a color mapping + color.r *= 3.0; + frag_color = int(color.r) << 2; + + color.g *= 3.0; + frag_color += int(color.g); + + // note 1x4, 4x1, 1x8, 8x1, 2x8 and 8x2 are not supported + // 4x8, 8x4 and 8x8 are only available on some GPUs +#endif /* MULTIVIEW */ } diff --git a/servers/rendering/renderer_rd/shaders/environment/gi.glsl b/servers/rendering/renderer_rd/shaders/environment/gi.glsl index ab927df678..459c4dcb1d 100644 --- a/servers/rendering/renderer_rd/shaders/environment/gi.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/gi.glsl @@ -108,7 +108,9 @@ layout(set = 0, binding = 18, std140) uniform SceneData { } scene_data; +#ifdef USE_VRS layout(r8ui, set = 0, binding = 19) uniform restrict readonly uimage2D vrs_buffer; +#endif layout(push_constant, std430) uniform Params { uint max_voxel_gi_instances; @@ -661,6 +663,7 @@ void main() { ivec2 pos = ivec2(gl_GlobalInvocationID.xy); uint vrs_x, vrs_y; +#ifdef USE_VRS if (sc_use_vrs) { ivec2 vrs_pos; @@ -684,6 +687,7 @@ void main() { return; } } +#endif if (sc_half_res) { pos <<= 1; @@ -708,6 +712,7 @@ void main() { imageStore(ambient_buffer, pos, ambient_light); imageStore(reflection_buffer, pos, reflection_light); +#ifdef USE_VRS if (sc_use_vrs) { if (vrs_x > 1) { imageStore(ambient_buffer, pos + ivec2(1, 0), ambient_light); @@ -766,4 +771,5 @@ void main() { imageStore(reflection_buffer, pos + ivec2(3, 3), reflection_light); } } +#endif } diff --git a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl index eed9038502..28507e6c12 100644 --- a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl @@ -381,7 +381,7 @@ void main() { float cell_depth_size = abs(view_pos.z - get_depth_at_pos(fog_cell_size.z, pos.z + 1)); //compute directional lights - if (total_density > 0.001) { + if (total_density > 0.00005) { for (uint i = 0; i < params.directional_light_count; i++) { if (directional_lights.data[i].volumetric_fog_energy > 0.001) { vec3 shadow_attenuation = vec3(1.0); diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl index 1a8a1f3aa3..be53a7ae49 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl @@ -62,7 +62,7 @@ vec3 oct_to_vec3(vec2 e) { vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y)); float t = max(-v.z, 0.0); v.xy += t * -sign(v.xy); - return v; + return normalize(v); } /* Varyings */ @@ -97,9 +97,7 @@ layout(location = 8) out vec4 prev_screen_position; #ifdef MATERIAL_UNIFORMS_USED layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms{ - #MATERIAL_UNIFORMS - } material; #endif @@ -691,7 +689,7 @@ vec4 fog_process(vec3 vertex) { void cluster_get_item_range(uint p_offset, out uint item_min, out uint item_max, out uint item_from, out uint item_to) { uint item_min_max = cluster_buffer.data[p_offset]; - item_min = item_min_max & 0xFFFF; + item_min = item_min_max & 0xFFFFu; item_max = item_min_max >> 16; item_from = item_min >> 5; @@ -828,7 +826,8 @@ void fragment_shader(in SceneData scene_data) { // alpha hash can be used in unison with alpha antialiasing #ifdef ALPHA_HASH_USED - if (alpha < compute_alpha_hash_threshold(vertex, alpha_hash_scale)) { + vec3 object_pos = (inverse(read_model_matrix) * inv_view_matrix * vec4(vertex, 1.0)).xyz; + if (alpha < compute_alpha_hash_threshold(object_pos, alpha_hash_scale)) { discard; } #endif // ALPHA_HASH_USED @@ -958,9 +957,9 @@ void fragment_shader(in SceneData scene_data) { while (merged_mask != 0) { uint bit = findMSB(merged_mask); - merged_mask &= ~(1 << bit); + merged_mask &= ~(1u << bit); #ifdef USE_SUBGROUPS - if (((1 << bit) & mask) == 0) { //do not process if not originally here + if (((1u << bit) & mask) == 0) { //do not process if not originally here continue; } #endif @@ -1085,12 +1084,13 @@ void fragment_shader(in SceneData scene_data) { #ifdef USE_RADIANCE_CUBEMAP_ARRAY float lod, blend; - blend = modf(roughness * MAX_ROUGHNESS_LOD, lod); + + blend = modf(sqrt(roughness) * MAX_ROUGHNESS_LOD, lod); specular_light = texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod)).rgb; specular_light = mix(specular_light, texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod + 1)).rgb, blend); #else - specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, roughness * MAX_ROUGHNESS_LOD).rgb; + specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, sqrt(roughness) * MAX_ROUGHNESS_LOD).rgb; #endif //USE_RADIANCE_CUBEMAP_ARRAY specular_light *= scene_data.IBL_exposure_normalization; @@ -1138,7 +1138,7 @@ void fragment_shader(in SceneData scene_data) { ref_vec = mix(ref_vec, n, clearcoat_roughness * clearcoat_roughness); float horizon = min(1.0 + dot(ref_vec, normal), 1.0); ref_vec = scene_data.radiance_inverse_xform * ref_vec; - float roughness_lod = mix(0.001, 0.1, clearcoat_roughness) * MAX_ROUGHNESS_LOD; + float roughness_lod = mix(0.001, 0.1, sqrt(clearcoat_roughness)) * MAX_ROUGHNESS_LOD; #ifdef USE_RADIANCE_CUBEMAP_ARRAY float lod, blend; @@ -1419,9 +1419,9 @@ void fragment_shader(in SceneData scene_data) { while (merged_mask != 0) { uint bit = findMSB(merged_mask); - merged_mask &= ~(1 << bit); + merged_mask &= ~(1u << bit); #ifdef USE_SUBGROUPS - if (((1 << bit) & mask) == 0) { //do not process if not originally here + if (((1u << bit) & mask) == 0) { //do not process if not originally here continue; } #endif @@ -1447,18 +1447,24 @@ void fragment_shader(in SceneData scene_data) { } //finalize ambient light here - ambient_light *= albedo.rgb; - ambient_light *= ao; + { +#if defined(AMBIENT_LIGHT_DISABLED) + ambient_light = vec3(0.0, 0.0, 0.0); +#else + ambient_light *= albedo.rgb; + ambient_light *= ao; + + if (bool(implementation_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSIL)) { + vec4 ssil = textureLod(sampler2D(ssil_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv, 0.0); + ambient_light *= 1.0 - ssil.a; + ambient_light += ssil.rgb * albedo.rgb; + } +#endif // AMBIENT_LIGHT_DISABLED + } // convert ao to direct light ao ao = mix(1.0, ao, ao_light_affect); - if (bool(implementation_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSIL)) { - vec4 ssil = textureLod(sampler2D(ssil_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv, 0.0); - ambient_light *= 1.0 - ssil.a; - ambient_light += ssil.rgb * albedo.rgb; - } - //this saves some VGPRs vec3 f0 = F0(metallic, specular, albedo); @@ -1479,7 +1485,7 @@ void fragment_shader(in SceneData scene_data) { float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y; vec2 env = vec2(-1.04, 1.04) * a004 + r.zw; - specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, 0.0, 1.0); + specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, metallic, 1.0); #endif } @@ -1775,9 +1781,9 @@ void fragment_shader(in SceneData scene_data) { float shadow = 1.0; #ifndef SHADOWS_DISABLED if (i < 4) { - shadow = float(shadow0 >> (i * 8) & 0xFF) / 255.0; + shadow = float(shadow0 >> (i * 8u) & 0xFFu) / 255.0; } else { - shadow = float(shadow1 >> ((i - 4) * 8) & 0xFF) / 255.0; + shadow = float(shadow1 >> ((i - 4u) * 8u) & 0xFFu) / 255.0; } shadow = shadow * directional_lights.data[i].shadow_opacity + 1.0 - directional_lights.data[i].shadow_opacity; @@ -1839,9 +1845,9 @@ void fragment_shader(in SceneData scene_data) { while (merged_mask != 0) { uint bit = findMSB(merged_mask); - merged_mask &= ~(1 << bit); + merged_mask &= ~(1u << bit); #ifdef USE_SUBGROUPS - if (((1 << bit) & mask) == 0) { //do not process if not originally here + if (((1u << bit) & mask) == 0) { //do not process if not originally here continue; } #endif @@ -1910,9 +1916,9 @@ void fragment_shader(in SceneData scene_data) { while (merged_mask != 0) { uint bit = findMSB(merged_mask); - merged_mask &= ~(1 << bit); + merged_mask &= ~(1u << bit); #ifdef USE_SUBGROUPS - if (((1 << bit) & mask) == 0) { //do not process if not originally here + if (((1u << bit) & mask) == 0) { //do not process if not originally here continue; } #endif @@ -2065,7 +2071,7 @@ void fragment_shader(in SceneData scene_data) { float sGreen = floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f); float sBlue = floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f); //store as 8985 to have 2 extra neighbour bits - uint light_rgbe = ((uint(sRed) & 0x1FF) >> 1) | ((uint(sGreen) & 0x1FF) << 8) | (((uint(sBlue) & 0x1FF) >> 1) << 17) | ((uint(exps) & 0x1F) << 25); + uint light_rgbe = ((uint(sRed) & 0x1FFu) >> 1) | ((uint(sGreen) & 0x1FFu) << 8) | (((uint(sBlue) & 0x1FFu) >> 1) << 17) | ((uint(exps) & 0x1Fu) << 25); imageStore(emission_grid, grid_pos, uvec4(light_rgbe)); imageStore(emission_aniso_grid, grid_pos, uvec4(light_aniso)); @@ -2099,8 +2105,8 @@ void fragment_shader(in SceneData scene_data) { if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_VOXEL_GI)) { // process voxel_gi_instances uint index1 = instances.data[instance_index].gi_offset & 0xFFFF; uint index2 = instances.data[instance_index].gi_offset >> 16; - voxel_gi_buffer.x = index1 & 0xFF; - voxel_gi_buffer.y = index2 & 0xFF; + voxel_gi_buffer.x = index1 & 0xFFu; + voxel_gi_buffer.y = index2 & 0xFFu; } else { voxel_gi_buffer.x = 0xFF; voxel_gi_buffer.y = 0xFF; diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl index 0d36b98645..3a45ab0059 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl @@ -4,14 +4,15 @@ #define MAX_VOXEL_GI_INSTANCES 8 #define MAX_VIEWS 2 +#ifndef MOLTENVK_USED #if defined(has_GL_KHR_shader_subgroup_ballot) && defined(has_GL_KHR_shader_subgroup_arithmetic) #extension GL_KHR_shader_subgroup_ballot : enable #extension GL_KHR_shader_subgroup_arithmetic : enable #define USE_SUBGROUPS - #endif +#endif // MOLTENVK_USED #if defined(USE_MULTIVIEW) && defined(has_VK_KHR_multiview) #extension GL_EXT_multiview : enable diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl index 33fd4c35b1..b45c68db5a 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl @@ -63,7 +63,7 @@ vec3 oct_to_vec3(vec2 e) { vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y)); float t = max(-v.z, 0.0); v.xy += t * -sign(v.xy); - return v; + return normalize(v); } /* Varyings */ @@ -779,7 +779,8 @@ void main() { // alpha hash can be used in unison with alpha antialiasing #ifdef ALPHA_HASH_USED - if (alpha < compute_alpha_hash_threshold(vertex, alpha_hash_scale)) { + vec3 object_pos = (inverse(read_model_matrix) * inv_view_matrix * vec4(vertex, 1.0)).xyz; + if (alpha < compute_alpha_hash_threshold(object_pos, alpha_hash_scale)) { discard; } #endif // ALPHA_HASH_USED @@ -986,12 +987,12 @@ void main() { #ifdef USE_RADIANCE_CUBEMAP_ARRAY float lod, blend; - blend = modf(roughness * MAX_ROUGHNESS_LOD, lod); + blend = modf(sqrt(roughness) * MAX_ROUGHNESS_LOD, lod); specular_light = texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod)).rgb; specular_light = mix(specular_light, texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod + 1)).rgb, blend); #else // USE_RADIANCE_CUBEMAP_ARRAY - specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, roughness * MAX_ROUGHNESS_LOD).rgb; + specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, sqrt(roughness) * MAX_ROUGHNESS_LOD).rgb; #endif //USE_RADIANCE_CUBEMAP_ARRAY specular_light *= sc_luminance_multiplier; @@ -1041,7 +1042,7 @@ void main() { float horizon = min(1.0 + dot(ref_vec, normal), 1.0); ref_vec = scene_data.radiance_inverse_xform * ref_vec; - float roughness_lod = mix(0.001, 0.1, clearcoat_roughness) * MAX_ROUGHNESS_LOD; + float roughness_lod = mix(0.001, 0.1, sqrt(clearcoat_roughness)) * MAX_ROUGHNESS_LOD; #ifdef USE_RADIANCE_CUBEMAP_ARRAY float lod, blend; @@ -1172,8 +1173,14 @@ void main() { } //Reflection probes // finalize ambient light here - ambient_light *= albedo.rgb; - ambient_light *= ao; + { +#if defined(AMBIENT_LIGHT_DISABLED) + ambient_light = vec3(0.0, 0.0, 0.0); +#else + ambient_light *= albedo.rgb; + ambient_light *= ao; +#endif // AMBIENT_LIGHT_DISABLED + } // convert ao to direct light ao ao = mix(1.0, ao, ao_light_affect); @@ -1198,7 +1205,7 @@ void main() { float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y; vec2 env = vec2(-1.04, 1.04) * a004 + r.zw; - specular_light *= env.x * f0 + env.y; + specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, metallic, 1.0); #endif } diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl index 3a6dd579b9..9f6aa7adc0 100644 --- a/servers/rendering/renderer_rd/shaders/particles.glsl +++ b/servers/rendering/renderer_rd/shaders/particles.glsl @@ -462,7 +462,7 @@ void main() { if (any(lessThan(uvw_pos, vec3(0.0))) || any(greaterThan(uvw_pos, vec3(1.0)))) { continue; } - vec3 s = texture(sampler3D(sdf_vec_textures[FRAME.attractors[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos).xyz * 2.0 - 1.0; + vec3 s = texture(sampler3D(sdf_vec_textures[FRAME.attractors[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos).xyz * -2.0 + 1.0; dir = mat3(FRAME.attractors[i].transform) * safe_normalize(s); //revert direction amount = length(s); diff --git a/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl index 048257e9ef..b57ee18521 100644 --- a/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl @@ -63,7 +63,7 @@ struct SceneData { float IBL_exposure_normalization; bool pancake_shadows; - uint pad1; + uint camera_visible_layers; uint pad2; uint pad3; }; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_aa_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_aa_inc.glsl index 97c913d489..71510ee06a 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_aa_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_aa_inc.glsl @@ -11,7 +11,8 @@ float hash_3d(vec3 p) { float compute_alpha_hash_threshold(vec3 pos, float hash_scale) { vec3 dx = dFdx(pos); - vec3 dy = dFdx(pos); + vec3 dy = dFdy(pos); + float delta_max_sqr = max(length(dx), length(dy)); float pix_scale = 1.0 / (hash_scale * delta_max_sqr); @@ -32,9 +33,9 @@ float compute_alpha_hash_threshold(vec3 pos, float hash_scale) { 1.0 - ((1.0 - a_interp) * (1.0 - a_interp) / (2.0 * min_lerp * (1.0 - min_lerp)))); float alpha_hash_threshold = - (lerp_factor < (1.0 - min_lerp)) ? ((lerp_factor < min_lerp) ? cases.x : cases.y) : cases.z; + (a_interp < (1.0 - min_lerp)) ? ((a_interp < min_lerp) ? cases.x : cases.y) : cases.z; - return clamp(alpha_hash_threshold, 0.0, 1.0); + return clamp(alpha_hash_threshold, 0.00001, 1.0); } #endif // ALPHA_HASH_USED diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl index 2fba1351f7..b30b0c8169 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl @@ -134,7 +134,8 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte #endif #if defined(LIGHT_RIM_USED) - float rim_light = pow(max(0.0, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0)); + // Epsilon min to prevent pow(0, 0) singularity which results in undefined behavior. + float rim_light = pow(max(1e-4, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0)); diffuse_light += rim_light * rim * mix(vec3(1.0), albedo, rim_tint) * light_color; #endif @@ -202,7 +203,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte float cLdotH5 = SchlickFresnel(cLdotH); // Calculate Fresnel using specular occlusion term from Filament: // https://google.github.io/filament/Filament.html#lighting/occlusion/specularocclusion - float f90 = clamp(dot(f0, vec3(50.0 * 0.33)), 0.0, 1.0); + float f90 = clamp(dot(f0, vec3(50.0 * 0.33)), metallic, 1.0); vec3 F = f0 + (f90 - f0) * cLdotH5; vec3 specular_brdf_NL = cNdotL * D * F * G; diff --git a/servers/rendering/renderer_rd/shaders/skeleton.glsl b/servers/rendering/renderer_rd/shaders/skeleton.glsl index 75bea9300b..f5b233cca0 100644 --- a/servers/rendering/renderer_rd/shaders/skeleton.glsl +++ b/servers/rendering/renderer_rd/shaders/skeleton.glsl @@ -63,7 +63,7 @@ vec3 oct_to_vec3(vec2 oct) { vec3 v = vec3(oct.xy, 1.0 - abs(oct.x) - abs(oct.y)); float t = max(-v.z, 0.0); v.xy += t * -sign(v.xy); - return v; + return normalize(v); } vec3 decode_uint_oct_to_norm(uint base) { @@ -143,8 +143,8 @@ void main() { uint skin_offset = params.skin_stride * index; uvec2 bones = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]); - uvec2 bones_01 = uvec2(bones.x & 0xFFFF, bones.x >> 16) * 3; //pre-add xform offset - uvec2 bones_23 = uvec2(bones.y & 0xFFFF, bones.y >> 16) * 3; + uvec2 bones_01 = uvec2(bones.x & 0xFFFF, bones.x >> 16) * 2; //pre-add xform offset + uvec2 bones_23 = uvec2(bones.y & 0xFFFF, bones.y >> 16) * 2; skin_offset += params.skin_weight_offset; @@ -161,6 +161,13 @@ void main() { //reverse order because its transposed vertex = (vec4(vertex, 0.0, 1.0) * m).xy; } + + uint dst_offset = index * params.vertex_stride; + + uvec2 uvertex = floatBitsToUint(vertex); + dst_vertices.data[dst_offset + 0] = uvertex.x; + dst_vertices.data[dst_offset + 1] = uvertex.y; + #else vec3 vertex; vec3 normal; diff --git a/servers/rendering/renderer_rd/spirv-reflect/SCsub b/servers/rendering/renderer_rd/spirv-reflect/SCsub new file mode 100644 index 0000000000..4c27e5bef7 --- /dev/null +++ b/servers/rendering/renderer_rd/spirv-reflect/SCsub @@ -0,0 +1,17 @@ +#!/usr/bin/env python + +Import("env") + +# Thirdparty source files + +thirdparty_dir = "#thirdparty/spirv-reflect/" +thirdparty_sources = [ + "spirv_reflect.c", +] + +thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] + +env_thirdparty = env.Clone() +env_thirdparty.disable_warnings() + +env_thirdparty.add_source_files(env.servers_sources, thirdparty_sources) diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp index c83473ef07..1dd95969e6 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp @@ -653,6 +653,14 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged if (light_data.shadow_opacity > 0.001) { RS::LightDirectionalShadowMode smode = light->directional_shadow_mode; + light_data.soft_shadow_scale = light->param[RS::LIGHT_PARAM_SHADOW_BLUR]; + light_data.softshadow_angle = angular_diameter; + light_data.bake_mode = light->bake_mode; + + if (angular_diameter <= 0.0) { + light_data.soft_shadow_scale *= RendererSceneRenderRD::get_singleton()->directional_shadow_quality_radius_get(); // Only use quality radius for PCF + } + int limit = smode == RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ? 0 : (smode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS ? 1 : 3); light_data.blend_splits = (smode != RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL) && light->directional_blend_splits; for (int j = 0; j < 4; j++) { @@ -669,7 +677,7 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged Projection shadow_mtx = rectm * bias * matrix * modelview; light_data.shadow_split_offsets[j] = split; - float bias_scale = light_instance->shadow_transform[j].bias_scale; + float bias_scale = light_instance->shadow_transform[j].bias_scale * light_data.soft_shadow_scale; light_data.shadow_bias[j] = light->param[RS::LIGHT_PARAM_SHADOW_BIAS] / 100.0 * bias_scale; light_data.shadow_normal_bias[j] = light->param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] * light_instance->shadow_transform[j].shadow_texel_size; light_data.shadow_transmittance_bias[j] = light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] * bias_scale; @@ -702,14 +710,6 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged float fade_start = light->param[RS::LIGHT_PARAM_SHADOW_FADE_START]; light_data.fade_from = -light_data.shadow_split_offsets[3] * MIN(fade_start, 0.999); //using 1.0 would break smoothstep light_data.fade_to = -light_data.shadow_split_offsets[3]; - - light_data.soft_shadow_scale = light->param[RS::LIGHT_PARAM_SHADOW_BLUR]; - light_data.softshadow_angle = angular_diameter; - light_data.bake_mode = light->bake_mode; - - if (angular_diameter <= 0.0) { - light_data.soft_shadow_scale *= RendererSceneRenderRD::get_singleton()->directional_shadow_quality_radius_get(); // Only use quality radius for PCF - } } r_directional_light_count++; @@ -978,6 +978,7 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged light_data.soft_shadow_size = 0.0; light_data.soft_shadow_scale *= RendererSceneRenderRD::get_singleton()->shadows_quality_radius_get(); // Only use quality radius for PCF } + light_data.shadow_bias *= light_data.soft_shadow_scale; } } else { light_data.shadow_opacity = 0.0; diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp index 1fecac9045..709e4b449f 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp @@ -85,7 +85,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[j + 3] = 0; // ignored } } else { - int v = value; + uint32_t v = value; gui[0] = v & 1 ? 1 : 0; gui[1] = v & 2 ? 1 : 0; } @@ -112,7 +112,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[j + 3] = 0; // ignored } } else { - int v = value; + uint32_t v = value; gui[0] = (v & 1) ? 1 : 0; gui[1] = (v & 2) ? 1 : 0; gui[2] = (v & 4) ? 1 : 0; @@ -141,7 +141,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } } } else { - int v = value; + uint32_t v = value; gui[0] = (v & 1) ? 1 : 0; gui[1] = (v & 2) ? 1 : 0; gui[2] = (v & 4) ? 1 : 0; @@ -734,7 +734,7 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, switch (type) { case ShaderLanguage::TYPE_BOOL: { uint32_t *gui = (uint32_t *)data; - *gui = value[0].boolean ? 1 : 0; + gui[0] = value[0].boolean ? 1 : 0; } break; case ShaderLanguage::TYPE_BVEC2: { uint32_t *gui = (uint32_t *)data; @@ -903,7 +903,9 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type, case ShaderLanguage::TYPE_BVEC3: case ShaderLanguage::TYPE_IVEC3: case ShaderLanguage::TYPE_UVEC3: - case ShaderLanguage::TYPE_VEC3: + case ShaderLanguage::TYPE_VEC3: { + memset(data, 0, 12 * p_array_size); + } break; case ShaderLanguage::TYPE_BVEC4: case ShaderLanguage::TYPE_IVEC4: case ShaderLanguage::TYPE_UVEC4: @@ -926,6 +928,104 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type, } /////////////////////////////////////////////////////////////////////////// +// MaterialStorage::ShaderData + +void MaterialStorage::ShaderData::set_path_hint(const String &p_hint) { + path = p_hint; +} + +void MaterialStorage::ShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { + if (!p_texture.is_valid()) { + if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { + default_texture_params[p_name].erase(p_index); + + if (default_texture_params[p_name].is_empty()) { + default_texture_params.erase(p_name); + } + } + } else { + if (!default_texture_params.has(p_name)) { + default_texture_params[p_name] = HashMap<int, RID>(); + } + default_texture_params[p_name][p_index] = p_texture; + } +} + +Variant MaterialStorage::ShaderData::get_default_parameter(const StringName &p_parameter) const { + if (uniforms.has(p_parameter)) { + ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; + Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; + return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); + } + return Variant(); +} + +void MaterialStorage::ShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { + SortArray<Pair<StringName, int>, ShaderLanguage::UniformOrderComparator> sorter; + LocalVector<Pair<StringName, int>> filtered_uniforms; + + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { + continue; + } + if (E.value.texture_order >= 0) { + filtered_uniforms.push_back(Pair<StringName, int>(E.key, E.value.texture_order + 100000)); + } else { + filtered_uniforms.push_back(Pair<StringName, int>(E.key, E.value.order)); + } + } + int uniform_count = filtered_uniforms.size(); + sorter.sort(filtered_uniforms.ptr(), uniform_count); + + String last_group; + for (int i = 0; i < uniform_count; i++) { + const StringName &uniform_name = filtered_uniforms[i].first; + const ShaderLanguage::ShaderNode::Uniform &uniform = uniforms[uniform_name]; + + String group = uniform.group; + if (!uniform.subgroup.is_empty()) { + group += "::" + uniform.subgroup; + } + + if (group != last_group) { + PropertyInfo pi; + pi.usage = PROPERTY_USAGE_GROUP; + pi.name = group; + p_param_list->push_back(pi); + + last_group = group; + } + + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniform); + pi.name = uniform_name; + p_param_list->push_back(pi); + } +} + +void MaterialStorage::ShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + continue; + } + + RendererMaterialStorage::InstanceShaderParam p; + p.info = ShaderLanguage::uniform_to_property_info(E.value); + p.info.name = E.key; //supply name + p.index = E.value.instance_index; + p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); + p_param_list->push_back(p); + } +} + +bool MaterialStorage::ShaderData::is_parameter_texture(const StringName &p_param) const { + if (!uniforms.has(p_param)) { + return false; + } + + return uniforms[p_param].texture_order >= 0; +} + +/////////////////////////////////////////////////////////////////////////// // MaterialStorage::MaterialData void MaterialStorage::MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const HashMap<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color) { @@ -1219,6 +1319,10 @@ void MaterialStorage::MaterialData::update_textures(const HashMap<StringName, Va roughness_detect_texture = tex; roughness_channel = RS::TextureDetectRoughnessChannel(p_texture_uniforms[i].hint - ShaderLanguage::ShaderNode::Uniform::HINT_ROUGHNESS_R); } + if (tex->render_target) { + tex->render_target->was_used = true; + render_target_cache.push_back(tex->render_target); + } #endif } if (rd_texture.is_null()) { @@ -1305,6 +1409,7 @@ bool MaterialStorage::MaterialData::update_parameters_uniform_set(const HashMap< if ((uint32_t)texture_cache.size() != tex_uniform_count || p_textures_dirty) { texture_cache.resize(tex_uniform_count); + render_target_cache.clear(); p_textures_dirty = true; //clear previous uniform set @@ -1365,6 +1470,12 @@ bool MaterialStorage::MaterialData::update_parameters_uniform_set(const HashMap< return true; } +void MaterialStorage::MaterialData::set_as_used() { + for (int i = 0; i < render_target_cache.size(); i++) { + render_target_cache[i]->was_used = true; + } +} + /////////////////////////////////////////////////////////////////////////// // MaterialStorage @@ -2111,7 +2222,7 @@ void MaterialStorage::global_shader_parameters_load_settings(bool p_load_texture for (const PropertyInfo &E : settings) { if (E.name.begins_with("shader_globals/")) { StringName name = E.name.get_slice("/", 1); - Dictionary d = ProjectSettings::get_singleton()->get(E.name); + Dictionary d = GLOBAL_GET(E.name); ERR_CONTINUE(!d.has("type")); ERR_CONTINUE(!d.has("value")); @@ -2211,7 +2322,7 @@ void MaterialStorage::global_shader_parameters_instance_free(RID p_instance) { global_shader_uniforms.instance_buffer_pos.erase(p_instance); } -void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) { +void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count) { if (!global_shader_uniforms.instance_buffer_pos.has(p_instance)) { return; //just not allocated, ignore } @@ -2221,7 +2332,9 @@ void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, i return; //again, not allocated, ignore } ERR_FAIL_INDEX(p_index, ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES); - ERR_FAIL_COND_MSG(p_value.get_type() > Variant::COLOR, "Unsupported variant type for instance parameter: " + Variant::get_type_name(p_value.get_type())); //anything greater not supported + + Variant::Type value_type = p_value.get_type(); + ERR_FAIL_COND_MSG(p_value.get_type() > Variant::COLOR, "Unsupported variant type for instance parameter: " + Variant::get_type_name(value_type)); //anything greater not supported const ShaderLanguage::DataType datatype_from_value[Variant::COLOR + 1] = { ShaderLanguage::TYPE_MAX, //nil @@ -2247,9 +2360,23 @@ void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, i ShaderLanguage::TYPE_VEC4 //color }; - ShaderLanguage::DataType datatype = datatype_from_value[p_value.get_type()]; - - ERR_FAIL_COND_MSG(datatype == ShaderLanguage::TYPE_MAX, "Unsupported variant type for instance parameter: " + Variant::get_type_name(p_value.get_type())); //anything greater not supported + ShaderLanguage::DataType datatype = ShaderLanguage::TYPE_MAX; + if (value_type == Variant::INT && p_flags_count > 0) { + switch (p_flags_count) { + case 1: + datatype = ShaderLanguage::TYPE_BVEC2; + break; + case 2: + datatype = ShaderLanguage::TYPE_BVEC3; + break; + case 3: + datatype = ShaderLanguage::TYPE_BVEC4; + break; + } + } else { + datatype = datatype_from_value[value_type]; + } + ERR_FAIL_COND_MSG(datatype == ShaderLanguage::TYPE_MAX, "Unsupported variant type for instance parameter: " + Variant::get_type_name(value_type)); //anything greater not supported pos += p_index; diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.h b/servers/rendering/renderer_rd/storage_rd/material_storage.h index 19c2f39553..989a0f7b45 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.h @@ -31,6 +31,8 @@ #ifndef MATERIAL_STORAGE_RD_H #define MATERIAL_STORAGE_RD_H +#include "texture_storage.h" + #include "core/math/projection.h" #include "core/templates/local_vector.h" #include "core/templates/rid_owner.h" @@ -54,24 +56,30 @@ public: }; struct ShaderData { - virtual void set_code(const String &p_Code) = 0; - virtual void set_path_hint(const String &p_hint) = 0; - virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) = 0; - virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const = 0; + String path; + HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; + HashMap<StringName, HashMap<int, RID>> default_texture_params; - virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const = 0; - virtual bool is_parameter_texture(const StringName &p_param) const = 0; + virtual void set_path_hint(const String &p_hint); + virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); + virtual Variant get_default_parameter(const StringName &p_parameter) const; + virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; + virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; + virtual bool is_parameter_texture(const StringName &p_param) const; + + virtual void set_code(const String &p_Code) = 0; virtual bool is_animated() const = 0; virtual bool casts_shadows() const = 0; - virtual Variant get_default_parameter(const StringName &p_parameter) const = 0; virtual RS::ShaderNativeSourceCode get_native_source_code() const { return RS::ShaderNativeSourceCode(); } virtual ~ShaderData() {} }; struct MaterialData { + Vector<RendererRD::TextureStorage::RenderTarget *> render_target_cache; void update_uniform_buffer(const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const HashMap<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color); void update_textures(const HashMap<StringName, Variant> &p_parameters, const HashMap<StringName, HashMap<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color); + void set_as_used(); virtual void set_render_priority(int p_priority) = 0; virtual void set_next_pass(RID p_pass) = 0; @@ -79,7 +87,7 @@ public: virtual ~MaterialData(); //to be used internally by update_parameters, in the most common configuration of material parameters - bool update_parameters_uniform_set(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const HashMap<StringName, HashMap<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, bool p_use_linear_color, uint32_t p_barrier = RD::BARRIER_MASK_ALL); + bool update_parameters_uniform_set(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const HashMap<StringName, HashMap<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, bool p_use_linear_color, uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS); void free_parameters_uniform_set(RID p_uniform_set); private: @@ -361,7 +369,7 @@ public: virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) override; virtual void global_shader_parameters_instance_free(RID p_instance) override; - virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) override; + virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0) override; RID global_shader_uniforms_get_storage_buffer() const; diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp index 1e74d31383..35fa3931f8 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp @@ -434,20 +434,8 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) } if (mesh->surface_count == 0) { - mesh->bone_aabbs = p_surface.bone_aabbs; mesh->aabb = p_surface.aabb; } else { - if (mesh->bone_aabbs.size() < p_surface.bone_aabbs.size()) { - // ArrayMesh::_surface_set_data only allocates bone_aabbs up to max_bone - // Each surface may affect different numbers of bones. - mesh->bone_aabbs.resize(p_surface.bone_aabbs.size()); - } - for (int i = 0; i < p_surface.bone_aabbs.size(); i++) { - const AABB &bone = p_surface.bone_aabbs[i]; - if (bone.has_volume()) { - mesh->bone_aabbs.write[i].merge_with(bone); - } - } mesh->aabb.merge_with(p_surface.aabb); } @@ -616,7 +604,7 @@ AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) { Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton); - if (!skeleton || skeleton->size == 0) { + if (!skeleton || skeleton->size == 0 || mesh->skeleton_aabb_version == skeleton->version) { return mesh->aabb; } @@ -708,6 +696,9 @@ AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) { } } + mesh->aabb = aabb; + + mesh->skeleton_aabb_version = skeleton->version; return aabb; } @@ -1841,7 +1832,7 @@ void MeshStorage::_update_dirty_multimeshes() { RD::get_singleton()->buffer_update(multimesh->buffer, buffer_offset * sizeof(float) + offset, MIN(region_size, size - offset), &data[region_start_index], RD::BARRIER_MASK_NO_BARRIER); } } - RD::get_singleton()->barrier(RD::BARRIER_MASK_NO_BARRIER, RD::BARRIER_MASK_ALL); + RD::get_singleton()->barrier(RD::BARRIER_MASK_NO_BARRIER, RD::BARRIER_MASK_ALL_BARRIERS); } memcpy(multimesh->previous_data_cache_dirty_regions, multimesh->data_cache_dirty_regions, data_cache_dirty_region_count * sizeof(bool)); diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h index c8a33bd4d7..a8feddc3b9 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h @@ -138,12 +138,11 @@ private: Surface **surfaces = nullptr; uint32_t surface_count = 0; - Vector<AABB> bone_aabbs; - bool has_bone_weights = false; AABB aabb; AABB custom_aabb; + uint64_t skeleton_aabb_version = 0; Vector<RID> material_cache; @@ -398,13 +397,11 @@ public: return s->index_count ? s->index_count : s->vertex_count; } - _FORCE_INLINE_ uint32_t mesh_surface_get_lod(void *p_surface, float p_model_scale, float p_distance_threshold, float p_mesh_lod_threshold, uint32_t *r_index_count = nullptr) const { + _FORCE_INLINE_ uint32_t mesh_surface_get_lod(void *p_surface, float p_model_scale, float p_distance_threshold, float p_mesh_lod_threshold, uint32_t &r_index_count) const { Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface); int32_t current_lod = -1; - if (r_index_count) { - *r_index_count = s->index_count; - } + r_index_count = s->index_count; for (uint32_t i = 0; i < s->lod_count; i++) { float screen_size = s->lods[i].edge_length * p_model_scale / p_distance_threshold; if (screen_size > p_mesh_lod_threshold) { @@ -415,9 +412,7 @@ public: if (current_lod == -1) { return 0; } else { - if (r_index_count) { - *r_index_count = s->lods[current_lod].index_count; - } + r_index_count = s->lods[current_lod].index_count; return current_lod + 1; } } @@ -668,7 +663,6 @@ public: 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; - void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform3D &p_world_transform); 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; diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp index 78f4c410c3..1e91982fe1 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "particles_storage.h" + #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #include "servers/rendering/rendering_server_globals.h" #include "texture_storage.h" @@ -424,7 +425,7 @@ void ParticlesStorage::particles_set_trails(RID p_particles, bool p_enable, doub p_length = MIN(10.0, p_length); particles->trails_enabled = p_enable; - particles->trail_length = p_length; + particles->trail_lifetime = p_length; _particles_free_data(particles); @@ -809,6 +810,15 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta //2D collision Transform2D xform = p_particles->sdf_collision_transform; //will use dotproduct manually so invert beforehand + + if (!p_particles->use_local_coords) { + Transform2D emission; + emission.columns[0] = Vector2(p_particles->emission_transform.basis.get_column(0).x, p_particles->emission_transform.basis.get_column(0).y); + emission.columns[1] = Vector2(p_particles->emission_transform.basis.get_column(1).x, p_particles->emission_transform.basis.get_column(1).y); + emission.set_origin(Vector2(p_particles->emission_transform.origin.x, p_particles->emission_transform.origin.y)); + xform = xform * emission.affine_inverse(); + } + Transform2D revert = xform.affine_inverse(); frame_params.collider_count = 1; frame_params.colliders[0].transform[0] = xform.columns[0][0]; @@ -1026,6 +1036,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta uniforms.push_back(u); } p_particles->collision_textures_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, particles_shader.default_shader_rd, 2); + p_particles->collision_heightmap_texture = collision_heightmap_texture; } } @@ -1105,6 +1116,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta if (m->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(m->uniform_set)) { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, m->uniform_set, 3); + m->set_as_used(); } RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ParticlesShader::PushConstant)); @@ -1219,7 +1231,9 @@ void ParticlesStorage::particles_set_view_axis(RID p_particles, const Vector3 &p RendererCompositorRD::singleton->get_effects()->sort_buffer(particles->particles_sort_uniform_set, particles->amount); } - copy_push_constant.total_particles *= copy_push_constant.total_particles; + if (particles->trails_enabled && particles->trail_bind_poses.size() > 1) { + copy_push_constant.total_particles *= particles->trail_bind_poses.size(); + } RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); uint32_t copy_pipeline = do_sort ? ParticlesShader::COPY_MODE_FILL_INSTANCES_WITH_SORT_BUFFER : ParticlesShader::COPY_MODE_FILL_INSTANCES; @@ -1334,10 +1348,7 @@ void ParticlesStorage::update_particles() { } } -#ifndef _MSC_VER -#warning Should use display refresh rate for all this -#endif - + // TODO: Should use display refresh rate for all this. float screen_hz = 60; int fixed_fps = 0; @@ -1351,7 +1362,7 @@ void ParticlesStorage::update_particles() { int history_size = 1; int trail_steps = 1; if (particles->trails_enabled && particles->trail_bind_poses.size() > 1) { - history_size = MAX(1, int(particles->trail_length * fixed_fps)); + history_size = MAX(1, int(particles->trail_lifetime * fixed_fps)); trail_steps = particles->trail_bind_poses.size(); } @@ -1533,9 +1544,6 @@ bool ParticlesStorage::particles_is_inactive(RID p_particles) const { /* Particles SHADER */ -void ParticlesStorage::ParticlesShaderData::set_path_hint(const String &p_path) { - path = p_path; -} void ParticlesStorage::ParticlesShaderData::set_code(const String &p_code) { ParticlesStorage *particles_storage = ParticlesStorage::get_singleton(); //compile @@ -1601,83 +1609,6 @@ void ParticlesStorage::ParticlesShaderData::set_code(const String &p_code) { valid = true; } -void ParticlesStorage::ParticlesShaderData::set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index) { - if (!p_texture.is_valid()) { - if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { - default_texture_params[p_name].erase(p_index); - - if (default_texture_params[p_name].is_empty()) { - default_texture_params.erase(p_name); - } - } - } else { - if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = HashMap<int, RID>(); - } - default_texture_params[p_name][p_index] = p_texture; - } -} - -void ParticlesStorage::ParticlesShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const { - HashMap<int, StringName> order; - - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - if (E.value.texture_order >= 0) { - order[E.value.texture_order + 100000] = E.key; - } else { - order[E.value.order] = E.key; - } - } - - String last_group; - for (const KeyValue<int, StringName> &E : order) { - String group = uniforms[E.value].group; - if (!uniforms[E.value].subgroup.is_empty()) { - group += "::" + uniforms[E.value].subgroup; - } - - if (group != last_group) { - PropertyInfo pi; - pi.usage = PROPERTY_USAGE_GROUP; - pi.name = group; - p_param_list->push_back(pi); - - last_group = group; - } - - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); - pi.name = E.value; - p_param_list->push_back(pi); - } -} - -void ParticlesStorage::ParticlesShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - RendererMaterialStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E.value); - p.info.name = E.key; //supply name - p.index = E.value.instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); - p_param_list->push_back(p); - } -} - -bool ParticlesStorage::ParticlesShaderData::is_parameter_texture(const StringName &p_param) const { - if (!uniforms.has(p_param)) { - return false; - } - - return uniforms[p_param].texture_order >= 0; -} - bool ParticlesStorage::ParticlesShaderData::is_animated() const { return false; } @@ -1686,15 +1617,6 @@ bool ParticlesStorage::ParticlesShaderData::casts_shadows() const { return false; } -Variant ParticlesStorage::ParticlesShaderData::get_default_parameter(const StringName &p_parameter) const { - if (uniforms.has(p_parameter)) { - ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; - Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; - return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); - } - return Variant(); -} - RS::ShaderNativeSourceCode ParticlesStorage::ParticlesShaderData::get_native_source_code() const { return ParticlesStorage::get_singleton()->particles_shader.shader.version_get_native_source_code(version); } diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.h b/servers/rendering/renderer_rd/storage_rd/particles_storage.h index 017844626f..ef3299ba1e 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h @@ -54,8 +54,7 @@ private: float velocity[3]; uint32_t active; float color[4]; - float custom[3]; - float lifetime; + float custom[4]; }; struct ParticlesFrameParams { @@ -97,7 +96,7 @@ private: uint32_t type; uint32_t texture_index; //texture index for vector field - real_t scale; + float scale; uint32_t pad[2]; }; @@ -106,8 +105,8 @@ private: float prev_system_phase; uint32_t cycle; - real_t explosiveness; - real_t randomness; + float explosiveness; + float randomness; float time; float delta; @@ -127,9 +126,6 @@ private: Collider colliders[MAX_COLLIDERS]; }; - struct ParticleEmissionBufferData { - }; - struct ParticleEmissionBuffer { struct Data { float xform[16]; @@ -232,7 +228,7 @@ private: Dependency dependency; - double trail_length = 1.0; + double trail_lifetime = 0.3; bool trails_enabled = false; LocalVector<ParticlesFrameParams> frame_history; LocalVector<ParticlesFrameParams> trail_params; @@ -317,15 +313,12 @@ private: RID version; bool uses_collision = false; - HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size = 0; - String path; String code; - HashMap<StringName, HashMap<int, RID>> default_texture_params; RID pipeline; @@ -335,14 +328,8 @@ private: uint32_t userdata_count = 0; virtual void set_code(const String &p_Code); - virtual void set_path_hint(const String &p_hint); - virtual void set_default_texture_parameter(const StringName &p_name, RID p_texture, int p_index); - virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const; - virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_parameter_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; - virtual Variant get_default_parameter(const StringName &p_parameter) const; virtual RS::ShaderNativeSourceCode get_native_source_code() const; ParticlesShaderData() {} @@ -412,7 +399,7 @@ public: bool owns_particles(RID p_rid) { return particles_owner.owns(p_rid); } virtual RID particles_allocate() override; - virtual void particles_initialize(RID p_particles_collision) override; + virtual void particles_initialize(RID p_rid) override; virtual void particles_free(RID p_rid) override; virtual void particles_set_mode(RID p_particles, RS::ParticlesMode p_mode) override; @@ -519,7 +506,7 @@ public: virtual void particles_add_collision(RID p_particles, RID p_particles_collision_instance) override; virtual void particles_remove_collision(RID p_particles, RID p_particles_collision_instance) override; - virtual 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 particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, RID p_texture); virtual void update_particles() override; @@ -546,7 +533,7 @@ public: virtual AABB particles_collision_get_aabb(RID p_particles_collision) const override; Vector3 particles_collision_get_extents(RID p_particles_collision) const; virtual bool particles_collision_is_heightfield(RID p_particles_collision) const override; - virtual RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const override; + RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const; Dependency *particles_collision_get_dependency(RID p_particles) const; diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp index 7dd790d1da..9b3d5a2d29 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp @@ -88,6 +88,7 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->directional_soft_shadow_kernel_get(), ubo.directional_soft_shadow_kernel); RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->penumbra_shadow_kernel_get(), ubo.penumbra_shadow_kernel); RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->soft_shadow_kernel_get(), ubo.soft_shadow_kernel); + ubo.camera_visible_layers = camera_visible_layers; ubo.viewport_size[0] = p_screen_size.x; ubo.viewport_size[1] = p_screen_size.y; diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h index c2dc7d5f4c..5ea4991e8e 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h @@ -45,6 +45,7 @@ public: Transform3D cam_transform; Projection cam_projection; Vector2 taa_jitter; + uint32_t camera_visible_layers; bool cam_orthogonal = false; // For stereo rendering @@ -61,7 +62,6 @@ public: float z_far = 0.0; float lod_distance_multiplier = 0.0; - Plane lod_camera_plane; float screen_mesh_lod_threshold = 0.0; uint32_t directional_light_count = 0; @@ -143,7 +143,7 @@ private: float IBL_exposure_normalization; // Adjusts for baked exposure. uint32_t pancake_shadows; - uint32_t pad1; + uint32_t camera_visible_layers; uint32_t pad2; uint32_t pad3; }; diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index b3a7e05ff5..67f013cfb0 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "texture_storage.h" + #include "../effects/copy_effects.h" #include "../framebuffer_cache_rd.h" #include "material_storage.h" @@ -418,11 +419,12 @@ TextureStorage::TextureStorage() { tformat.format = RD::DATA_FORMAT_R8_UINT; tformat.width = 4; tformat.height = 4; - tformat.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; - if (RD::get_singleton()->has_feature(RD::SUPPORTS_ATTACHMENT_VRS)) { - tformat.usage_bits |= RD::TEXTURE_USAGE_VRS_ATTACHMENT_BIT; - } + tformat.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_VRS_ATTACHMENT_BIT; tformat.texture_type = RD::TEXTURE_TYPE_2D; + if (!RD::get_singleton()->has_feature(RD::SUPPORTS_ATTACHMENT_VRS)) { + tformat.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; + tformat.format = RD::DATA_FORMAT_R8_UNORM; + } Vector<uint8_t> pv; pv.resize(4 * 4); @@ -559,6 +561,7 @@ void TextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS: void TextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) { CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); ERR_FAIL_NULL(ct); + ct->texture_repeat = p_repeat; ct->clear_sets(); } @@ -579,6 +582,9 @@ bool TextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasIte } ct = t->canvas_texture; + if (t->render_target) { + t->render_target->was_used = true; + } } else { ct = canvas_texture_owner.get_or_null(p_texture); } @@ -609,6 +615,9 @@ bool TextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasIte } else { u.append_id(t->rd_texture); ct->size_cache = Size2i(t->width_2d, t->height_2d); + if (t->render_target) { + t->render_target->was_used = true; + } } uniforms.push_back(u); } @@ -624,6 +633,9 @@ bool TextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasIte } else { u.append_id(t->rd_texture); ct->use_normal_cache = true; + if (t->render_target) { + t->render_target->was_used = true; + } } uniforms.push_back(u); } @@ -639,6 +651,9 @@ bool TextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasIte } else { u.append_id(t->rd_texture); ct->use_specular_cache = true; + if (t->render_target) { + t->render_target->was_used = true; + } } uniforms.push_back(u); } @@ -1123,9 +1138,7 @@ void TextureStorage::texture_proxy_update(RID p_texture, RID p_proxy_to) { void TextureStorage::texture_2d_placeholder_initialize(RID p_texture) { //this could be better optimized to reuse an existing image , done this way //for now to get it working - Ref<Image> image; - image.instantiate(); - image->create(4, 4, false, Image::FORMAT_RGBA8); + Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8); image->fill(Color(1, 0, 1, 1)); texture_2d_initialize(p_texture, image); @@ -1134,9 +1147,7 @@ void TextureStorage::texture_2d_placeholder_initialize(RID p_texture) { void TextureStorage::texture_2d_layered_placeholder_initialize(RID p_texture, RS::TextureLayeredType p_layered_type) { //this could be better optimized to reuse an existing image , done this way //for now to get it working - Ref<Image> image; - image.instantiate(); - image->create(4, 4, false, Image::FORMAT_RGBA8); + Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8); image->fill(Color(1, 0, 1, 1)); Vector<Ref<Image>> images; @@ -1155,9 +1166,7 @@ void TextureStorage::texture_2d_layered_placeholder_initialize(RID p_texture, RS void TextureStorage::texture_3d_placeholder_initialize(RID p_texture) { //this could be better optimized to reuse an existing image , done this way //for now to get it working - Ref<Image> image; - image.instantiate(); - image->create(4, 4, false, Image::FORMAT_RGBA8); + Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8); image->fill(Color(1, 0, 1, 1)); Vector<Ref<Image>> images; @@ -1180,9 +1189,7 @@ Ref<Image> TextureStorage::texture_2d_get(RID p_texture) const { #endif Vector<uint8_t> data = RD::get_singleton()->texture_get_data(tex->rd_texture, 0); ERR_FAIL_COND_V(data.size() == 0, Ref<Image>()); - Ref<Image> image; - image.instantiate(); - image->create(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data); + Ref<Image> image = Image::create_from_data(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data); ERR_FAIL_COND_V(image->is_empty(), Ref<Image>()); if (tex->format != tex->validated_format) { image->convert(tex->format); @@ -1203,9 +1210,7 @@ Ref<Image> TextureStorage::texture_2d_layer_get(RID p_texture, int p_layer) cons Vector<uint8_t> data = RD::get_singleton()->texture_get_data(tex->rd_texture, p_layer); ERR_FAIL_COND_V(data.size() == 0, Ref<Image>()); - Ref<Image> image; - image.instantiate(); - image->create(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data); + Ref<Image> image = Image::create_from_data(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data); ERR_FAIL_COND_V(image->is_empty(), Ref<Image>()); if (tex->format != tex->validated_format) { image->convert(tex->format); @@ -1231,9 +1236,7 @@ Vector<Ref<Image>> TextureStorage::texture_3d_get(RID p_texture) const { ERR_FAIL_COND_V(bs.offset + bs.buffer_size > (uint32_t)all_data.size(), Vector<Ref<Image>>()); Vector<uint8_t> sub_region = all_data.slice(bs.offset, bs.offset + bs.buffer_size); - Ref<Image> img; - img.instantiate(); - img->create(bs.size.width, bs.size.height, false, tex->validated_format, sub_region); + Ref<Image> img = Image::create_from_data(bs.size.width, bs.size.height, false, tex->validated_format, sub_region); ERR_FAIL_COND_V(img->is_empty(), Vector<Ref<Image>>()); if (tex->format != tex->validated_format) { img->convert(tex->format); @@ -1347,6 +1350,13 @@ Size2 TextureStorage::texture_size_with_proxy(RID p_proxy) { return texture_2d_get_size(p_proxy); } +RID TextureStorage::texture_get_rd_texture_rid(RID p_texture, bool p_srgb) const { + Texture *tex = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND_V(!tex, RID()); + + return (p_srgb && tex->rd_texture_srgb.is_valid()) ? tex->rd_texture_srgb : tex->rd_texture; +} + Ref<Image> TextureStorage::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) { Ref<Image> image = p_image->duplicate(); @@ -1496,9 +1506,7 @@ Ref<Image> TextureStorage::_validate_texture_format(const Ref<Image> &p_image, T } break; case Image::FORMAT_RGBE9995: { r_format.format = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32; -#ifndef _MSC_VER -#warning TODO need to make a function in Image to swap bits for this -#endif + // TODO: Need to make a function in Image to swap bits for this. r_format.swizzle_r = RD::TEXTURE_SWIZZLE_IDENTITY; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_IDENTITY; r_format.swizzle_b = RD::TEXTURE_SWIZZLE_IDENTITY; @@ -2403,6 +2411,10 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) { rt->color = RID(); rt->color_multisample = RID(); + if (rt->texture.is_valid()) { + Texture *tex = get_texture(rt->texture); + tex->render_target = nullptr; + } } void TextureStorage::_update_render_target(RenderTarget *rt) { @@ -2462,6 +2474,7 @@ void TextureStorage::_update_render_target(RenderTarget *rt) { RD::TEXTURE_SAMPLES_8, }; rd_color_multisample_format.samples = texture_samples[rt->msaa]; + rd_color_multisample_format.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; RD::TextureView rd_view_multisample; rd_color_multisample_format.is_resolve_buffer = false; rt->color_multisample = RD::get_singleton()->texture_create(rd_color_multisample_format, rd_view_multisample); @@ -2482,6 +2495,7 @@ void TextureStorage::_update_render_target(RenderTarget *rt) { tex->rd_texture = RID(); tex->rd_texture_srgb = RID(); + tex->render_target = rt; //create shared textures to the color buffer, //so transparent can be supported @@ -2606,11 +2620,13 @@ RID TextureStorage::render_target_get_texture(RID p_render_target) { return rt->texture; } -void TextureStorage::render_target_set_override_color(RID p_render_target, RID p_texture) { +void TextureStorage::render_target_set_override(RID p_render_target, RID p_color_texture, RID p_depth_texture, RID p_velocity_texture) { RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); - rt->overridden.color = p_texture; + rt->overridden.color = p_color_texture; + rt->overridden.depth = p_depth_texture; + rt->overridden.velocity = p_velocity_texture; } RID TextureStorage::render_target_get_override_color(RID p_render_target) const { @@ -2620,13 +2636,6 @@ RID TextureStorage::render_target_get_override_color(RID p_render_target) const return rt->overridden.color; } -void TextureStorage::render_target_set_override_depth(RID p_render_target, RID p_texture) { - RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - - rt->overridden.depth = p_texture; -} - RID TextureStorage::render_target_get_override_depth(RID p_render_target) const { RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, RID()); @@ -2653,13 +2662,6 @@ RID TextureStorage::render_target_get_override_depth_slice(RID p_render_target, } } -void TextureStorage::render_target_set_override_velocity(RID p_render_target, RID p_texture) { - RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - - rt->overridden.velocity = p_texture; -} - RID TextureStorage::render_target_get_override_velocity(RID p_render_target) const { RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, RID()); @@ -3136,9 +3138,11 @@ void TextureStorage::render_target_copy_to_back_buffer(RID p_render_target, cons // TODO figure out stereo support here - //single texture copy for backbuffer - //RD::get_singleton()->texture_copy(rt->color, rt->backbuffer_mipmap0, Vector3(region.position.x, region.position.y, 0), Vector3(region.position.x, region.position.y, 0), Vector3(region.size.x, region.size.y, 1), 0, 0, 0, 0, true); - copy_effects->copy_to_rect(rt->color, rt->backbuffer_mipmap0, region, false, false, false, true, true); + if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) { + copy_effects->copy_to_rect(rt->color, rt->backbuffer_mipmap0, region, false, false, false, true, true); + } else { + copy_effects->copy_to_fb_rect(rt->color, rt->backbuffer_fb, region, false, false, false, false, RID(), false, true); + } if (!p_gen_mipmaps) { return; @@ -3147,14 +3151,22 @@ void TextureStorage::render_target_copy_to_back_buffer(RID p_render_target, cons //then mipmap blur RID prev_texture = rt->color; //use color, not backbuffer, as bb has mipmaps. + Size2i texture_size = rt->size; + for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) { region.position.x >>= 1; region.position.y >>= 1; region.size.x = MAX(1, region.size.x >> 1); region.size.y = MAX(1, region.size.y >> 1); + texture_size.x = MAX(1, texture_size.x >> 1); + texture_size.y = MAX(1, texture_size.y >> 1); RID mipmap = rt->backbuffer_mipmaps[i]; - copy_effects->gaussian_blur(prev_texture, mipmap, region, true); + if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) { + copy_effects->gaussian_blur(prev_texture, mipmap, region, texture_size, true); + } else { + copy_effects->gaussian_blur_raster(prev_texture, mipmap, region, texture_size); + } prev_texture = mipmap; } RD::get_singleton()->draw_command_end_label(); @@ -3182,7 +3194,11 @@ void TextureStorage::render_target_clear_back_buffer(RID p_render_target, const } //single texture copy for backbuffer - copy_effects->set_color(rt->backbuffer_mipmap0, p_color, region, true); + if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) { + copy_effects->set_color(rt->backbuffer_mipmap0, p_color, region, true); + } else { + copy_effects->set_color_raster(rt->backbuffer_mipmap0, p_color, region); + } } void TextureStorage::render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region) { @@ -3208,15 +3224,23 @@ void TextureStorage::render_target_gen_back_buffer_mipmaps(RID p_render_target, RD::get_singleton()->draw_command_begin_label("Gaussian Blur Mipmaps2"); //then mipmap blur RID prev_texture = rt->backbuffer_mipmap0; + Size2i texture_size = rt->size; for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) { region.position.x >>= 1; region.position.y >>= 1; region.size.x = MAX(1, region.size.x >> 1); region.size.y = MAX(1, region.size.y >> 1); + texture_size.x = MAX(1, texture_size.x >> 1); + texture_size.y = MAX(1, texture_size.y >> 1); RID mipmap = rt->backbuffer_mipmaps[i]; - copy_effects->gaussian_blur(prev_texture, mipmap, region, true); + + if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) { + copy_effects->gaussian_blur(prev_texture, mipmap, region, texture_size, true); + } else { + copy_effects->gaussian_blur_raster(prev_texture, mipmap, region, texture_size); + } prev_texture = mipmap; } RD::get_singleton()->draw_command_end_label(); diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h index 00b4e50737..0c70d3f938 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h @@ -108,6 +108,8 @@ private: /* Texture API */ + struct RenderTarget; + class Texture { public: TextureType type; @@ -141,6 +143,7 @@ private: Vector<BufferSlice3D> buffer_slices_3d; uint32_t buffer_size_3d = 0; + RenderTarget *render_target = nullptr; bool is_render_target; bool is_proxy; @@ -491,6 +494,8 @@ public: virtual Size2 texture_size_with_proxy(RID p_proxy) override; + virtual RID texture_get_rd_texture_rid(RID p_texture, bool p_srgb = false) const override; + //internal usage _FORCE_INLINE_ TextureType texture_get_type(RID p_texture) { RendererRD::TextureStorage::Texture *tex = texture_owner.get_or_null(p_texture); @@ -718,12 +723,10 @@ public: virtual void render_target_set_vrs_texture(RID p_render_target, RID p_texture) override; virtual RID render_target_get_vrs_texture(RID p_render_target) const override; - virtual void render_target_set_override_color(RID p_render_target, RID p_texture) override; + virtual void render_target_set_override(RID p_render_target, RID p_color_texture, RID p_depth_texture, RID p_velocity_texture) override; virtual RID render_target_get_override_color(RID p_render_target) const override; - virtual void render_target_set_override_depth(RID p_render_target, RID p_texture) override; virtual RID render_target_get_override_depth(RID p_render_target) const override; RID render_target_get_override_depth_slice(RID p_render_target, const uint32_t p_layer) const; - virtual void render_target_set_override_velocity(RID p_render_target, RID p_texture) override; virtual RID render_target_get_override_velocity(RID p_render_target) const override; RID render_target_get_override_velocity_slice(RID p_render_target, const uint32_t p_layer) const; diff --git a/servers/rendering/renderer_rd/storage_rd/utilities.cpp b/servers/rendering/renderer_rd/storage_rd/utilities.cpp index e517186955..625f089f66 100644 --- a/servers/rendering/renderer_rd/storage_rd/utilities.cpp +++ b/servers/rendering/renderer_rd/storage_rd/utilities.cpp @@ -200,7 +200,7 @@ void Utilities::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_de if (p_enter) { if (!vn->enter_callback.is_null()) { if (p_deferred) { - vn->enter_callback.call_deferredp(nullptr, 0); + vn->enter_callback.call_deferred(); } else { Variant r; Callable::CallError ce; @@ -210,7 +210,7 @@ void Utilities::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_de } else { if (!vn->exit_callback.is_null()) { if (p_deferred) { - vn->exit_callback.call_deferredp(nullptr, 0); + vn->exit_callback.call_deferred(); } else { Variant r; Callable::CallError ce; @@ -321,3 +321,11 @@ RenderingDevice::DeviceType Utilities::get_video_adapter_type() const { String Utilities::get_video_adapter_api_version() const { return RenderingDevice::get_singleton()->get_device_api_version(); } + +Size2i Utilities::get_maximum_viewport_size() const { + RenderingDevice *device = RenderingDevice::get_singleton(); + + int max_x = device->limit_get(RenderingDevice::LIMIT_MAX_VIEWPORT_DIMENSIONS_X); + int max_y = device->limit_get(RenderingDevice::LIMIT_MAX_VIEWPORT_DIMENSIONS_Y); + return Size2i(max_x, max_y); +} diff --git a/servers/rendering/renderer_rd/storage_rd/utilities.h b/servers/rendering/renderer_rd/storage_rd/utilities.h index a80eb8510e..dda656c380 100644 --- a/servers/rendering/renderer_rd/storage_rd/utilities.h +++ b/servers/rendering/renderer_rd/storage_rd/utilities.h @@ -115,6 +115,8 @@ public: virtual String get_video_adapter_vendor() const override; virtual RenderingDevice::DeviceType get_video_adapter_type() const override; virtual String get_video_adapter_api_version() const override; + + virtual Size2i get_maximum_viewport_size() const override; }; } // namespace RendererRD diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index 66a64d4372..cfc25fc577 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -869,12 +869,7 @@ void RendererSceneCull::instance_set_transform(RID p_instance, const Transform3D for (int i = 0; i < 4; i++) { const Vector3 &v = i < 3 ? p_transform.basis.rows[i] : p_transform.origin; - ERR_FAIL_COND(Math::is_inf(v.x)); - ERR_FAIL_COND(Math::is_nan(v.x)); - ERR_FAIL_COND(Math::is_inf(v.y)); - ERR_FAIL_COND(Math::is_nan(v.y)); - ERR_FAIL_COND(Math::is_inf(v.z)); - ERR_FAIL_COND(Math::is_nan(v.z)); + ERR_FAIL_COND(!v.is_finite()); } #endif @@ -1454,8 +1449,23 @@ void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, c } else { E->value.value = p_value; if (E->value.index >= 0 && instance->instance_allocated_shader_uniforms) { + int flags_count = 0; + if (E->value.info.hint == PROPERTY_HINT_FLAGS) { + // A small hack to detect boolean flags count and prevent overhead. + switch (E->value.info.hint_string.length()) { + case 3: // "x,y" + flags_count = 1; + break; + case 5: // "x,y,z" + flags_count = 2; + break; + case 7: // "x,y,z,w" + flags_count = 3; + break; + } + } //update directly - RSG::material_storage->global_shader_parameters_instance_update(p_instance, E->value.index, p_value); + RSG::material_storage->global_shader_parameters_instance_update(p_instance, E->value.index, p_value, flags_count); } } } @@ -2502,7 +2512,7 @@ void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_bu } break; } - camera_data.set_camera(transform, projection, is_orthogonal, vaspect, jitter); + camera_data.set_camera(transform, projection, is_orthogonal, vaspect, jitter, camera->visible_layers); } else { // Setup our camera for our XR interface. // We can support multiple views here each with their own camera @@ -2510,7 +2520,7 @@ void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_bu Projection projections[RendererSceneRender::MAX_RENDER_VIEWS]; uint32_t view_count = p_xr_interface->get_view_count(); - ERR_FAIL_COND_MSG(view_count > RendererSceneRender::MAX_RENDER_VIEWS, "Requested view count is not supported"); + ERR_FAIL_COND_MSG(view_count == 0 || view_count > RendererSceneRender::MAX_RENDER_VIEWS, "Requested view count is not supported"); float aspect = p_viewport_size.width / (float)p_viewport_size.height; @@ -2524,7 +2534,7 @@ void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_bu } if (view_count == 1) { - camera_data.set_camera(transforms[0], projections[0], false, camera->vaspect, jitter); + camera_data.set_camera(transforms[0], projections[0], false, camera->vaspect, jitter, camera->visible_layers); } else if (view_count == 2) { camera_data.set_multiview_camera(view_count, transforms, projections, false, camera->vaspect); } else { @@ -3309,7 +3319,7 @@ void RendererSceneCull::render_empty_scene(const Ref<RenderSceneBuffers> &p_rend RendererSceneRender::CameraData camera_data; camera_data.set_camera(Transform3D(), Projection(), true, false); - scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RenderGeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr); + scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RenderGeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), environment, RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr); #endif } @@ -3862,7 +3872,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { } if (p_instance->material_overlay.is_valid()) { - can_cast_shadows = can_cast_shadows || RSG::material_storage->material_casts_shadows(p_instance->material_overlay); + can_cast_shadows = can_cast_shadows && RSG::material_storage->material_casts_shadows(p_instance->material_overlay); is_animated = is_animated || RSG::material_storage->material_is_animated(p_instance->material_overlay); _update_instance_shader_uniforms_from_material(isparams, p_instance->instance_shader_uniforms, p_instance->material_overlay); } @@ -3889,7 +3899,22 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { for (const KeyValue<StringName, Instance::InstanceShaderParameter> &E : p_instance->instance_shader_uniforms) { if (E.value.value.get_type() != Variant::NIL) { - RSG::material_storage->global_shader_parameters_instance_update(p_instance->self, E.value.index, E.value.value); + int flags_count = 0; + if (E.value.info.hint == PROPERTY_HINT_FLAGS) { + // A small hack to detect boolean flags count and prevent overhead. + switch (E.value.info.hint_string.length()) { + case 3: // "x,y" + flags_count = 1; + break; + case 5: // "x,y,z" + flags_count = 2; + break; + case 7: // "x,y,z,w" + flags_count = 3; + break; + } + } + RSG::material_storage->global_shader_parameters_instance_update(p_instance->self, E.value.index, E.value.value, flags_count); } } } else { diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index d085b84a8c..51f800381b 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -476,6 +476,7 @@ public: Instance *instance = (Instance *)tracker->userdata; switch (p_notification) { case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: + case Dependency::DEPENDENCY_CHANGED_SKELETON_BONES: case Dependency::DEPENDENCY_CHANGED_AABB: { singleton->_instance_queue_update(instance, true, false); @@ -491,8 +492,7 @@ public: case Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE: { singleton->_instance_queue_update(instance, true, true); } break; - case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: - case Dependency::DEPENDENCY_CHANGED_SKELETON_BONES: { + case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: { //ignored } break; case Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR: { @@ -1173,7 +1173,6 @@ public: PASS1RC(RID, environment_get_glow_map, RID) PASS1(environment_glow_set_use_bicubic_upscale, bool) - PASS1(environment_glow_set_use_high_quality, bool) // SSR PASS6(environment_set_ssr, RID, bool, int, float, float, float) diff --git a/servers/rendering/renderer_scene_occlusion_cull.cpp b/servers/rendering/renderer_scene_occlusion_cull.cpp index bda0950097..e1ca5a7103 100644 --- a/servers/rendering/renderer_scene_occlusion_cull.cpp +++ b/servers/rendering/renderer_scene_occlusion_cull.cpp @@ -180,7 +180,7 @@ RID RendererSceneOcclusionCull::HZBuffer::get_debug_texture() { ptrw[i] = MIN(mips[0][i] / debug_tex_range, 1.0) * 255; } - debug_image->create(sizes[0].x, sizes[0].y, false, Image::FORMAT_L8, debug_data); + debug_image->set_data(sizes[0].x, sizes[0].y, false, Image::FORMAT_L8, debug_data); if (debug_texture.is_null()) { debug_texture = RS::get_singleton()->texture_2d_create(debug_image); diff --git a/servers/rendering/renderer_scene_render.cpp b/servers/rendering/renderer_scene_render.cpp index f085168df3..3c069f6e2e 100644 --- a/servers/rendering/renderer_scene_render.cpp +++ b/servers/rendering/renderer_scene_render.cpp @@ -33,7 +33,7 @@ ///////////////////////////////////////////////////////////////////////////// // CameraData -void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter) { +void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter, const uint32_t p_visible_layers) { view_count = 1; is_orthogonal = p_is_orthogonal; vaspect = p_vaspect; @@ -41,6 +41,7 @@ void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, main_transform = p_transform; main_projection = p_projection; + visible_layers = p_visible_layers; view_offset[0] = Transform3D(); view_projection[0] = p_projection; taa_jitter = p_taa_jitter; @@ -49,6 +50,7 @@ void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect) { ERR_FAIL_COND_MSG(p_view_count != 2, "Incorrect view count for stereoscopic view"); + visible_layers = 0xFFFFFFFF; view_count = p_view_count; is_orthogonal = p_is_orthogonal; vaspect = p_vaspect; diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h index a8df897077..71f0a78ef3 100644 --- a/servers/rendering/renderer_scene_render.h +++ b/servers/rendering/renderer_scene_render.h @@ -162,7 +162,6 @@ public: RID environment_get_glow_map(RID p_env) const; virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; - virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; // SSR void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance); @@ -268,6 +267,7 @@ public: // flags uint32_t view_count; bool is_orthogonal; + uint32_t visible_layers; bool vaspect; // Main/center projection @@ -278,7 +278,7 @@ public: Projection view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; Vector2 taa_jitter; - void set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter = Vector2()); + void set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter = Vector2(), uint32_t p_visible_layers = 0xFFFFFFFF); void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect); }; diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 4f7683493b..8cec531393 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -530,7 +530,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { ptr = ptr->filter_next_ptr; } - RSG::canvas->render_canvas(p_viewport->render_target, canvas, xform, canvas_lights, canvas_directional_lights, clip_rect, p_viewport->texture_filter, p_viewport->texture_repeat, p_viewport->snap_2d_transforms_to_pixel, p_viewport->snap_2d_vertices_to_pixel); + RSG::canvas->render_canvas(p_viewport->render_target, canvas, xform, canvas_lights, canvas_directional_lights, clip_rect, p_viewport->texture_filter, p_viewport->texture_repeat, p_viewport->snap_2d_transforms_to_pixel, p_viewport->snap_2d_vertices_to_pixel, p_viewport->canvas_cull_mask); if (RSG::canvas->was_sdf_used()) { p_viewport->sdf_active = true; } @@ -550,6 +550,9 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { if (!can_draw_3d) { RSG::scene->render_empty_scene(p_viewport->render_buffers, p_viewport->scenario, p_viewport->shadow_atlas); } else { + // There may be an outstanding clear request if a clear was requested, but no 2D elements were drawn. + // Clear now otherwise we copy over garbage from the render target. + RSG::texture_storage->render_target_do_clear_request(p_viewport->render_target); _draw_3d(p_viewport); } } @@ -614,32 +617,32 @@ void RendererViewport::draw_viewports() { if (vp->use_xr) { if (xr_interface.is_valid()) { + // Ignore update mode we have to commit frames to our XR interface + visible = true; + // Override our size, make sure it matches our required size and is created as a stereo target Size2 xr_size = xr_interface->get_render_target_size(); _viewport_set_size(vp, xr_size.width, xr_size.height, xr_interface->get_view_count()); - - // Inform xr interface we're about to render its viewport, if this returns false we don't render - visible = xr_interface->pre_draw_viewport(vp->render_target); } else { // don't render anything visible = false; vp->size = Size2(); } - } - - if (vp->update_mode == RS::VIEWPORT_UPDATE_ALWAYS || vp->update_mode == RS::VIEWPORT_UPDATE_ONCE) { - visible = true; - } - - if (vp->update_mode == RS::VIEWPORT_UPDATE_WHEN_VISIBLE && RSG::texture_storage->render_target_was_used(vp->render_target)) { - visible = true; - } + } else { + if (vp->update_mode == RS::VIEWPORT_UPDATE_ALWAYS || vp->update_mode == RS::VIEWPORT_UPDATE_ONCE) { + visible = true; + } - if (vp->update_mode == RS::VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE) { - Viewport *parent = viewport_owner.get_or_null(vp->parent); - if (parent && parent->last_pass == draw_viewports_pass) { + if (vp->update_mode == RS::VIEWPORT_UPDATE_WHEN_VISIBLE && RSG::texture_storage->render_target_was_used(vp->render_target)) { visible = true; } + + if (vp->update_mode == RS::VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE) { + Viewport *parent = viewport_owner.get_or_null(vp->parent); + if (parent && parent->last_pass == draw_viewports_pass) { + visible = true; + } + } } visible = visible && vp->size.x > 1 && vp->size.y > 1; @@ -664,40 +667,43 @@ void RendererViewport::draw_viewports() { RSG::texture_storage->render_target_set_as_unused(vp->render_target); if (vp->use_xr && xr_interface.is_valid()) { - RSG::texture_storage->render_target_set_override_color(vp->render_target, xr_interface->get_color_texture()); - RSG::texture_storage->render_target_set_override_depth(vp->render_target, xr_interface->get_depth_texture()); - RSG::texture_storage->render_target_set_override_velocity(vp->render_target, xr_interface->get_velocity_texture()); - - // render... - RSG::scene->set_debug_draw_mode(vp->debug_draw); - - // and draw viewport - _draw_viewport(vp); - - // measure - - // commit our eyes - Vector<BlitToScreen> blits = xr_interface->post_draw_viewport(vp->render_target, vp->viewport_to_screen_rect); - if (vp->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID) { - if (OS::get_singleton()->get_current_rendering_driver_name() == "opengl3") { - if (blits.size() > 0) { - RSG::rasterizer->blit_render_targets_to_screen(vp->viewport_to_screen, blits.ptr(), blits.size()); - } - RSG::rasterizer->end_frame(true); - } else if (blits.size() > 0) { - if (!blit_to_screen_list.has(vp->viewport_to_screen)) { - blit_to_screen_list[vp->viewport_to_screen] = Vector<BlitToScreen>(); - } + // Inform XR interface we're about to render its viewport, + // if this returns false we don't render. + // This usually is a result of the player taking off their headset and OpenXR telling us to skip + // rendering frames. + if (xr_interface->pre_draw_viewport(vp->render_target)) { + RSG::texture_storage->render_target_set_override(vp->render_target, + xr_interface->get_color_texture(), + xr_interface->get_depth_texture(), + xr_interface->get_velocity_texture()); + + // render... + RSG::scene->set_debug_draw_mode(vp->debug_draw); + + // and draw viewport + _draw_viewport(vp); + + // commit our eyes + Vector<BlitToScreen> blits = xr_interface->post_draw_viewport(vp->render_target, vp->viewport_to_screen_rect); + if (vp->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID) { + if (OS::get_singleton()->get_current_rendering_driver_name() == "opengl3") { + if (blits.size() > 0) { + RSG::rasterizer->blit_render_targets_to_screen(vp->viewport_to_screen, blits.ptr(), blits.size()); + } + RSG::rasterizer->end_frame(true); + } else if (blits.size() > 0) { + if (!blit_to_screen_list.has(vp->viewport_to_screen)) { + blit_to_screen_list[vp->viewport_to_screen] = Vector<BlitToScreen>(); + } - for (int b = 0; b < blits.size(); b++) { - blit_to_screen_list[vp->viewport_to_screen].push_back(blits[b]); + for (int b = 0; b < blits.size(); b++) { + blit_to_screen_list[vp->viewport_to_screen].push_back(blits[b]); + } } } } } else { - RSG::texture_storage->render_target_set_override_color(vp->render_target, RID()); // TODO if fullscreen output, we can set this to our texture chain - RSG::texture_storage->render_target_set_override_depth(vp->render_target, RID()); - RSG::texture_storage->render_target_set_override_velocity(vp->render_target, RID()); + RSG::texture_storage->render_target_set_override(vp->render_target, RID(), RID(), RID()); RSG::scene->set_debug_draw_mode(vp->debug_draw); @@ -1349,6 +1355,12 @@ void RendererViewport::set_default_clear_color(const Color &p_color) { RSG::texture_storage->set_default_clear_color(p_color); } +void RendererViewport::viewport_set_canvas_cull_mask(RID p_viewport, uint32_t p_canvas_cull_mask) { + Viewport *viewport = viewport_owner.get_or_null(p_viewport); + ERR_FAIL_COND(!viewport); + viewport->canvas_cull_mask = p_canvas_cull_mask; +} + // Workaround for setting this on thread. void RendererViewport::call_set_vsync_mode(DisplayServer::VSyncMode p_mode, DisplayServer::WindowID p_window) { DisplayServer::get_singleton()->window_set_vsync_mode(p_mode, p_window); diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h index 55058a30b8..5e0c090ec0 100644 --- a/servers/rendering/renderer_viewport.h +++ b/servers/rendering/renderer_viewport.h @@ -117,6 +117,8 @@ public: bool transparent_bg = false; + uint32_t canvas_cull_mask = 0xffffffff; + struct CanvasKey { int64_t stacking; RID canvas; @@ -249,6 +251,8 @@ public: void viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform); void viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer); + void viewport_set_canvas_cull_mask(RID p_viewport, uint32_t p_canvas_cull_mask); + void viewport_set_positional_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = true); void viewport_set_positional_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv); diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index dd190437a3..28408ddb8e 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -32,8 +32,18 @@ #include "rendering_device_binds.h" +#include "thirdparty/spirv-reflect/spirv_reflect.h" + RenderingDevice *RenderingDevice::singleton = nullptr; +const char *RenderingDevice::shader_stage_names[RenderingDevice::SHADER_STAGE_MAX] = { + "Vertex", + "Fragment", + "TesselationControl", + "TesselationEvaluation", + "Compute", +}; + RenderingDevice *RenderingDevice::get_singleton() { return singleton; } @@ -170,10 +180,16 @@ RenderingDevice::VertexFormatID RenderingDevice::_vertex_format_create(const Typ return vertex_format_create(descriptions); } -RID RenderingDevice::_vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers) { +RID RenderingDevice::_vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers, const Vector<int64_t> &p_offsets) { Vector<RID> buffers = Variant(p_src_buffers); - return vertex_array_create(p_vertex_count, p_vertex_format, buffers); + Vector<uint64_t> offsets; + offsets.resize(p_offsets.size()); + for (int i = 0; i < p_offsets.size(); i++) { + offsets.write[i] = p_offsets[i]; + } + + return vertex_array_create(p_vertex_count, p_vertex_format, buffers, offsets); } Ref<RDShaderSPIRV> RenderingDevice::_shader_compile_spirv_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache) { @@ -246,7 +262,7 @@ RID RenderingDevice::_uniform_set_create(const TypedArray<RDUniform> &p_uniforms return uniform_set_create(uniforms, p_shader, p_shader_set); } -Error RenderingDevice::_buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, uint32_t p_post_barrier) { +Error RenderingDevice::_buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, BitField<BarrierMask> p_post_barrier) { return buffer_update(p_buffer, p_offset, p_size, p_data.ptr(), p_post_barrier); } @@ -280,7 +296,7 @@ static Vector<RenderingDevice::PipelineSpecializationConstant> _get_spec_constan return ret; } -RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags, uint32_t p_for_render_pass, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants) { +RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, BitField<PipelineDynamicStateFlags> p_dynamic_state_flags, uint32_t p_for_render_pass, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants) { PipelineRasterizationState rasterization_state; if (p_rasterization_state.is_valid()) { rasterization_state = p_rasterization_state->base; @@ -362,12 +378,329 @@ void RenderingDevice::_compute_list_set_push_constant(ComputeListID p_list, cons compute_list_set_push_constant(p_list, p_data.ptr(), p_data_size); } +Error RenderingDevice::_reflect_spirv(const Vector<ShaderStageSPIRVData> &p_spirv, SpirvReflectionData &r_reflection_data) { + r_reflection_data = {}; + + for (int i = 0; i < p_spirv.size(); i++) { + ShaderStage stage = p_spirv[i].shader_stage; + ShaderStage stage_flag = (ShaderStage)(1 << p_spirv[i].shader_stage); + + if (p_spirv[i].shader_stage == SHADER_STAGE_COMPUTE) { + r_reflection_data.is_compute = true; + ERR_FAIL_COND_V_MSG(p_spirv.size() != 1, FAILED, + "Compute shaders can only receive one stage, dedicated to compute."); + } + ERR_FAIL_COND_V_MSG(r_reflection_data.stages_mask.has_flag(stage_flag), FAILED, + "Stage " + String(shader_stage_names[p_spirv[i].shader_stage]) + " submitted more than once."); + + { + SpvReflectShaderModule module; + const uint8_t *spirv = p_spirv[i].spir_v.ptr(); + SpvReflectResult result = spvReflectCreateShaderModule(p_spirv[i].spir_v.size(), spirv, &module); + ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED, + "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed parsing shader."); + + if (r_reflection_data.is_compute) { + r_reflection_data.compute_local_size[0] = module.entry_points->local_size.x; + r_reflection_data.compute_local_size[1] = module.entry_points->local_size.y; + r_reflection_data.compute_local_size[2] = module.entry_points->local_size.z; + } + uint32_t binding_count = 0; + result = spvReflectEnumerateDescriptorBindings(&module, &binding_count, nullptr); + ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED, + "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed enumerating descriptor bindings."); + + if (binding_count > 0) { + // Parse bindings. + + Vector<SpvReflectDescriptorBinding *> bindings; + bindings.resize(binding_count); + result = spvReflectEnumerateDescriptorBindings(&module, &binding_count, bindings.ptrw()); + + ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED, + "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed getting descriptor bindings."); + + for (uint32_t j = 0; j < binding_count; j++) { + const SpvReflectDescriptorBinding &binding = *bindings[j]; + + SpirvReflectionData::Uniform info{}; + + bool need_array_dimensions = false; + bool need_block_size = false; + bool may_be_writable = false; + + switch (binding.descriptor_type) { + case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER: { + info.type = UNIFORM_TYPE_SAMPLER; + need_array_dimensions = true; + } break; + case SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: { + info.type = UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; + need_array_dimensions = true; + } break; + case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE: { + info.type = UNIFORM_TYPE_TEXTURE; + need_array_dimensions = true; + } break; + case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE: { + info.type = UNIFORM_TYPE_IMAGE; + need_array_dimensions = true; + may_be_writable = true; + } break; + case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: { + info.type = UNIFORM_TYPE_TEXTURE_BUFFER; + need_array_dimensions = true; + } break; + case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: { + info.type = UNIFORM_TYPE_IMAGE_BUFFER; + need_array_dimensions = true; + may_be_writable = true; + } break; + case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER: { + info.type = UNIFORM_TYPE_UNIFORM_BUFFER; + need_block_size = true; + } break; + case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER: { + info.type = UNIFORM_TYPE_STORAGE_BUFFER; + need_block_size = true; + may_be_writable = true; + } break; + case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: { + ERR_PRINT("Dynamic uniform buffer not supported."); + continue; + } break; + case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: { + ERR_PRINT("Dynamic storage buffer not supported."); + continue; + } break; + case SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: { + info.type = UNIFORM_TYPE_INPUT_ATTACHMENT; + need_array_dimensions = true; + } break; + case SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: { + ERR_PRINT("Acceleration structure not supported."); + continue; + } break; + } + + if (need_array_dimensions) { + if (binding.array.dims_count == 0) { + info.length = 1; + } else { + for (uint32_t k = 0; k < binding.array.dims_count; k++) { + if (k == 0) { + info.length = binding.array.dims[0]; + } else { + info.length *= binding.array.dims[k]; + } + } + } + + } else if (need_block_size) { + info.length = binding.block.size; + } else { + info.length = 0; + } + + if (may_be_writable) { + info.writable = !(binding.type_description->decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE) && !(binding.block.decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE); + } else { + info.writable = false; + } + + info.binding = binding.binding; + uint32_t set = binding.set; + + ERR_FAIL_COND_V_MSG(set >= MAX_UNIFORM_SETS, FAILED, + "On shader stage '" + String(shader_stage_names[stage]) + "', uniform '" + binding.name + "' uses a set (" + itos(set) + ") index larger than what is supported (" + itos(MAX_UNIFORM_SETS) + ")."); + + if (set < (uint32_t)r_reflection_data.uniforms.size()) { + // Check if this already exists. + bool exists = false; + for (int k = 0; k < r_reflection_data.uniforms[set].size(); k++) { + if (r_reflection_data.uniforms[set][k].binding == (uint32_t)info.binding) { + // Already exists, verify that it's the same type. + ERR_FAIL_COND_V_MSG(r_reflection_data.uniforms[set][k].type != info.type, FAILED, + "On shader stage '" + String(shader_stage_names[stage]) + "', uniform '" + binding.name + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(info.binding) + " with different uniform type."); + + // Also, verify that it's the same size. + ERR_FAIL_COND_V_MSG(r_reflection_data.uniforms[set][k].length != info.length, FAILED, + "On shader stage '" + String(shader_stage_names[stage]) + "', uniform '" + binding.name + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(info.binding) + " with different uniform size."); + + // Also, verify that it has the same writability. + ERR_FAIL_COND_V_MSG(r_reflection_data.uniforms[set][k].writable != info.writable, FAILED, + "On shader stage '" + String(shader_stage_names[stage]) + "', uniform '" + binding.name + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(info.binding) + " with different writability."); + + // Just append stage mask and return. + r_reflection_data.uniforms.write[set].write[k].stages_mask.set_flag(stage_flag); + exists = true; + break; + } + } + + if (exists) { + continue; // Merged. + } + } + + info.stages_mask.set_flag(stage_flag); + + if (set >= (uint32_t)r_reflection_data.uniforms.size()) { + r_reflection_data.uniforms.resize(set + 1); + } + + r_reflection_data.uniforms.write[set].push_back(info); + } + } + + { + // Specialization constants. + + uint32_t sc_count = 0; + result = spvReflectEnumerateSpecializationConstants(&module, &sc_count, nullptr); + ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED, + "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed enumerating specialization constants."); + + if (sc_count) { + Vector<SpvReflectSpecializationConstant *> spec_constants; + spec_constants.resize(sc_count); + + result = spvReflectEnumerateSpecializationConstants(&module, &sc_count, spec_constants.ptrw()); + ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED, + "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed obtaining specialization constants."); + + for (uint32_t j = 0; j < sc_count; j++) { + int32_t existing = -1; + SpirvReflectionData::SpecializationConstant sconst{}; + SpvReflectSpecializationConstant *spc = spec_constants[j]; + + sconst.constant_id = spc->constant_id; + sconst.int_value = 0; // Clear previous value JIC. + switch (spc->constant_type) { + case SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL: { + sconst.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL; + sconst.bool_value = spc->default_value.int_bool_value != 0; + } break; + case SPV_REFLECT_SPECIALIZATION_CONSTANT_INT: { + sconst.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT; + sconst.int_value = spc->default_value.int_bool_value; + } break; + case SPV_REFLECT_SPECIALIZATION_CONSTANT_FLOAT: { + sconst.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT; + sconst.float_value = spc->default_value.float_value; + } break; + } + sconst.stages_mask.set_flag(stage_flag); + + for (int k = 0; k < r_reflection_data.specialization_constants.size(); k++) { + if (r_reflection_data.specialization_constants[k].constant_id == sconst.constant_id) { + ERR_FAIL_COND_V_MSG(r_reflection_data.specialization_constants[k].type != sconst.type, FAILED, "More than one specialization constant used for id (" + itos(sconst.constant_id) + "), but their types differ."); + ERR_FAIL_COND_V_MSG(r_reflection_data.specialization_constants[k].int_value != sconst.int_value, FAILED, "More than one specialization constant used for id (" + itos(sconst.constant_id) + "), but their default values differ."); + existing = k; + break; + } + } + + if (existing > 0) { + r_reflection_data.specialization_constants.write[existing].stages_mask.set_flag(stage_flag); + } else { + r_reflection_data.specialization_constants.push_back(sconst); + } + } + } + } + + if (stage == SHADER_STAGE_VERTEX) { + uint32_t iv_count = 0; + result = spvReflectEnumerateInputVariables(&module, &iv_count, nullptr); + ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED, + "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed enumerating input variables."); + + if (iv_count) { + Vector<SpvReflectInterfaceVariable *> input_vars; + input_vars.resize(iv_count); + + result = spvReflectEnumerateInputVariables(&module, &iv_count, input_vars.ptrw()); + ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED, + "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed obtaining input variables."); + + for (uint32_t j = 0; j < iv_count; j++) { + if (input_vars[j] && input_vars[j]->decoration_flags == 0) { // Regular input. + r_reflection_data.vertex_input_mask |= (1 << uint32_t(input_vars[j]->location)); + } + } + } + } + + if (stage == SHADER_STAGE_FRAGMENT) { + uint32_t ov_count = 0; + result = spvReflectEnumerateOutputVariables(&module, &ov_count, nullptr); + ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED, + "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed enumerating output variables."); + + if (ov_count) { + Vector<SpvReflectInterfaceVariable *> output_vars; + output_vars.resize(ov_count); + + result = spvReflectEnumerateOutputVariables(&module, &ov_count, output_vars.ptrw()); + ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED, + "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed obtaining output variables."); + + for (uint32_t j = 0; j < ov_count; j++) { + const SpvReflectInterfaceVariable *refvar = output_vars[j]; + if (refvar != nullptr && refvar->built_in != SpvBuiltInFragDepth) { + r_reflection_data.fragment_output_mask |= 1 << refvar->location; + } + } + } + } + + uint32_t pc_count = 0; + result = spvReflectEnumeratePushConstantBlocks(&module, &pc_count, nullptr); + ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED, + "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed enumerating push constants."); + + if (pc_count) { + ERR_FAIL_COND_V_MSG(pc_count > 1, FAILED, + "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "': Only one push constant is supported, which should be the same across shader stages."); + + Vector<SpvReflectBlockVariable *> pconstants; + pconstants.resize(pc_count); + result = spvReflectEnumeratePushConstantBlocks(&module, &pc_count, pconstants.ptrw()); + ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED, + "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "' failed obtaining push constants."); +#if 0 + if (pconstants[0] == nullptr) { + Ref<FileAccess> f = FileAccess::open("res://popo.spv", FileAccess::WRITE); + f->store_buffer((const uint8_t *)&SpirV[0], SpirV.size() * sizeof(uint32_t)); + } +#endif + + ERR_FAIL_COND_V_MSG(r_reflection_data.push_constant_size && r_reflection_data.push_constant_size != pconstants[0]->size, FAILED, + "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_spirv[i].shader_stage]) + "': Push constant block must be the same across shader stages."); + + r_reflection_data.push_constant_size = pconstants[0]->size; + r_reflection_data.push_constant_stages_mask.set_flag(stage_flag); + + //print_line("Stage: " + String(shader_stage_names[stage]) + " push constant of size=" + itos(push_constant.push_constant_size)); + } + + // Destroy the reflection data when no longer required. + spvReflectDestroyShaderModule(&module); + } + + r_reflection_data.stages_mask.set_flag(stage_flag); + } + + return OK; +} + void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("texture_create", "format", "view", "data"), &RenderingDevice::_texture_create, DEFVAL(Array())); ClassDB::bind_method(D_METHOD("texture_create_shared", "view", "with_texture"), &RenderingDevice::_texture_create_shared); ClassDB::bind_method(D_METHOD("texture_create_shared_from_slice", "view", "with_texture", "layer", "mipmap", "mipmaps", "slice_type"), &RenderingDevice::_texture_create_shared_from_slice, DEFVAL(1), DEFVAL(TEXTURE_SLICE_2D)); - ClassDB::bind_method(D_METHOD("texture_update", "texture", "layer", "data", "post_barrier"), &RenderingDevice::texture_update, DEFVAL(BARRIER_MASK_ALL)); + ClassDB::bind_method(D_METHOD("texture_update", "texture", "layer", "data", "post_barrier"), &RenderingDevice::texture_update, DEFVAL(BARRIER_MASK_ALL_BARRIERS)); ClassDB::bind_method(D_METHOD("texture_get_data", "texture", "layer"), &RenderingDevice::texture_get_data); ClassDB::bind_method(D_METHOD("texture_is_format_supported_for_usage", "format", "usage_flags"), &RenderingDevice::texture_is_format_supported_for_usage); @@ -375,9 +708,9 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("texture_is_shared", "texture"), &RenderingDevice::texture_is_shared); ClassDB::bind_method(D_METHOD("texture_is_valid", "texture"), &RenderingDevice::texture_is_valid); - ClassDB::bind_method(D_METHOD("texture_copy", "from_texture", "to_texture", "from_pos", "to_pos", "size", "src_mipmap", "dst_mipmap", "src_layer", "dst_layer", "post_barrier"), &RenderingDevice::texture_copy, DEFVAL(BARRIER_MASK_ALL)); - ClassDB::bind_method(D_METHOD("texture_clear", "texture", "color", "base_mipmap", "mipmap_count", "base_layer", "layer_count", "post_barrier"), &RenderingDevice::texture_clear, DEFVAL(BARRIER_MASK_ALL)); - ClassDB::bind_method(D_METHOD("texture_resolve_multisample", "from_texture", "to_texture", "post_barrier"), &RenderingDevice::texture_resolve_multisample, DEFVAL(BARRIER_MASK_ALL)); + ClassDB::bind_method(D_METHOD("texture_copy", "from_texture", "to_texture", "from_pos", "to_pos", "size", "src_mipmap", "dst_mipmap", "src_layer", "dst_layer", "post_barrier"), &RenderingDevice::texture_copy, DEFVAL(BARRIER_MASK_ALL_BARRIERS)); + ClassDB::bind_method(D_METHOD("texture_clear", "texture", "color", "base_mipmap", "mipmap_count", "base_layer", "layer_count", "post_barrier"), &RenderingDevice::texture_clear, DEFVAL(BARRIER_MASK_ALL_BARRIERS)); + ClassDB::bind_method(D_METHOD("texture_resolve_multisample", "from_texture", "to_texture", "post_barrier"), &RenderingDevice::texture_resolve_multisample, DEFVAL(BARRIER_MASK_ALL_BARRIERS)); ClassDB::bind_method(D_METHOD("framebuffer_format_create", "attachments", "view_count"), &RenderingDevice::_framebuffer_format_create, DEFVAL(1)); ClassDB::bind_method(D_METHOD("framebuffer_format_create_multipass", "attachments", "passes", "view_count"), &RenderingDevice::_framebuffer_format_create_multipass, DEFVAL(1)); @@ -393,6 +726,7 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("vertex_buffer_create", "size_bytes", "data", "use_as_storage"), &RenderingDevice::vertex_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("vertex_format_create", "vertex_descriptions"), &RenderingDevice::_vertex_format_create); + ClassDB::bind_method(D_METHOD("vertex_array_create", "vertex_count", "vertex_format", "src_buffers", "offsets"), &RenderingDevice::_vertex_array_create, DEFVAL(Vector<int64_t>())); ClassDB::bind_method(D_METHOD("index_buffer_create", "size_indices", "format", "data", "use_restart_indices"), &RenderingDevice::index_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("index_array_create", "index_buffer", "index_offset", "index_count"), &RenderingDevice::index_array_create); @@ -410,8 +744,8 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("uniform_set_create", "uniforms", "shader", "shader_set"), &RenderingDevice::_uniform_set_create); ClassDB::bind_method(D_METHOD("uniform_set_is_valid", "uniform_set"), &RenderingDevice::uniform_set_is_valid); - ClassDB::bind_method(D_METHOD("buffer_update", "buffer", "offset", "size_bytes", "data", "post_barrier"), &RenderingDevice::_buffer_update, DEFVAL(BARRIER_MASK_ALL)); - ClassDB::bind_method(D_METHOD("buffer_clear", "buffer", "offset", "size_bytes", "post_barrier"), &RenderingDevice::buffer_clear, DEFVAL(BARRIER_MASK_ALL)); + ClassDB::bind_method(D_METHOD("buffer_update", "buffer", "offset", "size_bytes", "data", "post_barrier"), &RenderingDevice::_buffer_update, DEFVAL(BARRIER_MASK_ALL_BARRIERS)); + ClassDB::bind_method(D_METHOD("buffer_clear", "buffer", "offset", "size_bytes", "post_barrier"), &RenderingDevice::buffer_clear, DEFVAL(BARRIER_MASK_ALL_BARRIERS)); ClassDB::bind_method(D_METHOD("buffer_get_data", "buffer"), &RenderingDevice::buffer_get_data); ClassDB::bind_method(D_METHOD("render_pipeline_create", "shader", "framebuffer_format", "vertex_format", "primitive", "rasterization_state", "multisample_state", "stencil_state", "color_blend_state", "dynamic_state_flags", "for_render_pass", "specialization_constants"), &RenderingDevice::_render_pipeline_create, DEFVAL(0), DEFVAL(0), DEFVAL(TypedArray<RDPipelineSpecializationConstant>())); @@ -444,7 +778,7 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_list_switch_to_next_pass"), &RenderingDevice::draw_list_switch_to_next_pass); ClassDB::bind_method(D_METHOD("draw_list_switch_to_next_pass_split", "splits"), &RenderingDevice::_draw_list_switch_to_next_pass_split); - ClassDB::bind_method(D_METHOD("draw_list_end", "post_barrier"), &RenderingDevice::draw_list_end, DEFVAL(BARRIER_MASK_ALL)); + ClassDB::bind_method(D_METHOD("draw_list_end", "post_barrier"), &RenderingDevice::draw_list_end, DEFVAL(BARRIER_MASK_ALL_BARRIERS)); ClassDB::bind_method(D_METHOD("compute_list_begin", "allow_draw_overlap"), &RenderingDevice::compute_list_begin, DEFVAL(false)); ClassDB::bind_method(D_METHOD("compute_list_bind_compute_pipeline", "compute_list", "compute_pipeline"), &RenderingDevice::compute_list_bind_compute_pipeline); @@ -452,7 +786,7 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("compute_list_bind_uniform_set", "compute_list", "uniform_set", "set_index"), &RenderingDevice::compute_list_bind_uniform_set); ClassDB::bind_method(D_METHOD("compute_list_dispatch", "compute_list", "x_groups", "y_groups", "z_groups"), &RenderingDevice::compute_list_dispatch); ClassDB::bind_method(D_METHOD("compute_list_add_barrier", "compute_list"), &RenderingDevice::compute_list_add_barrier); - ClassDB::bind_method(D_METHOD("compute_list_end", "post_barrier"), &RenderingDevice::compute_list_end, DEFVAL(BARRIER_MASK_ALL)); + ClassDB::bind_method(D_METHOD("compute_list_end", "post_barrier"), &RenderingDevice::compute_list_end, DEFVAL(BARRIER_MASK_ALL_BARRIERS)); ClassDB::bind_method(D_METHOD("free_rid", "rid"), &RenderingDevice::free); @@ -468,7 +802,7 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("submit"), &RenderingDevice::submit); ClassDB::bind_method(D_METHOD("sync"), &RenderingDevice::sync); - ClassDB::bind_method(D_METHOD("barrier", "from", "to"), &RenderingDevice::barrier, DEFVAL(BARRIER_MASK_ALL), DEFVAL(BARRIER_MASK_ALL)); + ClassDB::bind_method(D_METHOD("barrier", "from", "to"), &RenderingDevice::barrier, DEFVAL(BARRIER_MASK_ALL_BARRIERS), DEFVAL(BARRIER_MASK_ALL_BARRIERS)); ClassDB::bind_method(D_METHOD("full_barrier"), &RenderingDevice::full_barrier); ClassDB::bind_method(D_METHOD("create_local_device"), &RenderingDevice::create_local_device); @@ -487,12 +821,6 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("get_driver_resource", "resource", "rid", "index"), &RenderingDevice::get_driver_resource); - BIND_CONSTANT(BARRIER_MASK_RASTER); - BIND_CONSTANT(BARRIER_MASK_COMPUTE); - BIND_CONSTANT(BARRIER_MASK_TRANSFER); - BIND_CONSTANT(BARRIER_MASK_ALL); - BIND_CONSTANT(BARRIER_MASK_NO_BARRIER); - BIND_ENUM_CONSTANT(DEVICE_TYPE_OTHER); BIND_ENUM_CONSTANT(DEVICE_TYPE_INTEGRATED_GPU); BIND_ENUM_CONSTANT(DEVICE_TYPE_DISCRETE_GPU); @@ -734,6 +1062,12 @@ void RenderingDevice::_bind_methods() { BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM); BIND_ENUM_CONSTANT(DATA_FORMAT_MAX); + BIND_BITFIELD_FLAG(BARRIER_MASK_RASTER); + BIND_BITFIELD_FLAG(BARRIER_MASK_COMPUTE); + BIND_BITFIELD_FLAG(BARRIER_MASK_TRANSFER); + BIND_BITFIELD_FLAG(BARRIER_MASK_ALL_BARRIERS); + BIND_BITFIELD_FLAG(BARRIER_MASK_NO_BARRIER); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_1D); BIND_ENUM_CONSTANT(TEXTURE_TYPE_2D); BIND_ENUM_CONSTANT(TEXTURE_TYPE_3D); @@ -752,16 +1086,16 @@ void RenderingDevice::_bind_methods() { BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_64); BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_MAX); - BIND_ENUM_CONSTANT(TEXTURE_USAGE_SAMPLING_BIT); - BIND_ENUM_CONSTANT(TEXTURE_USAGE_COLOR_ATTACHMENT_BIT); - BIND_ENUM_CONSTANT(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); - BIND_ENUM_CONSTANT(TEXTURE_USAGE_STORAGE_BIT); - BIND_ENUM_CONSTANT(TEXTURE_USAGE_STORAGE_ATOMIC_BIT); - BIND_ENUM_CONSTANT(TEXTURE_USAGE_CPU_READ_BIT); - BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_UPDATE_BIT); - BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_COPY_FROM_BIT); - BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_COPY_TO_BIT); - BIND_ENUM_CONSTANT(TEXTURE_USAGE_INPUT_ATTACHMENT_BIT); + BIND_BITFIELD_FLAG(TEXTURE_USAGE_SAMPLING_BIT); + BIND_BITFIELD_FLAG(TEXTURE_USAGE_COLOR_ATTACHMENT_BIT); + BIND_BITFIELD_FLAG(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); + BIND_BITFIELD_FLAG(TEXTURE_USAGE_STORAGE_BIT); + BIND_BITFIELD_FLAG(TEXTURE_USAGE_STORAGE_ATOMIC_BIT); + BIND_BITFIELD_FLAG(TEXTURE_USAGE_CPU_READ_BIT); + BIND_BITFIELD_FLAG(TEXTURE_USAGE_CAN_UPDATE_BIT); + BIND_BITFIELD_FLAG(TEXTURE_USAGE_CAN_COPY_FROM_BIT); + BIND_BITFIELD_FLAG(TEXTURE_USAGE_CAN_COPY_TO_BIT); + BIND_BITFIELD_FLAG(TEXTURE_USAGE_INPUT_ATTACHMENT_BIT); BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_IDENTITY); BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_ZERO); @@ -799,7 +1133,7 @@ void RenderingDevice::_bind_methods() { BIND_ENUM_CONSTANT(INDEX_BUFFER_FORMAT_UINT16); BIND_ENUM_CONSTANT(INDEX_BUFFER_FORMAT_UINT32); - BIND_ENUM_CONSTANT(STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT); + BIND_BITFIELD_FLAG(STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT); BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER); //for sampling only (sampler GLSL type) BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER_WITH_TEXTURE); // for sampling only); but includes a texture); (samplerXX GLSL type)); first a sampler then a texture @@ -899,13 +1233,13 @@ void RenderingDevice::_bind_methods() { BIND_ENUM_CONSTANT(BLEND_OP_MAXIMUM); BIND_ENUM_CONSTANT(BLEND_OP_MAX); - BIND_ENUM_CONSTANT(DYNAMIC_STATE_LINE_WIDTH); - BIND_ENUM_CONSTANT(DYNAMIC_STATE_DEPTH_BIAS); - BIND_ENUM_CONSTANT(DYNAMIC_STATE_BLEND_CONSTANTS); - BIND_ENUM_CONSTANT(DYNAMIC_STATE_DEPTH_BOUNDS); - BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_COMPARE_MASK); - BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_WRITE_MASK); - BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_REFERENCE); + BIND_BITFIELD_FLAG(DYNAMIC_STATE_LINE_WIDTH); + BIND_BITFIELD_FLAG(DYNAMIC_STATE_DEPTH_BIAS); + BIND_BITFIELD_FLAG(DYNAMIC_STATE_BLEND_CONSTANTS); + BIND_BITFIELD_FLAG(DYNAMIC_STATE_DEPTH_BOUNDS); + BIND_BITFIELD_FLAG(DYNAMIC_STATE_STENCIL_COMPARE_MASK); + BIND_BITFIELD_FLAG(DYNAMIC_STATE_STENCIL_WRITE_MASK); + BIND_BITFIELD_FLAG(DYNAMIC_STATE_STENCIL_REFERENCE); BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR); //start rendering and clear the framebuffer (supply params) BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR_REGION); //start rendering and clear the framebuffer (supply params) @@ -974,6 +1308,8 @@ void RenderingDevice::_bind_methods() { BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X); BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y); BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z); + BIND_ENUM_CONSTANT(LIMIT_MAX_VIEWPORT_DIMENSIONS_X); + BIND_ENUM_CONSTANT(LIMIT_MAX_VIEWPORT_DIMENSIONS_Y); BIND_ENUM_CONSTANT(MEMORY_TEXTURES); BIND_ENUM_CONSTANT(MEMORY_BUFFERS); diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 29e5c9cd77..0adc78894a 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -396,8 +396,8 @@ public: BARRIER_MASK_RASTER = 1, BARRIER_MASK_COMPUTE = 2, BARRIER_MASK_TRANSFER = 4, + BARRIER_MASK_ALL_BARRIERS = BARRIER_MASK_RASTER | BARRIER_MASK_COMPUTE | BARRIER_MASK_TRANSFER, // 7 BARRIER_MASK_NO_BARRIER = 8, - BARRIER_MASK_ALL = BARRIER_MASK_RASTER | BARRIER_MASK_COMPUTE | BARRIER_MASK_TRANSFER }; /*****************/ @@ -532,17 +532,17 @@ public: virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, uint32_t p_mipmaps = 1, TextureSliceType p_slice_type = TEXTURE_SLICE_2D) = 0; - virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; + virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0; virtual Vector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer) = 0; // CPU textures will return immediately, while GPU textures will most likely force a flush - virtual bool texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const = 0; + virtual bool texture_is_format_supported_for_usage(DataFormat p_format, BitField<RenderingDevice::TextureUsageBits> p_usage) const = 0; virtual bool texture_is_shared(RID p_texture) = 0; virtual bool texture_is_valid(RID p_texture) = 0; virtual Size2i texture_size(RID p_texture) = 0; - virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; - virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; - virtual Error texture_resolve_multisample(RID p_from_texture, RID p_to_texture, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; + virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0; + virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0; + virtual Error texture_resolve_multisample(RID p_from_texture, RID p_to_texture, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0; /*********************/ /**** FRAMEBUFFER ****/ @@ -683,7 +683,7 @@ public: // This ID is warranted to be unique for the same formats, does not need to be freed virtual VertexFormatID vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats) = 0; - virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers) = 0; + virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers, const Vector<uint64_t> &p_offsets = Vector<uint64_t>()) = 0; enum IndexBufferFormat { INDEX_BUFFER_FORMAT_UINT16, @@ -749,11 +749,11 @@ public: }; enum StorageBufferUsage { - STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT = 1 + STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT = 1, }; virtual RID uniform_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>()) = 0; - virtual RID storage_buffer_create(uint32_t p_size, const Vector<uint8_t> &p_data = Vector<uint8_t>(), uint32_t p_usage = 0) = 0; + virtual RID storage_buffer_create(uint32_t p_size, const Vector<uint8_t> &p_data = Vector<uint8_t>(), BitField<StorageBufferUsage> p_usage = 0) = 0; virtual RID texture_buffer_create(uint32_t p_size_elements, DataFormat p_format, const Vector<uint8_t> &p_data = Vector<uint8_t>()) = 0; struct Uniform { @@ -826,8 +826,8 @@ public: virtual bool uniform_set_is_valid(RID p_uniform_set) = 0; virtual void uniform_set_set_invalidation_callback(RID p_uniform_set, InvalidationCallback p_callback, void *p_userdata) = 0; - virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; - virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; + virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0; + virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0; virtual Vector<uint8_t> buffer_get_data(RID p_buffer) = 0; //this causes stall, only use to retrieve large buffers for saving /******************************************/ @@ -958,7 +958,7 @@ public: bool wireframe; PolygonCullMode cull_mode; PolygonFrontFace front_face; - bool depth_bias_enable; + bool depth_bias_enabled; float depth_bias_constant_factor; float depth_bias_clamp; float depth_bias_slope_factor; @@ -970,7 +970,7 @@ public: wireframe = false; cull_mode = POLYGON_CULL_DISABLED; front_face = POLYGON_FRONT_FACE_CLOCKWISE; - depth_bias_enable = false; + depth_bias_enabled = false; depth_bias_constant_factor = 0; depth_bias_clamp = 0; depth_bias_slope_factor = 0; @@ -1112,7 +1112,7 @@ public: }; virtual bool render_pipeline_is_valid(RID p_pipeline) = 0; - virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0, const Vector<PipelineSpecializationConstant> &p_specialization_constants = Vector<PipelineSpecializationConstant>()) = 0; + virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, BitField<PipelineDynamicStateFlags> p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0, const Vector<PipelineSpecializationConstant> &p_specialization_constants = Vector<PipelineSpecializationConstant>()) = 0; /**************************/ /**** COMPUTE PIPELINE ****/ @@ -1173,7 +1173,7 @@ public: virtual DrawListID draw_list_switch_to_next_pass() = 0; virtual Error draw_list_switch_to_next_pass_split(uint32_t p_splits, DrawListID *r_split_ids) = 0; - virtual void draw_list_end(uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; + virtual void draw_list_end(BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0; /***********************/ /**** COMPUTE LISTS ****/ @@ -1190,9 +1190,9 @@ public: virtual void compute_list_dispatch_indirect(ComputeListID p_list, RID p_buffer, uint32_t p_offset) = 0; virtual void compute_list_add_barrier(ComputeListID p_list) = 0; - virtual void compute_list_end(uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0; + virtual void compute_list_end(BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0; - virtual void barrier(uint32_t p_from = BARRIER_MASK_ALL, uint32_t p_to = BARRIER_MASK_ALL) = 0; + virtual void barrier(BitField<BarrierMask> p_from = BARRIER_MASK_ALL_BARRIERS, BitField<BarrierMask> p_to = BARRIER_MASK_ALL_BARRIERS) = 0; virtual void full_barrier() = 0; /***************/ @@ -1252,9 +1252,13 @@ public: LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X, LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y, LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z, + LIMIT_MAX_VIEWPORT_DIMENSIONS_X, + LIMIT_MAX_VIEWPORT_DIMENSIONS_Y, LIMIT_SUBGROUP_SIZE, LIMIT_SUBGROUP_IN_SHADERS, // Set flags using SHADER_STAGE_VERTEX_BIT, SHADER_STAGE_FRAGMENT_BIT, etc. LIMIT_SUBGROUP_OPERATIONS, + LIMIT_VRS_TEXEL_WIDTH, + LIMIT_VRS_TEXEL_HEIGHT, }; virtual uint64_t limit_get(Limit p_limit) const = 0; @@ -1297,6 +1301,10 @@ public: RenderingDevice(); protected: + static const char *shader_stage_names[RenderingDevice::SHADER_STAGE_MAX]; + + static const uint32_t MAX_UNIFORM_SETS = 16; + //binders to script API RID _texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data = Array()); RID _texture_create_shared(const Ref<RDTextureView> &p_view, RID p_with_texture); @@ -1308,7 +1316,7 @@ protected: RID _framebuffer_create_multipass(const TypedArray<RID> &p_textures, const TypedArray<RDFramebufferPass> &p_passes, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1); RID _sampler_create(const Ref<RDSamplerState> &p_state); VertexFormatID _vertex_format_create(const TypedArray<RDVertexAttribute> &p_vertex_formats); - RID _vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers); + RID _vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers, const Vector<int64_t> &p_offsets = Vector<int64_t>()); Ref<RDShaderSPIRV> _shader_compile_spirv_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache = true); Vector<uint8_t> _shader_compile_binary_from_spirv(const Ref<RDShaderSPIRV> &p_bytecode, const String &p_shader_name = ""); @@ -1316,15 +1324,48 @@ protected: RID _uniform_set_create(const TypedArray<RDUniform> &p_uniforms, RID p_shader, uint32_t p_shader_set); - Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL); + Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS); - RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags, uint32_t p_for_render_pass, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants); + RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, BitField<PipelineDynamicStateFlags> p_dynamic_state_flags, uint32_t p_for_render_pass, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants); RID _compute_pipeline_create(RID p_shader, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants); Vector<int64_t> _draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const TypedArray<RID> &p_storage_textures = TypedArray<RID>()); void _draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size); void _compute_list_set_push_constant(ComputeListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size); Vector<int64_t> _draw_list_switch_to_next_pass_split(uint32_t p_splits); + + struct SpirvReflectionData { + BitField<ShaderStage> stages_mask; + uint32_t vertex_input_mask; + uint32_t fragment_output_mask; + bool is_compute; + uint32_t compute_local_size[3]; + uint32_t push_constant_size; + BitField<ShaderStage> push_constant_stages_mask; + + struct Uniform { + UniformType type; + uint32_t binding; + BitField<ShaderStage> stages_mask; + uint32_t length; // Size of arrays (in total elements), or ubos (in bytes * total elements). + bool writable; + }; + Vector<Vector<Uniform>> uniforms; + + struct SpecializationConstant { + PipelineSpecializationConstantType type; + uint32_t constant_id; + union { + uint32_t int_value; + float float_value; + bool bool_value; + }; + BitField<ShaderStage> stages_mask; + }; + Vector<SpecializationConstant> specialization_constants; + }; + + Error _reflect_spirv(const Vector<ShaderStageSPIRVData> &p_spirv, SpirvReflectionData &r_reflection_data); }; VARIANT_ENUM_CAST(RenderingDevice::DeviceType) @@ -1333,9 +1374,10 @@ VARIANT_ENUM_CAST(RenderingDevice::ShaderStage) VARIANT_ENUM_CAST(RenderingDevice::ShaderLanguage) VARIANT_ENUM_CAST(RenderingDevice::CompareOperator) VARIANT_ENUM_CAST(RenderingDevice::DataFormat) +VARIANT_BITFIELD_CAST(RenderingDevice::BarrierMask); VARIANT_ENUM_CAST(RenderingDevice::TextureType) VARIANT_ENUM_CAST(RenderingDevice::TextureSamples) -VARIANT_ENUM_CAST(RenderingDevice::TextureUsageBits) +VARIANT_BITFIELD_CAST(RenderingDevice::TextureUsageBits) VARIANT_ENUM_CAST(RenderingDevice::TextureSwizzle) VARIANT_ENUM_CAST(RenderingDevice::TextureSliceType) VARIANT_ENUM_CAST(RenderingDevice::SamplerFilter) @@ -1343,7 +1385,7 @@ VARIANT_ENUM_CAST(RenderingDevice::SamplerRepeatMode) VARIANT_ENUM_CAST(RenderingDevice::SamplerBorderColor) VARIANT_ENUM_CAST(RenderingDevice::VertexFrequency) VARIANT_ENUM_CAST(RenderingDevice::IndexBufferFormat) -VARIANT_ENUM_CAST(RenderingDevice::StorageBufferUsage) +VARIANT_BITFIELD_CAST(RenderingDevice::StorageBufferUsage) VARIANT_ENUM_CAST(RenderingDevice::UniformType) VARIANT_ENUM_CAST(RenderingDevice::RenderPrimitive) VARIANT_ENUM_CAST(RenderingDevice::PolygonCullMode) @@ -1352,7 +1394,7 @@ VARIANT_ENUM_CAST(RenderingDevice::StencilOperation) VARIANT_ENUM_CAST(RenderingDevice::LogicOperation) VARIANT_ENUM_CAST(RenderingDevice::BlendFactor) VARIANT_ENUM_CAST(RenderingDevice::BlendOperation) -VARIANT_ENUM_CAST(RenderingDevice::PipelineDynamicStateFlags) +VARIANT_BITFIELD_CAST(RenderingDevice::PipelineDynamicStateFlags) VARIANT_ENUM_CAST(RenderingDevice::PipelineSpecializationConstantType) VARIANT_ENUM_CAST(RenderingDevice::InitialAction) VARIANT_ENUM_CAST(RenderingDevice::FinalAction) diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h index d95b46933c..dbff305794 100644 --- a/servers/rendering/rendering_device_binds.h +++ b/servers/rendering/rendering_device_binds.h @@ -66,7 +66,7 @@ public: RD_SETGET(uint32_t, mipmaps) RD_SETGET(RD::TextureType, texture_type) RD_SETGET(RD::TextureSamples, samples) - RD_SETGET(uint32_t, usage_bits) + RD_SETGET(BitField<RenderingDevice::TextureUsageBits>, usage_bits) void add_shareable_format(RD::DataFormat p_format) { base.shareable_formats.push_back(p_format); } void remove_shareable_format(RD::DataFormat p_format) { base.shareable_formats.erase(p_format); } @@ -517,7 +517,7 @@ public: RD_SETGET(bool, wireframe) RD_SETGET(RD::PolygonCullMode, cull_mode) RD_SETGET(RD::PolygonFrontFace, front_face) - RD_SETGET(bool, depth_bias_enable) + RD_SETGET(bool, depth_bias_enabled) RD_SETGET(float, depth_bias_constant_factor) RD_SETGET(float, depth_bias_clamp) RD_SETGET(float, depth_bias_slope_factor) @@ -531,7 +531,7 @@ protected: RD_BIND(Variant::BOOL, RDPipelineRasterizationState, wireframe); RD_BIND(Variant::INT, RDPipelineRasterizationState, cull_mode); RD_BIND(Variant::INT, RDPipelineRasterizationState, front_face); - RD_BIND(Variant::BOOL, RDPipelineRasterizationState, depth_bias_enable); + RD_BIND(Variant::BOOL, RDPipelineRasterizationState, depth_bias_enabled); RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_constant_factor); RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_clamp); RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_slope_factor); diff --git a/servers/rendering/rendering_method.h b/servers/rendering/rendering_method.h index c4d9e25ecd..51b9cb2bcf 100644 --- a/servers/rendering/rendering_method.h +++ b/servers/rendering/rendering_method.h @@ -203,7 +203,6 @@ public: virtual RID environment_get_glow_map(RID p_env) const = 0; virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; - virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; // SSR diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp index 9103b0cf56..c0cd564308 100644 --- a/servers/rendering/rendering_server_default.cpp +++ b/servers/rendering/rendering_server_default.cpp @@ -331,6 +331,14 @@ bool RenderingServerDefault::is_low_end() const { return RendererCompositor::is_low_end(); } +Size2i RenderingServerDefault::get_maximum_viewport_size() const { + if (RSG::utilities) { + return RSG::utilities->get_maximum_viewport_size(); + } else { + return Size2i(); + } +} + void RenderingServerDefault::_thread_exit() { exit.set(); } diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index fe212151e3..662b582411 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -212,6 +212,7 @@ public: FUNC1(texture_debug_usage, List<TextureInfo> *) FUNC2(texture_set_force_redraw_if_visible, RID, bool) + FUNC2RC(RID, texture_get_rd_texture_rid, RID, bool) /* SHADER API */ @@ -610,6 +611,8 @@ public: FUNC2(viewport_set_disable_environment, RID, bool) FUNC2(viewport_set_disable_3d, RID, bool) + FUNC2(viewport_set_canvas_cull_mask, RID, uint32_t) + FUNC2(viewport_attach_camera, RID, RID) FUNC2(viewport_set_scenario, RID, RID) FUNC2(viewport_attach_canvas, RID, RID) @@ -695,7 +698,6 @@ public: FUNC13(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float, float, RID) FUNC1(environment_glow_set_use_bicubic_upscale, bool) - FUNC1(environment_glow_set_use_high_quality, bool) FUNC4(environment_set_tonemap, RID, EnvironmentToneMapper, float, float) @@ -828,6 +830,8 @@ public: FUNC2(canvas_item_set_visible, RID, bool) FUNC2(canvas_item_set_light_mask, RID, int) + FUNC2(canvas_item_set_visibility_layer, RID, uint32_t) + FUNC2(canvas_item_set_update_when_visible, RID, bool) FUNC2(canvas_item_set_transform, RID, const Transform2D &) @@ -994,6 +998,8 @@ public: virtual void set_print_gpu_profile(bool p_enable) override; + virtual Size2i get_maximum_viewport_size() const override; + RenderingServerDefault(bool p_create_thread = false); ~RenderingServerDefault(); }; diff --git a/servers/rendering/shader_compiler.cpp b/servers/rendering/shader_compiler.cpp index 54cc7a011a..3604756fd8 100644 --- a/servers/rendering/shader_compiler.cpp +++ b/servers/rendering/shader_compiler.cpp @@ -373,16 +373,16 @@ void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const Str static String _get_global_shader_uniform_from_type_and_index(const String &p_buffer, const String &p_index, ShaderLanguage::DataType p_type) { switch (p_type) { case ShaderLanguage::TYPE_BOOL: { - return "(" + p_buffer + "[" + p_index + "].x != 0.0)"; + return "bool(floatBitsToUint(" + p_buffer + "[" + p_index + "].x))"; } case ShaderLanguage::TYPE_BVEC2: { - return "(notEqual(" + p_buffer + "[" + p_index + "].xy, vec2(0.0)))"; + return "bvec2(floatBitsToUint(" + p_buffer + "[" + p_index + "].xy))"; } case ShaderLanguage::TYPE_BVEC3: { - return "(notEqual(" + p_buffer + "[" + p_index + "].xyz, vec3(0.0)))"; + return "bvec3(floatBitsToUint(" + p_buffer + "[" + p_index + "].xyz))"; } case ShaderLanguage::TYPE_BVEC4: { - return "(notEqual(" + p_buffer + "[" + p_index + "].xyzw, vec4(0.0)))"; + return "bvec4(floatBitsToUint(" + p_buffer + "[" + p_index + "].xyzw))"; } case ShaderLanguage::TYPE_INT: { return "floatBitsToInt(" + p_buffer + "[" + p_index + "].x)"; @@ -1141,8 +1141,18 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene case SL::OP_STRUCT: case SL::OP_CONSTRUCT: { ERR_FAIL_COND_V(onode->arguments[0]->type != SL::Node::TYPE_VARIABLE, String()); - - SL::VariableNode *vnode = (SL::VariableNode *)onode->arguments[0]; + const SL::VariableNode *vnode = static_cast<const SL::VariableNode *>(onode->arguments[0]); + const SL::FunctionNode *func = nullptr; + const bool is_internal_func = internal_functions.has(vnode->name); + + if (!is_internal_func) { + for (int i = 0; i < shader->functions.size(); i++) { + if (shader->functions[i].name == vnode->name) { + func = shader->functions[i].function; + break; + } + } + } bool is_texture_func = false; bool is_screen_texture = false; @@ -1156,7 +1166,7 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene used_flag_pointers.insert(vnode->name); } - if (internal_functions.has(vnode->name)) { + if (is_internal_func) { code += vnode->name; is_texture_func = texture_functions.has(vnode->name); } else if (p_default_actions.renames.has(vnode->name)) { @@ -1172,6 +1182,44 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene if (i > 1) { code += ", "; } + + bool is_out_qualifier = false; + if (is_internal_func) { + is_out_qualifier = SL::is_builtin_func_out_parameter(vnode->name, i - 1); + } else if (func != nullptr) { + const SL::ArgumentQualifier qualifier = func->arguments[i - 1].qualifier; + is_out_qualifier = qualifier == SL::ARGUMENT_QUALIFIER_OUT || qualifier == SL::ARGUMENT_QUALIFIER_INOUT; + } + + if (is_out_qualifier) { + StringName name; + bool found = false; + { + const SL::Node *node = onode->arguments[i]; + + bool done = false; + do { + switch (node->type) { + case SL::Node::TYPE_VARIABLE: { + name = static_cast<const SL::VariableNode *>(node)->name; + done = true; + found = true; + } break; + case SL::Node::TYPE_MEMBER: { + node = static_cast<const SL::MemberNode *>(node)->owner; + } break; + default: { + done = true; + } break; + } + } while (!done); + } + + if (found && p_actions.write_flag_pointers.has(name)) { + *p_actions.write_flag_pointers[name] = true; + } + } + String node_code = _dump_node_code(onode->arguments[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); if (!RS::get_singleton()->is_low_end() && is_texture_func && i == 1) { //need to map from texture to sampler in order to sample when using Vulkan GLSL @@ -1239,7 +1287,7 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene } code += ")"; if (is_screen_texture && actions.apply_luminance_multiplier) { - code = "(" + code + " / vec4(vec3(sc_luminance_multiplier), 1.0))"; + code = "(" + code + " * vec4(vec3(sc_luminance_multiplier), 1.0))"; } } break; case SL::OP_INDEX: { diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index a92292209f..e451fb35c2 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -1251,7 +1251,7 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea if (is_shader_inc) { for (int i = 0; i < RenderingServer::SHADER_MAX; i++) { for (const KeyValue<StringName, FunctionInfo> &E : ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(i))) { - if ((current_function == E.key || E.key == "global") && E.value.built_ins.has(p_identifier)) { + if ((current_function == E.key || E.key == "global" || E.key == "constants") && E.value.built_ins.has(p_identifier)) { if (r_data_type) { *r_data_type = E.value.built_ins[p_identifier].type; } @@ -3645,7 +3645,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C switch (p_type) { case ShaderLanguage::TYPE_BOOL: if (array_size > 0) { - PackedInt32Array array = PackedInt32Array(); + PackedInt32Array array; for (int i = 0; i < array_size; i++) { array.push_back(p_value[i].boolean); } @@ -3658,7 +3658,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C array_size *= 2; if (array_size > 0) { - PackedInt32Array array = PackedInt32Array(); + PackedInt32Array array; for (int i = 0; i < array_size; i++) { array.push_back(p_value[i].boolean); } @@ -3671,7 +3671,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C array_size *= 3; if (array_size > 0) { - PackedInt32Array array = PackedInt32Array(); + PackedInt32Array array; for (int i = 0; i < array_size; i++) { array.push_back(p_value[i].boolean); } @@ -3684,7 +3684,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C array_size *= 4; if (array_size > 0) { - PackedInt32Array array = PackedInt32Array(); + PackedInt32Array array; for (int i = 0; i < array_size; i++) { array.push_back(p_value[i].boolean); } @@ -3695,7 +3695,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C break; case ShaderLanguage::TYPE_INT: if (array_size > 0) { - PackedInt32Array array = PackedInt32Array(); + PackedInt32Array array; for (int i = 0; i < array_size; i++) { array.push_back(p_value[i].sint); } @@ -3708,7 +3708,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C if (array_size > 0) { array_size *= 2; - PackedInt32Array array = PackedInt32Array(); + PackedInt32Array array; for (int i = 0; i < array_size; i++) { array.push_back(p_value[i].sint); } @@ -3721,7 +3721,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C if (array_size > 0) { array_size *= 3; - PackedInt32Array array = PackedInt32Array(); + PackedInt32Array array; for (int i = 0; i < array_size; i++) { array.push_back(p_value[i].sint); } @@ -3734,7 +3734,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C if (array_size > 0) { array_size *= 4; - PackedInt32Array array = PackedInt32Array(); + PackedInt32Array array; for (int i = 0; i < array_size; i++) { array.push_back(p_value[i].sint); } @@ -3745,7 +3745,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C break; case ShaderLanguage::TYPE_UINT: if (array_size > 0) { - PackedInt32Array array = PackedInt32Array(); + PackedInt32Array array; for (int i = 0; i < array_size; i++) { array.push_back(p_value[i].uint); } @@ -3758,7 +3758,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C if (array_size > 0) { array_size *= 2; - PackedInt32Array array = PackedInt32Array(); + PackedInt32Array array; for (int i = 0; i < array_size; i++) { array.push_back(p_value[i].uint); } @@ -3771,7 +3771,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C if (array_size > 0) { array_size *= 3; - PackedInt32Array array = PackedInt32Array(); + PackedInt32Array array; for (int i = 0; i < array_size; i++) { array.push_back(p_value[i].uint); } @@ -3784,7 +3784,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C if (array_size > 0) { array_size *= 4; - PackedInt32Array array = PackedInt32Array(); + PackedInt32Array array; for (int i = 0; i < array_size; i++) { array.push_back(p_value[i].uint); } @@ -3795,7 +3795,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C break; case ShaderLanguage::TYPE_FLOAT: if (array_size > 0) { - PackedFloat32Array array = PackedFloat32Array(); + PackedFloat32Array array; for (int i = 0; i < array_size; i++) { array.push_back(p_value[i].real); } @@ -3808,7 +3808,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C if (array_size > 0) { array_size *= 2; - PackedVector2Array array = PackedVector2Array(); + PackedVector2Array array; for (int i = 0; i < array_size; i += 2) { array.push_back(Vector2(p_value[i].real, p_value[i + 1].real)); } @@ -3822,13 +3822,13 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C array_size *= 3; if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) { - PackedColorArray array = PackedColorArray(); + PackedColorArray array; for (int i = 0; i < array_size; i += 3) { array.push_back(Color(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real)); } value = Variant(array); } else { - PackedVector3Array array = PackedVector3Array(); + PackedVector3Array array; for (int i = 0; i < array_size; i += 3) { array.push_back(Vector3(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real)); } @@ -3847,13 +3847,13 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C array_size *= 4; if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) { - PackedColorArray array = PackedColorArray(); + PackedColorArray array; for (int i = 0; i < array_size; i += 4) { array.push_back(Color(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real, p_value[i + 3].real)); } value = Variant(array); } else { - PackedFloat32Array array = PackedFloat32Array(); + PackedFloat32Array array; for (int i = 0; i < array_size; i += 4) { array.push_back(p_value[i].real); array.push_back(p_value[i + 1].real); @@ -3874,7 +3874,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C if (array_size > 0) { array_size *= 4; - PackedFloat32Array array = PackedFloat32Array(); + PackedFloat32Array array; for (int i = 0; i < array_size; i += 4) { array.push_back(p_value[i].real); array.push_back(p_value[i + 1].real); @@ -3890,7 +3890,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C if (array_size > 0) { array_size *= 9; - PackedFloat32Array array = PackedFloat32Array(); + PackedFloat32Array array; for (int i = 0; i < array_size; i += 9) { for (int j = 0; j < 9; j++) { array.push_back(p_value[i + j].real); @@ -3916,7 +3916,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C if (array_size > 0) { array_size *= 16; - PackedFloat32Array array = PackedFloat32Array(); + PackedFloat32Array array; for (int i = 0; i < array_size; i += 16) { for (int j = 0; j < 16; j++) { array.push_back(p_value[i + j].real); @@ -4110,43 +4110,41 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform case ShaderLanguage::TYPE_USAMPLER2D: { if (p_uniform.array_size > 0) { pi.type = Variant::ARRAY; + pi.hint = PROPERTY_HINT_ARRAY_TYPE; + pi.hint_string = MAKE_RESOURCE_TYPE_HINT("Texture2D"); } else { pi.type = Variant::OBJECT; + pi.hint = PROPERTY_HINT_RESOURCE_TYPE; + pi.hint_string = "Texture2D"; } - pi.hint = PROPERTY_HINT_RESOURCE_TYPE; - pi.hint_string = "Texture2D"; } break; case ShaderLanguage::TYPE_SAMPLER2DARRAY: case ShaderLanguage::TYPE_ISAMPLER2DARRAY: - case ShaderLanguage::TYPE_USAMPLER2DARRAY: { + case ShaderLanguage::TYPE_USAMPLER2DARRAY: + case ShaderLanguage::TYPE_SAMPLERCUBE: + case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: { if (p_uniform.array_size > 0) { pi.type = Variant::ARRAY; + pi.hint = PROPERTY_HINT_ARRAY_TYPE; + pi.hint_string = MAKE_RESOURCE_TYPE_HINT("TextureLayered"); } else { pi.type = Variant::OBJECT; + pi.hint = PROPERTY_HINT_RESOURCE_TYPE; + pi.hint_string = "TextureLayered"; } - pi.hint = PROPERTY_HINT_RESOURCE_TYPE; - pi.hint_string = "TextureLayered"; } break; case ShaderLanguage::TYPE_SAMPLER3D: case ShaderLanguage::TYPE_ISAMPLER3D: case ShaderLanguage::TYPE_USAMPLER3D: { if (p_uniform.array_size > 0) { pi.type = Variant::ARRAY; + pi.hint = PROPERTY_HINT_ARRAY_TYPE; + pi.hint_string = MAKE_RESOURCE_TYPE_HINT("Texture3D"); } else { pi.type = Variant::OBJECT; + pi.hint = PROPERTY_HINT_RESOURCE_TYPE; + pi.hint_string = "Texture3D"; } - pi.hint = PROPERTY_HINT_RESOURCE_TYPE; - pi.hint_string = "Texture3D"; - } break; - case ShaderLanguage::TYPE_SAMPLERCUBE: - case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: { - if (p_uniform.array_size > 0) { - pi.type = Variant::ARRAY; - } else { - pi.type = Variant::OBJECT; - } - pi.hint = PROPERTY_HINT_RESOURCE_TYPE; - pi.hint_string = "TextureLayered"; } break; case ShaderLanguage::TYPE_STRUCT: { // FIXME: Implement this. @@ -4309,8 +4307,18 @@ ShaderLanguage::DataType ShaderLanguage::get_scalar_type(DataType p_type) { TYPE_INT, TYPE_UINT, TYPE_FLOAT, + TYPE_INT, + TYPE_UINT, + TYPE_FLOAT, + TYPE_INT, + TYPE_UINT, + TYPE_FLOAT, + TYPE_FLOAT, + TYPE_VOID, }; + static_assert(sizeof(scalar_types) / sizeof(*scalar_types) == TYPE_MAX); + return scalar_types[p_type]; } @@ -4340,8 +4348,18 @@ int ShaderLanguage::get_cardinality(DataType p_type) { 1, 1, 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, }; + static_assert(sizeof(cardinality_table) / sizeof(*cardinality_table) == TYPE_MAX); + return cardinality_table[p_type]; } @@ -7570,7 +7588,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun return ERR_BUG; } - if (b && b->parent_function && p_function_info.main_function) { + if (b->parent_function && p_function_info.main_function) { _set_error(vformat(RTR("Using '%s' in the '%s' processor function is incorrect."), "return", b->parent_function->name)); return ERR_PARSE_ERROR; } @@ -8170,21 +8188,27 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f }; [[fallthrough]]; case TK_INSTANCE: { + if (tk.type == TK_INSTANCE) { #ifdef DEBUG_ENABLED - keyword_completion_context = CF_UNIFORM_KEYWORD; - if (_lookup_next(next)) { - if (next.type == TK_UNIFORM) { - keyword_completion_context ^= CF_UNIFORM_KEYWORD; + keyword_completion_context = CF_UNIFORM_KEYWORD; + if (_lookup_next(next)) { + if (next.type == TK_UNIFORM) { + keyword_completion_context ^= CF_UNIFORM_KEYWORD; + } } - } #endif // DEBUG_ENABLED - if (uniform_scope == ShaderNode::Uniform::SCOPE_LOCAL) { - tk = _get_token(); - if (tk.type != TK_UNIFORM) { - _set_expected_after_error("uniform", "instance"); + if (String(shader_type_identifier) != "spatial") { + _set_error(vformat(RTR("Uniform instances are not yet implemented for '%s' shaders."), shader_type_identifier)); return ERR_PARSE_ERROR; } - uniform_scope = ShaderNode::Uniform::SCOPE_INSTANCE; + if (uniform_scope == ShaderNode::Uniform::SCOPE_LOCAL) { + tk = _get_token(); + if (tk.type != TK_UNIFORM) { + _set_expected_after_error("uniform", "instance"); + return ERR_PARSE_ERROR; + } + uniform_scope = ShaderNode::Uniform::SCOPE_INSTANCE; + } } }; [[fallthrough]]; @@ -8635,12 +8659,15 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f } break; case TK_HINT_SCREEN_TEXTURE: { new_hint = ShaderNode::Uniform::HINT_SCREEN_TEXTURE; + --texture_uniforms; } break; case TK_HINT_NORMAL_ROUGHNESS_TEXTURE: { new_hint = ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE; + --texture_uniforms; } break; case TK_HINT_DEPTH_TEXTURE: { new_hint = ShaderNode::Uniform::HINT_DEPTH_TEXTURE; + --texture_uniforms; } break; case TK_FILTER_NEAREST: { new_filter = FILTER_NEAREST; @@ -8851,7 +8878,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f _set_error(RTR("Expected an uniform group identifier or `;`.")); } return ERR_PARSE_ERROR; - } else if (tk.type == TK_SEMICOLON && current_uniform_group_name.is_empty()) { + } else if (current_uniform_group_name.is_empty()) { _set_error(RTR("Group needs to be opened before.")); return ERR_PARSE_ERROR; } else { @@ -9710,6 +9737,25 @@ String ShaderLanguage::get_shader_type(const String &p_code) { return String(); } +bool ShaderLanguage::is_builtin_func_out_parameter(const String &p_name, int p_param) { + int i = 0; + while (builtin_func_out_args[i].name) { + if (p_name == builtin_func_out_args[i].name) { + for (int j = 0; j < BuiltinFuncOutArgs::MAX_ARGS; j++) { + int arg = builtin_func_out_args[i].arguments[j]; + if (arg == p_param) { + return true; + } + if (arg < 0) { + return false; + } + } + } + i++; + } + return false; +} + #ifdef DEBUG_ENABLED void ShaderLanguage::_check_warning_accums() { for (const KeyValue<ShaderWarning::Code, HashMap<StringName, HashMap<StringName, Usage>> *> &E : warnings_check_map2) { diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 1e302f5805..9c3cc9c5cd 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -720,6 +720,12 @@ public: Node(TYPE_SHADER) {} }; + struct UniformOrderComparator { + _FORCE_INLINE_ bool operator()(const Pair<StringName, int> &A, const Pair<StringName, int> &B) const { + return A.second < B.second; + } + }; + struct Expression { bool is_op; union { @@ -1119,6 +1125,7 @@ public: void clear(); static String get_shader_type(const String &p_code); + static bool is_builtin_func_out_parameter(const String &p_name, int p_param); struct ShaderCompileInfo { HashMap<StringName, FunctionInfo> functions; diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index 5e1da7c15d..86dd6a8b7e 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -100,6 +100,7 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["NODE_POSITION_WORLD"] = ShaderLanguage::TYPE_VEC3; shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CAMERA_POSITION_WORLD"] = ShaderLanguage::TYPE_VEC3; shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CAMERA_DIRECTION_WORLD"] = ShaderLanguage::TYPE_VEC3; + shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CAMERA_VISIBLE_LAYERS"] = ShaderLanguage::TYPE_UINT; shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["NODE_POSITION_VIEW"] = ShaderLanguage::TYPE_VEC3; shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VIEW_INDEX"] = constt(ShaderLanguage::TYPE_INT); @@ -147,6 +148,7 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NODE_POSITION_WORLD"] = ShaderLanguage::TYPE_VEC3; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["CAMERA_POSITION_WORLD"] = ShaderLanguage::TYPE_VEC3; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["CAMERA_DIRECTION_WORLD"] = ShaderLanguage::TYPE_VEC3; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["CAMERA_VISIBLE_LAYERS"] = ShaderLanguage::TYPE_UINT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NODE_POSITION_VIEW"] = ShaderLanguage::TYPE_VEC3; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["VIEW_INDEX"] = constt(ShaderLanguage::TYPE_INT); diff --git a/servers/rendering/storage/environment_storage.cpp b/servers/rendering/storage/environment_storage.cpp index 9b1842f1d9..78ce4eb4d0 100644 --- a/servers/rendering/storage/environment_storage.cpp +++ b/servers/rendering/storage/environment_storage.cpp @@ -283,7 +283,7 @@ void RendererEnvironmentStorage::environment_set_volumetric_fog(RID p_env, bool env->volumetric_fog_scattering = p_albedo; env->volumetric_fog_emission = p_emission; env->volumetric_fog_emission_energy = p_emission_energy; - env->volumetric_fog_anisotropy = p_anisotropy, + env->volumetric_fog_anisotropy = p_anisotropy; env->volumetric_fog_length = p_length; env->volumetric_fog_detail_spread = p_detail_spread; env->volumetric_fog_gi_inject = p_gi_inject; diff --git a/servers/rendering/storage/environment_storage.h b/servers/rendering/storage/environment_storage.h index 17bde94902..dea9487af6 100644 --- a/servers/rendering/storage/environment_storage.h +++ b/servers/rendering/storage/environment_storage.h @@ -98,7 +98,7 @@ private: float glow_hdr_luminance_cap = 12.0; float glow_hdr_bleed_scale = 2.0; float glow_map_strength = 0.0f; // 1.0f in GLES3 ?? - RID glow_map = RID(); + RID glow_map; // SSR bool ssr_enabled = false; @@ -143,7 +143,7 @@ private: float adjustments_contrast = 1.0f; float adjustments_saturation = 1.0f; bool use_1d_color_correction = false; - RID color_correction = RID(); + RID color_correction; }; mutable RID_Owner<Environment, true> environment_owner; diff --git a/servers/rendering/storage/material_storage.h b/servers/rendering/storage/material_storage.h index 396668c9ed..a3de6343e5 100644 --- a/servers/rendering/storage/material_storage.h +++ b/servers/rendering/storage/material_storage.h @@ -53,7 +53,7 @@ public: virtual int32_t global_shader_parameters_instance_allocate(RID p_instance) = 0; virtual void global_shader_parameters_instance_free(RID p_instance) = 0; - virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value) = 0; + virtual void global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count = 0) = 0; /* SHADER API */ virtual RID shader_allocate() = 0; diff --git a/servers/rendering/storage/particles_storage.h b/servers/rendering/storage/particles_storage.h index ee4b8679b3..5ef54346f2 100644 --- a/servers/rendering/storage/particles_storage.h +++ b/servers/rendering/storage/particles_storage.h @@ -94,8 +94,6 @@ public: virtual void particles_add_collision(RID p_particles, RID p_particles_collision_instance) = 0; virtual void particles_remove_collision(RID p_particles, RID p_particles_collision_instance) = 0; - virtual void particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, RID p_texture) = 0; - virtual void update_particles() = 0; /* PARTICLES COLLISION */ @@ -116,7 +114,6 @@ public: virtual void particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) = 0; //for SDF and vector field virtual AABB particles_collision_get_aabb(RID p_particles_collision) const = 0; virtual bool particles_collision_is_heightfield(RID p_particles_collision) const = 0; - virtual RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const = 0; //used from 2D and 3D virtual RID particles_collision_instance_create(RID p_collision) = 0; diff --git a/servers/rendering/storage/texture_storage.h b/servers/rendering/storage/texture_storage.h index 635f44786c..31fb5e8791 100644 --- a/servers/rendering/storage/texture_storage.h +++ b/servers/rendering/storage/texture_storage.h @@ -100,6 +100,8 @@ public: virtual Size2 texture_size_with_proxy(RID p_proxy) = 0; + virtual RID texture_get_rd_texture_rid(RID p_texture, bool p_srgb = false) const = 0; + /* Decal API */ virtual RID decal_allocate() = 0; virtual void decal_initialize(RID p_rid) = 0; @@ -160,11 +162,9 @@ public: virtual RID render_target_get_vrs_texture(RID p_render_target) const = 0; // override color, depth and velocity buffers (depth and velocity only for 3D) - virtual void render_target_set_override_color(RID p_render_target, RID p_texture) = 0; + virtual void render_target_set_override(RID p_render_target, RID p_color_texture, RID p_depth_texture, RID p_velocity_texture) = 0; virtual RID render_target_get_override_color(RID p_render_target) const = 0; - virtual void render_target_set_override_depth(RID p_render_target, RID p_texture) = 0; virtual RID render_target_get_override_depth(RID p_render_target) const = 0; - virtual void render_target_set_override_velocity(RID p_render_target, RID p_texture) = 0; virtual RID render_target_get_override_velocity(RID p_render_target) const = 0; // get textures diff --git a/servers/rendering/storage/utilities.h b/servers/rendering/storage/utilities.h index d240d58917..23a782c14a 100644 --- a/servers/rendering/storage/utilities.h +++ b/servers/rendering/storage/utilities.h @@ -181,6 +181,8 @@ public: virtual String get_video_adapter_vendor() const = 0; virtual RenderingDevice::DeviceType get_video_adapter_type() const = 0; virtual String get_video_adapter_api_version() const = 0; + + virtual Size2i get_maximum_viewport_size() const = 0; }; #endif // RENDERER_UTILITIES_H diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 627cd9f062..8d6d756edc 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -625,7 +625,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint const int *src = indices.ptr(); for (int i = 0; i < p_index_array_len; i++) { - if (p_vertex_array_len < (1 << 16) && p_vertex_array_len > 0) { + if (p_vertex_array_len <= (1 << 16) && p_vertex_array_len > 0) { uint16_t v = src[i]; memcpy(&iw[i * 2], &v, 2); @@ -835,10 +835,10 @@ void RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_format, i break; } /* determine whether using 16 or 32 bits indices */ - if (p_vertex_len >= (1 << 16) || p_vertex_len == 0) { - elem_size = 4; - } else { + if (p_vertex_len <= (1 << 16) && p_vertex_len > 0) { elem_size = 2; + } else { + elem_size = 4; } r_offsets[i] = elem_size; continue; @@ -1280,7 +1280,7 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t Vector<int> arr; arr.resize(p_index_len); - if (p_vertex_len < (1 << 16)) { + if (p_vertex_len <= (1 << 16)) { int *w = arr.ptrw(); for (int j = 0; j < p_index_len; j++) { @@ -1476,7 +1476,11 @@ RenderingDevice *RenderingServer::get_rendering_device() const { } RenderingDevice *RenderingServer::create_local_rendering_device() const { - return RenderingDevice::get_singleton()->create_local_device(); + RenderingDevice *device = RenderingDevice::get_singleton(); + if (!device) { + return nullptr; + } + return device->create_local_device(); } static Vector<Ref<Image>> _get_imgvec(const TypedArray<Image> &p_layers) { @@ -1691,6 +1695,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("texture_get_path", "texture"), &RenderingServer::texture_get_path); ClassDB::bind_method(D_METHOD("texture_set_force_redraw_if_visible", "texture", "enable"), &RenderingServer::texture_set_force_redraw_if_visible); + ClassDB::bind_method(D_METHOD("texture_get_rd_texture", "texture", "srgb"), &RenderingServer::texture_get_rd_texture_rid, DEFVAL(false)); BIND_ENUM_CONSTANT(TEXTURE_LAYERED_2D_ARRAY); BIND_ENUM_CONSTANT(TEXTURE_LAYERED_CUBEMAP); @@ -2182,6 +2187,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("viewport_set_parent_viewport", "viewport", "parent_viewport"), &RenderingServer::viewport_set_parent_viewport); ClassDB::bind_method(D_METHOD("viewport_attach_to_screen", "viewport", "rect", "screen"), &RenderingServer::viewport_attach_to_screen, DEFVAL(Rect2()), DEFVAL(DisplayServer::MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("viewport_set_render_direct_to_screen", "viewport", "enabled"), &RenderingServer::viewport_set_render_direct_to_screen); + ClassDB::bind_method(D_METHOD("viewport_set_canvas_cull_mask", "viewport", "canvas_cull_mask"), &RenderingServer::viewport_set_canvas_cull_mask); ClassDB::bind_method(D_METHOD("viewport_set_scaling_3d_mode", "viewport", "scaling_3d_mode"), &RenderingServer::viewport_set_scaling_3d_mode); ClassDB::bind_method(D_METHOD("viewport_set_scaling_3d_scale", "viewport", "scale"), &RenderingServer::viewport_set_scaling_3d_scale); @@ -2347,7 +2353,6 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("environment_set_volumetric_fog", "env", "enable", "density", "albedo", "emission", "emission_energy", "anisotropy", "length", "p_detail_spread", "gi_inject", "temporal_reprojection", "temporal_reprojection_amount", "ambient_inject", "sky_affect"), &RenderingServer::environment_set_volumetric_fog); ClassDB::bind_method(D_METHOD("environment_glow_set_use_bicubic_upscale", "enable"), &RenderingServer::environment_glow_set_use_bicubic_upscale); - ClassDB::bind_method(D_METHOD("environment_glow_set_use_high_quality", "enable"), &RenderingServer::environment_glow_set_use_high_quality); ClassDB::bind_method(D_METHOD("environment_set_ssr_roughness_quality", "quality"), &RenderingServer::environment_set_ssr_roughness_quality); ClassDB::bind_method(D_METHOD("environment_set_ssao_quality", "quality", "half_size", "adaptive_target", "blur_passes", "fadeout_from", "fadeout_to"), &RenderingServer::environment_set_ssao_quality); ClassDB::bind_method(D_METHOD("environment_set_ssil_quality", "quality", "half_size", "adaptive_target", "blur_passes", "fadeout_from", "fadeout_to"), &RenderingServer::environment_set_ssil_quality); @@ -2575,6 +2580,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("canvas_item_set_default_texture_repeat", "item", "repeat"), &RenderingServer::canvas_item_set_default_texture_repeat); ClassDB::bind_method(D_METHOD("canvas_item_set_visible", "item", "visible"), &RenderingServer::canvas_item_set_visible); ClassDB::bind_method(D_METHOD("canvas_item_set_light_mask", "item", "mask"), &RenderingServer::canvas_item_set_light_mask); + ClassDB::bind_method(D_METHOD("canvas_item_set_visibility_layer", "item", "visibility_layer"), &RenderingServer::canvas_item_set_visibility_layer); ClassDB::bind_method(D_METHOD("canvas_item_set_transform", "item", "transform"), &RenderingServer::canvas_item_set_transform); ClassDB::bind_method(D_METHOD("canvas_item_set_clip", "item", "clip"), &RenderingServer::canvas_item_set_clip); ClassDB::bind_method(D_METHOD("canvas_item_set_distance_field_mode", "item", "enabled"), &RenderingServer::canvas_item_set_distance_field_mode); @@ -2636,7 +2642,8 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(CANVAS_ITEM_TEXTURE_REPEAT_MAX); BIND_ENUM_CONSTANT(CANVAS_GROUP_MODE_DISABLED); - BIND_ENUM_CONSTANT(CANVAS_GROUP_MODE_OPAQUE); + BIND_ENUM_CONSTANT(CANVAS_GROUP_MODE_CLIP_ONLY); + BIND_ENUM_CONSTANT(CANVAS_GROUP_MODE_CLIP_AND_DRAW); BIND_ENUM_CONSTANT(CANVAS_GROUP_MODE_TRANSPARENT); /* CANVAS LIGHT */ @@ -2791,10 +2798,10 @@ void RenderingServer::mesh_add_surface_from_mesh_data(RID p_mesh, const Geometry Vector<Vector3> vertices; Vector<Vector3> normals; - for (int i = 0; i < p_mesh_data.faces.size(); i++) { + for (uint32_t i = 0; i < p_mesh_data.faces.size(); i++) { const Geometry3D::MeshData::Face &f = p_mesh_data.faces[i]; - for (int j = 2; j < f.indices.size(); j++) { + for (uint32_t j = 2; j < f.indices.size(); j++) { vertices.push_back(p_mesh_data.vertices[f.indices[0]]); normals.push_back(f.plane.normal); @@ -2846,8 +2853,12 @@ void RenderingServer::init() { GLOBAL_DEF_RST("rendering/textures/vram_compression/import_etc2", true); GLOBAL_DEF("rendering/textures/lossless_compression/force_png", false); - GLOBAL_DEF("rendering/textures/lossless_compression/webp_compression_level", 2); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/lossless_compression/webp_compression_level", PropertyInfo(Variant::INT, "rendering/textures/lossless_compression/webp_compression_level", PROPERTY_HINT_RANGE, "0,9,1")); + + GLOBAL_DEF("rendering/textures/webp_compression/compression_method", 2); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/webp_compression/compression_method", PropertyInfo(Variant::INT, "rendering/textures/webp_compression/compression_method", PROPERTY_HINT_RANGE, "0,6,1")); + + GLOBAL_DEF("rendering/textures/webp_compression/lossless_compression_factor", 25); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/webp_compression/lossless_compression_factor", PropertyInfo(Variant::FLOAT, "rendering/textures/webp_compression/lossless_compression_factor", PROPERTY_HINT_RANGE, "0,100,1")); GLOBAL_DEF("rendering/limits/time/time_rollover_secs", 3600); ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/time/time_rollover_secs", PropertyInfo(Variant::FLOAT, "rendering/limits/time/time_rollover_secs", PROPERTY_HINT_RANGE, "0,10000,1,or_greater")); @@ -2868,13 +2879,6 @@ void RenderingServer::init() { GLOBAL_DEF("rendering/2d/shadow_atlas/size", 2048); - // Already defined in RenderingDeviceVulkan::initialize which runs before this code. - // We re-define them here just for doctool's sake. Make sure to keep default values in sync. - GLOBAL_DEF("rendering/rendering_device/staging_buffer/block_size_kb", 256); - GLOBAL_DEF("rendering/rendering_device/staging_buffer/max_size_mb", 128); - GLOBAL_DEF("rendering/rendering_device/staging_buffer/texture_upload_region_size_px", 64); - GLOBAL_DEF("rendering/rendering_device/descriptor_pools/max_descriptors_per_pool", 64); - // Number of commands that can be drawn per frame. GLOBAL_DEF_RST("rendering/gl_compatibility/item_buffer_size", 16384); ProjectSettings::get_singleton()->set_custom_property_info("rendering/gl_compatibility/item_buffer_size", PropertyInfo(Variant::INT, "rendering/gl_compatibility/item_buffer_size", PROPERTY_HINT_RANGE, "1024,1048576,1")); @@ -2977,13 +2981,11 @@ void RenderingServer::init() { ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/light_projectors/filter", PropertyInfo(Variant::INT, "rendering/textures/light_projectors/filter", PROPERTY_HINT_ENUM, "Nearest (Fast),Linear (Fast),Nearest Mipmap (Fast),Linear Mipmap (Fast),Nearest Mipmap Anisotropic (Average),Linear Mipmap Anisotropic (Average)")); GLOBAL_DEF_RST("rendering/occlusion_culling/occlusion_rays_per_thread", 512); - GLOBAL_DEF_RST("rendering/occlusion_culling/bvh_build_quality", 2); ProjectSettings::get_singleton()->set_custom_property_info("rendering/occlusion_culling/bvh_build_quality", PropertyInfo(Variant::INT, "rendering/occlusion_culling/bvh_build_quality", PROPERTY_HINT_ENUM, "Low,Medium,High")); GLOBAL_DEF("rendering/environment/glow/upscale_mode", 1); ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/glow/upscale_mode", PropertyInfo(Variant::INT, "rendering/environment/glow/upscale_mode", PROPERTY_HINT_ENUM, "Linear (Fast),Bicubic (Slow)")); GLOBAL_DEF("rendering/environment/glow/upscale_mode.mobile", 0); - GLOBAL_DEF("rendering/environment/glow/use_high_quality", false); GLOBAL_DEF("rendering/environment/screen_space_reflection/roughness_quality", 1); ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/screen_space_reflection/roughness_quality", PropertyInfo(Variant::INT, "rendering/environment/screen_space_reflection/roughness_quality", PROPERTY_HINT_ENUM, "Disabled (Fastest),Low (Fast),Medium (Average),High (Slow)")); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 6885d80301..1d74bb54b9 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -157,6 +157,8 @@ public: virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0; + virtual RID texture_get_rd_texture_rid(RID p_texture, bool p_srgb = false) const = 0; + /* SHADER API */ enum ShaderMode { @@ -807,6 +809,7 @@ public: virtual void viewport_set_size(RID p_viewport, int p_width, int p_height) = 0; virtual void viewport_set_active(RID p_viewport, bool p_active) = 0; virtual void viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) = 0; + virtual void viewport_set_canvas_cull_mask(RID p_viewport, uint32_t p_canvas_cull_mask) = 0; virtual void viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect = Rect2(), DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID) = 0; virtual void viewport_set_render_direct_to_screen(RID p_viewport, bool p_enable) = 0; @@ -1035,7 +1038,6 @@ public: virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) = 0; virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; - virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; enum EnvironmentToneMapper { ENV_TONE_MAPPER_LINEAR, @@ -1320,6 +1322,7 @@ public: virtual void canvas_item_set_custom_rect(RID p_item, bool p_custom_rect, const Rect2 &p_rect = Rect2()) = 0; virtual void canvas_item_set_modulate(RID p_item, const Color &p_color) = 0; virtual void canvas_item_set_self_modulate(RID p_item, const Color &p_color) = 0; + virtual void canvas_item_set_visibility_layer(RID p_item, uint32_t p_visibility_layer) = 0; virtual void canvas_item_set_draw_behind_parent(RID p_item, bool p_enable) = 0; @@ -1367,7 +1370,8 @@ public: enum CanvasGroupMode { CANVAS_GROUP_MODE_DISABLED, - CANVAS_GROUP_MODE_OPAQUE, + CANVAS_GROUP_MODE_CLIP_ONLY, + CANVAS_GROUP_MODE_CLIP_AND_DRAW, CANVAS_GROUP_MODE_TRANSPARENT, }; @@ -1574,6 +1578,8 @@ public: virtual void set_print_gpu_profile(bool p_enable) = 0; + virtual Size2i get_maximum_viewport_size() const = 0; + RenderingDevice *get_rendering_device() const; RenderingDevice *create_local_rendering_device() const; diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp index 0e1069dcf4..4baa1db9bf 100644 --- a/servers/text/text_server_extension.cpp +++ b/servers/text/text_server_extension.cpp @@ -69,6 +69,12 @@ void TextServerExtension::_bind_methods() { GDVIRTUAL_BIND(_font_set_style_name, "font_rid", "name_style"); GDVIRTUAL_BIND(_font_get_style_name, "font_rid"); + GDVIRTUAL_BIND(_font_set_weight, "font_rid", "weight"); + GDVIRTUAL_BIND(_font_get_weight, "font_rid"); + + GDVIRTUAL_BIND(_font_set_stretch, "font_rid", "stretch"); + GDVIRTUAL_BIND(_font_get_stretch, "font_rid"); + GDVIRTUAL_BIND(_font_set_antialiasing, "font_rid", "antialiasing"); GDVIRTUAL_BIND(_font_get_antialiasing, "font_rid"); @@ -87,6 +93,9 @@ void TextServerExtension::_bind_methods() { GDVIRTUAL_BIND(_font_set_fixed_size, "font_rid", "fixed_size"); GDVIRTUAL_BIND(_font_get_fixed_size, "font_rid"); + GDVIRTUAL_BIND(_font_set_allow_system_fallback, "font_rid", "allow_system_fallback"); + GDVIRTUAL_BIND(_font_is_allow_system_fallback, "font_rid"); + GDVIRTUAL_BIND(_font_set_force_autohinter, "font_rid", "force_autohinter"); GDVIRTUAL_BIND(_font_is_force_autohinter, "font_rid"); @@ -231,8 +240,8 @@ void TextServerExtension::_bind_methods() { GDVIRTUAL_BIND(_shaped_text_get_spacing, "shaped", "spacing"); GDVIRTUAL_BIND(_shaped_text_add_string, "shaped", "text", "fonts", "size", "opentype_features", "language", "meta"); - GDVIRTUAL_BIND(_shaped_text_add_object, "shaped", "key", "size", "inline_align", "length"); - GDVIRTUAL_BIND(_shaped_text_resize_object, "shaped", "key", "size", "inline_align"); + GDVIRTUAL_BIND(_shaped_text_add_object, "shaped", "key", "size", "inline_align", "length", "baseline"); + GDVIRTUAL_BIND(_shaped_text_resize_object, "shaped", "key", "size", "inline_align", "baseline"); GDVIRTUAL_BIND(_shaped_get_span_count, "shaped"); GDVIRTUAL_BIND(_shaped_get_span_meta, "shaped", "index"); @@ -299,7 +308,7 @@ void TextServerExtension::_bind_methods() { GDVIRTUAL_BIND(_strip_diacritics, "string"); GDVIRTUAL_BIND(_is_valid_identifier, "string"); - GDVIRTUAL_BIND(_string_get_word_breaks, "string", "language"); + GDVIRTUAL_BIND(_string_get_word_breaks, "string", "language", "chars_per_line"); GDVIRTUAL_BIND(_is_confusable, "string", "dict"); GDVIRTUAL_BIND(_spoof_check, "string"); @@ -308,30 +317,26 @@ void TextServerExtension::_bind_methods() { GDVIRTUAL_BIND(_string_to_lower, "string", "language"); GDVIRTUAL_BIND(_parse_structured_text, "parser_type", "args", "text"); + + GDVIRTUAL_BIND(_cleanup); } bool TextServerExtension::has_feature(Feature p_feature) const { - bool ret; - if (GDVIRTUAL_CALL(_has_feature, p_feature, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_has_feature, p_feature, ret); + return ret; } String TextServerExtension::get_name() const { - String ret; - if (GDVIRTUAL_CALL(_get_name, ret)) { - return ret; - } - return "Unknown"; + String ret = "Unknown"; + GDVIRTUAL_CALL(_get_name, ret); + return ret; } int64_t TextServerExtension::get_features() const { - int64_t ret; - if (GDVIRTUAL_CALL(_get_features, ret)) { - return ret; - } - return 0; + int64_t ret = 0; + GDVIRTUAL_CALL(_get_features, ret); + return ret; } void TextServerExtension::free_rid(const RID &p_rid) { @@ -339,67 +344,51 @@ void TextServerExtension::free_rid(const RID &p_rid) { } bool TextServerExtension::has(const RID &p_rid) { - bool ret; - if (GDVIRTUAL_CALL(_has, p_rid, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_has, p_rid, ret); + return ret; } bool TextServerExtension::load_support_data(const String &p_filename) { - bool ret; - if (GDVIRTUAL_CALL(_load_support_data, p_filename, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_load_support_data, p_filename, ret); + return ret; } String TextServerExtension::get_support_data_filename() const { String ret; - if (GDVIRTUAL_CALL(_get_support_data_filename, ret)) { - return ret; - } - return String(); + GDVIRTUAL_CALL(_get_support_data_filename, ret); + return ret; } String TextServerExtension::get_support_data_info() const { String ret; - if (GDVIRTUAL_CALL(_get_support_data_info, ret)) { - return ret; - } - return String(); + GDVIRTUAL_CALL(_get_support_data_info, ret); + return ret; } bool TextServerExtension::save_support_data(const String &p_filename) const { - bool ret; - if (GDVIRTUAL_CALL(_save_support_data, p_filename, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_save_support_data, p_filename, ret); + return ret; } bool TextServerExtension::is_locale_right_to_left(const String &p_locale) const { - bool ret; - if (GDVIRTUAL_CALL(_is_locale_right_to_left, p_locale, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_is_locale_right_to_left, p_locale, ret); + return ret; } int64_t TextServerExtension::name_to_tag(const String &p_name) const { - int64_t ret; - if (GDVIRTUAL_CALL(_name_to_tag, p_name, ret)) { - return ret; - } - return 0; + int64_t ret = 0; + GDVIRTUAL_CALL(_name_to_tag, p_name, ret); + return ret; } String TextServerExtension::tag_to_name(int64_t p_tag) const { String ret; - if (GDVIRTUAL_CALL(_tag_to_name, p_tag, ret)) { - return ret; - } - return ""; + GDVIRTUAL_CALL(_tag_to_name, p_tag, ret); + return ret; } /*************************************************************************/ @@ -408,10 +397,8 @@ String TextServerExtension::tag_to_name(int64_t p_tag) const { RID TextServerExtension::create_font() { RID ret; - if (GDVIRTUAL_CALL(_create_font, ret)) { - return ret; - } - return RID(); + GDVIRTUAL_CALL(_create_font, ret); + return ret; } void TextServerExtension::font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) { @@ -427,19 +414,15 @@ void TextServerExtension::font_set_face_index(const RID &p_font_rid, int64_t p_i } int64_t TextServerExtension::font_get_face_index(const RID &p_font_rid) const { - int64_t ret; - if (GDVIRTUAL_CALL(_font_get_face_index, p_font_rid, ret)) { - return ret; - } - return 0; + int64_t ret = 0; + GDVIRTUAL_CALL(_font_get_face_index, p_font_rid, ret); + return ret; } int64_t TextServerExtension::font_get_face_count(const RID &p_font_rid) const { - int64_t ret; - if (GDVIRTUAL_CALL(_font_get_face_count, p_font_rid, ret)) { - return ret; - } - return 0; + int64_t ret = 0; + GDVIRTUAL_CALL(_font_get_face_count, p_font_rid, ret); + return ret; } void TextServerExtension::font_set_style(const RID &p_font_rid, BitField<TextServer::FontStyle> p_style) { @@ -448,10 +431,8 @@ void TextServerExtension::font_set_style(const RID &p_font_rid, BitField<TextSer BitField<TextServer::FontStyle> TextServerExtension::font_get_style(const RID &p_font_rid) const { BitField<TextServer::FontStyle> ret = 0; - if (GDVIRTUAL_CALL(_font_get_style, p_font_rid, ret)) { - return ret; - } - return 0; + GDVIRTUAL_CALL(_font_get_style, p_font_rid, ret); + return ret; } void TextServerExtension::font_set_style_name(const RID &p_font_rid, const String &p_name) { @@ -460,10 +441,28 @@ void TextServerExtension::font_set_style_name(const RID &p_font_rid, const Strin String TextServerExtension::font_get_style_name(const RID &p_font_rid) const { String ret; - if (GDVIRTUAL_CALL(_font_get_style_name, p_font_rid, ret)) { - return ret; - } - return String(); + GDVIRTUAL_CALL(_font_get_style_name, p_font_rid, ret); + return ret; +} + +void TextServerExtension::font_set_weight(const RID &p_font_rid, int64_t p_weight) { + GDVIRTUAL_CALL(_font_set_weight, p_font_rid, p_weight); +} + +int64_t TextServerExtension::font_get_weight(const RID &p_font_rid) const { + int64_t ret = 400; + GDVIRTUAL_CALL(_font_get_weight, p_font_rid, ret); + return ret; +} + +void TextServerExtension::font_set_stretch(const RID &p_font_rid, int64_t p_stretch) { + GDVIRTUAL_CALL(_font_set_stretch, p_font_rid, p_stretch); +} + +int64_t TextServerExtension::font_get_stretch(const RID &p_font_rid) const { + int64_t ret = 100; + GDVIRTUAL_CALL(_font_get_stretch, p_font_rid, ret); + return ret; } void TextServerExtension::font_set_name(const RID &p_font_rid, const String &p_name) { @@ -472,10 +471,8 @@ void TextServerExtension::font_set_name(const RID &p_font_rid, const String &p_n String TextServerExtension::font_get_name(const RID &p_font_rid) const { String ret; - if (GDVIRTUAL_CALL(_font_get_name, p_font_rid, ret)) { - return ret; - } - return String(); + GDVIRTUAL_CALL(_font_get_name, p_font_rid, ret); + return ret; } void TextServerExtension::font_set_antialiasing(const RID &p_font_rid, TextServer::FontAntialiasing p_antialiasing) { @@ -483,11 +480,9 @@ void TextServerExtension::font_set_antialiasing(const RID &p_font_rid, TextServe } TextServer::FontAntialiasing TextServerExtension::font_get_antialiasing(const RID &p_font_rid) const { - TextServer::FontAntialiasing ret; - if (GDVIRTUAL_CALL(_font_get_antialiasing, p_font_rid, ret)) { - return ret; - } - return TextServer::FONT_ANTIALIASING_NONE; + TextServer::FontAntialiasing ret = TextServer::FONT_ANTIALIASING_NONE; + GDVIRTUAL_CALL(_font_get_antialiasing, p_font_rid, ret); + return ret; } void TextServerExtension::font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) { @@ -495,11 +490,9 @@ void TextServerExtension::font_set_generate_mipmaps(const RID &p_font_rid, bool } bool TextServerExtension::font_get_generate_mipmaps(const RID &p_font_rid) const { - bool ret; - if (GDVIRTUAL_CALL(_font_get_generate_mipmaps, p_font_rid, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_font_get_generate_mipmaps, p_font_rid, ret); + return ret; } void TextServerExtension::font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) { @@ -507,11 +500,9 @@ void TextServerExtension::font_set_multichannel_signed_distance_field(const RID } bool TextServerExtension::font_is_multichannel_signed_distance_field(const RID &p_font_rid) const { - bool ret; - if (GDVIRTUAL_CALL(_font_is_multichannel_signed_distance_field, p_font_rid, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_font_is_multichannel_signed_distance_field, p_font_rid, ret); + return ret; } void TextServerExtension::font_set_msdf_pixel_range(const RID &p_font_rid, int64_t p_msdf_pixel_range) { @@ -519,11 +510,9 @@ void TextServerExtension::font_set_msdf_pixel_range(const RID &p_font_rid, int64 } int64_t TextServerExtension::font_get_msdf_pixel_range(const RID &p_font_rid) const { - int64_t ret; - if (GDVIRTUAL_CALL(_font_get_msdf_pixel_range, p_font_rid, ret)) { - return ret; - } - return 0; + int64_t ret = 0; + GDVIRTUAL_CALL(_font_get_msdf_pixel_range, p_font_rid, ret); + return ret; } void TextServerExtension::font_set_msdf_size(const RID &p_font_rid, int64_t p_msdf_size) { @@ -531,11 +520,9 @@ void TextServerExtension::font_set_msdf_size(const RID &p_font_rid, int64_t p_ms } int64_t TextServerExtension::font_get_msdf_size(const RID &p_font_rid) const { - int64_t ret; - if (GDVIRTUAL_CALL(_font_get_msdf_size, p_font_rid, ret)) { - return ret; - } - return 0; + int64_t ret = 0; + GDVIRTUAL_CALL(_font_get_msdf_size, p_font_rid, ret); + return ret; } void TextServerExtension::font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) { @@ -543,11 +530,19 @@ void TextServerExtension::font_set_fixed_size(const RID &p_font_rid, int64_t p_f } int64_t TextServerExtension::font_get_fixed_size(const RID &p_font_rid) const { - int64_t ret; - if (GDVIRTUAL_CALL(_font_get_fixed_size, p_font_rid, ret)) { - return ret; - } - return 0; + int64_t ret = 0; + GDVIRTUAL_CALL(_font_get_fixed_size, p_font_rid, ret); + return ret; +} + +void TextServerExtension::font_set_allow_system_fallback(const RID &p_font_rid, bool p_allow_system_fallback) { + GDVIRTUAL_CALL(_font_set_allow_system_fallback, p_font_rid, p_allow_system_fallback); +} + +bool TextServerExtension::font_is_allow_system_fallback(const RID &p_font_rid) const { + bool ret = false; + GDVIRTUAL_CALL(_font_is_allow_system_fallback, p_font_rid, ret); + return ret; } void TextServerExtension::font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) { @@ -555,11 +550,9 @@ void TextServerExtension::font_set_force_autohinter(const RID &p_font_rid, bool } bool TextServerExtension::font_is_force_autohinter(const RID &p_font_rid) const { - bool ret; - if (GDVIRTUAL_CALL(_font_is_force_autohinter, p_font_rid, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_font_is_force_autohinter, p_font_rid, ret); + return ret; } void TextServerExtension::font_set_hinting(const RID &p_font_rid, TextServer::Hinting p_hinting) { @@ -567,11 +560,9 @@ void TextServerExtension::font_set_hinting(const RID &p_font_rid, TextServer::Hi } TextServer::Hinting TextServerExtension::font_get_hinting(const RID &p_font_rid) const { - TextServer::Hinting ret; - if (GDVIRTUAL_CALL(_font_get_hinting, p_font_rid, ret)) { - return (TextServer::Hinting)ret; - } - return TextServer::Hinting::HINTING_NONE; + TextServer::Hinting ret = TextServer::HINTING_NONE; + GDVIRTUAL_CALL(_font_get_hinting, p_font_rid, ret); + return ret; } void TextServerExtension::font_set_subpixel_positioning(const RID &p_font_rid, TextServer::SubpixelPositioning p_subpixel) { @@ -579,11 +570,9 @@ void TextServerExtension::font_set_subpixel_positioning(const RID &p_font_rid, T } TextServer::SubpixelPositioning TextServerExtension::font_get_subpixel_positioning(const RID &p_font_rid) const { - TextServer::SubpixelPositioning ret; - if (GDVIRTUAL_CALL(_font_get_subpixel_positioning, p_font_rid, ret)) { - return (TextServer::SubpixelPositioning)ret; - } - return TextServer::SubpixelPositioning::SUBPIXEL_POSITIONING_DISABLED; + TextServer::SubpixelPositioning ret = TextServer::SUBPIXEL_POSITIONING_DISABLED; + GDVIRTUAL_CALL(_font_get_subpixel_positioning, p_font_rid, ret); + return ret; } void TextServerExtension::font_set_embolden(const RID &p_font_rid, double p_strength) { @@ -591,11 +580,9 @@ void TextServerExtension::font_set_embolden(const RID &p_font_rid, double p_stre } double TextServerExtension::font_get_embolden(const RID &p_font_rid) const { - double ret; - if (GDVIRTUAL_CALL(_font_get_embolden, p_font_rid, ret)) { - return ret; - } - return 0.0; + double ret = 0; + GDVIRTUAL_CALL(_font_get_embolden, p_font_rid, ret); + return ret; } void TextServerExtension::font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) { @@ -604,10 +591,8 @@ void TextServerExtension::font_set_transform(const RID &p_font_rid, const Transf Transform2D TextServerExtension::font_get_transform(const RID &p_font_rid) const { Transform2D ret; - if (GDVIRTUAL_CALL(_font_get_transform, p_font_rid, ret)) { - return ret; - } - return Transform2D(); + GDVIRTUAL_CALL(_font_get_transform, p_font_rid, ret); + return ret; } void TextServerExtension::font_set_variation_coordinates(const RID &p_font_rid, const Dictionary &p_variation_coordinates) { @@ -616,10 +601,8 @@ void TextServerExtension::font_set_variation_coordinates(const RID &p_font_rid, Dictionary TextServerExtension::font_get_variation_coordinates(const RID &p_font_rid) const { Dictionary ret; - if (GDVIRTUAL_CALL(_font_get_variation_coordinates, p_font_rid, ret)) { - return ret; - } - return Dictionary(); + GDVIRTUAL_CALL(_font_get_variation_coordinates, p_font_rid, ret); + return ret; } void TextServerExtension::font_set_oversampling(const RID &p_font_rid, double p_oversampling) { @@ -627,19 +610,15 @@ void TextServerExtension::font_set_oversampling(const RID &p_font_rid, double p_ } double TextServerExtension::font_get_oversampling(const RID &p_font_rid) const { - double ret; - if (GDVIRTUAL_CALL(_font_get_oversampling, p_font_rid, ret)) { - return ret; - } - return 0.0; + double ret = 0; + GDVIRTUAL_CALL(_font_get_oversampling, p_font_rid, ret); + return ret; } TypedArray<Vector2i> TextServerExtension::font_get_size_cache_list(const RID &p_font_rid) const { TypedArray<Vector2i> ret; - if (GDVIRTUAL_CALL(_font_get_size_cache_list, p_font_rid, ret)) { - return ret; - } - return TypedArray<Vector2i>(); + GDVIRTUAL_CALL(_font_get_size_cache_list, p_font_rid, ret); + return ret; } void TextServerExtension::font_clear_size_cache(const RID &p_font_rid) { @@ -655,11 +634,9 @@ void TextServerExtension::font_set_ascent(const RID &p_font_rid, int64_t p_size, } double TextServerExtension::font_get_ascent(const RID &p_font_rid, int64_t p_size) const { - double ret; - if (GDVIRTUAL_CALL(_font_get_ascent, p_font_rid, p_size, ret)) { - return ret; - } - return 0.0; + double ret = 0; + GDVIRTUAL_CALL(_font_get_ascent, p_font_rid, p_size, ret); + return ret; } void TextServerExtension::font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) { @@ -667,11 +644,9 @@ void TextServerExtension::font_set_descent(const RID &p_font_rid, int64_t p_size } double TextServerExtension::font_get_descent(const RID &p_font_rid, int64_t p_size) const { - double ret; - if (GDVIRTUAL_CALL(_font_get_descent, p_font_rid, p_size, ret)) { - return ret; - } - return 0.0; + double ret = 0; + GDVIRTUAL_CALL(_font_get_descent, p_font_rid, p_size, ret); + return ret; } void TextServerExtension::font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) { @@ -679,11 +654,9 @@ void TextServerExtension::font_set_underline_position(const RID &p_font_rid, int } double TextServerExtension::font_get_underline_position(const RID &p_font_rid, int64_t p_size) const { - double ret; - if (GDVIRTUAL_CALL(_font_get_underline_position, p_font_rid, p_size, ret)) { - return ret; - } - return 0.0; + double ret = 0; + GDVIRTUAL_CALL(_font_get_underline_position, p_font_rid, p_size, ret); + return ret; } void TextServerExtension::font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) { @@ -691,11 +664,9 @@ void TextServerExtension::font_set_underline_thickness(const RID &p_font_rid, in } double TextServerExtension::font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const { - double ret; - if (GDVIRTUAL_CALL(_font_get_underline_thickness, p_font_rid, p_size, ret)) { - return ret; - } - return 0.0; + double ret = 0; + GDVIRTUAL_CALL(_font_get_underline_thickness, p_font_rid, p_size, ret); + return ret; } void TextServerExtension::font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) { @@ -703,19 +674,15 @@ void TextServerExtension::font_set_scale(const RID &p_font_rid, int64_t p_size, } double TextServerExtension::font_get_scale(const RID &p_font_rid, int64_t p_size) const { - double ret; - if (GDVIRTUAL_CALL(_font_get_scale, p_font_rid, p_size, ret)) { - return ret; - } - return 0.0; + double ret = 0; + GDVIRTUAL_CALL(_font_get_scale, p_font_rid, p_size, ret); + return ret; } int64_t TextServerExtension::font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const { - int64_t ret; - if (GDVIRTUAL_CALL(_font_get_texture_count, p_font_rid, p_size, ret)) { - return ret; - } - return 0; + int64_t ret = 0; + GDVIRTUAL_CALL(_font_get_texture_count, p_font_rid, p_size, ret); + return ret; } void TextServerExtension::font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) { @@ -732,10 +699,8 @@ void TextServerExtension::font_set_texture_image(const RID &p_font_rid, const Ve Ref<Image> TextServerExtension::font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const { Ref<Image> ret; - if (GDVIRTUAL_CALL(_font_get_texture_image, p_font_rid, p_size, p_texture_index, ret)) { - return ret; - } - return Ref<Image>(); + GDVIRTUAL_CALL(_font_get_texture_image, p_font_rid, p_size, p_texture_index, ret); + return ret; } void TextServerExtension::font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) { @@ -744,18 +709,14 @@ void TextServerExtension::font_set_texture_offsets(const RID &p_font_rid, const PackedInt32Array TextServerExtension::font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const { PackedInt32Array ret; - if (GDVIRTUAL_CALL(_font_get_texture_offsets, p_font_rid, p_size, p_texture_index, ret)) { - return ret; - } - return PackedInt32Array(); + GDVIRTUAL_CALL(_font_get_texture_offsets, p_font_rid, p_size, p_texture_index, ret); + return ret; } PackedInt32Array TextServerExtension::font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const { PackedInt32Array ret; - if (GDVIRTUAL_CALL(_font_get_glyph_list, p_font_rid, p_size, ret)) { - return ret; - } - return PackedInt32Array(); + GDVIRTUAL_CALL(_font_get_glyph_list, p_font_rid, p_size, ret); + return ret; } void TextServerExtension::font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) { @@ -768,10 +729,8 @@ void TextServerExtension::font_remove_glyph(const RID &p_font_rid, const Vector2 Vector2 TextServerExtension::font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const { Vector2 ret; - if (GDVIRTUAL_CALL(_font_get_glyph_advance, p_font_rid, p_size, p_glyph, ret)) { - return ret; - } - return Vector2(); + GDVIRTUAL_CALL(_font_get_glyph_advance, p_font_rid, p_size, p_glyph, ret); + return ret; } void TextServerExtension::font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) { @@ -780,10 +739,8 @@ void TextServerExtension::font_set_glyph_advance(const RID &p_font_rid, int64_t Vector2 TextServerExtension::font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { Vector2 ret; - if (GDVIRTUAL_CALL(_font_get_glyph_offset, p_font_rid, p_size, p_glyph, ret)) { - return ret; - } - return Vector2(); + GDVIRTUAL_CALL(_font_get_glyph_offset, p_font_rid, p_size, p_glyph, ret); + return ret; } void TextServerExtension::font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) { @@ -792,10 +749,8 @@ void TextServerExtension::font_set_glyph_offset(const RID &p_font_rid, const Vec Vector2 TextServerExtension::font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { Vector2 ret; - if (GDVIRTUAL_CALL(_font_get_glyph_size, p_font_rid, p_size, p_glyph, ret)) { - return ret; - } - return Vector2(); + GDVIRTUAL_CALL(_font_get_glyph_size, p_font_rid, p_size, p_glyph, ret); + return ret; } void TextServerExtension::font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) { @@ -804,10 +759,8 @@ void TextServerExtension::font_set_glyph_size(const RID &p_font_rid, const Vecto Rect2 TextServerExtension::font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { Rect2 ret; - if (GDVIRTUAL_CALL(_font_get_glyph_uv_rect, p_font_rid, p_size, p_glyph, ret)) { - return ret; - } - return Rect2(); + GDVIRTUAL_CALL(_font_get_glyph_uv_rect, p_font_rid, p_size, p_glyph, ret); + return ret; } void TextServerExtension::font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) { @@ -815,11 +768,9 @@ void TextServerExtension::font_set_glyph_uv_rect(const RID &p_font_rid, const Ve } int64_t TextServerExtension::font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { - int64_t ret; - if (GDVIRTUAL_CALL(_font_get_glyph_texture_idx, p_font_rid, p_size, p_glyph, ret)) { - return ret; - } - return 0; + int64_t ret = 0; + GDVIRTUAL_CALL(_font_get_glyph_texture_idx, p_font_rid, p_size, p_glyph, ret); + return ret; } void TextServerExtension::font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) { @@ -828,34 +779,26 @@ void TextServerExtension::font_set_glyph_texture_idx(const RID &p_font_rid, cons RID TextServerExtension::font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { RID ret; - if (GDVIRTUAL_CALL(_font_get_glyph_texture_rid, p_font_rid, p_size, p_glyph, ret)) { - return ret; - } - return RID(); + GDVIRTUAL_CALL(_font_get_glyph_texture_rid, p_font_rid, p_size, p_glyph, ret); + return ret; } Size2 TextServerExtension::font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { Size2 ret; - if (GDVIRTUAL_CALL(_font_get_glyph_texture_size, p_font_rid, p_size, p_glyph, ret)) { - return ret; - } - return Size2(); + GDVIRTUAL_CALL(_font_get_glyph_texture_size, p_font_rid, p_size, p_glyph, ret); + return ret; } Dictionary TextServerExtension::font_get_glyph_contours(const RID &p_font_rid, int64_t p_size, int64_t p_index) const { Dictionary ret; - if (GDVIRTUAL_CALL(_font_get_glyph_contours, p_font_rid, p_size, p_index, ret)) { - return ret; - } - return Dictionary(); + GDVIRTUAL_CALL(_font_get_glyph_contours, p_font_rid, p_size, p_index, ret); + return ret; } TypedArray<Vector2i> TextServerExtension::font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const { TypedArray<Vector2i> ret; - if (GDVIRTUAL_CALL(_font_get_kerning_list, p_font_rid, p_size, ret)) { - return ret; - } - return TypedArray<Vector2i>(); + GDVIRTUAL_CALL(_font_get_kerning_list, p_font_rid, p_size, ret); + return ret; } void TextServerExtension::font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) { @@ -872,34 +815,26 @@ void TextServerExtension::font_set_kerning(const RID &p_font_rid, int64_t p_size Vector2 TextServerExtension::font_get_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) const { Vector2 ret; - if (GDVIRTUAL_CALL(_font_get_kerning, p_font_rid, p_size, p_glyph_pair, ret)) { - return ret; - } - return Vector2(); + GDVIRTUAL_CALL(_font_get_kerning, p_font_rid, p_size, p_glyph_pair, ret); + return ret; } int64_t TextServerExtension::font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector) const { - int64_t ret; - if (GDVIRTUAL_CALL(_font_get_glyph_index, p_font_rid, p_size, p_char, p_variation_selector, ret)) { - return ret; - } - return 0; + int64_t ret = 0; + GDVIRTUAL_CALL(_font_get_glyph_index, p_font_rid, p_size, p_char, p_variation_selector, ret); + return ret; } bool TextServerExtension::font_has_char(const RID &p_font_rid, int64_t p_char) const { - bool ret; - if (GDVIRTUAL_CALL(_font_has_char, p_font_rid, p_char, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_font_has_char, p_font_rid, p_char, ret); + return ret; } String TextServerExtension::font_get_supported_chars(const RID &p_font_rid) const { String ret; - if (GDVIRTUAL_CALL(_font_get_supported_chars, p_font_rid, ret)) { - return ret; - } - return String(); + GDVIRTUAL_CALL(_font_get_supported_chars, p_font_rid, ret); + return ret; } void TextServerExtension::font_render_range(const RID &p_font_rid, const Vector2i &p_size, int64_t p_start, int64_t p_end) { @@ -919,11 +854,9 @@ void TextServerExtension::font_draw_glyph_outline(const RID &p_font_rid, const R } bool TextServerExtension::font_is_language_supported(const RID &p_font_rid, const String &p_language) const { - bool ret; - if (GDVIRTUAL_CALL(_font_is_language_supported, p_font_rid, p_language, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_font_is_language_supported, p_font_rid, p_language, ret); + return ret; } void TextServerExtension::font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) { @@ -931,11 +864,9 @@ void TextServerExtension::font_set_language_support_override(const RID &p_font_r } bool TextServerExtension::font_get_language_support_override(const RID &p_font_rid, const String &p_language) { - bool ret; - if (GDVIRTUAL_CALL(_font_get_language_support_override, p_font_rid, p_language, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_font_get_language_support_override, p_font_rid, p_language, ret); + return ret; } void TextServerExtension::font_remove_language_support_override(const RID &p_font_rid, const String &p_language) { @@ -944,18 +875,14 @@ void TextServerExtension::font_remove_language_support_override(const RID &p_fon PackedStringArray TextServerExtension::font_get_language_support_overrides(const RID &p_font_rid) { PackedStringArray ret; - if (GDVIRTUAL_CALL(_font_get_language_support_overrides, p_font_rid, ret)) { - return ret; - } - return PackedStringArray(); + GDVIRTUAL_CALL(_font_get_language_support_overrides, p_font_rid, ret); + return ret; } bool TextServerExtension::font_is_script_supported(const RID &p_font_rid, const String &p_script) const { - bool ret; - if (GDVIRTUAL_CALL(_font_is_script_supported, p_font_rid, p_script, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_font_is_script_supported, p_font_rid, p_script, ret); + return ret; } void TextServerExtension::font_set_script_support_override(const RID &p_font_rid, const String &p_script, bool p_supported) { @@ -963,11 +890,9 @@ void TextServerExtension::font_set_script_support_override(const RID &p_font_rid } bool TextServerExtension::font_get_script_support_override(const RID &p_font_rid, const String &p_script) { - bool ret; - if (GDVIRTUAL_CALL(_font_get_script_support_override, p_font_rid, p_script, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_font_get_script_support_override, p_font_rid, p_script, ret); + return ret; } void TextServerExtension::font_remove_script_support_override(const RID &p_font_rid, const String &p_script) { @@ -976,10 +901,8 @@ void TextServerExtension::font_remove_script_support_override(const RID &p_font_ PackedStringArray TextServerExtension::font_get_script_support_overrides(const RID &p_font_rid) { PackedStringArray ret; - if (GDVIRTUAL_CALL(_font_get_script_support_overrides, p_font_rid, ret)) { - return ret; - } - return PackedStringArray(); + GDVIRTUAL_CALL(_font_get_script_support_overrides, p_font_rid, ret); + return ret; } void TextServerExtension::font_set_opentype_feature_overrides(const RID &p_font_rid, const Dictionary &p_overrides) { @@ -988,34 +911,26 @@ void TextServerExtension::font_set_opentype_feature_overrides(const RID &p_font_ Dictionary TextServerExtension::font_get_opentype_feature_overrides(const RID &p_font_rid) const { Dictionary ret; - if (GDVIRTUAL_CALL(_font_get_opentype_feature_overrides, p_font_rid, ret)) { - return ret; - } - return Dictionary(); + GDVIRTUAL_CALL(_font_get_opentype_feature_overrides, p_font_rid, ret); + return ret; } Dictionary TextServerExtension::font_supported_feature_list(const RID &p_font_rid) const { Dictionary ret; - if (GDVIRTUAL_CALL(_font_supported_feature_list, p_font_rid, ret)) { - return ret; - } - return Dictionary(); + GDVIRTUAL_CALL(_font_supported_feature_list, p_font_rid, ret); + return ret; } Dictionary TextServerExtension::font_supported_variation_list(const RID &p_font_rid) const { Dictionary ret; - if (GDVIRTUAL_CALL(_font_supported_variation_list, p_font_rid, ret)) { - return ret; - } - return Dictionary(); + GDVIRTUAL_CALL(_font_supported_variation_list, p_font_rid, ret); + return ret; } double TextServerExtension::font_get_global_oversampling() const { - double ret; - if (GDVIRTUAL_CALL(_font_get_global_oversampling, ret)) { - return ret; - } - return 0.0; + double ret = 0; + GDVIRTUAL_CALL(_font_get_global_oversampling, ret); + return ret; } void TextServerExtension::font_set_global_oversampling(double p_oversampling) { @@ -1042,10 +957,8 @@ void TextServerExtension::draw_hex_code_box(const RID &p_canvas, int64_t p_size, RID TextServerExtension::create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) { RID ret; - if (GDVIRTUAL_CALL(_create_shaped_text, p_direction, p_orientation, ret)) { - return ret; - } - return RID(); + GDVIRTUAL_CALL(_create_shaped_text, p_direction, p_orientation, ret); + return ret; } void TextServerExtension::shaped_text_clear(const RID &p_shaped) { @@ -1057,19 +970,15 @@ void TextServerExtension::shaped_text_set_direction(const RID &p_shaped, TextSer } TextServer::Direction TextServerExtension::shaped_text_get_direction(const RID &p_shaped) const { - TextServer::Direction ret; - if (GDVIRTUAL_CALL(_shaped_text_get_direction, p_shaped, ret)) { - return (TextServer::Direction)ret; - } - return TextServer::Direction::DIRECTION_AUTO; + TextServer::Direction ret = TextServer::DIRECTION_AUTO; + GDVIRTUAL_CALL(_shaped_text_get_direction, p_shaped, ret); + return ret; } TextServer::Direction TextServerExtension::shaped_text_get_inferred_direction(const RID &p_shaped) const { - TextServer::Direction ret; - if (GDVIRTUAL_CALL(_shaped_text_get_inferred_direction, p_shaped, ret)) { - return (TextServer::Direction)ret; - } - return TextServer::Direction::DIRECTION_LTR; + TextServer::Direction ret = TextServer::DIRECTION_LTR; + GDVIRTUAL_CALL(_shaped_text_get_inferred_direction, p_shaped, ret); + return ret; } void TextServerExtension::shaped_text_set_orientation(const RID &p_shaped, TextServer::Orientation p_orientation) { @@ -1077,11 +986,9 @@ void TextServerExtension::shaped_text_set_orientation(const RID &p_shaped, TextS } TextServer::Orientation TextServerExtension::shaped_text_get_orientation(const RID &p_shaped) const { - TextServer::Orientation ret; - if (GDVIRTUAL_CALL(_shaped_text_get_orientation, p_shaped, ret)) { - return (TextServer::Orientation)ret; - } - return TextServer::Orientation::ORIENTATION_HORIZONTAL; + TextServer::Orientation ret = TextServer::ORIENTATION_HORIZONTAL; + GDVIRTUAL_CALL(_shaped_text_get_orientation, p_shaped, ret); + return ret; } void TextServerExtension::shaped_text_set_bidi_override(const RID &p_shaped, const Array &p_override) { @@ -1094,10 +1001,8 @@ void TextServerExtension::shaped_text_set_custom_punctuation(const RID &p_shaped String TextServerExtension::shaped_text_get_custom_punctuation(const RID &p_shaped) const { String ret; - if (GDVIRTUAL_CALL(_shaped_text_get_custom_punctuation, p_shaped, ret)) { - return ret; - } - return String(); + GDVIRTUAL_CALL(_shaped_text_get_custom_punctuation, p_shaped, ret); + return ret; } void TextServerExtension::shaped_text_set_preserve_invalid(const RID &p_shaped, bool p_enabled) { @@ -1105,11 +1010,9 @@ void TextServerExtension::shaped_text_set_preserve_invalid(const RID &p_shaped, } bool TextServerExtension::shaped_text_get_preserve_invalid(const RID &p_shaped) const { - bool ret; - if (GDVIRTUAL_CALL(_shaped_text_get_preserve_invalid, p_shaped, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_shaped_text_get_preserve_invalid, p_shaped, ret); + return ret; } void TextServerExtension::shaped_text_set_preserve_control(const RID &p_shaped, bool p_enabled) { @@ -1117,11 +1020,9 @@ void TextServerExtension::shaped_text_set_preserve_control(const RID &p_shaped, } bool TextServerExtension::shaped_text_get_preserve_control(const RID &p_shaped) const { - bool ret; - if (GDVIRTUAL_CALL(_shaped_text_get_preserve_control, p_shaped, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_shaped_text_get_preserve_control, p_shaped, ret); + return ret; } void TextServerExtension::shaped_text_set_spacing(const RID &p_shaped, TextServer::SpacingType p_spacing, int64_t p_value) { @@ -1129,51 +1030,39 @@ void TextServerExtension::shaped_text_set_spacing(const RID &p_shaped, TextServe } int64_t TextServerExtension::shaped_text_get_spacing(const RID &p_shaped, TextServer::SpacingType p_spacing) const { - int64_t ret; - if (GDVIRTUAL_CALL(_shaped_text_get_spacing, p_shaped, p_spacing, ret)) { - return ret; - } - return 0; + int64_t ret = 0; + GDVIRTUAL_CALL(_shaped_text_get_spacing, p_shaped, p_spacing, ret); + return ret; } bool TextServerExtension::shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) { - bool ret; - if (GDVIRTUAL_CALL(_shaped_text_add_string, p_shaped, p_text, p_fonts, p_size, p_opentype_features, p_language, p_meta, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_shaped_text_add_string, p_shaped, p_text, p_fonts, p_size, p_opentype_features, p_language, p_meta, ret); + return ret; } -bool TextServerExtension::shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, int64_t p_length) { - bool ret; - if (GDVIRTUAL_CALL(_shaped_text_add_object, p_shaped, p_key, p_size, p_inline_align, p_length, ret)) { - return ret; - } - return false; +bool TextServerExtension::shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, int64_t p_length, float p_baseline) { + bool ret = false; + GDVIRTUAL_CALL(_shaped_text_add_object, p_shaped, p_key, p_size, p_inline_align, p_length, p_baseline, ret); + return ret; } -bool TextServerExtension::shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align) { - bool ret; - if (GDVIRTUAL_CALL(_shaped_text_resize_object, p_shaped, p_key, p_size, p_inline_align, ret)) { - return ret; - } - return false; +bool TextServerExtension::shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, float p_baseline) { + bool ret = false; + GDVIRTUAL_CALL(_shaped_text_resize_object, p_shaped, p_key, p_size, p_inline_align, p_baseline, ret); + return ret; } int64_t TextServerExtension::shaped_get_span_count(const RID &p_shaped) const { - int64_t ret; - if (GDVIRTUAL_CALL(_shaped_get_span_count, p_shaped, ret)) { - return ret; - } - return 0; + int64_t ret = 0; + GDVIRTUAL_CALL(_shaped_get_span_count, p_shaped, ret); + return ret; } Variant TextServerExtension::shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const { - Variant ret; - if (GDVIRTUAL_CALL(_shaped_get_span_meta, p_shaped, p_index, ret)) { - return ret; - } - return false; + Variant ret = false; + GDVIRTUAL_CALL(_shaped_get_span_meta, p_shaped, p_index, ret); + return ret; } void TextServerExtension::shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features) { @@ -1182,98 +1071,74 @@ void TextServerExtension::shaped_set_span_update_font(const RID &p_shaped, int64 RID TextServerExtension::shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const { RID ret; - if (GDVIRTUAL_CALL(_shaped_text_substr, p_shaped, p_start, p_length, ret)) { - return ret; - } - return RID(); + GDVIRTUAL_CALL(_shaped_text_substr, p_shaped, p_start, p_length, ret); + return ret; } RID TextServerExtension::shaped_text_get_parent(const RID &p_shaped) const { RID ret; - if (GDVIRTUAL_CALL(_shaped_text_get_parent, p_shaped, ret)) { - return ret; - } - return RID(); + GDVIRTUAL_CALL(_shaped_text_get_parent, p_shaped, ret); + return ret; } double TextServerExtension::shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<TextServer::JustificationFlag> p_jst_flags) { - double ret; - if (GDVIRTUAL_CALL(_shaped_text_fit_to_width, p_shaped, p_width, p_jst_flags, ret)) { - return ret; - } - return 0.0; + double ret = 0; + GDVIRTUAL_CALL(_shaped_text_fit_to_width, p_shaped, p_width, p_jst_flags, ret); + return ret; } double TextServerExtension::shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) { - double ret; - if (GDVIRTUAL_CALL(_shaped_text_tab_align, p_shaped, p_tab_stops, ret)) { - return ret; - } - return 0.0; + double ret = 0; + GDVIRTUAL_CALL(_shaped_text_tab_align, p_shaped, p_tab_stops, ret); + return ret; } bool TextServerExtension::shaped_text_shape(const RID &p_shaped) { - bool ret; - if (GDVIRTUAL_CALL(_shaped_text_shape, p_shaped, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_shaped_text_shape, p_shaped, ret); + return ret; } bool TextServerExtension::shaped_text_update_breaks(const RID &p_shaped) { - bool ret; - if (GDVIRTUAL_CALL(_shaped_text_update_breaks, p_shaped, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_shaped_text_update_breaks, p_shaped, ret); + return ret; } bool TextServerExtension::shaped_text_update_justification_ops(const RID &p_shaped) { - bool ret; - if (GDVIRTUAL_CALL(_shaped_text_update_justification_ops, p_shaped, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_shaped_text_update_justification_ops, p_shaped, ret); + return ret; } bool TextServerExtension::shaped_text_is_ready(const RID &p_shaped) const { - bool ret; - if (GDVIRTUAL_CALL(_shaped_text_is_ready, p_shaped, ret)) { - return ret; - } - return false; + bool ret = false; + GDVIRTUAL_CALL(_shaped_text_is_ready, p_shaped, ret); + return ret; } const Glyph *TextServerExtension::shaped_text_get_glyphs(const RID &p_shaped) const { - GDNativeConstPtr<const Glyph> ret; - if (GDVIRTUAL_CALL(_shaped_text_get_glyphs, p_shaped, ret)) { - return ret; - } - return nullptr; + GDExtensionConstPtr<const Glyph> ret; + GDVIRTUAL_CALL(_shaped_text_get_glyphs, p_shaped, ret); + return ret; } const Glyph *TextServerExtension::shaped_text_sort_logical(const RID &p_shaped) { - GDNativeConstPtr<const Glyph> ret; - if (GDVIRTUAL_CALL(_shaped_text_sort_logical, p_shaped, ret)) { - return ret; - } - return nullptr; + GDExtensionConstPtr<const Glyph> ret; + GDVIRTUAL_CALL(_shaped_text_sort_logical, p_shaped, ret); + return ret; } int64_t TextServerExtension::shaped_text_get_glyph_count(const RID &p_shaped) const { - int64_t ret; - if (GDVIRTUAL_CALL(_shaped_text_get_glyph_count, p_shaped, ret)) { - return ret; - } - return 0; + int64_t ret = 0; + GDVIRTUAL_CALL(_shaped_text_get_glyph_count, p_shaped, ret); + return ret; } Vector2i TextServerExtension::shaped_text_get_range(const RID &p_shaped) const { Vector2i ret; - if (GDVIRTUAL_CALL(_shaped_text_get_range, p_shaped, ret)) { - return ret; - } - return Vector2i(); + GDVIRTUAL_CALL(_shaped_text_get_range, p_shaped, ret); + return ret; } PackedInt32Array TextServerExtension::shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start, bool p_once, BitField<TextServer::LineBreakFlag> p_break_flags) const { @@ -1301,35 +1166,27 @@ PackedInt32Array TextServerExtension::shaped_text_get_word_breaks(const RID &p_s } int64_t TextServerExtension::shaped_text_get_trim_pos(const RID &p_shaped) const { - int64_t ret; - if (GDVIRTUAL_CALL(_shaped_text_get_trim_pos, p_shaped, ret)) { - return ret; - } - return -1; + int64_t ret = -1; + GDVIRTUAL_CALL(_shaped_text_get_trim_pos, p_shaped, ret); + return ret; } int64_t TextServerExtension::shaped_text_get_ellipsis_pos(const RID &p_shaped) const { - int64_t ret; - if (GDVIRTUAL_CALL(_shaped_text_get_ellipsis_pos, p_shaped, ret)) { - return ret; - } - return -1; + int64_t ret = -1; + GDVIRTUAL_CALL(_shaped_text_get_ellipsis_pos, p_shaped, ret); + return ret; } const Glyph *TextServerExtension::shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const { - GDNativeConstPtr<const Glyph> ret; - if (GDVIRTUAL_CALL(_shaped_text_get_ellipsis_glyphs, p_shaped, ret)) { - return ret; - } - return nullptr; + GDExtensionConstPtr<const Glyph> ret; + GDVIRTUAL_CALL(_shaped_text_get_ellipsis_glyphs, p_shaped, ret); + return ret; } int64_t TextServerExtension::shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const { - int64_t ret; - if (GDVIRTUAL_CALL(_shaped_text_get_ellipsis_glyph_count, p_shaped, ret)) { - return ret; - } - return -1; + int64_t ret = -1; + GDVIRTUAL_CALL(_shaped_text_get_ellipsis_glyph_count, p_shaped, ret); + return ret; } void TextServerExtension::shaped_text_overrun_trim_to_width(const RID &p_shaped_line, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) { @@ -1338,66 +1195,50 @@ void TextServerExtension::shaped_text_overrun_trim_to_width(const RID &p_shaped_ Array TextServerExtension::shaped_text_get_objects(const RID &p_shaped) const { Array ret; - if (GDVIRTUAL_CALL(_shaped_text_get_objects, p_shaped, ret)) { - return ret; - } - return Array(); + GDVIRTUAL_CALL(_shaped_text_get_objects, p_shaped, ret); + return ret; } Rect2 TextServerExtension::shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const { Rect2 ret; - if (GDVIRTUAL_CALL(_shaped_text_get_object_rect, p_shaped, p_key, ret)) { - return ret; - } - return Rect2(); + GDVIRTUAL_CALL(_shaped_text_get_object_rect, p_shaped, p_key, ret); + return ret; } Size2 TextServerExtension::shaped_text_get_size(const RID &p_shaped) const { Size2 ret; - if (GDVIRTUAL_CALL(_shaped_text_get_size, p_shaped, ret)) { - return ret; - } - return Size2(); + GDVIRTUAL_CALL(_shaped_text_get_size, p_shaped, ret); + return ret; } double TextServerExtension::shaped_text_get_ascent(const RID &p_shaped) const { - double ret; - if (GDVIRTUAL_CALL(_shaped_text_get_ascent, p_shaped, ret)) { - return ret; - } - return 0.0; + double ret = 0; + GDVIRTUAL_CALL(_shaped_text_get_ascent, p_shaped, ret); + return ret; } double TextServerExtension::shaped_text_get_descent(const RID &p_shaped) const { - double ret; - if (GDVIRTUAL_CALL(_shaped_text_get_descent, p_shaped, ret)) { - return ret; - } - return 0.0; + double ret = 0; + GDVIRTUAL_CALL(_shaped_text_get_descent, p_shaped, ret); + return ret; } double TextServerExtension::shaped_text_get_width(const RID &p_shaped) const { - double ret; - if (GDVIRTUAL_CALL(_shaped_text_get_width, p_shaped, ret)) { - return ret; - } - return 0.0; + double ret = 0; + GDVIRTUAL_CALL(_shaped_text_get_width, p_shaped, ret); + return ret; } double TextServerExtension::shaped_text_get_underline_position(const RID &p_shaped) const { - double ret; - if (GDVIRTUAL_CALL(_shaped_text_get_underline_position, p_shaped, ret)) { - return ret; - } - return 0.0; + double ret = 0; + GDVIRTUAL_CALL(_shaped_text_get_underline_position, p_shaped, ret); + return ret; } double TextServerExtension::shaped_text_get_underline_thickness(const RID &p_shaped) const { - double ret; - if (GDVIRTUAL_CALL(_shaped_text_get_underline_thickness, p_shaped, ret)) { - return ret; - } - return 0.0; + double ret = 0; + GDVIRTUAL_CALL(_shaped_text_get_underline_thickness, p_shaped, ret); + return ret; } TextServer::Direction TextServerExtension::shaped_text_get_dominant_direction_in_range(const RID &p_shaped, int64_t p_start, int64_t p_end) const { @@ -1495,11 +1336,9 @@ String TextServerExtension::parse_number(const String &p_string, const String &p } String TextServerExtension::percent_sign(const String &p_language) const { - String ret; - if (GDVIRTUAL_CALL(_percent_sign, p_language, ret)) { - return ret; - } - return "%"; + String ret = "%"; + GDVIRTUAL_CALL(_percent_sign, p_language, ret); + return ret; } bool TextServerExtension::is_valid_identifier(const String &p_string) const { @@ -1536,18 +1375,14 @@ String TextServerExtension::string_to_lower(const String &p_string, const String TypedArray<Vector2i> TextServerExtension::parse_structured_text(StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const { TypedArray<Vector2i> ret; - if (GDVIRTUAL_CALL(_parse_structured_text, p_parser_type, p_args, p_text, ret)) { - return ret; - } - return TypedArray<Vector2i>(); + GDVIRTUAL_CALL(_parse_structured_text, p_parser_type, p_args, p_text, ret); + return ret; } -PackedInt32Array TextServerExtension::string_get_word_breaks(const String &p_string, const String &p_language) const { +PackedInt32Array TextServerExtension::string_get_word_breaks(const String &p_string, const String &p_language, int p_chars_per_line) const { PackedInt32Array ret; - if (GDVIRTUAL_CALL(_string_get_word_breaks, p_string, p_language, ret)) { - return ret; - } - return PackedInt32Array(); + GDVIRTUAL_CALL(_string_get_word_breaks, p_string, p_language, p_chars_per_line, ret); + return ret; } int64_t TextServerExtension::is_confusable(const String &p_string, const PackedStringArray &p_dict) const { @@ -1566,6 +1401,10 @@ bool TextServerExtension::spoof_check(const String &p_string) const { return TextServer::spoof_check(p_string); } +void TextServerExtension::cleanup() { + GDVIRTUAL_CALL(_cleanup); +} + TextServerExtension::TextServerExtension() { //NOP } diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h index 992b708045..551e4e9087 100644 --- a/servers/text/text_server_extension.h +++ b/servers/text/text_server_extension.h @@ -84,7 +84,7 @@ public: virtual void font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) override; virtual void font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) override; GDVIRTUAL2(_font_set_data, RID, const PackedByteArray &); - GDVIRTUAL3(_font_set_data_ptr, RID, GDNativeConstPtr<const uint8_t>, int64_t); + GDVIRTUAL3(_font_set_data_ptr, RID, GDExtensionConstPtr<const uint8_t>, int64_t); virtual void font_set_face_index(const RID &p_font_rid, int64_t p_index) override; virtual int64_t font_get_face_index(const RID &p_font_rid) const override; @@ -109,6 +109,16 @@ public: GDVIRTUAL2(_font_set_style_name, RID, const String &); GDVIRTUAL1RC(String, _font_get_style_name, RID); + virtual void font_set_weight(const RID &p_font_rid, int64_t p_weight) override; + virtual int64_t font_get_weight(const RID &p_font_rid) const override; + GDVIRTUAL2(_font_set_weight, RID, int); + GDVIRTUAL1RC(int64_t, _font_get_weight, RID); + + virtual void font_set_stretch(const RID &p_font_rid, int64_t p_stretch) override; + virtual int64_t font_get_stretch(const RID &p_font_rid) const override; + GDVIRTUAL2(_font_set_stretch, RID, int); + GDVIRTUAL1RC(int64_t, _font_get_stretch, RID); + virtual void font_set_antialiasing(const RID &p_font_rid, TextServer::FontAntialiasing p_antialiasing) override; virtual TextServer::FontAntialiasing font_get_antialiasing(const RID &p_font_rid) const override; GDVIRTUAL2(_font_set_antialiasing, RID, TextServer::FontAntialiasing); @@ -154,6 +164,11 @@ public: GDVIRTUAL2(_font_set_transform, RID, Transform2D); GDVIRTUAL1RC(Transform2D, _font_get_transform, RID); + virtual void font_set_allow_system_fallback(const RID &p_font_rid, bool p_allow_system_fallback) override; + virtual bool font_is_allow_system_fallback(const RID &p_font_rid) const override; + GDVIRTUAL2(_font_set_allow_system_fallback, RID, bool); + GDVIRTUAL1RC(bool, _font_is_allow_system_fallback, RID); + virtual void font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) override; virtual bool font_is_force_autohinter(const RID &p_font_rid) const override; GDVIRTUAL2(_font_set_force_autohinter, RID, bool); @@ -380,11 +395,11 @@ public: GDVIRTUAL2RC(int64_t, _shaped_text_get_spacing, RID, SpacingType); virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override; - virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) override; - virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override; + virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1, float p_baseline = 0.0) override; + virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, float p_baseline = 0.0) override; GDVIRTUAL7R(bool, _shaped_text_add_string, RID, const String &, const TypedArray<RID> &, int64_t, const Dictionary &, const String &, const Variant &); - GDVIRTUAL5R(bool, _shaped_text_add_object, RID, const Variant &, const Size2 &, InlineAlignment, int64_t); - GDVIRTUAL4R(bool, _shaped_text_resize_object, RID, const Variant &, const Size2 &, InlineAlignment); + GDVIRTUAL6R(bool, _shaped_text_add_object, RID, const Variant &, const Size2 &, InlineAlignment, int64_t, float); + GDVIRTUAL5R(bool, _shaped_text_resize_object, RID, const Variant &, const Size2 &, InlineAlignment, float); virtual int64_t shaped_get_span_count(const RID &p_shaped) const override; virtual Variant shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const override; @@ -416,8 +431,8 @@ public: virtual const Glyph *shaped_text_get_glyphs(const RID &p_shaped) const override; virtual const Glyph *shaped_text_sort_logical(const RID &p_shaped) override; virtual int64_t shaped_text_get_glyph_count(const RID &p_shaped) const override; - GDVIRTUAL1RC(GDNativeConstPtr<const Glyph>, _shaped_text_get_glyphs, RID); - GDVIRTUAL1R(GDNativeConstPtr<const Glyph>, _shaped_text_sort_logical, RID); + GDVIRTUAL1RC(GDExtensionConstPtr<const Glyph>, _shaped_text_get_glyphs, RID); + GDVIRTUAL1R(GDExtensionConstPtr<const Glyph>, _shaped_text_sort_logical, RID); GDVIRTUAL1RC(int64_t, _shaped_text_get_glyph_count, RID); virtual Vector2i shaped_text_get_range(const RID &p_shaped) const override; @@ -436,7 +451,7 @@ public: virtual int64_t shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const override; GDVIRTUAL1RC(int64_t, _shaped_text_get_trim_pos, RID); GDVIRTUAL1RC(int64_t, _shaped_text_get_ellipsis_pos, RID); - GDVIRTUAL1RC(GDNativeConstPtr<const Glyph>, _shaped_text_get_ellipsis_glyphs, RID); + GDVIRTUAL1RC(GDExtensionConstPtr<const Glyph>, _shaped_text_get_ellipsis_glyphs, RID); GDVIRTUAL1RC(int64_t, _shaped_text_get_ellipsis_glyph_count, RID); virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) override; @@ -465,7 +480,7 @@ public: virtual CaretInfo shaped_text_get_carets(const RID &p_shaped, int64_t p_position) const override; virtual Vector<Vector2> shaped_text_get_selection(const RID &p_shaped, int64_t p_start, int64_t p_end) const override; - GDVIRTUAL3C(_shaped_text_get_carets, RID, int64_t, GDNativePtr<CaretInfo>); + GDVIRTUAL3C(_shaped_text_get_carets, RID, int64_t, GDExtensionPtr<CaretInfo>); GDVIRTUAL3RC(Vector<Vector2>, _shaped_text_get_selection, RID, int64_t, int64_t); virtual int64_t shaped_text_hit_test_grapheme(const RID &p_shaped, double p_coords) const override; @@ -495,8 +510,8 @@ public: virtual String strip_diacritics(const String &p_string) const override; GDVIRTUAL1RC(String, _strip_diacritics, const String &); - virtual PackedInt32Array string_get_word_breaks(const String &p_string, const String &p_language = "") const override; - GDVIRTUAL2RC(PackedInt32Array, _string_get_word_breaks, const String &, const String &); + virtual PackedInt32Array string_get_word_breaks(const String &p_string, const String &p_language = "", int p_chars_per_line = 0) const override; + GDVIRTUAL3RC(PackedInt32Array, _string_get_word_breaks, const String &, const String &, int); virtual bool is_valid_identifier(const String &p_string) const override; GDVIRTUAL1RC(bool, _is_valid_identifier, const String &); @@ -514,6 +529,9 @@ public: GDVIRTUAL2RC(int64_t, _is_confusable, const String &, const PackedStringArray &); GDVIRTUAL1RC(bool, _spoof_check, const String &); + virtual void cleanup() override; + GDVIRTUAL0(_cleanup); + TextServerExtension(); ~TextServerExtension(); }; diff --git a/servers/text_server.cpp b/servers/text_server.cpp index dfeb5cb70c..c0f235fe50 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -223,6 +223,12 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("font_set_style_name", "font_rid", "name"), &TextServer::font_set_style_name); ClassDB::bind_method(D_METHOD("font_get_style_name", "font_rid"), &TextServer::font_get_style_name); + ClassDB::bind_method(D_METHOD("font_set_weight", "font_rid", "weight"), &TextServer::font_set_weight); + ClassDB::bind_method(D_METHOD("font_get_weight", "font_rid"), &TextServer::font_get_weight); + + ClassDB::bind_method(D_METHOD("font_set_stretch", "font_rid", "weight"), &TextServer::font_set_stretch); + ClassDB::bind_method(D_METHOD("font_get_stretch", "font_rid"), &TextServer::font_get_stretch); + ClassDB::bind_method(D_METHOD("font_set_antialiasing", "font_rid", "antialiasing"), &TextServer::font_set_antialiasing); ClassDB::bind_method(D_METHOD("font_get_antialiasing", "font_rid"), &TextServer::font_get_antialiasing); @@ -241,6 +247,9 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("font_set_fixed_size", "font_rid", "fixed_size"), &TextServer::font_set_fixed_size); ClassDB::bind_method(D_METHOD("font_get_fixed_size", "font_rid"), &TextServer::font_get_fixed_size); + ClassDB::bind_method(D_METHOD("font_set_allow_system_fallback", "font_rid", "allow_system_fallback"), &TextServer::font_set_allow_system_fallback); + ClassDB::bind_method(D_METHOD("font_is_allow_system_fallback", "font_rid"), &TextServer::font_is_allow_system_fallback); + ClassDB::bind_method(D_METHOD("font_set_force_autohinter", "font_rid", "force_autohinter"), &TextServer::font_set_force_autohinter); ClassDB::bind_method(D_METHOD("font_is_force_autohinter", "font_rid"), &TextServer::font_is_force_autohinter); @@ -385,8 +394,8 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("shaped_text_get_spacing", "shaped", "spacing"), &TextServer::shaped_text_get_spacing); ClassDB::bind_method(D_METHOD("shaped_text_add_string", "shaped", "text", "fonts", "size", "opentype_features", "language", "meta"), &TextServer::shaped_text_add_string, DEFVAL(Dictionary()), DEFVAL(""), DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("shaped_text_add_object", "shaped", "key", "size", "inline_align", "length"), &TextServer::shaped_text_add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1)); - ClassDB::bind_method(D_METHOD("shaped_text_resize_object", "shaped", "key", "size", "inline_align"), &TextServer::shaped_text_resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER)); + ClassDB::bind_method(D_METHOD("shaped_text_add_object", "shaped", "key", "size", "inline_align", "length", "baseline"), &TextServer::shaped_text_add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1), DEFVAL(0.0)); + ClassDB::bind_method(D_METHOD("shaped_text_resize_object", "shaped", "key", "size", "inline_align", "baseline"), &TextServer::shaped_text_resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(0.0)); ClassDB::bind_method(D_METHOD("shaped_get_span_count", "shaped"), &TextServer::shaped_get_span_count); ClassDB::bind_method(D_METHOD("shaped_get_span_meta", "shaped", "index"), &TextServer::shaped_get_span_meta); @@ -445,7 +454,7 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("parse_number", "number", "language"), &TextServer::parse_number, DEFVAL("")); ClassDB::bind_method(D_METHOD("percent_sign", "language"), &TextServer::percent_sign, DEFVAL("")); - ClassDB::bind_method(D_METHOD("string_get_word_breaks", "string", "language"), &TextServer::string_get_word_breaks, DEFVAL("")); + ClassDB::bind_method(D_METHOD("string_get_word_breaks", "string", "language", "chars_per_line"), &TextServer::string_get_word_breaks, DEFVAL(""), DEFVAL(0)); ClassDB::bind_method(D_METHOD("is_confusable", "string", "dict"), &TextServer::is_confusable); ClassDB::bind_method(D_METHOD("spoof_check", "string"), &TextServer::spoof_check); diff --git a/servers/text_server.h b/servers/text_server.h index a4e6080fd0..0d94f45b79 100644 --- a/servers/text_server.h +++ b/servers/text_server.h @@ -250,6 +250,12 @@ public: virtual void font_set_style_name(const RID &p_font_rid, const String &p_name) = 0; virtual String font_get_style_name(const RID &p_font_rid) const = 0; + virtual void font_set_weight(const RID &p_font_rid, int64_t p_weight) = 0; + virtual int64_t font_get_weight(const RID &p_font_rid) const = 0; + + virtual void font_set_stretch(const RID &p_font_rid, int64_t p_stretch) = 0; + virtual int64_t font_get_stretch(const RID &p_font_rid) const = 0; + virtual void font_set_antialiasing(const RID &p_font_rid, FontAntialiasing p_antialiasing) = 0; virtual FontAntialiasing font_get_antialiasing(const RID &p_font_rid) const = 0; @@ -268,6 +274,9 @@ public: virtual void font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) = 0; virtual int64_t font_get_fixed_size(const RID &p_font_rid) const = 0; + virtual void font_set_allow_system_fallback(const RID &p_font_rid, bool p_allow_system_fallback) = 0; + virtual bool font_is_allow_system_fallback(const RID &p_font_rid) const = 0; + virtual void font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) = 0; virtual bool font_is_force_autohinter(const RID &p_font_rid) const = 0; @@ -411,8 +420,8 @@ public: virtual int64_t shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const = 0; virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) = 0; - virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) = 0; - virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) = 0; + virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1, float p_baseline = 0.0) = 0; + virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, float p_baseline = 0.0) = 0; virtual int64_t shaped_get_span_count(const RID &p_shaped) const = 0; virtual Variant shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const = 0; @@ -484,7 +493,7 @@ public: virtual String percent_sign(const String &p_language = "") const = 0; // String functions. - virtual PackedInt32Array string_get_word_breaks(const String &p_string, const String &p_language = "") const = 0; + virtual PackedInt32Array string_get_word_breaks(const String &p_string, const String &p_language = "", int p_chars_per_line = 0) const = 0; virtual int64_t is_confusable(const String &p_string, const PackedStringArray &p_dict) const { return -1; }; virtual bool spoof_check(const String &p_string) const { return false; }; @@ -498,6 +507,8 @@ public: TypedArray<Vector2i> parse_structured_text(StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const; + virtual void cleanup() {} + TextServer(); ~TextServer(); }; diff --git a/servers/xr/xr_interface.cpp b/servers/xr/xr_interface.cpp index 430e2042d9..ec4ae98397 100644 --- a/servers/xr/xr_interface.cpp +++ b/servers/xr/xr_interface.cpp @@ -72,6 +72,8 @@ void XRInterface::_bind_methods() { ClassDB::bind_method(D_METHOD("is_passthrough_enabled"), &XRInterface::is_passthrough_enabled); ClassDB::bind_method(D_METHOD("start_passthrough"), &XRInterface::start_passthrough); ClassDB::bind_method(D_METHOD("stop_passthrough"), &XRInterface::stop_passthrough); + ClassDB::bind_method(D_METHOD("get_transform_for_view", "view", "cam_transform"), &XRInterface::get_transform_for_view); + ClassDB::bind_method(D_METHOD("get_projection_for_view", "view", "aspect", "near", "far"), &XRInterface::get_projection_for_view); ADD_GROUP("AR", "ar_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ar_is_anchor_detection_enabled"), "set_anchor_detection_is_enabled", "get_anchor_detection_is_enabled"); @@ -165,11 +167,12 @@ RID XRInterface::get_vrs_texture() { // Default logic will return a standard VRS image based on our target size and default projections. // Note that this only gets called if VRS is supported on the hardware. - Size2 texel_size = Size2(16.0, 16.0); // For now we assume we always use 16x16 texels, seems to be the standard. + int32_t texel_width = RD::get_singleton()->limit_get(RD::LIMIT_VRS_TEXEL_WIDTH); + int32_t texel_height = RD::get_singleton()->limit_get(RD::LIMIT_VRS_TEXEL_HEIGHT); int view_count = get_view_count(); Size2 target_size = get_render_target_size(); real_t aspect = target_size.x / target_size.y; // is this y/x ? - Size2 vrs_size = Size2(round(0.5 + target_size.x / texel_size.x), round(0.5 + target_size.y / texel_size.y)); + Size2 vrs_size = Size2(round(0.5 + target_size.x / texel_width), round(0.5 + target_size.y / texel_height)); real_t radius = vrs_size.length() * 0.5; Size2 vrs_sizei = vrs_size; @@ -177,6 +180,8 @@ RID XRInterface::get_vrs_texture() { const uint8_t densities[] = { 0, // 1x1 1, // 1x2 + // 2, // 1x4 - not supported + // 3, // 1x8 - not supported // 4, // 2x1 5, // 2x2 6, // 2x4 @@ -222,12 +227,7 @@ RID XRInterface::get_vrs_texture() { data_ptr[d++] = density; } } - - Ref<Image> image; - image.instantiate(); - image->create_from_data(vrs_sizei.x, vrs_sizei.y, false, Image::FORMAT_R8, data); - - images.push_back(image); + images.push_back(Image::create_from_data(vrs_sizei.x, vrs_sizei.y, false, Image::FORMAT_R8, data)); } if (images.size() == 1) { diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h index 86d328d41c..2960074dd2 100644 --- a/servers/xr/xr_interface.h +++ b/servers/xr/xr_interface.h @@ -138,8 +138,6 @@ public: virtual bool start_passthrough() { return false; } virtual void stop_passthrough() {} - virtual void notification(int p_what){}; - XRInterface(); ~XRInterface(); diff --git a/servers/xr/xr_interface_extension.cpp b/servers/xr/xr_interface_extension.cpp index 0d4a53d287..2142ecd262 100644 --- a/servers/xr/xr_interface_extension.cpp +++ b/servers/xr/xr_interface_extension.cpp @@ -58,8 +58,6 @@ void XRInterfaceExtension::_bind_methods() { GDVIRTUAL_BIND(_post_draw_viewport, "render_target", "screen_rect"); GDVIRTUAL_BIND(_end_frame); - GDVIRTUAL_BIND(_notification, "what"); - /** input and output **/ GDVIRTUAL_BIND(_get_suggested_tracker_names); @@ -100,33 +98,21 @@ StringName XRInterfaceExtension::get_name() const { } uint32_t XRInterfaceExtension::get_capabilities() const { - uint32_t capabilities; - - if (GDVIRTUAL_CALL(_get_capabilities, capabilities)) { - return capabilities; - } - - return 0; + uint32_t capabilities = 0; + GDVIRTUAL_CALL(_get_capabilities, capabilities); + return capabilities; } bool XRInterfaceExtension::is_initialized() const { - bool initialised = false; - - if (GDVIRTUAL_CALL(_is_initialized, initialised)) { - return initialised; - } - - return false; + bool initialized = false; + GDVIRTUAL_CALL(_is_initialized, initialized); + return initialized; } bool XRInterfaceExtension::initialize() { - bool initialised = false; - - if (GDVIRTUAL_CALL(_initialize, initialised)) { - return initialised; - } - - return false; + bool initialized = false; + GDVIRTUAL_CALL(_initialize, initialized); + return initialized; } void XRInterfaceExtension::uninitialize() { @@ -150,13 +136,9 @@ PackedStringArray XRInterfaceExtension::get_suggested_pose_names(const StringNam } XRInterface::TrackingStatus XRInterfaceExtension::get_tracking_status() const { - uint32_t status; - - if (GDVIRTUAL_CALL(_get_tracking_status, status)) { - return TrackingStatus(status); - } - - return XR_UNKNOWN_TRACKING; + uint32_t status = XR_UNKNOWN_TRACKING; + GDVIRTUAL_CALL(_get_tracking_status, status); + return TrackingStatus(status); } void XRInterfaceExtension::trigger_haptic_pulse(const String &p_action_name, const StringName &p_tracker_name, double p_frequency, double p_amplitude, double p_duration_sec, double p_delay_sec) { @@ -164,52 +146,34 @@ void XRInterfaceExtension::trigger_haptic_pulse(const String &p_action_name, con } bool XRInterfaceExtension::supports_play_area_mode(XRInterface::PlayAreaMode p_mode) { - bool is_supported; - - if (GDVIRTUAL_CALL(_supports_play_area_mode, p_mode, is_supported)) { - return is_supported; - } - - return false; + bool is_supported = false; + GDVIRTUAL_CALL(_supports_play_area_mode, p_mode, is_supported); + return is_supported; } XRInterface::PlayAreaMode XRInterfaceExtension::get_play_area_mode() const { - uint32_t mode; - - if (GDVIRTUAL_CALL(_get_play_area_mode, mode)) { - return XRInterface::PlayAreaMode(mode); - } - - return XRInterface::XR_PLAY_AREA_UNKNOWN; + uint32_t mode = XR_PLAY_AREA_UNKNOWN; + GDVIRTUAL_CALL(_get_play_area_mode, mode); + return XRInterface::PlayAreaMode(mode); } bool XRInterfaceExtension::set_play_area_mode(XRInterface::PlayAreaMode p_mode) { - bool success; - - if (GDVIRTUAL_CALL(_set_play_area_mode, p_mode, success)) { - return success; - } - - return false; + bool success = false; + GDVIRTUAL_CALL(_set_play_area_mode, p_mode, success); + return success; } PackedVector3Array XRInterfaceExtension::get_play_area() const { PackedVector3Array arr; - GDVIRTUAL_CALL(_get_play_area, arr); - return arr; } /** these will only be implemented on AR interfaces, so we want dummies for VR **/ bool XRInterfaceExtension::get_anchor_detection_is_enabled() const { - bool enabled; - - if (GDVIRTUAL_CALL(_get_anchor_detection_is_enabled, enabled)) { - return enabled; - } - - return false; + bool enabled = false; + GDVIRTUAL_CALL(_get_anchor_detection_is_enabled, enabled); + return enabled; } void XRInterfaceExtension::set_anchor_detection_is_enabled(bool p_enable) { @@ -218,53 +182,33 @@ void XRInterfaceExtension::set_anchor_detection_is_enabled(bool p_enable) { } int XRInterfaceExtension::get_camera_feed_id() { - int feed_id; - - if (GDVIRTUAL_CALL(_get_camera_feed_id, feed_id)) { - return feed_id; - } - - return 0; + int feed_id = 0; + GDVIRTUAL_CALL(_get_camera_feed_id, feed_id); + return feed_id; } Size2 XRInterfaceExtension::get_render_target_size() { Size2 size; - - if (GDVIRTUAL_CALL(_get_render_target_size, size)) { - return size; - } - - return Size2(0, 0); + GDVIRTUAL_CALL(_get_render_target_size, size); + return size; } uint32_t XRInterfaceExtension::get_view_count() { - uint32_t view_count; - - if (GDVIRTUAL_CALL(_get_view_count, view_count)) { - return view_count; - } - - return 1; + uint32_t view_count = 1; + GDVIRTUAL_CALL(_get_view_count, view_count); + return view_count; } Transform3D XRInterfaceExtension::get_camera_transform() { Transform3D transform; - - if (GDVIRTUAL_CALL(_get_camera_transform, transform)) { - return transform; - } - - return Transform3D(); + GDVIRTUAL_CALL(_get_camera_transform, transform); + return transform; } Transform3D XRInterfaceExtension::get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) { Transform3D transform; - - if (GDVIRTUAL_CALL(_get_transform_for_view, p_view, p_cam_transform, transform)) { - return transform; - } - - return Transform3D(); + GDVIRTUAL_CALL(_get_transform_for_view, p_view, p_cam_transform, transform); + return transform; } Projection XRInterfaceExtension::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) { @@ -294,29 +238,20 @@ RID XRInterfaceExtension::get_vrs_texture() { RID XRInterfaceExtension::get_color_texture() { RID texture; - if (GDVIRTUAL_CALL(_get_color_texture, texture)) { - return texture; - } else { - return RID(); - } + GDVIRTUAL_CALL(_get_color_texture, texture); + return texture; } RID XRInterfaceExtension::get_depth_texture() { RID texture; - if (GDVIRTUAL_CALL(_get_depth_texture, texture)) { - return texture; - } else { - return RID(); - } + GDVIRTUAL_CALL(_get_depth_texture, texture); + return texture; } RID XRInterfaceExtension::get_velocity_texture() { RID texture; - if (GDVIRTUAL_CALL(_get_velocity_texture, texture)) { - return texture; - } else { - return RID(); - } + GDVIRTUAL_CALL(_get_velocity_texture, texture); + return texture; } void XRInterfaceExtension::add_blit(RID p_render_target, Rect2 p_src_rect, Rect2i p_dst_rect, bool p_use_layer, uint32_t p_layer, bool p_apply_lens_distortion, Vector2 p_eye_center, double p_k1, double p_k2, double p_upscale, double p_aspect_ratio) { @@ -351,13 +286,8 @@ void XRInterfaceExtension::pre_render() { bool XRInterfaceExtension::pre_draw_viewport(RID p_render_target) { bool do_render = true; - - if (GDVIRTUAL_CALL(_pre_draw_viewport, p_render_target, do_render)) { - return do_render; - } else { - // if not implemented we're returning true - return true; - } + GDVIRTUAL_CALL(_pre_draw_viewport, p_render_target, do_render); + return do_render; // If not implemented we're returning true. } Vector<BlitToScreen> XRInterfaceExtension::post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) { @@ -377,10 +307,6 @@ void XRInterfaceExtension::end_frame() { GDVIRTUAL_CALL(_end_frame); } -void XRInterfaceExtension::notification(int p_what) { - GDVIRTUAL_CALL(_notification, p_what); -} - RID XRInterfaceExtension::get_render_target_texture(RID p_render_target) { // In due time this will need to be enhance to return the correct INTERNAL RID for the chosen rendering engine. // So once a GLES driver is implemented we'll return that and the implemented plugin needs to handle this correctly too. diff --git a/servers/xr/xr_interface_extension.h b/servers/xr/xr_interface_extension.h index 2235b57cb3..123626864d 100644 --- a/servers/xr/xr_interface_extension.h +++ b/servers/xr/xr_interface_extension.h @@ -123,7 +123,6 @@ public: virtual bool pre_draw_viewport(RID p_render_target) override; virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) override; virtual void end_frame() override; - virtual void notification(int p_what) override; GDVIRTUAL0(_process); GDVIRTUAL0(_pre_render); @@ -131,8 +130,6 @@ public: GDVIRTUAL2(_post_draw_viewport, RID, const Rect2 &); GDVIRTUAL0(_end_frame); - GDVIRTUAL1(_notification, int); - /* access to some internals we need */ RID get_render_target_texture(RID p_render_target); // RID get_render_target_depth(RID p_render_target); diff --git a/servers/xr_server.h b/servers/xr_server.h index 57e42deccb..4da5619fd3 100644 --- a/servers/xr_server.h +++ b/servers/xr_server.h @@ -58,7 +58,7 @@ class XRServer : public Object { public: enum XRMode { - XRMODE_DEFAULT, /* Default behaviour, means we check project settings */ + XRMODE_DEFAULT, /* Default behavior, means we check project settings */ XRMODE_OFF, /* Ignore project settings, disable OpenXR, disable shaders */ XRMODE_ON, /* Ignore project settings, enable OpenXR, enable shaders, run editor in VR (if applicable) */ }; |