feat: modules moved and engine moved to submodule
This commit is contained in:
parent
dfb5e645cd
commit
c33d2130cc
5136 changed files with 225275 additions and 64485 deletions
|
|
@ -26,12 +26,19 @@ if env["xaudio2"]:
|
|||
print_error("Target platform '{}' does not support the XAudio2 audio driver".format(env["platform"]))
|
||||
Exit(255)
|
||||
SConscript("xaudio2/SCsub")
|
||||
|
||||
# Shared Apple platform drivers
|
||||
if env["platform"] in ["macos", "ios"]:
|
||||
SConscript("apple/SCsub")
|
||||
|
||||
# Accessibility
|
||||
if env["accesskit"] and env["platform"] in ["macos", "windows", "linuxbsd"]:
|
||||
SConscript("accesskit/SCsub")
|
||||
|
||||
# Midi drivers
|
||||
SConscript("alsamidi/SCsub")
|
||||
SConscript("coremidi/SCsub")
|
||||
if env["platform"] in ["macos", "ios"]:
|
||||
SConscript("coremidi/SCsub")
|
||||
SConscript("winmidi/SCsub")
|
||||
|
||||
# Graphics drivers
|
||||
|
|
|
|||
16
engine/drivers/accesskit/SCsub
Normal file
16
engine/drivers/accesskit/SCsub
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env python
|
||||
from misc.utility.scons_hints import *
|
||||
|
||||
Import("env")
|
||||
|
||||
# Driver source files
|
||||
env.add_source_files(env.drivers_sources, "accessibility_driver_accesskit.cpp")
|
||||
|
||||
if env["accesskit_sdk_path"] == "":
|
||||
if env["platform"] == "windows":
|
||||
env.add_source_files(env.drivers_sources, "dynwrappers/accesskit-dll_wrap.c")
|
||||
if env["platform"] == "macos":
|
||||
env.add_source_files(env.drivers_sources, "dynwrappers/accesskit-dylib_wrap.c")
|
||||
if env["platform"] == "linuxbsd":
|
||||
env.add_source_files(env.drivers_sources, "dynwrappers/accesskit-so_wrap.c")
|
||||
env.Prepend(CPPPATH=["#thirdparty/accesskit/include"])
|
||||
1653
engine/drivers/accesskit/accessibility_driver_accesskit.cpp
Normal file
1653
engine/drivers/accesskit/accessibility_driver_accesskit.cpp
Normal file
File diff suppressed because it is too large
Load diff
197
engine/drivers/accesskit/accessibility_driver_accesskit.h
Normal file
197
engine/drivers/accesskit/accessibility_driver_accesskit.h
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
/**************************************************************************/
|
||||
/* accessibility_driver_accesskit.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
|
||||
#include "core/templates/rid_owner.h"
|
||||
#include "servers/display_server.h"
|
||||
|
||||
#ifdef ACCESSKIT_DYNAMIC
|
||||
#ifdef LINUXBSD_ENABLED
|
||||
#include "drivers/accesskit/dynwrappers/accesskit-so_wrap.h"
|
||||
#endif
|
||||
#ifdef MACOS_ENABLED
|
||||
#include "drivers/accesskit/dynwrappers/accesskit-dylib_wrap.h"
|
||||
#endif
|
||||
#ifdef WINDOWS_ENABLED
|
||||
#include "drivers/accesskit/dynwrappers/accesskit-dll_wrap.h"
|
||||
#endif
|
||||
#else
|
||||
#include <accesskit.h>
|
||||
#endif
|
||||
|
||||
class AccessibilityDriverAccessKit : public AccessibilityDriver {
|
||||
static AccessibilityDriverAccessKit *singleton;
|
||||
|
||||
struct AccessibilityElement {
|
||||
HashMap<accesskit_action, Callable> actions;
|
||||
|
||||
DisplayServer::WindowID window_id = DisplayServer::INVALID_WINDOW_ID;
|
||||
RID parent;
|
||||
LocalVector<RID> children;
|
||||
Vector3i run;
|
||||
Variant meta;
|
||||
String name;
|
||||
String name_extra_info;
|
||||
|
||||
accesskit_role role = ACCESSKIT_ROLE_UNKNOWN;
|
||||
accesskit_node *node = nullptr;
|
||||
};
|
||||
mutable RID_PtrOwner<AccessibilityElement> rid_owner;
|
||||
|
||||
struct WindowData {
|
||||
// Adapter.
|
||||
#ifdef WINDOWS_ENABLED
|
||||
accesskit_windows_subclassing_adapter *adapter = nullptr;
|
||||
#endif
|
||||
#ifdef MACOS_ENABLED
|
||||
accesskit_macos_subclassing_adapter *adapter = nullptr;
|
||||
#endif
|
||||
#ifdef LINUXBSD_ENABLED
|
||||
accesskit_unix_adapter *adapter = nullptr;
|
||||
#endif
|
||||
|
||||
RID root_id;
|
||||
HashSet<RID> update;
|
||||
};
|
||||
|
||||
RID focus;
|
||||
|
||||
HashMap<DisplayServer::WindowID, WindowData> windows;
|
||||
|
||||
HashMap<DisplayServer::AccessibilityRole, accesskit_role> role_map;
|
||||
HashMap<DisplayServer::AccessibilityAction, accesskit_action> action_map;
|
||||
|
||||
_FORCE_INLINE_ accesskit_role _accessibility_role(DisplayServer::AccessibilityRole p_role) const;
|
||||
_FORCE_INLINE_ accesskit_action _accessibility_action(DisplayServer::AccessibilityAction p_action) const;
|
||||
|
||||
void _free_recursive(WindowData *p_wd, const RID &p_id);
|
||||
_FORCE_INLINE_ void _ensure_node(const RID &p_id, AccessibilityElement *p_ae);
|
||||
|
||||
static void _accessibility_action_callback(struct accesskit_action_request *p_request, void *p_user_data);
|
||||
static accesskit_tree_update *_accessibility_initial_tree_update_callback(void *p_user_data);
|
||||
static void _accessibility_deactivation_callback(void *p_user_data);
|
||||
static accesskit_tree_update *_accessibility_build_tree_update(void *p_user_data);
|
||||
|
||||
bool in_accessibility_update = false;
|
||||
Callable update_cb;
|
||||
|
||||
public:
|
||||
Error init() override;
|
||||
|
||||
bool window_create(DisplayServer::WindowID p_window_id, void *p_handle) override;
|
||||
void window_destroy(DisplayServer::WindowID p_window_id) override;
|
||||
|
||||
RID accessibility_create_element(DisplayServer::WindowID p_window_id, DisplayServer::AccessibilityRole p_role) override;
|
||||
RID accessibility_create_sub_element(const RID &p_parent_rid, DisplayServer::AccessibilityRole p_role, int p_insert_pos = -1) override;
|
||||
virtual RID accessibility_create_sub_text_edit_elements(const RID &p_parent_rid, const RID &p_shaped_text, float p_min_height, int p_insert_pos = -1) override;
|
||||
bool accessibility_has_element(const RID &p_id) const override;
|
||||
void accessibility_free_element(const RID &p_id) override;
|
||||
|
||||
void accessibility_element_set_meta(const RID &p_id, const Variant &p_meta) override;
|
||||
Variant accessibility_element_get_meta(const RID &p_id) const override;
|
||||
|
||||
void accessibility_update_if_active(const Callable &p_callable) override;
|
||||
|
||||
void accessibility_update_set_focus(const RID &p_id) override;
|
||||
RID accessibility_get_window_root(DisplayServer::WindowID p_window_id) const override;
|
||||
|
||||
void accessibility_set_window_rect(DisplayServer::WindowID p_window_id, const Rect2 &p_rect_out, const Rect2 &p_rect_in) override;
|
||||
void accessibility_set_window_focused(DisplayServer::WindowID p_window_id, bool p_focused) override;
|
||||
|
||||
void accessibility_update_set_role(const RID &p_id, DisplayServer::AccessibilityRole p_role) override;
|
||||
void accessibility_update_set_name(const RID &p_id, const String &p_name) override;
|
||||
void accessibility_update_set_extra_info(const RID &p_id, const String &p_name_extra_info) override;
|
||||
void accessibility_update_set_description(const RID &p_id, const String &p_description) override;
|
||||
void accessibility_update_set_value(const RID &p_id, const String &p_value) override;
|
||||
void accessibility_update_set_tooltip(const RID &p_id, const String &p_tooltip) override;
|
||||
void accessibility_update_set_bounds(const RID &p_id, const Rect2 &p_rect) override;
|
||||
void accessibility_update_set_transform(const RID &p_id, const Transform2D &p_transform) override;
|
||||
void accessibility_update_add_child(const RID &p_id, const RID &p_child_id) override;
|
||||
void accessibility_update_add_related_controls(const RID &p_id, const RID &p_related_id) override;
|
||||
void accessibility_update_add_related_details(const RID &p_id, const RID &p_related_id) override;
|
||||
void accessibility_update_add_related_described_by(const RID &p_id, const RID &p_related_id) override;
|
||||
void accessibility_update_add_related_flow_to(const RID &p_id, const RID &p_related_id) override;
|
||||
void accessibility_update_add_related_labeled_by(const RID &p_id, const RID &p_related_id) override;
|
||||
void accessibility_update_add_related_radio_group(const RID &p_id, const RID &p_related_id) override;
|
||||
void accessibility_update_set_active_descendant(const RID &p_id, const RID &p_other_id) override;
|
||||
void accessibility_update_set_next_on_line(const RID &p_id, const RID &p_other_id) override;
|
||||
void accessibility_update_set_previous_on_line(const RID &p_id, const RID &p_other_id) override;
|
||||
void accessibility_update_set_member_of(const RID &p_id, const RID &p_group_id) override;
|
||||
void accessibility_update_set_in_page_link_target(const RID &p_id, const RID &p_other_id) override;
|
||||
void accessibility_update_set_error_message(const RID &p_id, const RID &p_other_id) override;
|
||||
void accessibility_update_set_live(const RID &p_id, DisplayServer::AccessibilityLiveMode p_live) override;
|
||||
void accessibility_update_add_action(const RID &p_id, DisplayServer::AccessibilityAction p_action, const Callable &p_callable) override;
|
||||
void accessibility_update_add_custom_action(const RID &p_id, int p_action_id, const String &p_action_description) override;
|
||||
void accessibility_update_set_table_row_count(const RID &p_id, int p_count) override;
|
||||
void accessibility_update_set_table_column_count(const RID &p_id, int p_count) override;
|
||||
void accessibility_update_set_table_row_index(const RID &p_id, int p_index) override;
|
||||
void accessibility_update_set_table_column_index(const RID &p_id, int p_index) override;
|
||||
void accessibility_update_set_table_cell_position(const RID &p_id, int p_row_index, int p_column_index) override;
|
||||
void accessibility_update_set_table_cell_span(const RID &p_id, int p_row_span, int p_column_span) override;
|
||||
void accessibility_update_set_list_item_count(const RID &p_id, int p_size) override;
|
||||
void accessibility_update_set_list_item_index(const RID &p_id, int p_index) override;
|
||||
void accessibility_update_set_list_item_level(const RID &p_id, int p_level) override;
|
||||
void accessibility_update_set_list_item_selected(const RID &p_id, bool p_selected) override;
|
||||
void accessibility_update_set_list_item_expanded(const RID &p_id, bool p_expanded) override;
|
||||
void accessibility_update_set_popup_type(const RID &p_id, DisplayServer::AccessibilityPopupType p_popup) override;
|
||||
void accessibility_update_set_checked(const RID &p_id, bool p_checekd) override;
|
||||
void accessibility_update_set_num_value(const RID &p_id, double p_position) override;
|
||||
void accessibility_update_set_num_range(const RID &p_id, double p_min, double p_max) override;
|
||||
void accessibility_update_set_num_step(const RID &p_id, double p_step) override;
|
||||
void accessibility_update_set_num_jump(const RID &p_id, double p_jump) override;
|
||||
void accessibility_update_set_scroll_x(const RID &p_id, double p_position) override;
|
||||
void accessibility_update_set_scroll_x_range(const RID &p_id, double p_min, double p_max) override;
|
||||
void accessibility_update_set_scroll_y(const RID &p_id, double p_position) override;
|
||||
void accessibility_update_set_scroll_y_range(const RID &p_id, double p_min, double p_max) override;
|
||||
void accessibility_update_set_text_decorations(const RID &p_id, bool p_underline, bool p_strikethrough, bool p_overline) override;
|
||||
void accessibility_update_set_text_align(const RID &p_id, HorizontalAlignment p_align) override;
|
||||
void accessibility_update_set_text_selection(const RID &p_id, const RID &p_text_start_id, int p_start_char, const RID &p_text_end_id, int p_end_char) override;
|
||||
void accessibility_update_set_flag(const RID &p_id, DisplayServer::AccessibilityFlags p_flag, bool p_value) override;
|
||||
void accessibility_update_set_classname(const RID &p_id, const String &p_classname) override;
|
||||
void accessibility_update_set_placeholder(const RID &p_id, const String &p_placeholder) override;
|
||||
void accessibility_update_set_language(const RID &p_id, const String &p_language) override;
|
||||
void accessibility_update_set_text_orientation(const RID &p_id, bool p_vertical) override;
|
||||
void accessibility_update_set_list_orientation(const RID &p_id, bool p_vertical) override;
|
||||
void accessibility_update_set_shortcut(const RID &p_id, const String &p_shortcut) override;
|
||||
void accessibility_update_set_url(const RID &p_id, const String &p_url) override;
|
||||
void accessibility_update_set_role_description(const RID &p_id, const String &p_description) override;
|
||||
void accessibility_update_set_state_description(const RID &p_id, const String &p_description) override;
|
||||
void accessibility_update_set_color_value(const RID &p_id, const Color &p_color) override;
|
||||
void accessibility_update_set_background_color(const RID &p_id, const Color &p_color) override;
|
||||
void accessibility_update_set_foreground_color(const RID &p_id, const Color &p_color) override;
|
||||
|
||||
AccessibilityDriverAccessKit();
|
||||
~AccessibilityDriverAccessKit();
|
||||
};
|
||||
|
||||
#endif // ACCESSKIT_ENABLED
|
||||
4319
engine/drivers/accesskit/dynwrappers/accesskit-dll_wrap.c
Normal file
4319
engine/drivers/accesskit/dynwrappers/accesskit-dll_wrap.c
Normal file
File diff suppressed because it is too large
Load diff
1574
engine/drivers/accesskit/dynwrappers/accesskit-dll_wrap.h
Normal file
1574
engine/drivers/accesskit/dynwrappers/accesskit-dll_wrap.h
Normal file
File diff suppressed because it is too large
Load diff
4349
engine/drivers/accesskit/dynwrappers/accesskit-dylib_wrap.c
Normal file
4349
engine/drivers/accesskit/dynwrappers/accesskit-dylib_wrap.c
Normal file
File diff suppressed because it is too large
Load diff
1594
engine/drivers/accesskit/dynwrappers/accesskit-dylib_wrap.h
Normal file
1594
engine/drivers/accesskit/dynwrappers/accesskit-dylib_wrap.h
Normal file
File diff suppressed because it is too large
Load diff
4250
engine/drivers/accesskit/dynwrappers/accesskit-so_wrap.c
Normal file
4250
engine/drivers/accesskit/dynwrappers/accesskit-so_wrap.c
Normal file
File diff suppressed because it is too large
Load diff
1558
engine/drivers/accesskit/dynwrappers/accesskit-so_wrap.h
Normal file
1558
engine/drivers/accesskit/dynwrappers/accesskit-so_wrap.h
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef AUDIO_DRIVER_ALSA_H
|
||||
#define AUDIO_DRIVER_ALSA_H
|
||||
#pragma once
|
||||
|
||||
#ifdef ALSA_ENABLED
|
||||
|
||||
|
|
@ -95,5 +94,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // ALSA_ENABLED
|
||||
|
||||
#endif // AUDIO_DRIVER_ALSA_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef MIDI_DRIVER_ALSAMIDI_H
|
||||
#define MIDI_DRIVER_ALSAMIDI_H
|
||||
#pragma once
|
||||
|
||||
#ifdef ALSAMIDI_ENABLED
|
||||
|
||||
|
|
@ -78,5 +77,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // ALSAMIDI_ENABLED
|
||||
|
||||
#endif // MIDI_DRIVER_ALSAMIDI_H
|
||||
|
|
|
|||
|
|
@ -5,3 +5,4 @@ Import("env")
|
|||
|
||||
# Driver source files
|
||||
env.add_source_files(env.drivers_sources, "*.mm")
|
||||
env.add_source_files(env.drivers_sources, "*.cpp")
|
||||
|
|
|
|||
|
|
@ -28,7 +28,10 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/input/input.h"
|
||||
#include "core/input/input_enums.h"
|
||||
|
||||
#define Key _QKey
|
||||
#import <GameController/GameController.h>
|
||||
|
|
@ -43,6 +46,11 @@ struct GameController {
|
|||
RumbleContext *rumble_context API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) = nil;
|
||||
NSInteger ff_effect_timestamp = 0;
|
||||
bool force_feedback = false;
|
||||
bool double_nintendo_joycon_layout = false;
|
||||
bool single_nintendo_joycon_layout = false;
|
||||
|
||||
bool axis_changed[(int)JoyAxis::MAX];
|
||||
double axis_value[(int)JoyAxis::MAX];
|
||||
|
||||
GameController(int p_joy_id, GCController *p_controller);
|
||||
~GameController();
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#import "joypad_apple.h"
|
||||
|
||||
#include <CoreHaptics/CoreHaptics.h>
|
||||
#import <CoreHaptics/CoreHaptics.h>
|
||||
#import <os/log.h>
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
|
|
@ -134,6 +134,11 @@ public:
|
|||
GameController::GameController(int p_joy_id, GCController *p_controller) :
|
||||
joy_id(p_joy_id), controller(p_controller) {
|
||||
force_feedback = NO;
|
||||
|
||||
for (int i = 0; i < (int)JoyAxis::MAX; i++) {
|
||||
axis_changed[i] = false;
|
||||
axis_value[i] = 0.0;
|
||||
}
|
||||
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (controller.haptics != nil) {
|
||||
// Create a rumble context for the controller.
|
||||
|
|
@ -144,6 +149,16 @@ GameController::GameController(int p_joy_id, GCController *p_controller) :
|
|||
}
|
||||
}
|
||||
|
||||
if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) {
|
||||
if ([controller.productCategory isEqualToString:@"Switch Pro Controller"] || [controller.productCategory isEqualToString:@"Nintendo Switch Joy-Con (L/R)"]) {
|
||||
double_nintendo_joycon_layout = true;
|
||||
}
|
||||
|
||||
if ([controller.productCategory isEqualToString:@"Nintendo Switch Joy-Con (L)"] || [controller.productCategory isEqualToString:@"Nintendo Switch Joy-Con (R)"]) {
|
||||
single_nintendo_joycon_layout = true;
|
||||
}
|
||||
}
|
||||
|
||||
int l_joy_id = joy_id;
|
||||
|
||||
auto BUTTON = [l_joy_id](JoyButton p_button) {
|
||||
|
|
@ -152,13 +167,199 @@ GameController::GameController(int p_joy_id, GCController *p_controller) :
|
|||
};
|
||||
};
|
||||
|
||||
if (controller.extendedGamepad != nil) {
|
||||
auto JOYSTICK_LEFT = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) {
|
||||
if (axis_value[(int)JoyAxis::LEFT_X] != xValue) {
|
||||
axis_changed[(int)JoyAxis::LEFT_X] = true;
|
||||
axis_value[(int)JoyAxis::LEFT_X] = xValue;
|
||||
}
|
||||
if (axis_value[(int)JoyAxis::LEFT_Y] != -yValue) {
|
||||
axis_changed[(int)JoyAxis::LEFT_Y] = true;
|
||||
axis_value[(int)JoyAxis::LEFT_Y] = -yValue;
|
||||
}
|
||||
};
|
||||
|
||||
auto JOYSTICK_RIGHT = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) {
|
||||
if (axis_value[(int)JoyAxis::RIGHT_X] != xValue) {
|
||||
axis_changed[(int)JoyAxis::RIGHT_X] = true;
|
||||
axis_value[(int)JoyAxis::RIGHT_X] = xValue;
|
||||
}
|
||||
if (axis_value[(int)JoyAxis::RIGHT_Y] != -yValue) {
|
||||
axis_changed[(int)JoyAxis::RIGHT_Y] = true;
|
||||
axis_value[(int)JoyAxis::RIGHT_Y] = -yValue;
|
||||
}
|
||||
};
|
||||
|
||||
auto TRIGGER_LEFT = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
|
||||
if (axis_value[(int)JoyAxis::TRIGGER_LEFT] != value) {
|
||||
axis_changed[(int)JoyAxis::TRIGGER_LEFT] = true;
|
||||
axis_value[(int)JoyAxis::TRIGGER_LEFT] = value;
|
||||
}
|
||||
};
|
||||
|
||||
auto TRIGGER_RIGHT = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
|
||||
if (axis_value[(int)JoyAxis::TRIGGER_RIGHT] != value) {
|
||||
axis_changed[(int)JoyAxis::TRIGGER_RIGHT] = true;
|
||||
axis_value[(int)JoyAxis::TRIGGER_RIGHT] = value;
|
||||
}
|
||||
};
|
||||
|
||||
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (controller.physicalInputProfile != nil) {
|
||||
GCPhysicalInputProfile *profile = controller.physicalInputProfile;
|
||||
|
||||
GCControllerButtonInput *buttonA = profile.buttons[GCInputButtonA];
|
||||
GCControllerButtonInput *buttonB = profile.buttons[GCInputButtonB];
|
||||
GCControllerButtonInput *buttonX = profile.buttons[GCInputButtonX];
|
||||
GCControllerButtonInput *buttonY = profile.buttons[GCInputButtonY];
|
||||
if (double_nintendo_joycon_layout) {
|
||||
if (buttonA) {
|
||||
buttonA.pressedChangedHandler = BUTTON(JoyButton::B);
|
||||
}
|
||||
if (buttonB) {
|
||||
buttonB.pressedChangedHandler = BUTTON(JoyButton::A);
|
||||
}
|
||||
if (buttonX) {
|
||||
buttonX.pressedChangedHandler = BUTTON(JoyButton::Y);
|
||||
}
|
||||
if (buttonY) {
|
||||
buttonY.pressedChangedHandler = BUTTON(JoyButton::X);
|
||||
}
|
||||
} else if (single_nintendo_joycon_layout) {
|
||||
if (buttonA) {
|
||||
buttonA.pressedChangedHandler = BUTTON(JoyButton::A);
|
||||
}
|
||||
if (buttonB) {
|
||||
buttonB.pressedChangedHandler = BUTTON(JoyButton::X);
|
||||
}
|
||||
if (buttonX) {
|
||||
buttonX.pressedChangedHandler = BUTTON(JoyButton::B);
|
||||
}
|
||||
if (buttonY) {
|
||||
buttonY.pressedChangedHandler = BUTTON(JoyButton::Y);
|
||||
}
|
||||
} else {
|
||||
if (buttonA) {
|
||||
buttonA.pressedChangedHandler = BUTTON(JoyButton::A);
|
||||
}
|
||||
if (buttonB) {
|
||||
buttonB.pressedChangedHandler = BUTTON(JoyButton::B);
|
||||
}
|
||||
if (buttonX) {
|
||||
buttonX.pressedChangedHandler = BUTTON(JoyButton::X);
|
||||
}
|
||||
if (buttonY) {
|
||||
buttonY.pressedChangedHandler = BUTTON(JoyButton::Y);
|
||||
}
|
||||
}
|
||||
|
||||
GCControllerButtonInput *leftThumbstickButton = profile.buttons[GCInputLeftThumbstickButton];
|
||||
GCControllerButtonInput *rightThumbstickButton = profile.buttons[GCInputRightThumbstickButton];
|
||||
if (leftThumbstickButton) {
|
||||
leftThumbstickButton.pressedChangedHandler = BUTTON(JoyButton::LEFT_STICK);
|
||||
}
|
||||
if (rightThumbstickButton) {
|
||||
rightThumbstickButton.pressedChangedHandler = BUTTON(JoyButton::RIGHT_STICK);
|
||||
}
|
||||
|
||||
GCControllerButtonInput *leftShoulder = profile.buttons[GCInputLeftShoulder];
|
||||
GCControllerButtonInput *rightShoulder = profile.buttons[GCInputRightShoulder];
|
||||
if (leftShoulder) {
|
||||
leftShoulder.pressedChangedHandler = BUTTON(JoyButton::LEFT_SHOULDER);
|
||||
}
|
||||
if (rightShoulder) {
|
||||
rightShoulder.pressedChangedHandler = BUTTON(JoyButton::RIGHT_SHOULDER);
|
||||
}
|
||||
|
||||
GCControllerButtonInput *leftTrigger = profile.buttons[GCInputLeftTrigger];
|
||||
GCControllerButtonInput *rightTrigger = profile.buttons[GCInputRightTrigger];
|
||||
if (leftTrigger) {
|
||||
leftTrigger.valueChangedHandler = TRIGGER_LEFT;
|
||||
}
|
||||
if (rightTrigger) {
|
||||
rightTrigger.valueChangedHandler = TRIGGER_RIGHT;
|
||||
}
|
||||
|
||||
GCControllerButtonInput *buttonMenu = profile.buttons[GCInputButtonMenu];
|
||||
GCControllerButtonInput *buttonHome = profile.buttons[GCInputButtonHome];
|
||||
GCControllerButtonInput *buttonOptions = profile.buttons[GCInputButtonOptions];
|
||||
if (buttonMenu) {
|
||||
buttonMenu.pressedChangedHandler = BUTTON(JoyButton::START);
|
||||
}
|
||||
if (buttonHome) {
|
||||
buttonHome.pressedChangedHandler = BUTTON(JoyButton::GUIDE);
|
||||
}
|
||||
if (buttonOptions) {
|
||||
buttonOptions.pressedChangedHandler = BUTTON(JoyButton::BACK);
|
||||
}
|
||||
|
||||
// Xbox controller buttons.
|
||||
if (@available(macOS 12.0, iOS 15.0, tvOS 15.0, *)) {
|
||||
GCControllerButtonInput *buttonShare = profile.buttons[GCInputButtonShare];
|
||||
if (buttonShare) {
|
||||
buttonShare.pressedChangedHandler = BUTTON(JoyButton::MISC1);
|
||||
}
|
||||
}
|
||||
|
||||
GCControllerButtonInput *paddleButton1 = profile.buttons[GCInputXboxPaddleOne];
|
||||
GCControllerButtonInput *paddleButton2 = profile.buttons[GCInputXboxPaddleTwo];
|
||||
GCControllerButtonInput *paddleButton3 = profile.buttons[GCInputXboxPaddleThree];
|
||||
GCControllerButtonInput *paddleButton4 = profile.buttons[GCInputXboxPaddleFour];
|
||||
if (paddleButton1) {
|
||||
paddleButton1.pressedChangedHandler = BUTTON(JoyButton::PADDLE1);
|
||||
}
|
||||
if (paddleButton2) {
|
||||
paddleButton2.pressedChangedHandler = BUTTON(JoyButton::PADDLE2);
|
||||
}
|
||||
if (paddleButton3) {
|
||||
paddleButton3.pressedChangedHandler = BUTTON(JoyButton::PADDLE3);
|
||||
}
|
||||
if (paddleButton4) {
|
||||
paddleButton4.pressedChangedHandler = BUTTON(JoyButton::PADDLE4);
|
||||
}
|
||||
|
||||
GCControllerDirectionPad *leftThumbstick = profile.dpads[GCInputLeftThumbstick];
|
||||
if (leftThumbstick) {
|
||||
leftThumbstick.valueChangedHandler = JOYSTICK_LEFT;
|
||||
}
|
||||
|
||||
GCControllerDirectionPad *rightThumbstick = profile.dpads[GCInputRightThumbstick];
|
||||
if (rightThumbstick) {
|
||||
rightThumbstick.valueChangedHandler = JOYSTICK_RIGHT;
|
||||
}
|
||||
|
||||
GCControllerDirectionPad *dpad = nil;
|
||||
if (controller.extendedGamepad != nil) {
|
||||
dpad = controller.extendedGamepad.dpad;
|
||||
} else if (controller.microGamepad != nil) {
|
||||
dpad = controller.microGamepad.dpad;
|
||||
}
|
||||
if (dpad) {
|
||||
dpad.up.pressedChangedHandler = BUTTON(JoyButton::DPAD_UP);
|
||||
dpad.down.pressedChangedHandler = BUTTON(JoyButton::DPAD_DOWN);
|
||||
dpad.left.pressedChangedHandler = BUTTON(JoyButton::DPAD_LEFT);
|
||||
dpad.right.pressedChangedHandler = BUTTON(JoyButton::DPAD_RIGHT);
|
||||
}
|
||||
}
|
||||
} else if (controller.extendedGamepad != nil) {
|
||||
GCExtendedGamepad *gamepad = controller.extendedGamepad;
|
||||
|
||||
gamepad.buttonA.pressedChangedHandler = BUTTON(JoyButton::A);
|
||||
gamepad.buttonB.pressedChangedHandler = BUTTON(JoyButton::B);
|
||||
gamepad.buttonX.pressedChangedHandler = BUTTON(JoyButton::X);
|
||||
gamepad.buttonY.pressedChangedHandler = BUTTON(JoyButton::Y);
|
||||
if (double_nintendo_joycon_layout) {
|
||||
gamepad.buttonA.pressedChangedHandler = BUTTON(JoyButton::B);
|
||||
gamepad.buttonB.pressedChangedHandler = BUTTON(JoyButton::A);
|
||||
gamepad.buttonX.pressedChangedHandler = BUTTON(JoyButton::Y);
|
||||
gamepad.buttonY.pressedChangedHandler = BUTTON(JoyButton::X);
|
||||
} else if (single_nintendo_joycon_layout) {
|
||||
gamepad.buttonA.pressedChangedHandler = BUTTON(JoyButton::A);
|
||||
gamepad.buttonB.pressedChangedHandler = BUTTON(JoyButton::X);
|
||||
gamepad.buttonX.pressedChangedHandler = BUTTON(JoyButton::B);
|
||||
gamepad.buttonY.pressedChangedHandler = BUTTON(JoyButton::Y);
|
||||
} else {
|
||||
gamepad.buttonA.pressedChangedHandler = BUTTON(JoyButton::A);
|
||||
gamepad.buttonB.pressedChangedHandler = BUTTON(JoyButton::B);
|
||||
gamepad.buttonX.pressedChangedHandler = BUTTON(JoyButton::X);
|
||||
gamepad.buttonY.pressedChangedHandler = BUTTON(JoyButton::Y);
|
||||
}
|
||||
|
||||
gamepad.leftShoulder.pressedChangedHandler = BUTTON(JoyButton::LEFT_SHOULDER);
|
||||
gamepad.rightShoulder.pressedChangedHandler = BUTTON(JoyButton::RIGHT_SHOULDER);
|
||||
gamepad.dpad.up.pressedChangedHandler = BUTTON(JoyButton::DPAD_UP);
|
||||
|
|
@ -166,21 +367,10 @@ GameController::GameController(int p_joy_id, GCController *p_controller) :
|
|||
gamepad.dpad.left.pressedChangedHandler = BUTTON(JoyButton::DPAD_LEFT);
|
||||
gamepad.dpad.right.pressedChangedHandler = BUTTON(JoyButton::DPAD_RIGHT);
|
||||
|
||||
gamepad.leftThumbstick.valueChangedHandler = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) {
|
||||
Input::get_singleton()->joy_axis(l_joy_id, JoyAxis::LEFT_X, xValue);
|
||||
Input::get_singleton()->joy_axis(l_joy_id, JoyAxis::LEFT_Y, -yValue);
|
||||
};
|
||||
|
||||
gamepad.rightThumbstick.valueChangedHandler = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) {
|
||||
Input::get_singleton()->joy_axis(l_joy_id, JoyAxis::RIGHT_X, xValue);
|
||||
Input::get_singleton()->joy_axis(l_joy_id, JoyAxis::RIGHT_Y, -yValue);
|
||||
};
|
||||
gamepad.leftTrigger.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
|
||||
Input::get_singleton()->joy_axis(l_joy_id, JoyAxis::TRIGGER_LEFT, value);
|
||||
};
|
||||
gamepad.rightTrigger.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
|
||||
Input::get_singleton()->joy_axis(l_joy_id, JoyAxis::TRIGGER_RIGHT, value);
|
||||
};
|
||||
gamepad.leftThumbstick.valueChangedHandler = JOYSTICK_LEFT;
|
||||
gamepad.rightThumbstick.valueChangedHandler = JOYSTICK_RIGHT;
|
||||
gamepad.leftTrigger.valueChangedHandler = TRIGGER_LEFT;
|
||||
gamepad.rightTrigger.valueChangedHandler = TRIGGER_RIGHT;
|
||||
|
||||
if (@available(macOS 10.14.1, iOS 12.1, tvOS 12.1, *)) {
|
||||
gamepad.leftThumbstickButton.pressedChangedHandler = BUTTON(JoyButton::LEFT_STICK);
|
||||
|
|
@ -313,7 +503,13 @@ void JoypadApple::add_joypad(GCController *p_controller) {
|
|||
}
|
||||
|
||||
// Tell Godot about our new controller.
|
||||
Input::get_singleton()->joy_connection_changed(joy_id, true, String::utf8(p_controller.vendorName.UTF8String));
|
||||
char const *device_name;
|
||||
if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) {
|
||||
device_name = p_controller.productCategory.UTF8String;
|
||||
} else {
|
||||
device_name = p_controller.vendorName.UTF8String;
|
||||
}
|
||||
Input::get_singleton()->joy_connection_changed(joy_id, true, String::utf8(device_name));
|
||||
|
||||
// Assign our player index.
|
||||
joypads.insert(joy_id, memnew(GameController(joy_id, p_controller)));
|
||||
|
|
@ -404,6 +600,13 @@ void JoypadApple::process_joypads() {
|
|||
int id = E.key;
|
||||
GameController &joypad = *E.value;
|
||||
|
||||
for (int i = 0; i < (int)JoyAxis::MAX; i++) {
|
||||
if (joypad.axis_changed[i]) {
|
||||
joypad.axis_changed[i] = false;
|
||||
Input::get_singleton()->joy_axis(id, (JoyAxis)i, joypad.axis_value[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (joypad.force_feedback) {
|
||||
Input *input = Input::get_singleton();
|
||||
uint64_t timestamp = input->get_joy_vibration_timestamp(id);
|
||||
|
|
|
|||
129
engine/drivers/apple/thread_apple.cpp
Normal file
129
engine/drivers/apple/thread_apple.cpp
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/**************************************************************************/
|
||||
/* thread_apple.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "thread_apple.h"
|
||||
|
||||
#include "core/error/error_macros.h"
|
||||
#include "core/object/script_language.h"
|
||||
#include "core/string/ustring.h"
|
||||
|
||||
SafeNumeric<uint64_t> Thread::id_counter(1); // The first value after .increment() is 2, hence by default the main thread ID should be 1.
|
||||
thread_local Thread::ID Thread::caller_id = Thread::id_counter.increment();
|
||||
|
||||
struct ThreadData {
|
||||
Thread::Callback callback;
|
||||
void *userdata;
|
||||
Thread::ID caller_id;
|
||||
};
|
||||
|
||||
void *Thread::thread_callback(void *p_data) {
|
||||
ThreadData *thread_data = static_cast<ThreadData *>(p_data);
|
||||
|
||||
// Set the caller ID for this thread
|
||||
caller_id = thread_data->caller_id;
|
||||
|
||||
ScriptServer::thread_enter(); // Scripts may need to attach a stack.
|
||||
|
||||
// Call the actual callback
|
||||
thread_data->callback(thread_data->userdata);
|
||||
|
||||
ScriptServer::thread_exit();
|
||||
|
||||
// Clean up
|
||||
memdelete(thread_data);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Error Thread::set_name(const String &p_name) {
|
||||
int err = pthread_setname_np(p_name.utf8().get_data());
|
||||
return err == 0 ? OK : ERR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Thread::ID Thread::start(Thread::Callback p_callback, void *p_user, const Settings &p_settings) {
|
||||
ERR_FAIL_COND_V_MSG(id != UNASSIGNED_ID, UNASSIGNED_ID, "A Thread object has been re-started without wait_to_finish() having been called on it.");
|
||||
id = id_counter.increment();
|
||||
|
||||
ThreadData *thread_data = memnew(ThreadData);
|
||||
thread_data->callback = p_callback;
|
||||
thread_data->userdata = p_user;
|
||||
thread_data->caller_id = id;
|
||||
|
||||
// Create the thread
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
|
||||
switch (p_settings.priority) {
|
||||
case PRIORITY_LOW:
|
||||
pthread_attr_set_qos_class_np(&attr, QOS_CLASS_UTILITY, 0);
|
||||
break;
|
||||
case PRIORITY_NORMAL:
|
||||
pthread_attr_set_qos_class_np(&attr, QOS_CLASS_USER_INITIATED, 0);
|
||||
break;
|
||||
case PRIORITY_HIGH:
|
||||
pthread_attr_set_qos_class_np(&attr, QOS_CLASS_USER_INTERACTIVE, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (p_settings.stack_size > 0) {
|
||||
pthread_attr_setstacksize(&attr, p_settings.stack_size);
|
||||
}
|
||||
|
||||
// Create the thread
|
||||
pthread_create(&pthread, &attr, thread_callback, thread_data);
|
||||
|
||||
// Clean up attributes
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void Thread::wait_to_finish() {
|
||||
ERR_FAIL_COND_MSG(id == UNASSIGNED_ID, "Attempt of waiting to finish on a thread that was never started.");
|
||||
ERR_FAIL_COND_MSG(id == get_caller_id(), "Threads can't wait to finish on themselves, another thread must wait.");
|
||||
|
||||
int err = pthread_join(pthread, nullptr);
|
||||
if (err != 0) {
|
||||
ERR_FAIL_MSG("Thread::wait_to_finish() failed to join thread.");
|
||||
}
|
||||
pthread = pthread_t();
|
||||
id = UNASSIGNED_ID;
|
||||
}
|
||||
|
||||
Thread::~Thread() {
|
||||
if (id != UNASSIGNED_ID) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
WARN_PRINT(
|
||||
"A Thread object is being destroyed without its completion having been realized.\n"
|
||||
"Please call wait_to_finish() on it to ensure correct cleanup.");
|
||||
#endif
|
||||
pthread_detach(pthread);
|
||||
}
|
||||
}
|
||||
110
engine/drivers/apple/thread_apple.h
Normal file
110
engine/drivers/apple/thread_apple.h
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/**************************************************************************/
|
||||
/* thread_apple.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/templates/safe_refcount.h"
|
||||
#include "core/typedefs.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <new> // For hardware interference size
|
||||
|
||||
class String;
|
||||
|
||||
class Thread {
|
||||
public:
|
||||
typedef void (*Callback)(void *p_userdata);
|
||||
|
||||
typedef uint64_t ID;
|
||||
|
||||
enum : ID {
|
||||
UNASSIGNED_ID = 0,
|
||||
MAIN_ID = 1
|
||||
};
|
||||
|
||||
enum Priority {
|
||||
PRIORITY_LOW,
|
||||
PRIORITY_NORMAL,
|
||||
PRIORITY_HIGH
|
||||
};
|
||||
|
||||
struct Settings {
|
||||
Priority priority;
|
||||
/// Override the default stack size (0 means default)
|
||||
uint64_t stack_size = 0;
|
||||
Settings() { priority = PRIORITY_NORMAL; }
|
||||
};
|
||||
|
||||
#if defined(__cpp_lib_hardware_interference_size)
|
||||
GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Winterference-size")
|
||||
static constexpr size_t CACHE_LINE_BYTES = std::hardware_destructive_interference_size;
|
||||
GODOT_GCC_WARNING_POP
|
||||
#else
|
||||
// At a negligible memory cost, we use a conservatively high value.
|
||||
static constexpr size_t CACHE_LINE_BYTES = 128;
|
||||
#endif
|
||||
|
||||
private:
|
||||
friend class Main;
|
||||
|
||||
ID id = UNASSIGNED_ID;
|
||||
pthread_t pthread;
|
||||
|
||||
static SafeNumeric<uint64_t> id_counter;
|
||||
static thread_local ID caller_id;
|
||||
|
||||
static void *thread_callback(void *p_data);
|
||||
|
||||
static void make_main_thread() { caller_id = MAIN_ID; }
|
||||
static void release_main_thread() { caller_id = id_counter.increment(); }
|
||||
|
||||
public:
|
||||
_FORCE_INLINE_ static void yield() { pthread_yield_np(); }
|
||||
|
||||
_FORCE_INLINE_ ID get_id() const { return id; }
|
||||
// get the ID of the caller thread
|
||||
_FORCE_INLINE_ static ID get_caller_id() {
|
||||
return caller_id;
|
||||
}
|
||||
// get the ID of the main thread
|
||||
_FORCE_INLINE_ static ID get_main_id() { return MAIN_ID; }
|
||||
|
||||
_FORCE_INLINE_ static bool is_main_thread() { return caller_id == MAIN_ID; }
|
||||
|
||||
static Error set_name(const String &p_name);
|
||||
|
||||
ID start(Thread::Callback p_callback, void *p_user, const Settings &p_settings = Settings());
|
||||
bool is_started() const { return id != UNASSIGNED_ID; }
|
||||
/// Waits until thread is finished, and deallocates it.
|
||||
void wait_to_finish();
|
||||
|
||||
Thread() = default;
|
||||
~Thread();
|
||||
};
|
||||
|
|
@ -26,7 +26,7 @@ thirdparty_sources = [
|
|||
]
|
||||
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
|
||||
|
||||
env_backtrace.Prepend(CPPPATH=[thirdparty_dir])
|
||||
env_backtrace.Prepend(CPPEXTPATH=[thirdparty_dir])
|
||||
|
||||
env_thirdparty = env_backtrace.Clone()
|
||||
env_thirdparty.disable_warnings()
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef AUDIO_DRIVER_COREAUDIO_H
|
||||
#define AUDIO_DRIVER_COREAUDIO_H
|
||||
#pragma once
|
||||
|
||||
#ifdef COREAUDIO_ENABLED
|
||||
|
||||
|
|
@ -126,5 +125,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // COREAUDIO_ENABLED
|
||||
|
||||
#endif // AUDIO_DRIVER_COREAUDIO_H
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "audio_driver_coreaudio.h"
|
||||
#import "audio_driver_coreaudio.h"
|
||||
|
||||
#ifdef COREAUDIO_ENABLED
|
||||
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ from misc.utility.scons_hints import *
|
|||
Import("env")
|
||||
|
||||
# Driver source files
|
||||
env.add_source_files(env.drivers_sources, "*.cpp")
|
||||
env.add_source_files(env.drivers_sources, "*.mm")
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef MIDI_DRIVER_COREMIDI_H
|
||||
#define MIDI_DRIVER_COREMIDI_H
|
||||
#pragma once
|
||||
|
||||
#ifdef COREMIDI_ENABLED
|
||||
|
||||
|
|
@ -67,5 +66,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // COREMIDI_ENABLED
|
||||
|
||||
#endif // MIDI_DRIVER_COREMIDI_H
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**************************************************************************/
|
||||
/* midi_driver_coremidi.cpp */
|
||||
/* midi_driver_coremidi.mm */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "midi_driver_coremidi.h"
|
||||
#import "midi_driver_coremidi.h"
|
||||
|
||||
#ifdef COREMIDI_ENABLED
|
||||
|
||||
|
|
@ -15,15 +15,15 @@ thirdparty_obj = []
|
|||
|
||||
# DirectX Headers (must take precedence over Windows SDK's).
|
||||
|
||||
env.Prepend(CPPPATH=["#thirdparty/directx_headers/include/directx"])
|
||||
env_d3d12_rdd.Prepend(CPPPATH=["#thirdparty/directx_headers/include/directx"])
|
||||
env_d3d12_rdd.Prepend(CPPPATH=["#thirdparty/directx_headers/include/dxguids"])
|
||||
env.Prepend(CPPEXTPATH=["#thirdparty/directx_headers/include/directx"])
|
||||
env_d3d12_rdd.Prepend(CPPEXTPATH=["#thirdparty/directx_headers/include/directx"])
|
||||
env_d3d12_rdd.Prepend(CPPEXTPATH=["#thirdparty/directx_headers/include/dxguids"])
|
||||
|
||||
|
||||
# Direct3D 12 Memory Allocator.
|
||||
|
||||
env.Append(CPPPATH=["#thirdparty/d3d12ma"])
|
||||
env_d3d12_rdd.Append(CPPPATH=["#thirdparty/d3d12ma"])
|
||||
env.Append(CPPEXTPATH=["#thirdparty/d3d12ma"])
|
||||
env_d3d12_rdd.Append(CPPEXTPATH=["#thirdparty/d3d12ma"])
|
||||
|
||||
|
||||
# Agility SDK.
|
||||
|
|
@ -38,7 +38,7 @@ if env["agility_sdk_path"] != "" and os.path.exists(env["agility_sdk_path"]):
|
|||
|
||||
if env["use_pix"]:
|
||||
env_d3d12_rdd.Append(CPPDEFINES=["PIX_ENABLED"])
|
||||
env_d3d12_rdd.Append(CPPPATH=[env["pix_path"] + "/Include"])
|
||||
env_d3d12_rdd.Append(CPPEXTPATH=[env["pix_path"] + "/Include"])
|
||||
|
||||
|
||||
# Mesa (SPIR-V to DXIL functionality).
|
||||
|
|
@ -147,7 +147,7 @@ else:
|
|||
env.Append(CCFLAGS=["-Wno-unknown-pragmas"])
|
||||
|
||||
# This is needed since rendering_device_d3d12.cpp needs to include some Mesa internals.
|
||||
env_d3d12_rdd.Prepend(CPPPATH=mesa_private_inc_paths)
|
||||
env_d3d12_rdd.Prepend(CPPEXTPATH=mesa_private_inc_paths)
|
||||
# For the same reason as above, the defines must be the same as in the 3rd-party code itself.
|
||||
env_d3d12_rdd.Append(CPPDEFINES=extra_defines)
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef D3D12_GODOT_NIR_BRIDGE_H
|
||||
#define D3D12_GODOT_NIR_BRIDGE_H
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
|
@ -56,5 +55,3 @@ typedef struct GodotNirCallbacks {
|
|||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // D3D12_GODOT_NIR_BRIDGE_H
|
||||
|
|
|
|||
|
|
@ -30,35 +30,4 @@
|
|||
|
||||
#include "rendering_context_driver_d3d12.h"
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#pragma GCC diagnostic ignored "-Wswitch"
|
||||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
#pragma GCC diagnostic ignored "-Wduplicated-branches"
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#pragma GCC diagnostic ignored "-Wnonnull-compare"
|
||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#pragma clang diagnostic ignored "-Wstring-plus-int"
|
||||
#pragma clang diagnostic ignored "-Wswitch"
|
||||
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
|
||||
#pragma clang diagnostic ignored "-Wtautological-undefined-compare"
|
||||
#pragma clang diagnostic ignored "-Wunused-variable"
|
||||
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
|
||||
#pragma clang diagnostic ignored "-Wunused-function"
|
||||
#pragma clang diagnostic ignored "-Wunused-private-field"
|
||||
#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable : 4189 4505)
|
||||
#endif
|
||||
|
||||
#include "thirdparty/d3d12ma/D3D12MemAlloc.cpp"
|
||||
#include <D3D12MemAlloc.cpp>
|
||||
|
|
|
|||
|
|
@ -28,12 +28,9 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DXIL_HASH_H
|
||||
#define DXIL_HASH_H
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
void compute_dxil_hash(const BYTE *pData, UINT byteCount, BYTE *pOutHash);
|
||||
|
||||
#endif // DXIL_HASH_H
|
||||
|
|
|
|||
|
|
@ -37,27 +37,7 @@
|
|||
#include "core/version.h"
|
||||
#include "servers/rendering/rendering_device.h"
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#pragma GCC diagnostic ignored "-Wswitch"
|
||||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#pragma clang diagnostic ignored "-Wstring-plus-int"
|
||||
#pragma clang diagnostic ignored "-Wswitch"
|
||||
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
|
||||
#endif
|
||||
|
||||
#include "dxcapi.h"
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
#include <dxcapi.h>
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
#include <guiddef.h>
|
||||
|
|
|
|||
|
|
@ -28,10 +28,8 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RENDERING_CONTEXT_DRIVER_D3D12_H
|
||||
#define RENDERING_CONTEXT_DRIVER_D3D12_H
|
||||
#pragma once
|
||||
|
||||
#include "core/error/error_list.h"
|
||||
#include "core/os/mutex.h"
|
||||
#include "core/string/ustring.h"
|
||||
#include "core/templates/rid_owner.h"
|
||||
|
|
@ -39,22 +37,6 @@
|
|||
#include "servers/display_server.h"
|
||||
#include "servers/rendering/rendering_context_driver.h"
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#pragma GCC diagnostic ignored "-Wswitch"
|
||||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#pragma clang diagnostic ignored "-Wstring-plus-int"
|
||||
#pragma clang diagnostic ignored "-Wswitch"
|
||||
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
|
||||
#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
|
||||
#endif
|
||||
|
||||
#if defined(AS)
|
||||
#undef AS
|
||||
#endif
|
||||
|
|
@ -73,20 +55,14 @@
|
|||
#include <dcomp.h>
|
||||
#endif
|
||||
|
||||
#include "d3dx12.h"
|
||||
#include <d3dx12.h>
|
||||
#include <dxgi1_6.h>
|
||||
|
||||
#include <wrl/client.h>
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
using Microsoft::WRL::ComPtr;
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
#define ARRAY_SIZE(a) std::size(a)
|
||||
|
||||
class RenderingContextDriverD3D12 : public RenderingContextDriver {
|
||||
ComPtr<ID3D12DeviceFactory> device_factory;
|
||||
|
|
@ -146,5 +122,3 @@ public:
|
|||
RenderingContextDriverD3D12();
|
||||
virtual ~RenderingContextDriverD3D12() override;
|
||||
};
|
||||
|
||||
#endif // RENDERING_CONTEXT_DRIVER_D3D12_H
|
||||
|
|
|
|||
|
|
@ -39,44 +39,13 @@
|
|||
#include "dxil_hash.h"
|
||||
#include "rendering_context_driver_d3d12.h"
|
||||
|
||||
// No point in fighting warnings in Mesa.
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4200) // "nonstandard extension used: zero-sized array in struct/union".
|
||||
#pragma warning(disable : 4806) // "'&': unsafe operation: no value of type 'bool' promoted to type 'uint32_t' can equal the given constant".
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#pragma GCC diagnostic ignored "-Wswitch"
|
||||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#pragma clang diagnostic ignored "-Wstring-plus-int"
|
||||
#pragma clang diagnostic ignored "-Wswitch"
|
||||
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
|
||||
#endif
|
||||
|
||||
#include "nir_spirv.h"
|
||||
#include "nir_to_dxil.h"
|
||||
#include "spirv_to_dxil.h"
|
||||
#include <nir_spirv.h>
|
||||
#include <nir_to_dxil.h>
|
||||
#include <spirv_to_dxil.h>
|
||||
extern "C" {
|
||||
#include "dxil_spirv_nir.h"
|
||||
#include <dxil_spirv_nir.h>
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
#include <guiddef.h>
|
||||
|
||||
|
|
@ -332,6 +301,20 @@ const RenderingDeviceDriverD3D12::D3D12Format RenderingDeviceDriverD3D12::RD_TO_
|
|||
/* DATA_FORMAT_G16_B16_R16_3PLANE_422_UNORM */ {},
|
||||
/* DATA_FORMAT_G16_B16R16_2PLANE_422_UNORM */ {},
|
||||
/* DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM */ {},
|
||||
/* DATA_FORMAT_ASTC_4x4_SFLOAT_BLOCK */ {},
|
||||
/* DATA_FORMAT_ASTC_5x4_SFLOAT_BLOCK */ {},
|
||||
/* DATA_FORMAT_ASTC_5x5_SFLOAT_BLOCK */ {},
|
||||
/* DATA_FORMAT_ASTC_6x5_SFLOAT_BLOCK */ {},
|
||||
/* DATA_FORMAT_ASTC_6x6_SFLOAT_BLOCK */ {},
|
||||
/* DATA_FORMAT_ASTC_8x5_SFLOAT_BLOCK */ {},
|
||||
/* DATA_FORMAT_ASTC_8x6_SFLOAT_BLOCK */ {},
|
||||
/* DATA_FORMAT_ASTC_8x8_SFLOAT_BLOCK */ {},
|
||||
/* DATA_FORMAT_ASTC_10x5_SFLOAT_BLOCK*/ {},
|
||||
/* DATA_FORMAT_ASTC_10x6_SFLOAT_BLOCK */ {},
|
||||
/* DATA_FORMAT_ASTC_10x8_SFLOAT_BLOCK */ {},
|
||||
/* DATA_FORMAT_ASTC_10x10_SFLOAT_BLOCK */ {},
|
||||
/* DATA_FORMAT_ASTC_12x10_SFLOAT_BLOCK */ {},
|
||||
/* DATA_FORMAT_ASTC_12x12_SFLOAT_BLOCK */ {},
|
||||
};
|
||||
|
||||
Error RenderingDeviceDriverD3D12::DescriptorsHeap::allocate(ID3D12Device *p_device, D3D12_DESCRIPTOR_HEAP_TYPE p_type, uint32_t p_descriptor_count, bool p_for_gpu) {
|
||||
|
|
@ -1208,7 +1191,7 @@ RDD::TextureID RenderingDeviceDriverD3D12::texture_create(const TextureFormat &p
|
|||
if ((p_format.usage_bits & TEXTURE_USAGE_STORAGE_BIT)) {
|
||||
resource_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
||||
}
|
||||
if ((p_format.usage_bits & TEXTURE_USAGE_VRS_ATTACHMENT_BIT)) {
|
||||
if ((p_format.usage_bits & TEXTURE_USAGE_VRS_ATTACHMENT_BIT) && (p_format.usage_bits & TEXTURE_USAGE_VRS_FRAGMENT_SHADING_RATE_BIT)) {
|
||||
// For VRS images we can't use the typeless format.
|
||||
resource_desc.Format = DXGI_FORMAT_R8_UINT;
|
||||
}
|
||||
|
|
@ -1353,14 +1336,9 @@ RDD::TextureID RenderingDeviceDriverD3D12::texture_create(const TextureFormat &p
|
|||
}
|
||||
tex_info->states_ptr = &tex_info->owner_info.states;
|
||||
tex_info->format = p_format.format;
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||
#endif
|
||||
GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Wstrict-aliasing")
|
||||
tex_info->desc = *(CD3DX12_RESOURCE_DESC *)&resource_desc;
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
GODOT_GCC_WARNING_POP
|
||||
tex_info->base_layer = 0;
|
||||
tex_info->layers = resource_desc.ArraySize();
|
||||
tex_info->base_mip = 0;
|
||||
|
|
@ -1813,8 +1791,11 @@ static D3D12_BARRIER_ACCESS _rd_texture_layout_access_mask(RDD::TextureLayout p_
|
|||
return D3D12_BARRIER_ACCESS_RESOLVE_SOURCE;
|
||||
case RDD::TEXTURE_LAYOUT_RESOLVE_DST_OPTIMAL:
|
||||
return D3D12_BARRIER_ACCESS_RESOLVE_DEST;
|
||||
case RDD::TEXTURE_LAYOUT_VRS_ATTACHMENT_OPTIMAL:
|
||||
case RDD::TEXTURE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL:
|
||||
return D3D12_BARRIER_ACCESS_SHADING_RATE_SOURCE;
|
||||
case RDD::TEXTURE_LAYOUT_FRAGMENT_DENSITY_MAP_ATTACHMENT_OPTIMAL:
|
||||
DEV_ASSERT(false && "Fragment density maps are not supported in D3D12.");
|
||||
return D3D12_BARRIER_ACCESS_NO_ACCESS;
|
||||
default:
|
||||
return D3D12_BARRIER_ACCESS_NO_ACCESS;
|
||||
}
|
||||
|
|
@ -1933,7 +1914,7 @@ static void _rd_stages_to_d3d12(BitField<RDD::PipelineStageBits> p_stages, D3D12
|
|||
r_sync |= D3D12_BARRIER_SYNC_VERTEX_SHADING;
|
||||
}
|
||||
|
||||
if (p_stages.has_flag(RDD::PIPELINE_STAGE_FRAGMENT_SHADER_BIT)) {
|
||||
if (p_stages.has_flag(RDD::PIPELINE_STAGE_FRAGMENT_SHADER_BIT) || p_stages.has_flag(RDD::PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT)) {
|
||||
r_sync |= D3D12_BARRIER_SYNC_PIXEL_SHADING;
|
||||
}
|
||||
|
||||
|
|
@ -2028,8 +2009,11 @@ static D3D12_BARRIER_LAYOUT _rd_texture_layout_to_d3d12_barrier_layout(RDD::Text
|
|||
return D3D12_BARRIER_LAYOUT_RESOLVE_SOURCE;
|
||||
case RDD::TEXTURE_LAYOUT_RESOLVE_DST_OPTIMAL:
|
||||
return D3D12_BARRIER_LAYOUT_RESOLVE_DEST;
|
||||
case RDD::TEXTURE_LAYOUT_VRS_ATTACHMENT_OPTIMAL:
|
||||
case RDD::TEXTURE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL:
|
||||
return D3D12_BARRIER_LAYOUT_SHADING_RATE_SOURCE;
|
||||
case RDD::TEXTURE_LAYOUT_FRAGMENT_DENSITY_MAP_ATTACHMENT_OPTIMAL:
|
||||
DEV_ASSERT(false && "Fragment density maps are not supported in D3D12.");
|
||||
return D3D12_BARRIER_LAYOUT_UNDEFINED;
|
||||
default:
|
||||
DEV_ASSERT(false && "Unknown texture layout.");
|
||||
return D3D12_BARRIER_LAYOUT_UNDEFINED;
|
||||
|
|
@ -2437,7 +2421,7 @@ RDD::SwapChainID RenderingDeviceDriverD3D12::swap_chain_create(RenderingContextD
|
|||
color_ref.aspect.set_flag(RDD::TEXTURE_ASPECT_COLOR_BIT);
|
||||
subpass.color_references.push_back(color_ref);
|
||||
|
||||
RenderPassID render_pass = render_pass_create(attachment, subpass, {}, 1);
|
||||
RenderPassID render_pass = render_pass_create(attachment, subpass, {}, 1, AttachmentReference());
|
||||
ERR_FAIL_COND_V(!render_pass, SwapChainID());
|
||||
|
||||
// Create the empty swap chain until it is resized.
|
||||
|
|
@ -2797,8 +2781,8 @@ RDD::FramebufferID RenderingDeviceDriverD3D12::_framebuffer_create(RenderPassID
|
|||
|
||||
uint32_t vrs_index = UINT32_MAX;
|
||||
for (const Subpass &E : pass_info->subpasses) {
|
||||
if (E.vrs_reference.attachment != AttachmentReference::UNUSED) {
|
||||
vrs_index = E.vrs_reference.attachment;
|
||||
if (E.fragment_shading_rate_reference.attachment != AttachmentReference::UNUSED) {
|
||||
vrs_index = E.fragment_shading_rate_reference.attachment;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3074,7 +3058,7 @@ Vector<uint8_t> RenderingDeviceDriverD3D12::shader_compile_binary_from_spirv(Vec
|
|||
|
||||
// Translate SPIR-V shaders to DXIL, and collect shader info from the new representation.
|
||||
HashMap<ShaderStage, Vector<uint8_t>> dxil_blobs;
|
||||
BitField<ShaderStage> stages_processed;
|
||||
BitField<ShaderStage> stages_processed = {};
|
||||
{
|
||||
HashMap<int, nir_shader *> stages_nir_shaders;
|
||||
|
||||
|
|
@ -3529,7 +3513,7 @@ Vector<uint8_t> RenderingDeviceDriverD3D12::shader_compile_binary_from_spirv(Vec
|
|||
ComPtr<ID3DBlob> error_blob;
|
||||
HRESULT res = D3DX12SerializeVersionedRootSignature(context_driver->lib_d3d12, &root_sig_desc, D3D_ROOT_SIGNATURE_VERSION_1_1, root_sig_blob.GetAddressOf(), error_blob.GetAddressOf());
|
||||
ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), Vector<uint8_t>(),
|
||||
"Serialization of root signature failed with error " + vformat("0x%08ux", (uint64_t)res) + " and the following message:\n" + String((char *)error_blob->GetBufferPointer(), error_blob->GetBufferSize()));
|
||||
"Serialization of root signature failed with error " + vformat("0x%08ux", (uint64_t)res) + " and the following message:\n" + String::ascii(Span((char *)error_blob->GetBufferPointer(), error_blob->GetBufferSize())));
|
||||
|
||||
binary_data.root_signature_crc = crc32(0, nullptr, 0);
|
||||
binary_data.root_signature_crc = crc32(binary_data.root_signature_crc, (const Bytef *)root_sig_blob->GetBufferPointer(), root_sig_blob->GetBufferSize());
|
||||
|
|
@ -3677,7 +3661,8 @@ RDD::ShaderID RenderingDeviceDriverD3D12::shader_create_from_bytecode(const Vect
|
|||
read_offset += sizeof(uint32_t) * 3 + bin_data_size;
|
||||
|
||||
if (binary_data.shader_name_len) {
|
||||
r_name.parse_utf8((const char *)(binptr + read_offset), binary_data.shader_name_len);
|
||||
r_name.clear();
|
||||
r_name.append_utf8((const char *)(binptr + read_offset), binary_data.shader_name_len);
|
||||
read_offset += STEPIFY(binary_data.shader_name_len, 4);
|
||||
}
|
||||
|
||||
|
|
@ -4949,7 +4934,9 @@ Vector<uint8_t> RenderingDeviceDriverD3D12::pipeline_cache_serialize() {
|
|||
|
||||
// ----- SUBPASS -----
|
||||
|
||||
RDD::RenderPassID RenderingDeviceDriverD3D12::render_pass_create(VectorView<Attachment> p_attachments, VectorView<Subpass> p_subpasses, VectorView<SubpassDependency> p_subpass_dependencies, uint32_t p_view_count) {
|
||||
RDD::RenderPassID RenderingDeviceDriverD3D12::render_pass_create(VectorView<Attachment> p_attachments, VectorView<Subpass> p_subpasses, VectorView<SubpassDependency> p_subpass_dependencies, uint32_t p_view_count, AttachmentReference p_fragment_density_map_attachment) {
|
||||
ERR_FAIL_COND_V_MSG(p_fragment_density_map_attachment.attachment != AttachmentReference::UNUSED, RenderPassID(), "Fragment density maps are not supported in D3D12.");
|
||||
|
||||
// Pre-bookkeep.
|
||||
RenderPassInfo *pass_info = VersatileResource::allocate<RenderPassInfo>(resources_allocator);
|
||||
|
||||
|
|
@ -5050,7 +5037,7 @@ void RenderingDeviceDriverD3D12::command_begin_render_pass(CommandBufferID p_cmd
|
|||
}
|
||||
}
|
||||
|
||||
if (fb_info->vrs_attachment && vrs_capabilities.ss_image_supported) {
|
||||
if (fb_info->vrs_attachment && fsr_capabilities.attachment_supported) {
|
||||
ComPtr<ID3D12GraphicsCommandList5> cmd_list_5;
|
||||
cmd_buf_info->cmd_list->QueryInterface(cmd_list_5.GetAddressOf());
|
||||
if (cmd_list_5) {
|
||||
|
|
@ -5170,7 +5157,7 @@ void RenderingDeviceDriverD3D12::command_end_render_pass(CommandBufferID p_cmd_b
|
|||
const FramebufferInfo *fb_info = cmd_buf_info->render_pass_state.fb_info;
|
||||
const RenderPassInfo *pass_info = cmd_buf_info->render_pass_state.pass_info;
|
||||
|
||||
if (vrs_capabilities.ss_image_supported) {
|
||||
if (fsr_capabilities.attachment_supported) {
|
||||
ComPtr<ID3D12GraphicsCommandList5> cmd_list_5;
|
||||
cmd_buf_info->cmd_list->QueryInterface(cmd_list_5.GetAddressOf());
|
||||
if (cmd_list_5) {
|
||||
|
|
@ -6218,6 +6205,8 @@ uint64_t RenderingDeviceDriverD3D12::limit_get(Limit p_limit) {
|
|||
return D3D12_CS_THREAD_GROUP_MAX_Y;
|
||||
case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z:
|
||||
return D3D12_CS_THREAD_GROUP_MAX_Z;
|
||||
case LIMIT_MAX_COMPUTE_SHARED_MEMORY_SIZE:
|
||||
return D3D12_CS_TGSM_REGISTER_COUNT * sizeof(float);
|
||||
case LIMIT_SUBGROUP_SIZE:
|
||||
// Note in min/max. Shader model 6.6 supports it (see https://microsoft.github.io/DirectX-Specs/d3d/HLSL_SM_6_6_WaveSize.html),
|
||||
// but at this time I don't know the implications on the transpilation to DXIL, etc.
|
||||
|
|
@ -6228,12 +6217,6 @@ uint64_t RenderingDeviceDriverD3D12::limit_get(Limit p_limit) {
|
|||
return subgroup_capabilities.supported_stages_flags_rd();
|
||||
case LIMIT_SUBGROUP_OPERATIONS:
|
||||
return subgroup_capabilities.supported_operations_flags_rd();
|
||||
case LIMIT_VRS_TEXEL_WIDTH:
|
||||
case LIMIT_VRS_TEXEL_HEIGHT:
|
||||
return vrs_capabilities.ss_image_tile_size;
|
||||
case LIMIT_VRS_MAX_FRAGMENT_WIDTH:
|
||||
case LIMIT_VRS_MAX_FRAGMENT_HEIGHT:
|
||||
return vrs_capabilities.ss_max_fragment_size;
|
||||
case LIMIT_MAX_SHADER_VARYINGS:
|
||||
return MIN(D3D12_VS_OUTPUT_REGISTER_COUNT, D3D12_PS_INPUT_REGISTER_COUNT);
|
||||
default: {
|
||||
|
|
@ -6270,12 +6253,8 @@ uint64_t RenderingDeviceDriverD3D12::api_trait_get(ApiTrait p_trait) {
|
|||
|
||||
bool RenderingDeviceDriverD3D12::has_feature(Features p_feature) {
|
||||
switch (p_feature) {
|
||||
case SUPPORTS_MULTIVIEW:
|
||||
return multiview_capabilities.is_supported && multiview_capabilities.max_view_count > 1;
|
||||
case SUPPORTS_FSR_HALF_FLOAT:
|
||||
return shader_capabilities.native_16bit_ops && storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported;
|
||||
case SUPPORTS_ATTACHMENT_VRS:
|
||||
return vrs_capabilities.ss_image_supported;
|
||||
case SUPPORTS_FRAGMENT_SHADER_WITH_ONLY_SIDE_EFFECTS:
|
||||
return true;
|
||||
case SUPPORTS_BUFFER_DEVICE_ADDRESS:
|
||||
|
|
@ -6289,6 +6268,14 @@ const RDD::MultiviewCapabilities &RenderingDeviceDriverD3D12::get_multiview_capa
|
|||
return multiview_capabilities;
|
||||
}
|
||||
|
||||
const RDD::FragmentShadingRateCapabilities &RenderingDeviceDriverD3D12::get_fragment_shading_rate_capabilities() {
|
||||
return fsr_capabilities;
|
||||
}
|
||||
|
||||
const RDD::FragmentDensityMapCapabilities &RenderingDeviceDriverD3D12::get_fragment_density_map_capabilities() {
|
||||
return fdm_capabilities;
|
||||
}
|
||||
|
||||
String RenderingDeviceDriverD3D12::get_api_name() const {
|
||||
return "D3D12";
|
||||
}
|
||||
|
|
@ -6450,12 +6437,6 @@ Error RenderingDeviceDriverD3D12::_check_capabilities() {
|
|||
device_capabilities.version_minor = feature_level % 10;
|
||||
|
||||
// Assume not supported until proven otherwise.
|
||||
vrs_capabilities.draw_call_supported = false;
|
||||
vrs_capabilities.primitive_supported = false;
|
||||
vrs_capabilities.primitive_in_multiviewport = false;
|
||||
vrs_capabilities.ss_image_supported = false;
|
||||
vrs_capabilities.ss_image_tile_size = 1;
|
||||
vrs_capabilities.additional_rates_supported = false;
|
||||
multiview_capabilities.is_supported = false;
|
||||
multiview_capabilities.geometry_shader_is_supported = false;
|
||||
multiview_capabilities.tessellation_shader_is_supported = false;
|
||||
|
|
@ -6546,14 +6527,12 @@ Error RenderingDeviceDriverD3D12::_check_capabilities() {
|
|||
res = device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS6, &options6, sizeof(options6));
|
||||
if (SUCCEEDED(res)) {
|
||||
if (options6.VariableShadingRateTier >= D3D12_VARIABLE_SHADING_RATE_TIER_1) {
|
||||
vrs_capabilities.draw_call_supported = true;
|
||||
fsr_capabilities.pipeline_supported = true;
|
||||
if (options6.VariableShadingRateTier >= D3D12_VARIABLE_SHADING_RATE_TIER_2) {
|
||||
vrs_capabilities.primitive_supported = true;
|
||||
vrs_capabilities.primitive_in_multiviewport = options6.PerPrimitiveShadingRateSupportedWithViewportIndexing;
|
||||
vrs_capabilities.ss_image_supported = true;
|
||||
vrs_capabilities.ss_image_tile_size = options6.ShadingRateImageTileSize;
|
||||
vrs_capabilities.ss_max_fragment_size = 8; // TODO figure out if this is supplied and/or needed
|
||||
vrs_capabilities.additional_rates_supported = options6.AdditionalShadingRatesSupported;
|
||||
fsr_capabilities.primitive_supported = true;
|
||||
fsr_capabilities.attachment_supported = true;
|
||||
fsr_capabilities.min_texel_size = Size2i(options6.ShadingRateImageTileSize, options6.ShadingRateImageTileSize);
|
||||
fsr_capabilities.max_texel_size = Size2i(8, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6565,19 +6544,16 @@ Error RenderingDeviceDriverD3D12::_check_capabilities() {
|
|||
barrier_capabilities.enhanced_barriers_supported = options12.EnhancedBarriersSupported;
|
||||
}
|
||||
|
||||
if (vrs_capabilities.draw_call_supported || vrs_capabilities.primitive_supported || vrs_capabilities.ss_image_supported) {
|
||||
if (fsr_capabilities.pipeline_supported || fsr_capabilities.primitive_supported || fsr_capabilities.attachment_supported) {
|
||||
print_verbose("- D3D12 Variable Rate Shading supported:");
|
||||
if (vrs_capabilities.draw_call_supported) {
|
||||
if (fsr_capabilities.pipeline_supported) {
|
||||
print_verbose(" Draw call");
|
||||
}
|
||||
if (vrs_capabilities.primitive_supported) {
|
||||
print_verbose(String(" Per-primitive (multi-viewport: ") + (vrs_capabilities.primitive_in_multiviewport ? "yes" : "no") + ")");
|
||||
if (fsr_capabilities.primitive_supported) {
|
||||
print_verbose(" Primitive");
|
||||
}
|
||||
if (vrs_capabilities.ss_image_supported) {
|
||||
print_verbose(String(" Screen-space image (tile size: ") + itos(vrs_capabilities.ss_image_tile_size) + ")");
|
||||
}
|
||||
if (vrs_capabilities.additional_rates_supported) {
|
||||
print_verbose(String(" Additional rates: ") + (vrs_capabilities.additional_rates_supported ? "yes" : "no"));
|
||||
if (fsr_capabilities.attachment_supported) {
|
||||
print_verbose(String(" Screen-space image (tile size: ") + itos(fsr_capabilities.min_texel_size.x) + ")");
|
||||
}
|
||||
} else {
|
||||
print_verbose("- D3D12 Variable Rate Shading not supported");
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RENDERING_DEVICE_DRIVER_D3D12_H
|
||||
#define RENDERING_DEVICE_DRIVER_D3D12_H
|
||||
#pragma once
|
||||
|
||||
#include "core/templates/hash_map.h"
|
||||
#include "core/templates/paged_allocator.h"
|
||||
|
|
@ -41,26 +40,10 @@
|
|||
#define __REQUIRED_RPCNDR_H_VERSION__ 475
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#pragma GCC diagnostic ignored "-Wswitch"
|
||||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#pragma clang diagnostic ignored "-Wstring-plus-int"
|
||||
#pragma clang diagnostic ignored "-Wswitch"
|
||||
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
|
||||
#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
|
||||
#endif
|
||||
|
||||
#include "d3dx12.h"
|
||||
#include <d3dx12.h>
|
||||
#include <dxgi1_6.h>
|
||||
#define D3D12MA_D3D12_HEADERS_ALREADY_INCLUDED
|
||||
#include "D3D12MemAlloc.h"
|
||||
#include <D3D12MemAlloc.h>
|
||||
|
||||
#include <wrl/client.h>
|
||||
|
||||
|
|
@ -69,12 +52,6 @@
|
|||
#undef MemoryBarrier
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
using Microsoft::WRL::ComPtr;
|
||||
|
||||
#define D3D12_BITCODE_OFFSETS_NUM_STAGES 3
|
||||
|
|
@ -116,16 +93,6 @@ class RenderingDeviceDriverD3D12 : public RenderingDeviceDriver {
|
|||
uint32_t supported_operations_flags_rd() const;
|
||||
};
|
||||
|
||||
struct VRSCapabilities {
|
||||
bool draw_call_supported = false; // We can specify our fragment rate on a draw call level.
|
||||
bool primitive_supported = false; // We can specify our fragment rate on each drawcall.
|
||||
bool primitive_in_multiviewport = false;
|
||||
bool ss_image_supported = false; // We can provide a density map attachment on our framebuffer.
|
||||
uint32_t ss_image_tile_size = 0;
|
||||
uint32_t ss_max_fragment_size = 0;
|
||||
bool additional_rates_supported = false;
|
||||
};
|
||||
|
||||
struct ShaderCapabilities {
|
||||
D3D_SHADER_MODEL shader_model = (D3D_SHADER_MODEL)0;
|
||||
bool native_16bit_ops = false;
|
||||
|
|
@ -157,7 +124,8 @@ class RenderingDeviceDriverD3D12 : public RenderingDeviceDriver {
|
|||
uint32_t feature_level = 0; // Major * 10 + minor.
|
||||
SubgroupCapabilities subgroup_capabilities;
|
||||
RDD::MultiviewCapabilities multiview_capabilities;
|
||||
VRSCapabilities vrs_capabilities;
|
||||
FragmentShadingRateCapabilities fsr_capabilities;
|
||||
FragmentDensityMapCapabilities fdm_capabilities;
|
||||
ShaderCapabilities shader_capabilities;
|
||||
StorageBufferCapabilities storage_buffer_capabilities;
|
||||
FormatCapabilities format_capabilities;
|
||||
|
|
@ -834,7 +802,7 @@ private:
|
|||
};
|
||||
|
||||
public:
|
||||
virtual RenderPassID render_pass_create(VectorView<Attachment> p_attachments, VectorView<Subpass> p_subpasses, VectorView<SubpassDependency> p_subpass_dependencies, uint32_t p_view_count) override final;
|
||||
virtual RenderPassID render_pass_create(VectorView<Attachment> p_attachments, VectorView<Subpass> p_subpasses, VectorView<SubpassDependency> p_subpass_dependencies, uint32_t p_view_count, AttachmentReference p_fragment_density_map_attachment) override final;
|
||||
virtual void render_pass_free(RenderPassID p_render_pass) override final;
|
||||
|
||||
// ----- COMMANDS -----
|
||||
|
|
@ -1002,6 +970,8 @@ public:
|
|||
virtual uint64_t api_trait_get(ApiTrait p_trait) override final;
|
||||
virtual bool has_feature(Features p_feature) override final;
|
||||
virtual const MultiviewCapabilities &get_multiview_capabilities() override final;
|
||||
virtual const FragmentShadingRateCapabilities &get_fragment_shading_rate_capabilities() override final;
|
||||
virtual const FragmentDensityMapCapabilities &get_fragment_density_map_capabilities() override final;
|
||||
virtual String get_api_name() const override final;
|
||||
virtual String get_api_version() const override final;
|
||||
virtual String get_pipeline_cache_uuid() const override final;
|
||||
|
|
@ -1036,5 +1006,3 @@ public:
|
|||
RenderingDeviceDriverD3D12(RenderingContextDriverD3D12 *p_context_driver);
|
||||
virtual ~RenderingDeviceDriverD3D12();
|
||||
};
|
||||
|
||||
#endif // RENDERING_DEVICE_DRIVER_D3D12_H
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ int EGLManager::_get_gldisplay_id(void *p_display) {
|
|||
String EGLManager::shader_cache_dir;
|
||||
|
||||
void EGLManager::_set_cache(const void *p_key, EGLsizeiANDROID p_key_size, const void *p_value, EGLsizeiANDROID p_value_size) {
|
||||
String name = CryptoCore::b64_encode_str((const uint8_t *)p_key, p_key_size).replace("/", "_");
|
||||
String name = CryptoCore::b64_encode_str((const uint8_t *)p_key, p_key_size).replace_char('/', '_');
|
||||
String path = shader_cache_dir.path_join(name) + ".cache";
|
||||
|
||||
Error err = OK;
|
||||
|
|
@ -163,7 +163,7 @@ void EGLManager::_set_cache(const void *p_key, EGLsizeiANDROID p_key_size, const
|
|||
}
|
||||
|
||||
EGLsizeiANDROID EGLManager::_get_cache(const void *p_key, EGLsizeiANDROID p_key_size, void *p_value, EGLsizeiANDROID p_value_size) {
|
||||
String name = CryptoCore::b64_encode_str((const uint8_t *)p_key, p_key_size).replace("/", "_");
|
||||
String name = CryptoCore::b64_encode_str((const uint8_t *)p_key, p_key_size).replace_char('/', '_');
|
||||
String path = shader_cache_dir.path_join(name) + ".cache";
|
||||
|
||||
Error err = OK;
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EGL_MANAGER_H
|
||||
#define EGL_MANAGER_H
|
||||
#pragma once
|
||||
|
||||
#ifdef EGL_ENABLED
|
||||
|
||||
|
|
@ -119,5 +118,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // EGL_ENABLED
|
||||
|
||||
#endif // EGL_MANAGER_H
|
||||
|
|
|
|||
|
|
@ -13,12 +13,7 @@ if env["platform"] in ["macos", "windows", "linuxbsd"]:
|
|||
|
||||
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
|
||||
|
||||
# Treat glad headers as system headers to avoid raising warnings. Not supported on MSVC.
|
||||
if not env.msvc:
|
||||
env.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path])
|
||||
else:
|
||||
env.Prepend(CPPPATH=[thirdparty_dir])
|
||||
|
||||
env.Prepend(CPPEXTPATH=[thirdparty_dir])
|
||||
env.Append(CPPDEFINES=["GLAD_ENABLED"])
|
||||
env.Append(CPPDEFINES=["EGL_ENABLED"])
|
||||
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ void CopyEffects::gaussian_blur(GLuint p_source_texture, int p_mipmap_count, con
|
|||
|
||||
glBindTexture(GL_TEXTURE_2D, p_source_texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, i - 1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, i - 1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, i);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_source_texture, i);
|
||||
#ifdef DEV_ENABLED
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef COPY_EFFECTS_GLES3_H
|
||||
#define COPY_EFFECTS_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
|
|
@ -77,5 +76,3 @@ public:
|
|||
} //namespace GLES3
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // COPY_EFFECTS_GLES3_H
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ CubemapFilter::~CubemapFilter() {
|
|||
|
||||
Vector3 importance_sample_GGX(Vector2 xi, float roughness4) {
|
||||
// Compute distribution direction
|
||||
float phi = 2.0 * Math_PI * xi.x;
|
||||
float phi = 2.0 * Math::PI * xi.x;
|
||||
float cos_theta = sqrt((1.0 - xi.y) / (1.0 + (roughness4 - 1.0) * xi.y));
|
||||
float sin_theta = sqrt(1.0 - cos_theta * cos_theta);
|
||||
|
||||
|
|
@ -107,7 +107,7 @@ Vector3 importance_sample_GGX(Vector2 xi, float roughness4) {
|
|||
float distribution_GGX(float NdotH, float roughness4) {
|
||||
float NdotH2 = NdotH * NdotH;
|
||||
float denom = (NdotH2 * (roughness4 - 1.0) + 1.0);
|
||||
denom = Math_PI * denom * denom;
|
||||
denom = Math::PI * denom * denom;
|
||||
|
||||
return roughness4 / denom;
|
||||
}
|
||||
|
|
@ -157,7 +157,7 @@ void CubemapFilter::filter_radiance(GLuint p_source_cubemap, GLuint p_dest_cubem
|
|||
float roughness4 = roughness * roughness;
|
||||
roughness4 *= roughness4;
|
||||
|
||||
float solid_angle_texel = 4.0 * Math_PI / float(6 * size * size);
|
||||
float solid_angle_texel = 4.0 * Math::PI / float(6 * size * size);
|
||||
|
||||
LocalVector<float> sample_directions;
|
||||
sample_directions.resize(4 * sample_count);
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef CUBEMAP_FILTER_GLES3_H
|
||||
#define CUBEMAP_FILTER_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
|
|
@ -66,5 +65,3 @@ public:
|
|||
} //namespace GLES3
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // CUBEMAP_FILTER_GLES3_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FEED_EFFECTS_GLES3_H
|
||||
#define FEED_EFFECTS_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
|
|
@ -65,5 +64,3 @@ private:
|
|||
} // namespace GLES3
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // FEED_EFFECTS_GLES3_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GLOW_GLES3_H
|
||||
#define GLOW_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
|
|
@ -85,5 +84,3 @@ public:
|
|||
} //namespace GLES3
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // GLOW_GLES3_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef POST_EFFECTS_GLES3_H
|
||||
#define POST_EFFECTS_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
|
|
@ -65,5 +64,3 @@ public:
|
|||
} //namespace GLES3
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // POST_EFFECTS_GLES3_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FOG_GLES3_H
|
||||
#define FOG_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
|
|
@ -55,5 +54,3 @@ public:
|
|||
} // namespace GLES3
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // FOG_GLES3_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GI_GLES3_H
|
||||
#define GI_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
|
|
@ -87,5 +86,3 @@ public:
|
|||
}; // namespace GLES3
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // GI_GLES3_H
|
||||
|
|
|
|||
|
|
@ -1152,6 +1152,12 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
|
|||
// Reset base data.
|
||||
_update_transform_2d_to_mat2x3(base_transform * draw_transform, state.instance_data_array[r_index].world);
|
||||
_prepare_canvas_texture(state.canvas_instance_batches[state.current_batch_index].tex, state.canvas_instance_batches[state.current_batch_index].filter, state.canvas_instance_batches[state.current_batch_index].repeat, r_index, texpixel_size);
|
||||
state.instance_data_array[r_index].lights[0] = lights[0];
|
||||
state.instance_data_array[r_index].lights[1] = lights[1];
|
||||
state.instance_data_array[r_index].lights[2] = lights[2];
|
||||
state.instance_data_array[r_index].lights[3] = lights[3];
|
||||
state.instance_data_array[r_index].flags = base_flags;
|
||||
state.instance_data_array[r_index].instance_uniforms_ofs = p_item->instance_allocated_shader_uniforms_offset;
|
||||
|
||||
for (uint32_t j = 0; j < 3; j++) {
|
||||
int offset = j == 0 ? 0 : 1;
|
||||
|
|
@ -1289,7 +1295,7 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
|
|||
|
||||
_FORCE_INLINE_ static uint32_t _indices_to_primitives(RS::PrimitiveType p_primitive, uint32_t p_indices) {
|
||||
static const uint32_t divisor[RS::PRIMITIVE_MAX] = { 1, 2, 1, 3, 1 };
|
||||
static const uint32_t subtractor[RS::PRIMITIVE_MAX] = { 0, 0, 1, 0, 1 };
|
||||
static const uint32_t subtractor[RS::PRIMITIVE_MAX] = { 0, 0, 1, 0, 2 };
|
||||
return (p_indices - subtractor[p_primitive]) / divisor[p_primitive];
|
||||
}
|
||||
|
||||
|
|
@ -1566,7 +1572,7 @@ void RasterizerCanvasGLES3::_add_to_batch(uint32_t &r_index, bool &r_batch_broke
|
|||
}
|
||||
|
||||
void RasterizerCanvasGLES3::_new_batch(bool &r_batch_broken) {
|
||||
if (state.canvas_instance_batches.size() == 0) {
|
||||
if (state.canvas_instance_batches.is_empty()) {
|
||||
Batch new_batch;
|
||||
new_batch.instance_buffer_index = state.current_instance_buffer_index;
|
||||
state.canvas_instance_batches.push_back(new_batch);
|
||||
|
|
@ -1686,7 +1692,7 @@ void RasterizerCanvasGLES3::light_update_shadow(RID p_rid, int p_shadow_index, c
|
|||
}
|
||||
|
||||
// Precomputed:
|
||||
// Vector3 cam_target = Basis::from_euler(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_targets[i], Vector3(0, 0, -1)).affine_inverse());
|
||||
const Projection projections[4] = {
|
||||
projection * Projection(Vector4(0, 0, -1, 0), Vector4(1, 0, 0, 0), Vector4(0, -1, 0, 0), Vector4(0, 0, 0, 1)),
|
||||
|
|
@ -1761,7 +1767,7 @@ void RasterizerCanvasGLES3::light_update_directional_shadow(RID p_rid, int p_sha
|
|||
|
||||
Vector2 center = p_clip_rect.get_center();
|
||||
|
||||
float to_edge_distance = ABS(light_dir.dot(p_clip_rect.get_support(-light_dir)) - light_dir.dot(center));
|
||||
float to_edge_distance = Math::abs(light_dir.dot(p_clip_rect.get_support(-light_dir)) - light_dir.dot(center));
|
||||
|
||||
Vector2 from_pos = center - light_dir * (to_edge_distance + p_cull_distance);
|
||||
float distance = to_edge_distance * 2.0 + p_cull_distance;
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RASTERIZER_CANVAS_GLES3_H
|
||||
#define RASTERIZER_CANVAS_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
|
|
@ -388,5 +387,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // RASTERIZER_CANVAS_GLES3_H
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
#define _EXT_DEBUG_TYPE_PORTABILITY_ARB 0x824F
|
||||
#define _EXT_DEBUG_TYPE_PERFORMANCE_ARB 0x8250
|
||||
#define _EXT_DEBUG_TYPE_OTHER_ARB 0x8251
|
||||
#define _EXT_DEBUG_TYPE_MARKER_ARB 0x8268
|
||||
#define _EXT_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143
|
||||
#define _EXT_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144
|
||||
#define _EXT_DEBUG_LOGGED_MESSAGES_ARB 0x9145
|
||||
|
|
@ -140,7 +141,7 @@ void RasterizerGLES3::clear_depth(float p_depth) {
|
|||
#ifdef CAN_DEBUG
|
||||
static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const GLvoid *userParam) {
|
||||
// These are ultimately annoying, so removing for now.
|
||||
if (type == _EXT_DEBUG_TYPE_OTHER_ARB || type == _EXT_DEBUG_TYPE_PERFORMANCE_ARB) {
|
||||
if (type == _EXT_DEBUG_TYPE_OTHER_ARB || type == _EXT_DEBUG_TYPE_PERFORMANCE_ARB || type == _EXT_DEBUG_TYPE_MARKER_ARB) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RASTERIZER_GLES3_H
|
||||
#define RASTERIZER_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
|
|
@ -105,6 +104,7 @@ public:
|
|||
|
||||
void blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount);
|
||||
|
||||
bool is_opengl() { return true; }
|
||||
void gl_end_frame(bool p_swap_buffers);
|
||||
void end_frame(bool p_swap_buffers);
|
||||
|
||||
|
|
@ -141,5 +141,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // RASTERIZER_GLES3_H
|
||||
|
|
|
|||
|
|
@ -708,12 +708,7 @@ void RasterizerSceneGLES3::_setup_sky(const RenderDataGLES3 *p_render_data, cons
|
|||
sky_light_data.enabled = true;
|
||||
|
||||
float angular_diameter = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
|
||||
if (angular_diameter > 0.0) {
|
||||
angular_diameter = Math::tan(Math::deg_to_rad(angular_diameter));
|
||||
} else {
|
||||
angular_diameter = 0.0;
|
||||
}
|
||||
sky_light_data.size = angular_diameter;
|
||||
sky_light_data.size = Math::deg_to_rad(angular_diameter);
|
||||
sky_globals.directional_light_count++;
|
||||
if (sky_globals.directional_light_count >= sky_globals.max_directional_lights) {
|
||||
break;
|
||||
|
|
@ -1224,7 +1219,7 @@ void RasterizerSceneGLES3::voxel_gi_set_quality(RS::VoxelGIQuality) {
|
|||
|
||||
_FORCE_INLINE_ static uint32_t _indices_to_primitives(RS::PrimitiveType p_primitive, uint32_t p_indices) {
|
||||
static const uint32_t divisor[RS::PRIMITIVE_MAX] = { 1, 2, 1, 3, 1 };
|
||||
static const uint32_t subtractor[RS::PRIMITIVE_MAX] = { 0, 0, 1, 0, 1 };
|
||||
static const uint32_t subtractor[RS::PRIMITIVE_MAX] = { 0, 0, 1, 0, 2 };
|
||||
return (p_indices - subtractor[p_primitive]) / divisor[p_primitive];
|
||||
}
|
||||
void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const RenderDataGLES3 *p_render_data, PassMode p_pass_mode, bool p_append) {
|
||||
|
|
@ -1677,7 +1672,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b
|
|||
if (is_using_physical_light_units()) {
|
||||
light_data.energy *= light_storage->light_get_param(base, RS::LIGHT_PARAM_INTENSITY);
|
||||
} else {
|
||||
light_data.energy *= Math_PI;
|
||||
light_data.energy *= Math::PI;
|
||||
}
|
||||
|
||||
if (p_render_data->camera_attributes.is_valid()) {
|
||||
|
|
@ -1867,14 +1862,14 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b
|
|||
|
||||
// Convert from Luminous Power to Luminous Intensity
|
||||
if (type == RS::LIGHT_OMNI) {
|
||||
energy *= 1.0 / (Math_PI * 4.0);
|
||||
energy *= 1.0 / (Math::PI * 4.0);
|
||||
} else {
|
||||
// Spot Lights are not physically accurate, Luminous Intensity should change in relation to the cone angle.
|
||||
// We make this assumption to keep them easy to control.
|
||||
energy *= 1.0 / Math_PI;
|
||||
energy *= 1.0 / Math::PI;
|
||||
}
|
||||
} else {
|
||||
energy *= Math_PI;
|
||||
energy *= Math::PI;
|
||||
}
|
||||
|
||||
if (p_render_data->camera_attributes.is_valid()) {
|
||||
|
|
@ -3223,11 +3218,11 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
|
|||
spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL;
|
||||
spec_constants |= SceneShaderGLES3::DISABLE_LIGHTMAP;
|
||||
} else {
|
||||
if (inst->omni_light_gl_cache.size() == 0) {
|
||||
if (inst->omni_light_gl_cache.is_empty()) {
|
||||
spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_OMNI;
|
||||
}
|
||||
|
||||
if (inst->spot_light_gl_cache.size() == 0) {
|
||||
if (inst->spot_light_gl_cache.is_empty()) {
|
||||
spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_SPOT;
|
||||
}
|
||||
|
||||
|
|
@ -3235,7 +3230,7 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
|
|||
spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL;
|
||||
}
|
||||
|
||||
if (inst->reflection_probe_rid_cache.size() == 0) {
|
||||
if (inst->reflection_probe_rid_cache.is_empty()) {
|
||||
// We don't have any probes.
|
||||
spec_constants |= SceneShaderGLES3::DISABLE_REFLECTION_PROBE;
|
||||
} else if (inst->reflection_probe_rid_cache.size() > 1) {
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RASTERIZER_SCENE_GLES3_H
|
||||
#define RASTERIZER_SCENE_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
|
|
@ -740,7 +739,7 @@ protected:
|
|||
float baked_exposure = 1.0;
|
||||
|
||||
//State to track when radiance cubemap needs updating
|
||||
GLES3::SkyMaterialData *prev_material;
|
||||
GLES3::SkyMaterialData *prev_material = nullptr;
|
||||
Vector3 prev_position = Vector3(0.0, 0.0, 0.0);
|
||||
float prev_time = 0.0f;
|
||||
};
|
||||
|
|
@ -879,5 +878,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // RASTERIZER_SCENE_GLES3_H
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ void ShaderGLES3::_add_stage(const char *p_code, StageType p_stage_type) {
|
|||
} else if (l.begins_with("#CODE")) {
|
||||
chunk.type = StageTemplate::Chunk::TYPE_CODE;
|
||||
push_chunk = true;
|
||||
chunk.code = l.replace_first("#CODE", String()).replace(":", "").strip_edges().to_upper();
|
||||
chunk.code = l.replace_first("#CODE", String()).remove_char(':').strip_edges().to_upper();
|
||||
} else {
|
||||
text += l + "\n";
|
||||
}
|
||||
|
|
@ -690,7 +690,7 @@ void ShaderGLES3::_save_to_cache(Version *p_version) {
|
|||
|
||||
void ShaderGLES3::_clear_version(Version *p_version) {
|
||||
// Variants not compiled yet, just return
|
||||
if (p_version->variants.size() == 0) {
|
||||
if (p_version->variants.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef SHADER_GLES3_H
|
||||
#define SHADER_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/projection.h"
|
||||
#include "core/os/mutex.h"
|
||||
|
|
@ -189,7 +188,7 @@ protected:
|
|||
Version *version = version_owner.get_or_null(p_version);
|
||||
ERR_FAIL_NULL_V(version, false);
|
||||
|
||||
if (version->variants.size() == 0) {
|
||||
if (version->variants.is_empty()) {
|
||||
_initialize_version(version); //may lack initialization
|
||||
}
|
||||
|
||||
|
|
@ -258,5 +257,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // SHADER_GLES3_H
|
||||
|
|
|
|||
|
|
@ -78,8 +78,8 @@ Config::Config() {
|
|||
#endif
|
||||
|
||||
bptc_supported = extensions.has("GL_ARB_texture_compression_bptc") || extensions.has("EXT_texture_compression_bptc");
|
||||
astc_supported = extensions.has("GL_KHR_texture_compression_astc") || extensions.has("GL_OES_texture_compression_astc") || extensions.has("GL_KHR_texture_compression_astc_ldr") || extensions.has("GL_KHR_texture_compression_astc_hdr");
|
||||
astc_hdr_supported = extensions.has("GL_KHR_texture_compression_astc_hdr");
|
||||
astc_supported = astc_hdr_supported || extensions.has("GL_KHR_texture_compression_astc") || extensions.has("GL_OES_texture_compression_astc") || extensions.has("GL_KHR_texture_compression_astc_ldr") || extensions.has("WEBGL_compressed_texture_astc");
|
||||
astc_layered_supported = extensions.has("GL_KHR_texture_compression_astc_sliced_3d");
|
||||
|
||||
if (RasterizerGLES3::is_gles_over_gl()) {
|
||||
|
|
@ -226,7 +226,7 @@ Config::Config() {
|
|||
// OpenGL ES 3.0 V@331.0 (GIT@35e467f, Ice9844a736) (Date:04/15/19)
|
||||
// OpenGL ES 3.0 V@415.0 (GIT@d39f783, I79de86aa2c, 1591296226) (Date:06/04/20)
|
||||
// OpenGL ES 3.0 V@0502.0 (GIT@09fef447e8, I1fe547a144, 1661493934) (Date:08/25/22)
|
||||
String driver_version = gl_version.get_slice("V@", 1).get_slice(" ", 0);
|
||||
String driver_version = gl_version.get_slice("V@", 1).get_slicec(' ', 0);
|
||||
if (driver_version.is_valid_float() && driver_version.to_float() >= 331.0) {
|
||||
flip_xy_workaround = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef CONFIG_GLES3_H
|
||||
#define CONFIG_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
|
|
@ -123,5 +122,3 @@ public:
|
|||
} // namespace GLES3
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // CONFIG_GLES3_H
|
||||
|
|
|
|||
|
|
@ -1181,7 +1181,7 @@ void LightStorage::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point,
|
|||
return; // Nothing could be done.
|
||||
}
|
||||
|
||||
node = ABS(node) - 1;
|
||||
node = Math::abs(node) - 1;
|
||||
|
||||
uint32_t *tetrahedron = (uint32_t *)&lm->tetrahedra[node * 4];
|
||||
Vector3 points[4] = { lm->points[tetrahedron[0]], lm->points[tetrahedron[1]], lm->points[tetrahedron[2]], lm->points[tetrahedron[3]] };
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef LIGHT_STORAGE_GLES3_H
|
||||
#define LIGHT_STORAGE_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
|
|
@ -909,5 +908,3 @@ public:
|
|||
} // namespace GLES3
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // LIGHT_STORAGE_GLES3_H
|
||||
|
|
|
|||
|
|
@ -1143,9 +1143,9 @@ MaterialStorage::MaterialStorage() {
|
|||
actions.renames["CANVAS_MATRIX"] = "canvas_transform";
|
||||
actions.renames["SCREEN_MATRIX"] = "screen_transform";
|
||||
actions.renames["TIME"] = "time";
|
||||
actions.renames["PI"] = _MKSTR(Math_PI);
|
||||
actions.renames["TAU"] = _MKSTR(Math_TAU);
|
||||
actions.renames["E"] = _MKSTR(Math_E);
|
||||
actions.renames["PI"] = String::num(Math::PI);
|
||||
actions.renames["TAU"] = String::num(Math::TAU);
|
||||
actions.renames["E"] = String::num(Math::E);
|
||||
actions.renames["AT_LIGHT_PASS"] = "false";
|
||||
actions.renames["INSTANCE_CUSTOM"] = "instance_custom";
|
||||
|
||||
|
|
@ -1238,9 +1238,9 @@ MaterialStorage::MaterialStorage() {
|
|||
|
||||
actions.renames["TIME"] = "scene_data.time";
|
||||
actions.renames["EXPOSURE"] = "(1.0 / scene_data.emissive_exposure_normalization)";
|
||||
actions.renames["PI"] = _MKSTR(Math_PI);
|
||||
actions.renames["TAU"] = _MKSTR(Math_TAU);
|
||||
actions.renames["E"] = _MKSTR(Math_E);
|
||||
actions.renames["PI"] = String::num(Math::PI);
|
||||
actions.renames["TAU"] = String::num(Math::TAU);
|
||||
actions.renames["E"] = String::num(Math::E);
|
||||
actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB";
|
||||
actions.renames["CLIP_SPACE_FAR"] = "SHADER_SPACE_FAR";
|
||||
actions.renames["VIEWPORT_SIZE"] = "scene_data.viewport_size";
|
||||
|
|
@ -1406,9 +1406,9 @@ MaterialStorage::MaterialStorage() {
|
|||
}
|
||||
actions.renames["TRANSFORM"] = "xform";
|
||||
actions.renames["TIME"] = "time";
|
||||
actions.renames["PI"] = _MKSTR(Math_PI);
|
||||
actions.renames["TAU"] = _MKSTR(Math_TAU);
|
||||
actions.renames["E"] = _MKSTR(Math_E);
|
||||
actions.renames["PI"] = String::num(Math::PI);
|
||||
actions.renames["TAU"] = String::num(Math::TAU);
|
||||
actions.renames["E"] = String::num(Math::E);
|
||||
actions.renames["LIFETIME"] = "lifetime";
|
||||
actions.renames["DELTA"] = "local_delta";
|
||||
actions.renames["NUMBER"] = "particle_number";
|
||||
|
|
@ -1463,9 +1463,9 @@ MaterialStorage::MaterialStorage() {
|
|||
actions.renames["SCREEN_UV"] = "uv";
|
||||
actions.renames["TIME"] = "time";
|
||||
actions.renames["FRAGCOORD"] = "gl_FragCoord";
|
||||
actions.renames["PI"] = _MKSTR(Math_PI);
|
||||
actions.renames["TAU"] = _MKSTR(Math_TAU);
|
||||
actions.renames["E"] = _MKSTR(Math_E);
|
||||
actions.renames["PI"] = String::num(Math::PI);
|
||||
actions.renames["TAU"] = String::num(Math::TAU);
|
||||
actions.renames["E"] = String::num(Math::E);
|
||||
actions.renames["HALF_RES_COLOR"] = "half_res_color";
|
||||
actions.renames["QUARTER_RES_COLOR"] = "quarter_res_color";
|
||||
actions.renames["RADIANCE"] = "radiance";
|
||||
|
|
@ -1925,7 +1925,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);
|
||||
StringName name = E.name.get_slicec('/', 1);
|
||||
Dictionary d = GLOBAL_GET(E.name);
|
||||
|
||||
ERR_CONTINUE(!d.has("type"));
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef MATERIAL_STORAGE_GLES3_H
|
||||
#define MATERIAL_STORAGE_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
|
|
@ -634,5 +633,3 @@ public:
|
|||
} // namespace GLES3
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // MATERIAL_STORAGE_GLES3_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef MESH_STORAGE_GLES3_H
|
||||
#define MESH_STORAGE_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
|
|
@ -604,5 +603,3 @@ public:
|
|||
} // namespace GLES3
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // MESH_STORAGE_GLES3_H
|
||||
|
|
|
|||
|
|
@ -513,7 +513,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
|
|||
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
|
||||
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
|
||||
|
||||
double new_phase = Math::fmod(p_particles->phase + (p_delta / p_particles->lifetime) * p_particles->speed_scale, 1.0);
|
||||
double new_phase = Math::fmod(p_particles->phase + (p_delta / p_particles->lifetime), 1.0);
|
||||
|
||||
//update current frame
|
||||
ParticlesFrameParams frame_params;
|
||||
|
|
@ -534,7 +534,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
|
|||
p_particles->phase = new_phase;
|
||||
|
||||
frame_params.time = RSG::rasterizer->get_total_time();
|
||||
frame_params.delta = p_delta * p_particles->speed_scale;
|
||||
frame_params.delta = p_delta;
|
||||
frame_params.random_seed = p_particles->random_seed;
|
||||
frame_params.explosiveness = p_particles->explosiveness;
|
||||
frame_params.randomness = p_particles->randomness;
|
||||
|
|
@ -1097,8 +1097,6 @@ void ParticlesStorage::update_particles() {
|
|||
fixed_fps = particles->fixed_fps;
|
||||
}
|
||||
|
||||
bool zero_time_scale = Engine::get_singleton()->get_time_scale() <= 0.0;
|
||||
|
||||
if (particles->clear && particles->pre_process_time > 0.0) {
|
||||
double frame_time;
|
||||
if (fixed_fps > 0) {
|
||||
|
|
@ -1115,37 +1113,27 @@ void ParticlesStorage::update_particles() {
|
|||
}
|
||||
}
|
||||
|
||||
double time_scale = MAX(particles->speed_scale, 0.0);
|
||||
|
||||
if (fixed_fps > 0) {
|
||||
double frame_time;
|
||||
double decr;
|
||||
if (zero_time_scale) {
|
||||
frame_time = 0.0;
|
||||
decr = 1.0 / fixed_fps;
|
||||
} else {
|
||||
frame_time = 1.0 / fixed_fps;
|
||||
decr = frame_time;
|
||||
}
|
||||
double frame_time = 1.0 / fixed_fps;
|
||||
double delta = RSG::rasterizer->get_frame_delta_time();
|
||||
if (delta > 0.1) { //avoid recursive stalls if fps goes below 10
|
||||
delta = 0.1;
|
||||
} else if (delta <= 0.0) { //unlikely but..
|
||||
delta = 0.001;
|
||||
}
|
||||
double todo = particles->frame_remainder + delta;
|
||||
double todo = particles->frame_remainder + delta * time_scale;
|
||||
|
||||
while (todo >= frame_time) {
|
||||
_particles_process(particles, frame_time);
|
||||
todo -= decr;
|
||||
todo -= frame_time;
|
||||
}
|
||||
|
||||
particles->frame_remainder = todo;
|
||||
|
||||
} else {
|
||||
if (zero_time_scale) {
|
||||
_particles_process(particles, 0.0);
|
||||
} else {
|
||||
_particles_process(particles, RSG::rasterizer->get_frame_delta_time());
|
||||
}
|
||||
_particles_process(particles, RSG::rasterizer->get_frame_delta_time() * time_scale);
|
||||
}
|
||||
|
||||
if (particles->request_process_time > 0.0) {
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef PARTICLES_STORAGE_GLES3_H
|
||||
#define PARTICLES_STORAGE_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
|
|
@ -460,5 +459,3 @@ public:
|
|||
} // namespace GLES3
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // PARTICLES_STORAGE_GLES3_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RENDER_SCENE_BUFFERS_GLES3_H
|
||||
#define RENDER_SCENE_BUFFERS_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
|
|
@ -164,5 +163,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // RENDER_SCENE_BUFFERS_GLES3_H
|
||||
|
|
|
|||
|
|
@ -1468,8 +1468,8 @@ void TextureStorage::texture_debug_usage(List<RS::TextureInfo> *r_info) {
|
|||
List<RID> textures;
|
||||
texture_owner.get_owned_list(&textures);
|
||||
|
||||
for (List<RID>::Element *E = textures.front(); E; E = E->next()) {
|
||||
Texture *t = texture_owner.get_or_null(E->get());
|
||||
for (const RID &rid : textures) {
|
||||
Texture *t = texture_owner.get_or_null(rid);
|
||||
if (!t) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEXTURE_STORAGE_GLES3_H
|
||||
#define TEXTURE_STORAGE_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
|
|
@ -730,5 +729,3 @@ inline String TextureStorage::get_framebuffer_error(GLenum p_status) {
|
|||
} // namespace GLES3
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // TEXTURE_STORAGE_GLES3_H
|
||||
|
|
|
|||
|
|
@ -421,6 +421,9 @@ bool Utilities::has_os_feature(const String &p_feature) const {
|
|||
if (p_feature == "etc2") {
|
||||
return config->etc2_supported;
|
||||
}
|
||||
if (p_feature == "astc_hdr") {
|
||||
return config->astc_hdr_supported;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef UTILITIES_GLES3_H
|
||||
#define UTILITIES_GLES3_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
|
|
@ -233,5 +232,3 @@ public:
|
|||
} // namespace GLES3
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // UTILITIES_GLES3_H
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ thirdparty_sources = [
|
|||
]
|
||||
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
|
||||
|
||||
env_metal.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "/include"])
|
||||
env_metal.Prepend(CPPEXTPATH=[thirdparty_dir, thirdparty_dir + "/include"])
|
||||
|
||||
# Must enable exceptions for SPIRV-Cross; otherwise, it will abort the process on errors.
|
||||
if "-fno-exceptions" in env_metal["CXXFLAGS"]:
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef INFLECTION_MAP_H
|
||||
#define INFLECTION_MAP_H
|
||||
#pragma once
|
||||
|
||||
#include "core/templates/hash_map.h"
|
||||
#include "core/templates/local_vector.h"
|
||||
|
|
@ -121,5 +120,3 @@ protected:
|
|||
HashMap<KeyType, IndexValue> _inflection_indexes;
|
||||
IndexValue _linear_indexes[LinearCount];
|
||||
};
|
||||
|
||||
#endif // INFLECTION_MAP_H
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Portions of this code were derived from MoltenVK. */
|
||||
|
|
@ -48,9 +50,6 @@
|
|||
/* permissions and limitations under the License. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef METAL_DEVICE_PROPERTIES_H
|
||||
#define METAL_DEVICE_PROPERTIES_H
|
||||
|
||||
#import "servers/rendering/rendering_device.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
|
@ -125,6 +124,7 @@ struct MetalLimits {
|
|||
uint32_t maxVertexInputBindingStride;
|
||||
uint32_t maxDrawIndexedIndexValue;
|
||||
uint32_t maxShaderVaryings;
|
||||
uint32_t maxThreadGroupMemoryAllocation;
|
||||
|
||||
double temporalScalerInputContentMinScale;
|
||||
double temporalScalerInputContentMaxScale;
|
||||
|
|
@ -152,5 +152,3 @@ public:
|
|||
private:
|
||||
static const SampleCount sample_count[RenderingDevice::TextureSamples::TEXTURE_SAMPLES_MAX];
|
||||
};
|
||||
|
||||
#endif // METAL_DEVICE_PROPERTIES_H
|
||||
|
|
|
|||
|
|
@ -305,6 +305,14 @@ void MetalDeviceProperties::init_limits(id<MTLDevice> p_device) {
|
|||
limits.maxVertexInputBindingStride = (2 * KIBI);
|
||||
limits.maxShaderVaryings = 31; // Accurate on Apple4 and above. See: https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
|
||||
|
||||
if ([p_device supportsFamily:MTLGPUFamilyApple4]) {
|
||||
limits.maxThreadGroupMemoryAllocation = 32768;
|
||||
} else if ([p_device supportsFamily:MTLGPUFamilyApple3]) {
|
||||
limits.maxThreadGroupMemoryAllocation = 16384;
|
||||
} else {
|
||||
limits.maxThreadGroupMemoryAllocation = 16352;
|
||||
}
|
||||
|
||||
#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
|
||||
limits.minUniformBufferOffsetAlignment = 64;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Portions of this code were derived from MoltenVK. */
|
||||
|
|
@ -48,14 +50,11 @@
|
|||
/* permissions and limitations under the License. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef METAL_OBJECTS_H
|
||||
#define METAL_OBJECTS_H
|
||||
|
||||
#import "metal_device_properties.h"
|
||||
#import "metal_utils.h"
|
||||
#import "pixel_formats.h"
|
||||
|
||||
#import "servers/rendering/rendering_device_driver.h"
|
||||
#include "servers/rendering/rendering_device_driver.h"
|
||||
|
||||
#import <CommonCrypto/CommonDigest.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
|
@ -787,20 +786,20 @@ struct BoundUniformSet {
|
|||
|
||||
class API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) MDUniformSet {
|
||||
private:
|
||||
void bind_uniforms_argument_buffers(MDShader *p_shader, MDCommandBuffer::RenderState &p_state);
|
||||
void bind_uniforms_direct(MDShader *p_shader, MDCommandBuffer::RenderState &p_state);
|
||||
void bind_uniforms_argument_buffers(MDShader *p_shader, MDCommandBuffer::ComputeState &p_state);
|
||||
void bind_uniforms_direct(MDShader *p_shader, MDCommandBuffer::ComputeState &p_state);
|
||||
void bind_uniforms_argument_buffers(MDShader *p_shader, MDCommandBuffer::RenderState &p_state, uint32_t p_set_index);
|
||||
void bind_uniforms_direct(MDShader *p_shader, MDCommandBuffer::RenderState &p_state, uint32_t p_set_index);
|
||||
void bind_uniforms_argument_buffers(MDShader *p_shader, MDCommandBuffer::ComputeState &p_state, uint32_t p_set_index);
|
||||
void bind_uniforms_direct(MDShader *p_shader, MDCommandBuffer::ComputeState &p_state, uint32_t p_set_index);
|
||||
|
||||
public:
|
||||
uint32_t index;
|
||||
LocalVector<RDD::BoundUniform> uniforms;
|
||||
HashMap<MDShader *, BoundUniformSet> bound_uniforms;
|
||||
|
||||
void bind_uniforms(MDShader *p_shader, MDCommandBuffer::RenderState &p_state);
|
||||
void bind_uniforms(MDShader *p_shader, MDCommandBuffer::ComputeState &p_state);
|
||||
void bind_uniforms(MDShader *p_shader, MDCommandBuffer::RenderState &p_state, uint32_t p_set_index);
|
||||
void bind_uniforms(MDShader *p_shader, MDCommandBuffer::ComputeState &p_state, uint32_t p_set_index);
|
||||
|
||||
BoundUniformSet &bound_uniform_set(MDShader *p_shader, id<MTLDevice> p_device, ResourceUsageMap &p_resource_usage);
|
||||
BoundUniformSet &bound_uniform_set(MDShader *p_shader, id<MTLDevice> p_device, ResourceUsageMap &p_resource_usage, uint32_t p_set_index);
|
||||
};
|
||||
|
||||
class API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) MDPipeline {
|
||||
|
|
@ -975,5 +974,3 @@ auto release(RDD::ID p_id) {
|
|||
}
|
||||
|
||||
} // namespace rid
|
||||
|
||||
#endif // METAL_OBJECTS_H
|
||||
|
|
|
|||
|
|
@ -213,36 +213,38 @@ void MDCommandBuffer::render_bind_uniform_set(RDD::UniformSetID p_uniform_set, R
|
|||
DEV_ASSERT(type == MDCommandBufferStateType::Render);
|
||||
|
||||
MDUniformSet *set = (MDUniformSet *)(p_uniform_set.id);
|
||||
if (render.uniform_sets.size() <= set->index) {
|
||||
if (render.uniform_sets.size() <= p_set_index) {
|
||||
uint32_t s = render.uniform_sets.size();
|
||||
render.uniform_sets.resize(set->index + 1);
|
||||
render.uniform_sets.resize(p_set_index + 1);
|
||||
// Set intermediate values to null.
|
||||
std::fill(&render.uniform_sets[s], &render.uniform_sets[set->index] + 1, nullptr);
|
||||
std::fill(&render.uniform_sets[s], &render.uniform_sets[p_set_index] + 1, nullptr);
|
||||
}
|
||||
|
||||
if (render.uniform_sets[set->index] != set) {
|
||||
if (render.uniform_sets[p_set_index] != set) {
|
||||
render.dirty.set_flag(RenderState::DIRTY_UNIFORMS);
|
||||
render.uniform_set_mask |= 1ULL << set->index;
|
||||
render.uniform_sets[set->index] = set;
|
||||
render.uniform_set_mask |= 1ULL << p_set_index;
|
||||
render.uniform_sets[p_set_index] = set;
|
||||
}
|
||||
}
|
||||
|
||||
void MDCommandBuffer::render_bind_uniform_sets(VectorView<RDD::UniformSetID> p_uniform_sets, RDD::ShaderID p_shader, uint32_t p_first_set_index, uint32_t p_set_count) {
|
||||
DEV_ASSERT(type == MDCommandBufferStateType::Render);
|
||||
|
||||
for (size_t i = 0u; i < p_set_count; ++i) {
|
||||
for (size_t i = 0; i < p_set_count; ++i) {
|
||||
MDUniformSet *set = (MDUniformSet *)(p_uniform_sets[i].id);
|
||||
if (render.uniform_sets.size() <= set->index) {
|
||||
|
||||
uint32_t index = p_first_set_index + i;
|
||||
if (render.uniform_sets.size() <= index) {
|
||||
uint32_t s = render.uniform_sets.size();
|
||||
render.uniform_sets.resize(set->index + 1);
|
||||
render.uniform_sets.resize(index + 1);
|
||||
// Set intermediate values to null.
|
||||
std::fill(&render.uniform_sets[s], &render.uniform_sets[set->index] + 1, nullptr);
|
||||
std::fill(&render.uniform_sets[s], &render.uniform_sets[index] + 1, nullptr);
|
||||
}
|
||||
|
||||
if (render.uniform_sets[set->index] != set) {
|
||||
if (render.uniform_sets[index] != set) {
|
||||
render.dirty.set_flag(RenderState::DIRTY_UNIFORMS);
|
||||
render.uniform_set_mask |= 1ULL << set->index;
|
||||
render.uniform_sets[set->index] = set;
|
||||
render.uniform_set_mask |= 1ULL << index;
|
||||
render.uniform_sets[index] = set;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -474,14 +476,14 @@ void MDCommandBuffer::_render_bind_uniform_sets() {
|
|||
|
||||
while (set_uniforms != 0) {
|
||||
// Find the index of the next set bit.
|
||||
int index = __builtin_ctzll(set_uniforms);
|
||||
uint32_t index = (uint32_t)__builtin_ctzll(set_uniforms);
|
||||
// Clear the set bit.
|
||||
set_uniforms &= (set_uniforms - 1);
|
||||
MDUniformSet *set = render.uniform_sets[index];
|
||||
if (set == nullptr || set->index >= (uint32_t)shader->sets.size()) {
|
||||
if (set == nullptr || index >= (uint32_t)shader->sets.size()) {
|
||||
continue;
|
||||
}
|
||||
set->bind_uniforms(shader, render);
|
||||
set->bind_uniforms(shader, render, index);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -610,7 +612,7 @@ void MDCommandBuffer::_render_clear_render_area() {
|
|||
bool shouldClearStencil = (ds_index != RDD::AttachmentReference::UNUSED && pass.attachments[ds_index].shouldClear(subpass, true));
|
||||
if (shouldClearDepth || shouldClearStencil) {
|
||||
MDAttachment const &attachment = pass.attachments[ds_index];
|
||||
BitField<RDD::TextureAspectBits> bits;
|
||||
BitField<RDD::TextureAspectBits> bits = {};
|
||||
if (shouldClearDepth && attachment.type & MDAttachmentType::Depth) {
|
||||
bits.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT);
|
||||
}
|
||||
|
|
@ -955,7 +957,7 @@ void MDCommandBuffer::compute_bind_uniform_set(RDD::UniformSetID p_uniform_set,
|
|||
|
||||
MDShader *shader = (MDShader *)(p_shader.id);
|
||||
MDUniformSet *set = (MDUniformSet *)(p_uniform_set.id);
|
||||
set->bind_uniforms(shader, compute);
|
||||
set->bind_uniforms(shader, compute, p_set_index);
|
||||
}
|
||||
|
||||
void MDCommandBuffer::compute_bind_uniform_sets(VectorView<RDD::UniformSetID> p_uniform_sets, RDD::ShaderID p_shader, uint32_t p_first_set_index, uint32_t p_set_count) {
|
||||
|
|
@ -966,7 +968,7 @@ void MDCommandBuffer::compute_bind_uniform_sets(VectorView<RDD::UniformSetID> p_
|
|||
// TODO(sgc): Bind multiple buffers using [encoder setBuffers:offsets:withRange:]
|
||||
for (size_t i = 0u; i < p_set_count; ++i) {
|
||||
MDUniformSet *set = (MDUniformSet *)(p_uniform_sets[i].id);
|
||||
set->bind_uniforms(shader, compute);
|
||||
set->bind_uniforms(shader, compute, p_first_set_index + i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1052,50 +1054,50 @@ void MDRenderShader::encode_push_constant_data(VectorView<uint32_t> p_data, MDCo
|
|||
}
|
||||
}
|
||||
|
||||
void MDUniformSet::bind_uniforms_argument_buffers(MDShader *p_shader, MDCommandBuffer::RenderState &p_state) {
|
||||
void MDUniformSet::bind_uniforms_argument_buffers(MDShader *p_shader, MDCommandBuffer::RenderState &p_state, uint32_t p_set_index) {
|
||||
DEV_ASSERT(p_shader->uses_argument_buffers);
|
||||
DEV_ASSERT(p_state.encoder != nil);
|
||||
|
||||
UniformSet const &set_info = p_shader->sets[index];
|
||||
UniformSet const &set_info = p_shader->sets[p_set_index];
|
||||
|
||||
id<MTLRenderCommandEncoder> __unsafe_unretained enc = p_state.encoder;
|
||||
id<MTLDevice> __unsafe_unretained device = enc.device;
|
||||
|
||||
BoundUniformSet &bus = bound_uniform_set(p_shader, device, p_state.resource_usage);
|
||||
BoundUniformSet &bus = bound_uniform_set(p_shader, device, p_state.resource_usage, p_set_index);
|
||||
|
||||
// Set the buffer for the vertex stage.
|
||||
{
|
||||
uint32_t const *offset = set_info.offsets.getptr(RDD::SHADER_STAGE_VERTEX);
|
||||
if (offset) {
|
||||
[enc setVertexBuffer:bus.buffer offset:*offset atIndex:index];
|
||||
[enc setVertexBuffer:bus.buffer offset:*offset atIndex:p_set_index];
|
||||
}
|
||||
}
|
||||
// Set the buffer for the fragment stage.
|
||||
{
|
||||
uint32_t const *offset = set_info.offsets.getptr(RDD::SHADER_STAGE_FRAGMENT);
|
||||
if (offset) {
|
||||
[enc setFragmentBuffer:bus.buffer offset:*offset atIndex:index];
|
||||
[enc setFragmentBuffer:bus.buffer offset:*offset atIndex:p_set_index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MDUniformSet::bind_uniforms_direct(MDShader *p_shader, MDCommandBuffer::RenderState &p_state) {
|
||||
void MDUniformSet::bind_uniforms_direct(MDShader *p_shader, MDCommandBuffer::RenderState &p_state, uint32_t p_set_index) {
|
||||
DEV_ASSERT(!p_shader->uses_argument_buffers);
|
||||
DEV_ASSERT(p_state.encoder != nil);
|
||||
|
||||
id<MTLRenderCommandEncoder> __unsafe_unretained enc = p_state.encoder;
|
||||
|
||||
UniformSet const &set = p_shader->sets[index];
|
||||
UniformSet const &set = p_shader->sets[p_set_index];
|
||||
|
||||
for (uint32_t i = 0; i < MIN(uniforms.size(), set.uniforms.size()); i++) {
|
||||
RDD::BoundUniform const &uniform = uniforms[i];
|
||||
UniformInfo ui = set.uniforms[i];
|
||||
const UniformInfo &ui = set.uniforms[i];
|
||||
|
||||
static const RDC::ShaderStage stage_usages[2] = { RDC::ShaderStage::SHADER_STAGE_VERTEX, RDC::ShaderStage::SHADER_STAGE_FRAGMENT };
|
||||
for (const RDC::ShaderStage stage : stage_usages) {
|
||||
ShaderStageUsage const stage_usage = ShaderStageUsage(1 << stage);
|
||||
|
||||
BindingInfo *bi = ui.bindings.getptr(stage);
|
||||
const BindingInfo *bi = ui.bindings.getptr(stage);
|
||||
if (bi == nullptr) {
|
||||
// No binding for this stage.
|
||||
continue;
|
||||
|
|
@ -1129,7 +1131,7 @@ void MDUniformSet::bind_uniforms_direct(MDShader *p_shader, MDCommandBuffer::Ren
|
|||
samplers[j] = sampler;
|
||||
textures[j] = texture;
|
||||
}
|
||||
BindingInfo *sbi = ui.bindings_secondary.getptr(stage);
|
||||
const BindingInfo *sbi = ui.bindings_secondary.getptr(stage);
|
||||
if (sbi) {
|
||||
if (stage == RDD::SHADER_STAGE_VERTEX) {
|
||||
[enc setVertexSamplerStates:samplers withRange:NSMakeRange(sbi->index, count)];
|
||||
|
|
@ -1175,7 +1177,7 @@ void MDUniformSet::bind_uniforms_direct(MDShader *p_shader, MDCommandBuffer::Ren
|
|||
[enc setFragmentTexture:obj atIndex:bi->index];
|
||||
}
|
||||
|
||||
BindingInfo *sbi = ui.bindings_secondary.getptr(stage);
|
||||
const BindingInfo *sbi = ui.bindings_secondary.getptr(stage);
|
||||
if (sbi) {
|
||||
id<MTLTexture> tex = obj.parentTexture ? obj.parentTexture : obj;
|
||||
id<MTLBuffer> buf = tex.buffer;
|
||||
|
|
@ -1256,47 +1258,47 @@ void MDUniformSet::bind_uniforms_direct(MDShader *p_shader, MDCommandBuffer::Ren
|
|||
}
|
||||
}
|
||||
|
||||
void MDUniformSet::bind_uniforms(MDShader *p_shader, MDCommandBuffer::RenderState &p_state) {
|
||||
void MDUniformSet::bind_uniforms(MDShader *p_shader, MDCommandBuffer::RenderState &p_state, uint32_t p_set_index) {
|
||||
if (p_shader->uses_argument_buffers) {
|
||||
bind_uniforms_argument_buffers(p_shader, p_state);
|
||||
bind_uniforms_argument_buffers(p_shader, p_state, p_set_index);
|
||||
} else {
|
||||
bind_uniforms_direct(p_shader, p_state);
|
||||
bind_uniforms_direct(p_shader, p_state, p_set_index);
|
||||
}
|
||||
}
|
||||
|
||||
void MDUniformSet::bind_uniforms_argument_buffers(MDShader *p_shader, MDCommandBuffer::ComputeState &p_state) {
|
||||
void MDUniformSet::bind_uniforms_argument_buffers(MDShader *p_shader, MDCommandBuffer::ComputeState &p_state, uint32_t p_set_index) {
|
||||
DEV_ASSERT(p_shader->uses_argument_buffers);
|
||||
DEV_ASSERT(p_state.encoder != nil);
|
||||
|
||||
UniformSet const &set_info = p_shader->sets[index];
|
||||
UniformSet const &set_info = p_shader->sets[p_set_index];
|
||||
|
||||
id<MTLComputeCommandEncoder> enc = p_state.encoder;
|
||||
id<MTLDevice> device = enc.device;
|
||||
|
||||
BoundUniformSet &bus = bound_uniform_set(p_shader, device, p_state.resource_usage);
|
||||
BoundUniformSet &bus = bound_uniform_set(p_shader, device, p_state.resource_usage, p_set_index);
|
||||
|
||||
uint32_t const *offset = set_info.offsets.getptr(RDD::SHADER_STAGE_COMPUTE);
|
||||
if (offset) {
|
||||
[enc setBuffer:bus.buffer offset:*offset atIndex:index];
|
||||
[enc setBuffer:bus.buffer offset:*offset atIndex:p_set_index];
|
||||
}
|
||||
}
|
||||
|
||||
void MDUniformSet::bind_uniforms_direct(MDShader *p_shader, MDCommandBuffer::ComputeState &p_state) {
|
||||
void MDUniformSet::bind_uniforms_direct(MDShader *p_shader, MDCommandBuffer::ComputeState &p_state, uint32_t p_set_index) {
|
||||
DEV_ASSERT(!p_shader->uses_argument_buffers);
|
||||
DEV_ASSERT(p_state.encoder != nil);
|
||||
|
||||
id<MTLComputeCommandEncoder> __unsafe_unretained enc = p_state.encoder;
|
||||
|
||||
UniformSet const &set = p_shader->sets[index];
|
||||
UniformSet const &set = p_shader->sets[p_set_index];
|
||||
|
||||
for (uint32_t i = 0; i < uniforms.size(); i++) {
|
||||
RDD::BoundUniform const &uniform = uniforms[i];
|
||||
UniformInfo ui = set.uniforms[i];
|
||||
const UniformInfo &ui = set.uniforms[i];
|
||||
|
||||
const RDC::ShaderStage stage = RDC::ShaderStage::SHADER_STAGE_COMPUTE;
|
||||
const ShaderStageUsage stage_usage = ShaderStageUsage(1 << stage);
|
||||
|
||||
BindingInfo *bi = ui.bindings.getptr(stage);
|
||||
const BindingInfo *bi = ui.bindings.getptr(stage);
|
||||
if (bi == nullptr) {
|
||||
// No binding for this stage.
|
||||
continue;
|
||||
|
|
@ -1326,7 +1328,7 @@ void MDUniformSet::bind_uniforms_direct(MDShader *p_shader, MDCommandBuffer::Com
|
|||
samplers[j] = sampler;
|
||||
textures[j] = texture;
|
||||
}
|
||||
BindingInfo *sbi = ui.bindings_secondary.getptr(stage);
|
||||
const BindingInfo *sbi = ui.bindings_secondary.getptr(stage);
|
||||
if (sbi) {
|
||||
[enc setSamplerStates:samplers withRange:NSMakeRange(sbi->index, count)];
|
||||
}
|
||||
|
|
@ -1352,7 +1354,7 @@ void MDUniformSet::bind_uniforms_direct(MDShader *p_shader, MDCommandBuffer::Com
|
|||
id<MTLTexture> obj = rid::get(uniform.ids[0]);
|
||||
[enc setTexture:obj atIndex:bi->index];
|
||||
|
||||
BindingInfo *sbi = ui.bindings_secondary.getptr(stage);
|
||||
const BindingInfo *sbi = ui.bindings_secondary.getptr(stage);
|
||||
if (sbi) {
|
||||
id<MTLTexture> tex = obj.parentTexture ? obj.parentTexture : obj;
|
||||
id<MTLBuffer> buf = tex.buffer;
|
||||
|
|
@ -1407,22 +1409,22 @@ void MDUniformSet::bind_uniforms_direct(MDShader *p_shader, MDCommandBuffer::Com
|
|||
}
|
||||
}
|
||||
|
||||
void MDUniformSet::bind_uniforms(MDShader *p_shader, MDCommandBuffer::ComputeState &p_state) {
|
||||
void MDUniformSet::bind_uniforms(MDShader *p_shader, MDCommandBuffer::ComputeState &p_state, uint32_t p_set_index) {
|
||||
if (p_shader->uses_argument_buffers) {
|
||||
bind_uniforms_argument_buffers(p_shader, p_state);
|
||||
bind_uniforms_argument_buffers(p_shader, p_state, p_set_index);
|
||||
} else {
|
||||
bind_uniforms_direct(p_shader, p_state);
|
||||
bind_uniforms_direct(p_shader, p_state, p_set_index);
|
||||
}
|
||||
}
|
||||
|
||||
BoundUniformSet &MDUniformSet::bound_uniform_set(MDShader *p_shader, id<MTLDevice> p_device, ResourceUsageMap &p_resource_usage) {
|
||||
BoundUniformSet &MDUniformSet::bound_uniform_set(MDShader *p_shader, id<MTLDevice> p_device, ResourceUsageMap &p_resource_usage, uint32_t p_set_index) {
|
||||
BoundUniformSet *sus = bound_uniforms.getptr(p_shader);
|
||||
if (sus != nullptr) {
|
||||
sus->merge_into(p_resource_usage);
|
||||
return *sus;
|
||||
}
|
||||
|
||||
UniformSet const &set = p_shader->sets[index];
|
||||
UniformSet const &set = p_shader->sets[p_set_index];
|
||||
|
||||
HashMap<id<MTLResource>, StageResourceUsage> bound_resources;
|
||||
auto add_usage = [&bound_resources](id<MTLResource> __unsafe_unretained res, RDD::ShaderStage stage, MTLResourceUsage usage) {
|
||||
|
|
|
|||
|
|
@ -28,11 +28,12 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef METAL_UTILS_H
|
||||
#define METAL_UTILS_H
|
||||
#pragma once
|
||||
|
||||
#import <os/log.h>
|
||||
|
||||
#import <functional>
|
||||
|
||||
#pragma mark - Boolean flags
|
||||
|
||||
namespace flags {
|
||||
|
|
@ -101,5 +102,3 @@ private:
|
|||
extern os_log_t LOG_DRIVER;
|
||||
// Used for dynamic tracing.
|
||||
extern os_log_t LOG_INTERVALS;
|
||||
|
||||
#endif // METAL_UTILS_H
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Portions of this code were derived from MoltenVK. */
|
||||
|
|
@ -48,16 +50,14 @@
|
|||
/* permissions and limitations under the License. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef PIXEL_FORMATS_H
|
||||
#define PIXEL_FORMATS_H
|
||||
#include "core/typedefs.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wdeprecated-declarations")
|
||||
|
||||
#import "inflection_map.h"
|
||||
#import "metal_device_properties.h"
|
||||
|
||||
#import "servers/rendering/rendering_device.h"
|
||||
#include "servers/rendering/rendering_device.h"
|
||||
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
|
|
@ -408,6 +408,4 @@ protected:
|
|||
TightLocalVector<MTLFormatDesc> _mtl_vertex_format_descs;
|
||||
};
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
#endif // PIXEL_FORMATS_H
|
||||
GODOT_CLANG_WARNING_POP
|
||||
|
|
|
|||
|
|
@ -450,8 +450,7 @@ void PixelFormats::initDataFormatCapabilities() {
|
|||
|
||||
addDataFormatDesc(X8_D24_UNORM_PACK32, Invalid, Depth24Unorm_Stencil8, Invalid, Invalid, 1, 1, 4, DepthStencil);
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability"
|
||||
GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wunguarded-availability")
|
||||
|
||||
addDataFormatDesc(BC1_RGB_UNORM_BLOCK, BC1_RGBA, Invalid, Invalid, Invalid, 4, 4, 8, Compressed);
|
||||
addDataFormatDesc(BC1_RGB_SRGB_BLOCK, BC1_RGBA_sRGB, Invalid, Invalid, Invalid, 4, 4, 8, Compressed);
|
||||
|
|
@ -476,7 +475,7 @@ void PixelFormats::initDataFormatCapabilities() {
|
|||
addDataFormatDesc(BC7_UNORM_BLOCK, BC7_RGBAUnorm, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
|
||||
addDataFormatDesc(BC7_SRGB_BLOCK, BC7_RGBAUnorm_sRGB, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
GODOT_CLANG_WARNING_POP
|
||||
|
||||
addDataFormatDesc(ETC2_R8G8B8_UNORM_BLOCK, ETC2_RGB8, Invalid, Invalid, Invalid, 4, 4, 8, Compressed);
|
||||
addDataFormatDesc(ETC2_R8G8B8_SRGB_BLOCK, ETC2_RGB8_sRGB, Invalid, Invalid, Invalid, 4, 4, 8, Compressed);
|
||||
|
|
@ -493,32 +492,46 @@ void PixelFormats::initDataFormatCapabilities() {
|
|||
addDataFormatDesc(EAC_R11G11_SNORM_BLOCK, EAC_RG11Snorm, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
|
||||
|
||||
addDataFormatDesc(ASTC_4x4_UNORM_BLOCK, ASTC_4x4_LDR, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_4x4_SFLOAT_BLOCK, ASTC_4x4_HDR, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_4x4_SRGB_BLOCK, ASTC_4x4_sRGB, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_5x4_UNORM_BLOCK, ASTC_5x4_LDR, Invalid, Invalid, Invalid, 5, 4, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_5x4_SFLOAT_BLOCK, ASTC_5x4_HDR, Invalid, Invalid, Invalid, 5, 4, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_5x4_SRGB_BLOCK, ASTC_5x4_sRGB, Invalid, Invalid, Invalid, 5, 4, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_5x5_UNORM_BLOCK, ASTC_5x5_LDR, Invalid, Invalid, Invalid, 5, 5, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_5x5_SFLOAT_BLOCK, ASTC_5x5_HDR, Invalid, Invalid, Invalid, 5, 5, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_5x5_SRGB_BLOCK, ASTC_5x5_sRGB, Invalid, Invalid, Invalid, 5, 5, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_6x5_UNORM_BLOCK, ASTC_6x5_LDR, Invalid, Invalid, Invalid, 6, 5, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_6x5_SFLOAT_BLOCK, ASTC_6x5_HDR, Invalid, Invalid, Invalid, 6, 5, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_6x5_SRGB_BLOCK, ASTC_6x5_sRGB, Invalid, Invalid, Invalid, 6, 5, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_6x6_UNORM_BLOCK, ASTC_6x6_LDR, Invalid, Invalid, Invalid, 6, 6, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_6x6_SFLOAT_BLOCK, ASTC_6x6_HDR, Invalid, Invalid, Invalid, 6, 6, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_6x6_SRGB_BLOCK, ASTC_6x6_sRGB, Invalid, Invalid, Invalid, 6, 6, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_8x5_UNORM_BLOCK, ASTC_8x5_LDR, Invalid, Invalid, Invalid, 8, 5, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_8x5_SFLOAT_BLOCK, ASTC_8x5_HDR, Invalid, Invalid, Invalid, 8, 5, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_8x5_SRGB_BLOCK, ASTC_8x5_sRGB, Invalid, Invalid, Invalid, 8, 5, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_8x6_UNORM_BLOCK, ASTC_8x6_LDR, Invalid, Invalid, Invalid, 8, 6, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_8x6_SFLOAT_BLOCK, ASTC_8x6_HDR, Invalid, Invalid, Invalid, 8, 6, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_8x6_SRGB_BLOCK, ASTC_8x6_sRGB, Invalid, Invalid, Invalid, 8, 6, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_8x8_UNORM_BLOCK, ASTC_8x8_LDR, Invalid, Invalid, Invalid, 8, 8, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_8x8_SFLOAT_BLOCK, ASTC_8x8_HDR, Invalid, Invalid, Invalid, 8, 8, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_8x8_SRGB_BLOCK, ASTC_8x8_sRGB, Invalid, Invalid, Invalid, 8, 8, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_10x5_UNORM_BLOCK, ASTC_10x5_LDR, Invalid, Invalid, Invalid, 10, 5, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_10x5_SFLOAT_BLOCK, ASTC_10x5_HDR, Invalid, Invalid, Invalid, 10, 5, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_10x5_SRGB_BLOCK, ASTC_10x5_sRGB, Invalid, Invalid, Invalid, 10, 5, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_10x6_UNORM_BLOCK, ASTC_10x6_LDR, Invalid, Invalid, Invalid, 10, 6, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_10x6_SFLOAT_BLOCK, ASTC_10x6_HDR, Invalid, Invalid, Invalid, 10, 6, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_10x6_SRGB_BLOCK, ASTC_10x6_sRGB, Invalid, Invalid, Invalid, 10, 6, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_10x8_UNORM_BLOCK, ASTC_10x8_LDR, Invalid, Invalid, Invalid, 10, 8, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_10x8_SFLOAT_BLOCK, ASTC_10x8_HDR, Invalid, Invalid, Invalid, 10, 8, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_10x8_SRGB_BLOCK, ASTC_10x8_sRGB, Invalid, Invalid, Invalid, 10, 8, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_10x10_UNORM_BLOCK, ASTC_10x10_LDR, Invalid, Invalid, Invalid, 10, 10, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_10x10_SFLOAT_BLOCK, ASTC_10x10_HDR, Invalid, Invalid, Invalid, 10, 10, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_10x10_SRGB_BLOCK, ASTC_10x10_sRGB, Invalid, Invalid, Invalid, 10, 10, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_12x10_UNORM_BLOCK, ASTC_12x10_LDR, Invalid, Invalid, Invalid, 12, 10, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_12x10_SFLOAT_BLOCK, ASTC_12x10_HDR, Invalid, Invalid, Invalid, 12, 10, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_12x10_SRGB_BLOCK, ASTC_12x10_sRGB, Invalid, Invalid, Invalid, 12, 10, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_12x12_UNORM_BLOCK, ASTC_12x12_LDR, Invalid, Invalid, Invalid, 12, 12, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_12x12_SFLOAT_BLOCK, ASTC_12x12_HDR, Invalid, Invalid, Invalid, 12, 12, 16, Compressed);
|
||||
addDataFormatDesc(ASTC_12x12_SRGB_BLOCK, ASTC_12x12_sRGB, Invalid, Invalid, Invalid, 12, 12, 16, Compressed);
|
||||
|
||||
addDfFormatDescChromaSubsampling(G8B8G8R8_422_UNORM, GBGR422, 1, 8, 2, 1, 4);
|
||||
|
|
@ -715,8 +728,7 @@ void PixelFormats::initMTLPixelFormatCapabilities() {
|
|||
addMTLPixelFormatDescSRGB(ASTC_12x12_sRGB, ASTC_12x12, RF, ASTC_12x12_LDR);
|
||||
addMTLPixelFormatDesc(ASTC_12x12_HDR, ASTC_12x12, RF);
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability"
|
||||
GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wunguarded-availability")
|
||||
|
||||
addMTLPixelFormatDesc(BC1_RGBA, BC1_RGBA, RF);
|
||||
addMTLPixelFormatDescSRGB(BC1_RGBA_sRGB, BC1_RGBA, RF, BC1_RGBA);
|
||||
|
|
@ -733,7 +745,7 @@ void PixelFormats::initMTLPixelFormatCapabilities() {
|
|||
addMTLPixelFormatDesc(BC7_RGBAUnorm, BC7_RGBA, RF);
|
||||
addMTLPixelFormatDescSRGB(BC7_RGBAUnorm_sRGB, BC7_RGBA, RF, BC7_RGBAUnorm);
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
GODOT_CLANG_WARNING_POP
|
||||
|
||||
// YUV pixel formats
|
||||
addMTLPixelFormatDesc(GBGR422, None, RF);
|
||||
|
|
@ -954,8 +966,7 @@ void PixelFormats::modifyMTLFormatCapabilities(const MetalFeatures &p_feat) {
|
|||
setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_12x10_HDR, None);
|
||||
setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_12x12_HDR, None);
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability"
|
||||
GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wunguarded-availability")
|
||||
|
||||
bool noBC = !p_feat.supportsBCTextureCompression;
|
||||
setMTLPixFmtCapsIf(noBC, BC1_RGBA, None);
|
||||
|
|
@ -973,7 +984,7 @@ void PixelFormats::modifyMTLFormatCapabilities(const MetalFeatures &p_feat) {
|
|||
setMTLPixFmtCapsIf(noBC, BC7_RGBAUnorm, None);
|
||||
setMTLPixFmtCapsIf(noBC, BC7_RGBAUnorm_sRGB, None);
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
GODOT_CLANG_WARNING_POP
|
||||
|
||||
setMTLPixFmtCapsIf(iosOnly2, BGRA10_XR, None);
|
||||
setMTLPixFmtCapsIf(iosOnly2, BGRA10_XR_sRGB, None);
|
||||
|
|
|
|||
|
|
@ -28,13 +28,12 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RENDERING_CONTEXT_DRIVER_METAL_H
|
||||
#define RENDERING_CONTEXT_DRIVER_METAL_H
|
||||
#pragma once
|
||||
|
||||
#ifdef METAL_ENABLED
|
||||
|
||||
#import "servers/rendering/rendering_context_driver.h"
|
||||
#import "servers/rendering/rendering_device_driver.h"
|
||||
#include "servers/rendering/rendering_context_driver.h"
|
||||
#include "servers/rendering/rendering_device_driver.h"
|
||||
|
||||
#import <CoreGraphics/CGGeometry.h>
|
||||
|
||||
|
|
@ -143,5 +142,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // METAL_ENABLED
|
||||
|
||||
#endif // RENDERING_CONTEXT_DRIVER_METAL_H
|
||||
|
|
|
|||
|
|
@ -28,12 +28,11 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RENDERING_DEVICE_DRIVER_METAL_H
|
||||
#define RENDERING_DEVICE_DRIVER_METAL_H
|
||||
#pragma once
|
||||
|
||||
#import "metal_objects.h"
|
||||
|
||||
#import "servers/rendering/rendering_device_driver.h"
|
||||
#include "servers/rendering/rendering_device_driver.h"
|
||||
|
||||
#import <Metal/Metal.h>
|
||||
#import <variant>
|
||||
|
|
@ -66,6 +65,8 @@ class API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) RenderingDeviceDriverMet
|
|||
|
||||
RDD::Capabilities capabilities;
|
||||
RDD::MultiviewCapabilities multiview_capabilities;
|
||||
RDD::FragmentShadingRateCapabilities fsr_capabilities;
|
||||
RDD::FragmentDensityMapCapabilities fdm_capabilities;
|
||||
|
||||
id<MTLBinaryArchive> archive = nil;
|
||||
uint32_t archive_count = 0;
|
||||
|
|
@ -316,7 +317,7 @@ public:
|
|||
|
||||
// ----- SUBPASS -----
|
||||
|
||||
virtual RenderPassID render_pass_create(VectorView<Attachment> p_attachments, VectorView<Subpass> p_subpasses, VectorView<SubpassDependency> p_subpass_dependencies, uint32_t p_view_count) override final;
|
||||
virtual RenderPassID render_pass_create(VectorView<Attachment> p_attachments, VectorView<Subpass> p_subpasses, VectorView<SubpassDependency> p_subpass_dependencies, uint32_t p_view_count, AttachmentReference p_fragment_density_map_attachment) override final;
|
||||
virtual void render_pass_free(RenderPassID p_render_pass) override final;
|
||||
|
||||
// ----- COMMANDS -----
|
||||
|
|
@ -421,6 +422,8 @@ public:
|
|||
virtual uint64_t api_trait_get(ApiTrait p_trait) override final;
|
||||
virtual bool has_feature(Features p_feature) override final;
|
||||
virtual const MultiviewCapabilities &get_multiview_capabilities() override final;
|
||||
virtual const FragmentShadingRateCapabilities &get_fragment_shading_rate_capabilities() override final;
|
||||
virtual const FragmentDensityMapCapabilities &get_fragment_density_map_capabilities() override final;
|
||||
virtual String get_api_name() const override final { return "Metal"; }
|
||||
virtual String get_api_version() const override final;
|
||||
virtual String get_pipeline_cache_uuid() const override final;
|
||||
|
|
@ -444,5 +447,3 @@ public:
|
|||
RenderingDeviceDriverMetal(RenderingContextDriverMetal *p_context_driver);
|
||||
~RenderingDeviceDriverMetal();
|
||||
};
|
||||
|
||||
#endif // RENDERING_DEVICE_DRIVER_METAL_H
|
||||
|
|
|
|||
|
|
@ -53,10 +53,10 @@
|
|||
#import "pixel_formats.h"
|
||||
#import "rendering_context_driver_metal.h"
|
||||
|
||||
#import "core/io/compression.h"
|
||||
#import "core/io/marshalls.h"
|
||||
#import "core/string/ustring.h"
|
||||
#import "core/templates/hash_map.h"
|
||||
#include "core/io/compression.h"
|
||||
#include "core/io/marshalls.h"
|
||||
#include "core/string/ustring.h"
|
||||
#include "core/templates/hash_map.h"
|
||||
|
||||
#import <Metal/MTLTexture.h>
|
||||
#import <Metal/Metal.h>
|
||||
|
|
@ -405,6 +405,15 @@ RDD::TextureID RenderingDeviceDriverMetal::texture_create_from_extension(uint64_
|
|||
RDD::TextureID RenderingDeviceDriverMetal::texture_create_shared(TextureID p_original_texture, const TextureView &p_view) {
|
||||
id<MTLTexture> src_texture = rid::get(p_original_texture);
|
||||
|
||||
NSUInteger slices = src_texture.arrayLength;
|
||||
if (src_texture.textureType == MTLTextureTypeCube) {
|
||||
// Metal expects Cube textures to have a slice count of 6.
|
||||
slices = 6;
|
||||
} else if (src_texture.textureType == MTLTextureTypeCubeArray) {
|
||||
// Metal expects Cube Array textures to have 6 slices per layer.
|
||||
slices *= 6;
|
||||
}
|
||||
|
||||
#if DEV_ENABLED
|
||||
if (src_texture.sampleCount > 1) {
|
||||
// TODO(sgc): is it ok to create a shared texture from a multi-sample texture?
|
||||
|
|
@ -434,7 +443,7 @@ RDD::TextureID RenderingDeviceDriverMetal::texture_create_shared(TextureID p_ori
|
|||
id<MTLTexture> obj = [src_texture newTextureViewWithPixelFormat:format
|
||||
textureType:src_texture.textureType
|
||||
levels:NSMakeRange(0, src_texture.mipmapLevelCount)
|
||||
slices:NSMakeRange(0, src_texture.arrayLength)
|
||||
slices:NSMakeRange(0, slices)
|
||||
swizzle:swizzle];
|
||||
ERR_FAIL_NULL_V_MSG(obj, TextureID(), "Unable to create shared texture");
|
||||
return rid::make(obj);
|
||||
|
|
@ -566,7 +575,14 @@ void RenderingDeviceDriverMetal::texture_get_copyable_layout(TextureID p_texture
|
|||
r_layout->size = get_image_format_required_size(format, sz.width, sz.height, sz.depth, 1, &sbw, &sbh);
|
||||
r_layout->row_pitch = r_layout->size / ((sbh / bh) * sz.depth);
|
||||
r_layout->depth_pitch = r_layout->size / sz.depth;
|
||||
r_layout->layer_pitch = r_layout->size / obj.arrayLength;
|
||||
|
||||
uint32_t array_length = obj.arrayLength;
|
||||
if (obj.textureType == MTLTextureTypeCube) {
|
||||
array_length = 6;
|
||||
} else if (obj.textureType == MTLTextureTypeCubeArray) {
|
||||
array_length *= 6;
|
||||
}
|
||||
r_layout->layer_pitch = r_layout->size / array_length;
|
||||
} else {
|
||||
CRASH_NOW_MSG("need to calculate layout for shared texture");
|
||||
}
|
||||
|
|
@ -974,7 +990,7 @@ RDD::SwapChainID RenderingDeviceDriverMetal::swap_chain_create(RenderingContextD
|
|||
color_ref.aspect.set_flag(RDD::TEXTURE_ASPECT_COLOR_BIT);
|
||||
subpass.color_references.push_back(color_ref);
|
||||
|
||||
RenderPassID render_pass = render_pass_create(attachment, subpass, {}, 1);
|
||||
RenderPassID render_pass = render_pass_create(attachment, subpass, {}, 1, RDD::AttachmentReference());
|
||||
ERR_FAIL_COND_V(!render_pass, SwapChainID());
|
||||
|
||||
// Create the empty swap chain until it is resized.
|
||||
|
|
@ -2460,6 +2476,8 @@ RDD::ShaderID RenderingDeviceDriverMetal::shader_create_from_bytecode(const Vect
|
|||
HashMap<ShaderStage, MDLibrary *> libraries;
|
||||
|
||||
for (ShaderStageData &shader_data : binary_data.stages) {
|
||||
r_shader_desc.stages.push_back(shader_data.stage);
|
||||
|
||||
SHA256Digest key = SHA256Digest(shader_data.source.ptr(), shader_data.source.length());
|
||||
|
||||
if (ShaderCacheEntry **p = _shader_cache.getptr(key); p != nullptr) {
|
||||
|
|
@ -2506,7 +2524,7 @@ RDD::ShaderID RenderingDeviceDriverMetal::shader_create_from_bytecode(const Vect
|
|||
su.writable = uniform.writable;
|
||||
su.length = uniform.length;
|
||||
su.binding = uniform.binding;
|
||||
su.stages = uniform.stages;
|
||||
su.stages = (ShaderStage)(uint8_t)uniform.stages;
|
||||
uset.write[i] = su;
|
||||
|
||||
UniformInfo ui;
|
||||
|
|
@ -2572,7 +2590,7 @@ RDD::ShaderID RenderingDeviceDriverMetal::shader_create_from_bytecode(const Vect
|
|||
sc.type = c.type;
|
||||
sc.constant_id = c.constant_id;
|
||||
sc.int_value = c.int_value;
|
||||
sc.stages = c.stages;
|
||||
sc.stages = (ShaderStage)(uint8_t)c.stages;
|
||||
r_shader_desc.specialization_constants.write[i] = sc;
|
||||
}
|
||||
|
||||
|
|
@ -3044,7 +3062,7 @@ void RenderingDeviceDriverMetal::command_bind_push_constants(CommandBufferID p_c
|
|||
|
||||
String RenderingDeviceDriverMetal::_pipeline_get_cache_path() const {
|
||||
String path = OS::get_singleton()->get_user_data_dir() + "/metal/pipelines";
|
||||
path += "." + context_device.name.validate_filename().replace(" ", "_").to_lower();
|
||||
path += "." + context_device.name.validate_filename().replace_char(' ', '_').to_lower();
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
path += ".editor";
|
||||
}
|
||||
|
|
@ -3102,7 +3120,7 @@ Vector<uint8_t> RenderingDeviceDriverMetal::pipeline_cache_serialize() {
|
|||
|
||||
// ----- SUBPASS -----
|
||||
|
||||
RDD::RenderPassID RenderingDeviceDriverMetal::render_pass_create(VectorView<Attachment> p_attachments, VectorView<Subpass> p_subpasses, VectorView<SubpassDependency> p_subpass_dependencies, uint32_t p_view_count) {
|
||||
RDD::RenderPassID RenderingDeviceDriverMetal::render_pass_create(VectorView<Attachment> p_attachments, VectorView<Subpass> p_subpasses, VectorView<SubpassDependency> p_subpass_dependencies, uint32_t p_view_count, AttachmentReference p_fragment_density_map_attachment) {
|
||||
PixelFormats &pf = *pixel_formats;
|
||||
|
||||
size_t subpass_count = p_subpasses.size();
|
||||
|
|
@ -3899,16 +3917,16 @@ uint64_t RenderingDeviceDriverMetal::get_lazily_memory_used() {
|
|||
uint64_t RenderingDeviceDriverMetal::limit_get(Limit p_limit) {
|
||||
MetalDeviceProperties const &props = (*device_properties);
|
||||
MetalLimits const &limits = props.limits;
|
||||
|
||||
uint64_t safe_unbounded = ((uint64_t)1 << 30);
|
||||
#if defined(DEV_ENABLED)
|
||||
#define UNKNOWN(NAME) \
|
||||
case NAME: \
|
||||
WARN_PRINT_ONCE("Returning maximum value for unknown limit " #NAME "."); \
|
||||
return (uint64_t)1 << 30;
|
||||
return safe_unbounded;
|
||||
#else
|
||||
#define UNKNOWN(NAME) \
|
||||
case NAME: \
|
||||
return (uint64_t)1 << 30
|
||||
return safe_unbounded
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
|
|
@ -3981,6 +3999,8 @@ uint64_t RenderingDeviceDriverMetal::limit_get(Limit p_limit) {
|
|||
return limits.maxThreadsPerThreadGroup.height;
|
||||
case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z:
|
||||
return limits.maxThreadsPerThreadGroup.depth;
|
||||
case LIMIT_MAX_COMPUTE_SHARED_MEMORY_SIZE:
|
||||
return limits.maxThreadGroupMemoryAllocation;
|
||||
case LIMIT_MAX_VIEWPORT_DIMENSIONS_X:
|
||||
return limits.maxViewportDimensionX;
|
||||
case LIMIT_MAX_VIEWPORT_DIMENSIONS_Y:
|
||||
|
|
@ -4002,12 +4022,12 @@ uint64_t RenderingDeviceDriverMetal::limit_get(Limit p_limit) {
|
|||
return (uint64_t)((1.0 / limits.temporalScalerInputContentMinScale) * 1000'000);
|
||||
case LIMIT_MAX_SHADER_VARYINGS:
|
||||
return limits.maxShaderVaryings;
|
||||
UNKNOWN(LIMIT_VRS_TEXEL_WIDTH);
|
||||
UNKNOWN(LIMIT_VRS_TEXEL_HEIGHT);
|
||||
UNKNOWN(LIMIT_VRS_MAX_FRAGMENT_WIDTH);
|
||||
UNKNOWN(LIMIT_VRS_MAX_FRAGMENT_HEIGHT);
|
||||
default:
|
||||
ERR_FAIL_V(0);
|
||||
default: {
|
||||
#ifdef DEV_ENABLED
|
||||
WARN_PRINT("Returning maximum value for unknown limit " + itos(p_limit) + ".");
|
||||
#endif
|
||||
return safe_unbounded;
|
||||
}
|
||||
}
|
||||
// clang-format on
|
||||
return 0;
|
||||
|
|
@ -4024,17 +4044,8 @@ uint64_t RenderingDeviceDriverMetal::api_trait_get(ApiTrait p_trait) {
|
|||
|
||||
bool RenderingDeviceDriverMetal::has_feature(Features p_feature) {
|
||||
switch (p_feature) {
|
||||
case SUPPORTS_MULTIVIEW:
|
||||
return multiview_capabilities.is_supported;
|
||||
case SUPPORTS_FSR_HALF_FLOAT:
|
||||
return true;
|
||||
case SUPPORTS_ATTACHMENT_VRS:
|
||||
// TODO(sgc): Maybe supported via https://developer.apple.com/documentation/metal/render_passes/rendering_at_different_rasterization_rates?language=objc
|
||||
// See also:
|
||||
//
|
||||
// * https://forum.beyond3d.com/threads/variable-rate-shading-vs-variable-rate-rasterization.62243/post-2191363
|
||||
//
|
||||
return false;
|
||||
case SUPPORTS_FRAGMENT_SHADER_WITH_ONLY_SIDE_EFFECTS:
|
||||
return true;
|
||||
case SUPPORTS_BUFFER_DEVICE_ADDRESS:
|
||||
|
|
@ -4052,6 +4063,14 @@ const RDD::MultiviewCapabilities &RenderingDeviceDriverMetal::get_multiview_capa
|
|||
return multiview_capabilities;
|
||||
}
|
||||
|
||||
const RDD::FragmentShadingRateCapabilities &RenderingDeviceDriverMetal::get_fragment_shading_rate_capabilities() {
|
||||
return fsr_capabilities;
|
||||
}
|
||||
|
||||
const RDD::FragmentDensityMapCapabilities &RenderingDeviceDriverMetal::get_fragment_density_map_capabilities() {
|
||||
return fdm_capabilities;
|
||||
}
|
||||
|
||||
String RenderingDeviceDriverMetal::get_api_version() const {
|
||||
return vformat("%d.%d", version_major, version_minor);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@ if env["builtin_libpng"]:
|
|||
]
|
||||
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
|
||||
|
||||
env_png.Prepend(CPPPATH=[thirdparty_dir])
|
||||
env_png.Prepend(CPPEXTPATH=[thirdparty_dir])
|
||||
# Needed for drivers includes and in platform/web.
|
||||
env.Prepend(CPPPATH=[thirdparty_dir])
|
||||
env.Prepend(CPPEXTPATH=[thirdparty_dir])
|
||||
|
||||
env_thirdparty = env_png.Clone()
|
||||
env_thirdparty.disable_warnings()
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef IMAGE_LOADER_PNG_H
|
||||
#define IMAGE_LOADER_PNG_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/image_loader.h"
|
||||
|
||||
|
|
@ -45,5 +44,3 @@ public:
|
|||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
ImageLoaderPNG();
|
||||
};
|
||||
|
||||
#endif // IMAGE_LOADER_PNG_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef PNG_DRIVER_COMMON_H
|
||||
#define PNG_DRIVER_COMMON_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/image.h"
|
||||
|
||||
|
|
@ -42,5 +41,3 @@ Error png_to_image(const uint8_t *p_source, size_t p_size, bool p_force_linear,
|
|||
// Contents of p_buffer is unspecified if error returned.
|
||||
Error image_to_png(const Ref<Image> &p_image, Vector<uint8_t> &p_buffer);
|
||||
} // namespace PNGDriverCommon
|
||||
|
||||
#endif // PNG_DRIVER_COMMON_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RESOURCE_SAVER_PNG_H
|
||||
#define RESOURCE_SAVER_PNG_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/image.h"
|
||||
#include "core/io/resource_saver.h"
|
||||
|
|
@ -45,5 +44,3 @@ public:
|
|||
|
||||
ResourceSaverPNG();
|
||||
};
|
||||
|
||||
#endif // RESOURCE_SAVER_PNG_H
|
||||
|
|
|
|||
|
|
@ -312,11 +312,11 @@ Error AudioDriverPulseAudio::init() {
|
|||
|
||||
String context_name;
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
context_name = VERSION_NAME " Editor";
|
||||
context_name = GODOT_VERSION_NAME " Editor";
|
||||
} else {
|
||||
context_name = GLOBAL_GET("application/config/name");
|
||||
if (context_name.is_empty()) {
|
||||
context_name = VERSION_NAME " Project";
|
||||
context_name = GODOT_VERSION_NAME " Project";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef AUDIO_DRIVER_PULSEAUDIO_H
|
||||
#define AUDIO_DRIVER_PULSEAUDIO_H
|
||||
#pragma once
|
||||
|
||||
#ifdef PULSEAUDIO_ENABLED
|
||||
|
||||
|
|
@ -128,5 +127,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // PULSEAUDIO_ENABLED
|
||||
|
||||
#endif // AUDIO_DRIVER_PULSEAUDIO_H
|
||||
|
|
|
|||
|
|
@ -28,13 +28,10 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef REGISTER_DRIVER_TYPES_H
|
||||
#define REGISTER_DRIVER_TYPES_H
|
||||
#pragma once
|
||||
|
||||
void register_core_driver_types();
|
||||
void unregister_core_driver_types();
|
||||
|
||||
void register_driver_types();
|
||||
void unregister_driver_types();
|
||||
|
||||
#endif // REGISTER_DRIVER_TYPES_H
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#ifdef HAVE_MNTENT
|
||||
|
|
@ -256,7 +257,7 @@ static void _get_drives(List<String> *list) {
|
|||
// Parse only file:// links
|
||||
if (strncmp(string, "file://", 7) == 0) {
|
||||
// Strip any unwanted edges on the strings and push_back if it's not a duplicate.
|
||||
String fpath = String::utf8(string + 7).strip_edges().split_spaces()[0].uri_decode();
|
||||
String fpath = String::utf8(string + 7).strip_edges().split_spaces()[0].uri_file_decode();
|
||||
if (!list->find(fpath)) {
|
||||
list->push_back(fpath);
|
||||
}
|
||||
|
|
@ -342,7 +343,7 @@ Error DirAccessUnix::change_dir(String p_dir) {
|
|||
String prev_dir;
|
||||
char real_current_dir_name[2048];
|
||||
ERR_FAIL_NULL_V(getcwd(real_current_dir_name, 2048), ERR_BUG);
|
||||
if (prev_dir.parse_utf8(real_current_dir_name) != OK) {
|
||||
if (prev_dir.append_utf8(real_current_dir_name) != OK) {
|
||||
prev_dir = real_current_dir_name; //no utf8, maybe latin?
|
||||
}
|
||||
|
||||
|
|
@ -365,7 +366,7 @@ Error DirAccessUnix::change_dir(String p_dir) {
|
|||
if (!base.is_empty() && !try_dir.begins_with(base)) {
|
||||
ERR_FAIL_NULL_V(getcwd(real_current_dir_name, 2048), ERR_BUG);
|
||||
String new_dir;
|
||||
new_dir.parse_utf8(real_current_dir_name);
|
||||
new_dir.append_utf8(real_current_dir_name);
|
||||
|
||||
if (!new_dir.begins_with(base)) {
|
||||
try_dir = current_dir; //revert
|
||||
|
|
@ -383,7 +384,7 @@ String DirAccessUnix::get_current_dir(bool p_include_drive) const {
|
|||
if (!base.is_empty()) {
|
||||
String bd = current_dir.replace_first(base, "");
|
||||
if (bd.begins_with("/")) {
|
||||
return _get_root_string() + bd.substr(1, bd.length());
|
||||
return _get_root_string() + bd.substr(1);
|
||||
} else {
|
||||
return _get_root_string() + bd;
|
||||
}
|
||||
|
|
@ -486,7 +487,7 @@ String DirAccessUnix::read_link(String p_file) {
|
|||
ssize_t len = readlink(p_file.utf8().get_data(), buf, sizeof(buf));
|
||||
String link;
|
||||
if (len > 0) {
|
||||
link.parse_utf8(buf, len);
|
||||
link.append_utf8(buf, len);
|
||||
}
|
||||
return link;
|
||||
}
|
||||
|
|
@ -544,6 +545,24 @@ bool DirAccessUnix::is_case_sensitive(const String &p_path) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DirAccessUnix::is_equivalent(const String &p_path_a, const String &p_path_b) const {
|
||||
String f1 = fix_path(p_path_a);
|
||||
struct stat st1 = {};
|
||||
int err = stat(f1.utf8().get_data(), &st1);
|
||||
if (err) {
|
||||
return DirAccess::is_equivalent(p_path_a, p_path_b);
|
||||
}
|
||||
|
||||
String f2 = fix_path(p_path_b);
|
||||
struct stat st2 = {};
|
||||
err = stat(f2.utf8().get_data(), &st2);
|
||||
if (err) {
|
||||
return DirAccess::is_equivalent(p_path_a, p_path_b);
|
||||
}
|
||||
|
||||
return (st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino);
|
||||
}
|
||||
|
||||
DirAccessUnix::DirAccessUnix() {
|
||||
dir_stream = nullptr;
|
||||
_cisdir = false;
|
||||
|
|
@ -553,7 +572,8 @@ DirAccessUnix::DirAccessUnix() {
|
|||
// set current directory to an absolute path of the current directory
|
||||
char real_current_dir_name[2048];
|
||||
ERR_FAIL_NULL(getcwd(real_current_dir_name, 2048));
|
||||
if (current_dir.parse_utf8(real_current_dir_name) != OK) {
|
||||
current_dir.clear();
|
||||
if (current_dir.append_utf8(real_current_dir_name) != OK) {
|
||||
current_dir = real_current_dir_name;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DIR_ACCESS_UNIX_H
|
||||
#define DIR_ACCESS_UNIX_H
|
||||
#pragma once
|
||||
|
||||
#if defined(UNIX_ENABLED)
|
||||
|
||||
|
|
@ -41,6 +40,7 @@
|
|||
#include <unistd.h>
|
||||
|
||||
class DirAccessUnix : public DirAccess {
|
||||
GDSOFTCLASS(DirAccessUnix, DirAccess);
|
||||
DIR *dir_stream = nullptr;
|
||||
|
||||
bool _cisdir = false;
|
||||
|
|
@ -86,6 +86,7 @@ public:
|
|||
virtual Error create_link(String p_source, String p_target) override;
|
||||
|
||||
virtual bool is_case_sensitive(const String &p_path) const override;
|
||||
virtual bool is_equivalent(const String &p_path_a, const String &p_path_b) const override;
|
||||
|
||||
virtual uint64_t get_space_left() override;
|
||||
|
||||
|
|
@ -96,5 +97,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // UNIX_ENABLED
|
||||
|
||||
#endif // DIR_ACCESS_UNIX_H
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ String FileAccessUnix::get_real_path() const {
|
|||
}
|
||||
|
||||
String result;
|
||||
Error parse_ok = result.parse_utf8(resolved_path);
|
||||
Error parse_ok = result.append_utf8(resolved_path);
|
||||
::free(resolved_path);
|
||||
|
||||
if (parse_ok != OK) {
|
||||
|
|
@ -336,16 +336,19 @@ bool FileAccessUnix::file_exists(const String &p_path) {
|
|||
|
||||
uint64_t FileAccessUnix::_get_modified_time(const String &p_file) {
|
||||
String file = fix_path(p_file);
|
||||
struct stat status = {};
|
||||
int err = stat(file.utf8().get_data(), &status);
|
||||
struct stat st = {};
|
||||
int err = stat(file.utf8().get_data(), &st);
|
||||
|
||||
if (!err) {
|
||||
uint64_t modified_time = status.st_mtime;
|
||||
uint64_t modified_time = 0;
|
||||
if ((st.st_mode & S_IFMT) == S_IFLNK || (st.st_mode & S_IFMT) == S_IFREG || (st.st_mode & S_IFDIR) == S_IFDIR) {
|
||||
modified_time = st.st_mtime;
|
||||
}
|
||||
#ifdef ANDROID_ENABLED
|
||||
// Workaround for GH-101007
|
||||
//FIXME: After saving, all timestamps (st_mtime, st_ctime, st_atime) are set to the same value.
|
||||
// After exporting or after some time, only 'modified_time' resets to a past timestamp.
|
||||
uint64_t created_time = status.st_ctime;
|
||||
uint64_t created_time = st.st_ctime;
|
||||
if (modified_time < created_time) {
|
||||
modified_time = created_time;
|
||||
}
|
||||
|
|
@ -356,6 +359,32 @@ uint64_t FileAccessUnix::_get_modified_time(const String &p_file) {
|
|||
}
|
||||
}
|
||||
|
||||
uint64_t FileAccessUnix::_get_access_time(const String &p_file) {
|
||||
String file = fix_path(p_file);
|
||||
struct stat st = {};
|
||||
int err = stat(file.utf8().get_data(), &st);
|
||||
|
||||
if (!err) {
|
||||
if ((st.st_mode & S_IFMT) == S_IFLNK || (st.st_mode & S_IFMT) == S_IFREG || (st.st_mode & S_IFDIR) == S_IFDIR) {
|
||||
return st.st_atime;
|
||||
}
|
||||
}
|
||||
ERR_FAIL_V_MSG(0, "Failed to get access time for: " + p_file + "");
|
||||
}
|
||||
|
||||
int64_t FileAccessUnix::_get_size(const String &p_file) {
|
||||
String file = fix_path(p_file);
|
||||
struct stat st = {};
|
||||
int err = stat(file.utf8().get_data(), &st);
|
||||
|
||||
if (!err) {
|
||||
if ((st.st_mode & S_IFMT) == S_IFLNK || (st.st_mode & S_IFMT) == S_IFREG) {
|
||||
return st.st_size;
|
||||
}
|
||||
}
|
||||
ERR_FAIL_V_MSG(-1, "Failed to get size for: " + p_file + "");
|
||||
}
|
||||
|
||||
BitField<FileAccess::UnixPermissionFlags> FileAccessUnix::_get_unix_permissions(const String &p_file) {
|
||||
String file = fix_path(p_file);
|
||||
struct stat status = {};
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FILE_ACCESS_UNIX_H
|
||||
#define FILE_ACCESS_UNIX_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/os/memory.h"
|
||||
|
|
@ -39,6 +38,7 @@
|
|||
#if defined(UNIX_ENABLED)
|
||||
|
||||
class FileAccessUnix : public FileAccess {
|
||||
GDSOFTCLASS(FileAccessUnix, FileAccess);
|
||||
FILE *f = nullptr;
|
||||
int flags = 0;
|
||||
void check_errors(bool p_write = false) const;
|
||||
|
|
@ -81,6 +81,8 @@ public:
|
|||
virtual bool file_exists(const String &p_path) override; ///< return true if a file exists
|
||||
|
||||
virtual uint64_t _get_modified_time(const String &p_file) override;
|
||||
virtual uint64_t _get_access_time(const String &p_file) override;
|
||||
virtual int64_t _get_size(const String &p_file) override;
|
||||
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override;
|
||||
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override;
|
||||
|
||||
|
|
@ -96,5 +98,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // UNIX_ENABLED
|
||||
|
||||
#endif // FILE_ACCESS_UNIX_H
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ Error FileAccessUnixPipe::open_internal(const String &p_path, int p_mode_flags)
|
|||
path_src = p_path;
|
||||
ERR_FAIL_COND_V_MSG(fd[0] >= 0 || fd[1] >= 0, ERR_ALREADY_IN_USE, "Pipe is already in use.");
|
||||
|
||||
path = String("/tmp/") + p_path.replace("pipe://", "").replace("/", "_");
|
||||
path = String("/tmp/") + p_path.replace("pipe://", "").replace_char('/', '_');
|
||||
const CharString path_utf8 = path.utf8();
|
||||
|
||||
struct stat st = {};
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FILE_ACCESS_UNIX_PIPE_H
|
||||
#define FILE_ACCESS_UNIX_PIPE_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/os/memory.h"
|
||||
|
|
@ -39,6 +38,7 @@
|
|||
#if defined(UNIX_ENABLED)
|
||||
|
||||
class FileAccessUnixPipe : public FileAccess {
|
||||
GDSOFTCLASS(FileAccessUnixPipe, FileAccess);
|
||||
bool unlink_on_close = false;
|
||||
|
||||
int fd[2] = { -1, -1 };
|
||||
|
|
@ -76,6 +76,8 @@ public:
|
|||
virtual bool file_exists(const String &p_path) override { return false; }
|
||||
|
||||
virtual uint64_t _get_modified_time(const String &p_file) override { return 0; }
|
||||
virtual uint64_t _get_access_time(const String &p_file) override { return 0; }
|
||||
virtual int64_t _get_size(const String &p_file) override { return -1; }
|
||||
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
|
||||
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return ERR_UNAVAILABLE; }
|
||||
|
||||
|
|
@ -91,5 +93,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // UNIX_ENABLED
|
||||
|
||||
#endif // FILE_ACCESS_UNIX_PIPE_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef IP_UNIX_H
|
||||
#define IP_UNIX_H
|
||||
#pragma once
|
||||
|
||||
#if defined(UNIX_ENABLED) && !defined(UNIX_SOCKET_UNAVAILABLE)
|
||||
|
||||
|
|
@ -50,5 +49,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // UNIX_ENABLED
|
||||
|
||||
#endif // IP_UNIX_H
|
||||
|
|
|
|||
|
|
@ -135,10 +135,7 @@ NetSocketUnix::~NetSocketUnix() {
|
|||
|
||||
// Silence a warning reported in GH-27594.
|
||||
// EAGAIN and EWOULDBLOCK have the same value on most platforms, but it's not guaranteed.
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wlogical-op"
|
||||
#endif
|
||||
GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Wlogical-op")
|
||||
|
||||
NetSocketUnix::NetError NetSocketUnix::_get_socket_error() const {
|
||||
if (errno == EISCONN) {
|
||||
|
|
@ -163,9 +160,7 @@ NetSocketUnix::NetError NetSocketUnix::_get_socket_error() const {
|
|||
return ERR_NET_OTHER;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
GODOT_GCC_WARNING_POP
|
||||
|
||||
bool NetSocketUnix::_can_use_ip(const IPAddress &p_ip, const bool p_for_bind) const {
|
||||
if (p_for_bind && !(p_ip.is_valid() || p_ip.is_wildcard())) {
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef NET_SOCKET_UNIX_H
|
||||
#define NET_SOCKET_UNIX_H
|
||||
#pragma once
|
||||
|
||||
#if defined(UNIX_ENABLED) && !defined(UNIX_SOCKET_UNAVAILABLE)
|
||||
|
||||
|
|
@ -98,5 +97,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // UNIX_ENABLED && !UNIX_SOCKET_UNAVAILABLE
|
||||
|
||||
#endif // NET_SOCKET_UNIX_H
|
||||
|
|
|
|||
|
|
@ -580,6 +580,126 @@ Dictionary OS_Unix::get_memory_info() const {
|
|||
return meminfo;
|
||||
}
|
||||
|
||||
#ifndef __GLIBC__
|
||||
void OS_Unix::_load_iconv() {
|
||||
#if defined(MACOS_ENABLED) || defined(IOS_ENABLED)
|
||||
String iconv_lib_aliases[] = { "/usr/lib/libiconv.2.dylib" };
|
||||
String iconv_func_aliases[] = { "iconv" };
|
||||
String charset_lib_aliases[] = { "/usr/lib/libcharset.1.dylib" };
|
||||
#else
|
||||
String iconv_lib_aliases[] = { "", "libiconv.2.so", "libiconv.so" };
|
||||
String iconv_func_aliases[] = { "libiconv", "iconv", "bsd_iconv", "rpl_iconv" };
|
||||
String charset_lib_aliases[] = { "", "libcharset.1.so", "libcharset.so" };
|
||||
#endif
|
||||
|
||||
for (size_t i = 0; i < sizeof(iconv_lib_aliases) / sizeof(iconv_lib_aliases[0]); i++) {
|
||||
void *iconv_lib = iconv_lib_aliases[i].is_empty() ? RTLD_NEXT : dlopen(iconv_lib_aliases[i].utf8().get_data(), RTLD_NOW);
|
||||
if (iconv_lib) {
|
||||
for (size_t j = 0; j < sizeof(iconv_func_aliases) / sizeof(iconv_func_aliases[0]); j++) {
|
||||
gd_iconv_open = (PIConvOpen)dlsym(iconv_lib, (iconv_func_aliases[j] + "_open").utf8().get_data());
|
||||
gd_iconv = (PIConv)dlsym(iconv_lib, (iconv_func_aliases[j]).utf8().get_data());
|
||||
gd_iconv_close = (PIConvClose)dlsym(iconv_lib, (iconv_func_aliases[j] + "_close").utf8().get_data());
|
||||
if (gd_iconv_open && gd_iconv && gd_iconv_close) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gd_iconv_open && gd_iconv && gd_iconv_close) {
|
||||
break;
|
||||
}
|
||||
if (!iconv_lib_aliases[i].is_empty()) {
|
||||
dlclose(iconv_lib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sizeof(charset_lib_aliases) / sizeof(charset_lib_aliases[0]); i++) {
|
||||
void *cs_lib = charset_lib_aliases[i].is_empty() ? RTLD_NEXT : dlopen(charset_lib_aliases[i].utf8().get_data(), RTLD_NOW);
|
||||
if (cs_lib) {
|
||||
gd_locale_charset = (PIConvLocaleCharset)dlsym(cs_lib, "locale_charset");
|
||||
if (gd_locale_charset) {
|
||||
break;
|
||||
}
|
||||
if (!charset_lib_aliases[i].is_empty()) {
|
||||
dlclose(cs_lib);
|
||||
}
|
||||
}
|
||||
}
|
||||
_iconv_ok = gd_iconv_open && gd_iconv && gd_iconv_close && gd_locale_charset;
|
||||
}
|
||||
#endif
|
||||
|
||||
String OS_Unix::multibyte_to_string(const String &p_encoding, const PackedByteArray &p_array) const {
|
||||
ERR_FAIL_COND_V_MSG(!_iconv_ok, String(), "Conversion failed: Unable to load libiconv");
|
||||
|
||||
LocalVector<char> chars;
|
||||
#ifdef __GLIBC__
|
||||
gd_iconv_t ctx = gd_iconv_open("UTF-8", p_encoding.is_empty() ? nl_langinfo(CODESET) : p_encoding.utf8().get_data());
|
||||
#else
|
||||
gd_iconv_t ctx = gd_iconv_open("UTF-8", p_encoding.is_empty() ? gd_locale_charset() : p_encoding.utf8().get_data());
|
||||
#endif
|
||||
ERR_FAIL_COND_V_MSG(ctx == (gd_iconv_t)(-1), String(), "Conversion failed: Unknown encoding");
|
||||
|
||||
char *in_ptr = (char *)p_array.ptr();
|
||||
size_t in_size = p_array.size();
|
||||
|
||||
chars.resize(in_size);
|
||||
char *out_ptr = (char *)chars.ptr();
|
||||
size_t out_size = chars.size();
|
||||
|
||||
while (gd_iconv(ctx, &in_ptr, &in_size, &out_ptr, &out_size) == (size_t)-1) {
|
||||
if (errno != E2BIG) {
|
||||
gd_iconv_close(ctx);
|
||||
ERR_FAIL_V_MSG(String(), vformat("Conversion failed: %d - %s", errno, strerror(errno)));
|
||||
}
|
||||
int64_t rate = (chars.size()) / (p_array.size() - in_size);
|
||||
size_t oldpos = chars.size() - out_size;
|
||||
chars.resize(chars.size() + in_size * rate);
|
||||
out_ptr = (char *)chars.ptr() + oldpos;
|
||||
out_size = chars.size() - oldpos;
|
||||
}
|
||||
chars.resize(chars.size() - out_size);
|
||||
gd_iconv_close(ctx);
|
||||
|
||||
return String::utf8((const char *)chars.ptr(), chars.size());
|
||||
}
|
||||
|
||||
PackedByteArray OS_Unix::string_to_multibyte(const String &p_encoding, const String &p_string) const {
|
||||
ERR_FAIL_COND_V_MSG(!_iconv_ok, PackedByteArray(), "Conversion failed: Unable to load libiconv");
|
||||
|
||||
CharString charstr = p_string.utf8();
|
||||
|
||||
PackedByteArray ret;
|
||||
#ifdef __GLIBC__
|
||||
gd_iconv_t ctx = gd_iconv_open(p_encoding.is_empty() ? nl_langinfo(CODESET) : p_encoding.utf8().get_data(), "UTF-8");
|
||||
#else
|
||||
gd_iconv_t ctx = gd_iconv_open(p_encoding.is_empty() ? gd_locale_charset() : p_encoding.utf8().get_data(), "UTF-8");
|
||||
#endif
|
||||
ERR_FAIL_COND_V_MSG(ctx == (gd_iconv_t)(-1), PackedByteArray(), "Conversion failed: Unknown encoding");
|
||||
|
||||
char *in_ptr = (char *)charstr.ptr();
|
||||
size_t in_size = charstr.size();
|
||||
|
||||
ret.resize(in_size);
|
||||
char *out_ptr = (char *)ret.ptrw();
|
||||
size_t out_size = ret.size();
|
||||
|
||||
while (gd_iconv(ctx, &in_ptr, &in_size, &out_ptr, &out_size) == (size_t)-1) {
|
||||
if (errno != E2BIG) {
|
||||
gd_iconv_close(ctx);
|
||||
ERR_FAIL_V_MSG(PackedByteArray(), vformat("Conversion failed: %d - %s", errno, strerror(errno)));
|
||||
}
|
||||
int64_t rate = (ret.size()) / (charstr.size() - in_size);
|
||||
size_t oldpos = ret.size() - out_size;
|
||||
ret.resize(ret.size() + in_size * rate);
|
||||
out_ptr = (char *)ret.ptrw() + oldpos;
|
||||
out_size = ret.size() - oldpos;
|
||||
}
|
||||
ret.resize(ret.size() - out_size);
|
||||
gd_iconv_close(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Dictionary OS_Unix::execute_with_pipe(const String &p_path, const List<String> &p_arguments, bool p_blocking) {
|
||||
#define CLEAN_PIPES \
|
||||
if (pipe_in[0] >= 0) { \
|
||||
|
|
@ -685,6 +805,57 @@ Dictionary OS_Unix::execute_with_pipe(const String &p_path, const List<String> &
|
|||
#endif
|
||||
}
|
||||
|
||||
int OS_Unix::_wait_for_pid_completion(const pid_t p_pid, int *r_status, int p_options) {
|
||||
while (true) {
|
||||
if (waitpid(p_pid, r_status, p_options) != -1) {
|
||||
// Thread exited normally.
|
||||
return 0;
|
||||
}
|
||||
const int error = errno;
|
||||
if (error == EINTR) {
|
||||
// We're in a debugger, should call waitpid again.
|
||||
// See https://stackoverflow.com/a/45472920/730797.
|
||||
continue;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
bool OS_Unix::_check_pid_is_running(const pid_t p_pid, int *r_status) const {
|
||||
const ProcessInfo *pi = process_map->getptr(p_pid);
|
||||
|
||||
if (pi && !pi->is_running) {
|
||||
// Can return cached value.
|
||||
if (r_status) {
|
||||
*r_status = pi->exit_code;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int status = 0;
|
||||
const int result = _wait_for_pid_completion(p_pid, &status, WNOHANG);
|
||||
if (result == 0) {
|
||||
// Thread is still running.
|
||||
return true;
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V_MSG(result == -1, false, vformat("Thread %d exited with errno: %d", (int)p_pid, errno));
|
||||
// Thread exited normally.
|
||||
|
||||
status = WIFEXITED(status) ? WEXITSTATUS(status) : status;
|
||||
|
||||
if (pi) {
|
||||
pi->is_running = false;
|
||||
pi->exit_code = status;
|
||||
}
|
||||
|
||||
if (r_status) {
|
||||
*r_status = status;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex, bool p_open_console) {
|
||||
#ifdef __EMSCRIPTEN__
|
||||
// Don't compile this code at all to avoid undefined references.
|
||||
|
|
@ -710,7 +881,7 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, St
|
|||
p_pipe_mutex->lock();
|
||||
}
|
||||
String pipe_out;
|
||||
if (pipe_out.parse_utf8(buf) == OK) {
|
||||
if (pipe_out.append_utf8(buf) == OK) {
|
||||
(*r_pipe) += pipe_out;
|
||||
} else {
|
||||
(*r_pipe) += String(buf); // If not valid UTF-8 try decode as Latin-1
|
||||
|
|
@ -750,12 +921,12 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, St
|
|||
raise(SIGKILL);
|
||||
}
|
||||
|
||||
int status;
|
||||
waitpid(pid, &status, 0);
|
||||
int status = 0;
|
||||
const int result = _wait_for_pid_completion(pid, &status, 0);
|
||||
if (r_exitcode) {
|
||||
*r_exitcode = WIFEXITED(status) ? WEXITSTATUS(status) : status;
|
||||
}
|
||||
return OK;
|
||||
return result ? FAILED : OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -809,7 +980,7 @@ Error OS_Unix::kill(const ProcessID &p_pid) {
|
|||
if (!ret) {
|
||||
//avoid zombie process
|
||||
int st;
|
||||
::waitpid(p_pid, &st, 0);
|
||||
_wait_for_pid_completion(p_pid, &st, 0);
|
||||
}
|
||||
return ret ? ERR_INVALID_PARAMETER : OK;
|
||||
}
|
||||
|
|
@ -820,42 +991,19 @@ int OS_Unix::get_process_id() const {
|
|||
|
||||
bool OS_Unix::is_process_running(const ProcessID &p_pid) const {
|
||||
MutexLock lock(process_map_mutex);
|
||||
const ProcessInfo *pi = process_map->getptr(p_pid);
|
||||
|
||||
if (pi && !pi->is_running) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int status = 0;
|
||||
if (waitpid(p_pid, &status, WNOHANG) != 0) {
|
||||
if (pi) {
|
||||
pi->is_running = false;
|
||||
pi->exit_code = status;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return _check_pid_is_running(p_pid, nullptr);
|
||||
}
|
||||
|
||||
int OS_Unix::get_process_exit_code(const ProcessID &p_pid) const {
|
||||
MutexLock lock(process_map_mutex);
|
||||
const ProcessInfo *pi = process_map->getptr(p_pid);
|
||||
|
||||
if (pi && !pi->is_running) {
|
||||
return pi->exit_code;
|
||||
int exit_code = 0;
|
||||
if (_check_pid_is_running(p_pid, &exit_code)) {
|
||||
// Thread is still running
|
||||
return -1;
|
||||
}
|
||||
|
||||
int status = 0;
|
||||
if (waitpid(p_pid, &status, WNOHANG) != 0) {
|
||||
status = WIFEXITED(status) ? WEXITSTATUS(status) : status;
|
||||
if (pi) {
|
||||
pi->is_running = false;
|
||||
pi->exit_code = status;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
return -1;
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
String OS_Unix::get_locale() const {
|
||||
|
|
@ -942,7 +1090,7 @@ String OS_Unix::get_environment(const String &p_var) const {
|
|||
return "";
|
||||
}
|
||||
String s;
|
||||
if (s.parse_utf8(val) == OK) {
|
||||
if (s.append_utf8(val) == OK) {
|
||||
return s;
|
||||
}
|
||||
return String(val); // Not valid UTF-8, so return as-is
|
||||
|
|
@ -971,7 +1119,7 @@ String OS_Unix::get_executable_path() const {
|
|||
ssize_t len = readlink("/proc/self/exe", buf, sizeof(buf));
|
||||
String b;
|
||||
if (len > 0) {
|
||||
b.parse_utf8(buf, len);
|
||||
b.append_utf8(buf, len);
|
||||
}
|
||||
if (b.is_empty()) {
|
||||
WARN_PRINT("Couldn't get executable path from /proc/self/exe, using argv[0]");
|
||||
|
|
@ -1007,9 +1155,8 @@ String OS_Unix::get_executable_path() const {
|
|||
WARN_PRINT("Couldn't get executable path from sysctl");
|
||||
return OS::get_executable_path();
|
||||
}
|
||||
String b;
|
||||
b.parse_utf8(buf);
|
||||
return b;
|
||||
|
||||
return String::utf8(buf);
|
||||
#elif defined(__APPLE__)
|
||||
char temp_path[1];
|
||||
uint32_t buff_size = 1;
|
||||
|
|
@ -1082,6 +1229,10 @@ void UnixTerminalLogger::log_error(const char *p_function, const char *p_file, i
|
|||
UnixTerminalLogger::~UnixTerminalLogger() {}
|
||||
|
||||
OS_Unix::OS_Unix() {
|
||||
#ifndef __GLIBC__
|
||||
_load_iconv();
|
||||
#endif
|
||||
|
||||
Vector<Logger *> loggers;
|
||||
loggers.push_back(memnew(UnixTerminalLogger));
|
||||
_set_logger(memnew(CompositeLogger(loggers)));
|
||||
|
|
|
|||
|
|
@ -28,14 +28,28 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef OS_UNIX_H
|
||||
#define OS_UNIX_H
|
||||
#pragma once
|
||||
|
||||
#ifdef UNIX_ENABLED
|
||||
|
||||
#include "core/os/os.h"
|
||||
#include "drivers/unix/ip_unix.h"
|
||||
|
||||
#ifdef __GLIBC__
|
||||
#include <iconv.h>
|
||||
#include <langinfo.h>
|
||||
#define gd_iconv_t iconv_t
|
||||
#define gd_iconv_open iconv_open
|
||||
#define gd_iconv iconv
|
||||
#define gd_iconv_close iconv_close
|
||||
#else
|
||||
typedef void *gd_iconv_t;
|
||||
typedef gd_iconv_t (*PIConvOpen)(const char *, const char *);
|
||||
typedef size_t (*PIConv)(gd_iconv_t, char **, size_t *, char **, size_t *);
|
||||
typedef int (*PIConvClose)(gd_iconv_t);
|
||||
typedef const char *(*PIConvLocaleCharset)(void);
|
||||
#endif
|
||||
|
||||
class OS_Unix : public OS {
|
||||
struct ProcessInfo {
|
||||
mutable bool is_running = true;
|
||||
|
|
@ -44,6 +58,22 @@ class OS_Unix : public OS {
|
|||
HashMap<ProcessID, ProcessInfo> *process_map = nullptr;
|
||||
Mutex process_map_mutex;
|
||||
|
||||
#ifdef __GLIBC__
|
||||
bool _iconv_ok = true;
|
||||
#else
|
||||
bool _iconv_ok = false;
|
||||
|
||||
PIConvOpen gd_iconv_open = nullptr;
|
||||
PIConv gd_iconv = nullptr;
|
||||
PIConvClose gd_iconv_close = nullptr;
|
||||
PIConvLocaleCharset gd_locale_charset = nullptr;
|
||||
|
||||
void _load_iconv();
|
||||
#endif
|
||||
|
||||
static int _wait_for_pid_completion(const pid_t p_pid, int *r_status, int p_options);
|
||||
bool _check_pid_is_running(const pid_t p_pid, int *r_status) const;
|
||||
|
||||
protected:
|
||||
// UNIX only handles the core functions.
|
||||
// inheriting platforms under unix (eg. X11) should handle the rest
|
||||
|
|
@ -88,6 +118,9 @@ public:
|
|||
|
||||
virtual Dictionary get_memory_info() const override;
|
||||
|
||||
virtual String multibyte_to_string(const String &p_encoding, const PackedByteArray &p_array) const override;
|
||||
virtual PackedByteArray string_to_multibyte(const String &p_encoding, const String &p_string) const override;
|
||||
|
||||
virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr, bool p_open_console = false) override;
|
||||
virtual Dictionary execute_with_pipe(const String &p_path, const List<String> &p_arguments, bool p_blocking = true) override;
|
||||
virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr, bool p_open_console = false) override;
|
||||
|
|
@ -116,5 +149,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // UNIX_ENABLED
|
||||
|
||||
#endif // OS_UNIX_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef SYSLOG_LOGGER_H
|
||||
#define SYSLOG_LOGGER_H
|
||||
#pragma once
|
||||
|
||||
#ifdef UNIX_ENABLED
|
||||
|
||||
|
|
@ -44,5 +43,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // UNIX_ENABLED
|
||||
|
||||
#endif // SYSLOG_LOGGER_H
|
||||
|
|
|
|||
|
|
@ -35,6 +35,11 @@
|
|||
#include "core/os/thread.h"
|
||||
#include "core/string/ustring.h"
|
||||
|
||||
#if defined(PLATFORM_THREAD_OVERRIDE) && defined(__APPLE__)
|
||||
void init_thread_posix() {
|
||||
}
|
||||
#else
|
||||
|
||||
#ifdef PTHREAD_BSD_SET_NAME
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
|
|
@ -73,4 +78,6 @@ void init_thread_posix() {
|
|||
Thread::_set_platform_functions({ .set_name = set_name });
|
||||
}
|
||||
|
||||
#endif // PLATFORM_THREAD_OVERRIDE && __APPLE__
|
||||
|
||||
#endif // UNIX_ENABLED
|
||||
|
|
|
|||
|
|
@ -28,9 +28,6 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef THREAD_POSIX_H
|
||||
#define THREAD_POSIX_H
|
||||
#pragma once
|
||||
|
||||
void init_thread_posix();
|
||||
|
||||
#endif // THREAD_POSIX_H
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ thirdparty_dir = "#thirdparty/vulkan"
|
|||
thirdparty_volk_dir = "#thirdparty/volk"
|
||||
|
||||
# Use bundled Vulkan headers
|
||||
env.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "/include"])
|
||||
env.Prepend(CPPEXTPATH=[thirdparty_dir, thirdparty_dir + "/include"])
|
||||
|
||||
if env["use_volk"]:
|
||||
env.AppendUnique(CPPDEFINES=["USE_VOLK"])
|
||||
env.Prepend(CPPPATH=[thirdparty_volk_dir])
|
||||
env.Prepend(CPPEXTPATH=[thirdparty_volk_dir])
|
||||
|
||||
if env["platform"] == "android":
|
||||
env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_ANDROID_KHR"])
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GODOT_VULKAN_H
|
||||
#define GODOT_VULKAN_H
|
||||
#pragma once
|
||||
|
||||
#ifdef USE_VOLK
|
||||
#include <volk.h>
|
||||
|
|
@ -38,5 +37,3 @@
|
|||
#define VK_NO_STDINT_H
|
||||
#include <vulkan/vulkan.h>
|
||||
#endif
|
||||
|
||||
#endif // GODOT_VULKAN_H
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue