summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/SCsub3
-rw-r--r--drivers/coreaudio/SCsub2
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.h7
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.mm (renamed from drivers/coreaudio/audio_driver_coreaudio.cpp)69
-rw-r--r--drivers/d3d12/rendering_device_driver_d3d12.cpp4
-rw-r--r--drivers/gles3/storage/config.h2
-rw-r--r--drivers/gles3/storage/light_storage.h22
-rw-r--r--drivers/gles3/storage/material_storage.h8
-rw-r--r--drivers/gles3/storage/mesh_storage.h16
-rw-r--r--drivers/gles3/storage/texture_storage.cpp2
-rw-r--r--drivers/gles3/storage/texture_storage.h12
-rw-r--r--drivers/gles3/storage/utilities.h4
-rw-r--r--drivers/metal/metal_objects.h4
-rw-r--r--drivers/metal/rendering_device_driver_metal.h2
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.h2
-rw-r--r--drivers/vulkan/rendering_device_driver_vulkan.cpp156
-rw-r--r--drivers/vulkan/rendering_device_driver_vulkan.h10
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp2
18 files changed, 257 insertions, 70 deletions
diff --git a/drivers/SCsub b/drivers/SCsub
index e0bfa138f5..03ad70649b 100644
--- a/drivers/SCsub
+++ b/drivers/SCsub
@@ -14,7 +14,8 @@ SConscript("windows/SCsub")
# Sounds drivers
SConscript("alsa/SCsub")
-SConscript("coreaudio/SCsub")
+if env["platform"] == "ios" or env["platform"] == "macos":
+ SConscript("coreaudio/SCsub")
SConscript("pulseaudio/SCsub")
if env["platform"] == "windows":
SConscript("wasapi/SCsub")
diff --git a/drivers/coreaudio/SCsub b/drivers/coreaudio/SCsub
index 69d667c57b..83ac27f4b6 100644
--- a/drivers/coreaudio/SCsub
+++ b/drivers/coreaudio/SCsub
@@ -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")
diff --git a/drivers/coreaudio/audio_driver_coreaudio.h b/drivers/coreaudio/audio_driver_coreaudio.h
index 2f76b0de78..f889ffc998 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.h
+++ b/drivers/coreaudio/audio_driver_coreaudio.h
@@ -40,6 +40,8 @@
#import <AudioUnit/AudioUnit.h>
#ifdef MACOS_ENABLED
#import <CoreAudio/AudioHardware.h>
+#else
+#import <AVFoundation/AVFoundation.h>
#endif
class AudioDriverCoreAudio : public AudioDriver {
@@ -53,9 +55,11 @@ class AudioDriverCoreAudio : public AudioDriver {
String input_device_name = "Default";
int mix_rate = 0;
+ int capture_mix_rate = 0;
unsigned int channels = 2;
unsigned int capture_channels = 2;
unsigned int buffer_frames = 0;
+ unsigned int capture_buffer_frames = 0;
Vector<int32_t> samples_in;
Vector<int16_t> input_buf;
@@ -91,11 +95,12 @@ class AudioDriverCoreAudio : public AudioDriver {
public:
virtual const char *get_name() const override {
return "CoreAudio";
- };
+ }
virtual Error init() override;
virtual void start() override;
virtual int get_mix_rate() const override;
+ virtual int get_input_mix_rate() const override;
virtual SpeakerMode get_speaker_mode() const override;
virtual void lock() override;
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.mm
index 5455fc52b2..33e210afcf 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.cpp
+++ b/drivers/coreaudio/audio_driver_coreaudio.mm
@@ -1,5 +1,5 @@
/**************************************************************************/
-/* audio_driver_coreaudio.cpp */
+/* audio_driver_coreaudio.mm */
/**************************************************************************/
/* This file is part of: */
/* REDOT ENGINE */
@@ -123,7 +123,24 @@ Error AudioDriverCoreAudio::init() {
break;
}
- mix_rate = _get_configured_mix_rate();
+#ifdef MACOS_ENABLED
+ AudioDeviceID device_id;
+ UInt32 dev_id_size = sizeof(AudioDeviceID);
+
+ AudioObjectPropertyAddress property_dev_id = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
+ result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property_dev_id, 0, nullptr, &dev_id_size, &device_id);
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
+ double hw_mix_rate;
+ UInt32 hw_mix_rate_size = sizeof(hw_mix_rate);
+
+ AudioObjectPropertyAddress property_sr = { kAudioDevicePropertyNominalSampleRate, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMain };
+ result = AudioObjectGetPropertyData(device_id, &property_sr, 0, nullptr, &hw_mix_rate_size, &hw_mix_rate);
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+#else
+ double hw_mix_rate = [AVAudioSession sharedInstance].sampleRate;
+#endif
+ mix_rate = hw_mix_rate;
memset(&strdesc, 0, sizeof(strdesc));
strdesc.mFormatID = kAudioFormatLinearPCM;
@@ -149,10 +166,10 @@ Error AudioDriverCoreAudio::init() {
unsigned int buffer_size = buffer_frames * channels;
samples_in.resize(buffer_size);
- input_buf.resize(buffer_size);
print_verbose("CoreAudio: detected " + itos(channels) + " channels");
- print_verbose("CoreAudio: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
+ print_verbose("CoreAudio: output sampling rate: " + itos(mix_rate) + " Hz");
+ print_verbose("CoreAudio: output audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
AURenderCallbackStruct callback;
memset(&callback, 0, sizeof(AURenderCallbackStruct));
@@ -277,6 +294,10 @@ int AudioDriverCoreAudio::get_mix_rate() const {
return mix_rate;
}
+int AudioDriverCoreAudio::get_input_mix_rate() const {
+ return capture_mix_rate;
+}
+
AudioDriver::SpeakerMode AudioDriverCoreAudio::get_speaker_mode() const {
return get_speaker_mode_by_total_channels(channels);
}
@@ -380,14 +401,14 @@ Error AudioDriverCoreAudio::init_input_device() {
UInt32 size;
#ifdef MACOS_ENABLED
- AudioDeviceID deviceId;
+ AudioDeviceID device_id;
size = sizeof(AudioDeviceID);
AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultInputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMain };
- result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property, 0, nullptr, &size, &deviceId);
+ result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property, 0, nullptr, &size, &device_id);
ERR_FAIL_COND_V(result != noErr, FAILED);
- result = AudioUnitSetProperty(input_unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &deviceId, sizeof(AudioDeviceID));
+ result = AudioUnitSetProperty(input_unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &device_id, sizeof(AudioDeviceID));
ERR_FAIL_COND_V(result != noErr, FAILED);
#endif
@@ -412,13 +433,23 @@ Error AudioDriverCoreAudio::init_input_device() {
break;
}
- mix_rate = _get_configured_mix_rate();
+#ifdef MACOS_ENABLED
+ double hw_mix_rate;
+ UInt32 hw_mix_rate_size = sizeof(hw_mix_rate);
+
+ AudioObjectPropertyAddress property_sr = { kAudioDevicePropertyNominalSampleRate, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMain };
+ result = AudioObjectGetPropertyData(device_id, &property_sr, 0, nullptr, &hw_mix_rate_size, &hw_mix_rate);
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+#else
+ double hw_mix_rate = [AVAudioSession sharedInstance].sampleRate;
+#endif
+ capture_mix_rate = hw_mix_rate;
memset(&strdesc, 0, sizeof(strdesc));
strdesc.mFormatID = kAudioFormatLinearPCM;
strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
strdesc.mChannelsPerFrame = capture_channels;
- strdesc.mSampleRate = mix_rate;
+ strdesc.mSampleRate = capture_mix_rate;
strdesc.mFramesPerPacket = 1;
strdesc.mBitsPerChannel = 16;
strdesc.mBytesPerFrame = strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8;
@@ -427,6 +458,13 @@ Error AudioDriverCoreAudio::init_input_device() {
result = AudioUnitSetProperty(input_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &strdesc, sizeof(strdesc));
ERR_FAIL_COND_V(result != noErr, FAILED);
+ int latency = Engine::get_singleton()->get_audio_output_latency();
+ // Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
+ capture_buffer_frames = closest_power_of_2(latency * capture_mix_rate / 1000);
+
+ unsigned int buffer_size = capture_buffer_frames * capture_channels;
+ input_buf.resize(buffer_size);
+
AURenderCallbackStruct callback;
memset(&callback, 0, sizeof(AURenderCallbackStruct));
callback.inputProc = &AudioDriverCoreAudio::input_callback;
@@ -437,6 +475,9 @@ Error AudioDriverCoreAudio::init_input_device() {
result = AudioUnitInitialize(input_unit);
ERR_FAIL_COND_V(result != noErr, FAILED);
+ print_verbose("CoreAudio: input sampling rate: " + itos(capture_mix_rate) + " Hz");
+ print_verbose("CoreAudio: input audio buffer frames: " + itos(capture_buffer_frames) + " calculated latency: " + itos(capture_buffer_frames * 1000 / capture_mix_rate) + "ms");
+
return OK;
}
@@ -479,7 +520,7 @@ void AudioDriverCoreAudio::finish_input_device() {
}
Error AudioDriverCoreAudio::input_start() {
- input_buffer_init(buffer_frames);
+ input_buffer_init(capture_buffer_frames);
OSStatus result = AudioOutputUnitStart(input_unit);
if (result != noErr) {
@@ -563,7 +604,7 @@ PackedStringArray AudioDriverCoreAudio::_get_device_list(bool input) {
}
void AudioDriverCoreAudio::_set_device(const String &output_device, bool input) {
- AudioDeviceID deviceId;
+ AudioDeviceID device_id;
bool found = false;
if (output_device != "Default") {
AudioObjectPropertyAddress prop;
@@ -610,7 +651,7 @@ void AudioDriverCoreAudio::_set_device(const String &output_device, bool input)
if (CFStringGetCString(cfname, buffer, maxSize, kCFStringEncodingUTF8)) {
String name = String::utf8(buffer) + " (" + itos(audioDevices[i]) + ")";
if (name == output_device) {
- deviceId = audioDevices[i];
+ device_id = audioDevices[i];
found = true;
}
}
@@ -628,14 +669,14 @@ void AudioDriverCoreAudio::_set_device(const String &output_device, bool input)
UInt32 elem = input ? kAudioHardwarePropertyDefaultInputDevice : kAudioHardwarePropertyDefaultOutputDevice;
AudioObjectPropertyAddress property = { elem, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMain };
- OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property, 0, nullptr, &size, &deviceId);
+ OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property, 0, nullptr, &size, &device_id);
ERR_FAIL_COND(result != noErr);
found = true;
}
if (found) {
- OSStatus result = AudioUnitSetProperty(input ? input_unit : audio_unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &deviceId, sizeof(AudioDeviceID));
+ OSStatus result = AudioUnitSetProperty(input ? input_unit : audio_unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &device_id, sizeof(AudioDeviceID));
ERR_FAIL_COND(result != noErr);
if (input) {
diff --git a/drivers/d3d12/rendering_device_driver_d3d12.cpp b/drivers/d3d12/rendering_device_driver_d3d12.cpp
index 7e05f988bc..35c8ea6b01 100644
--- a/drivers/d3d12/rendering_device_driver_d3d12.cpp
+++ b/drivers/d3d12/rendering_device_driver_d3d12.cpp
@@ -2463,8 +2463,6 @@ Error RenderingDeviceDriverD3D12::swap_chain_resize(CommandQueueID p_cmd_queue,
break;
}
- print_verbose("Using swap chain flags: " + itos(creation_flags) + ", sync interval: " + itos(sync_interval) + ", present flags: " + itos(present_flags));
-
if (swap_chain->d3d_swap_chain != nullptr && creation_flags != swap_chain->creation_flags) {
// The swap chain must be recreated if the creation flags are different.
_swap_chain_release(swap_chain);
@@ -6587,7 +6585,7 @@ static Error create_command_signature(ID3D12Device *device, D3D12_INDIRECT_ARGUM
HRESULT res = device->CreateCommandSignature(&cs_desc, nullptr, IID_PPV_ARGS(r_cmd_sig->GetAddressOf()));
ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), ERR_CANT_CREATE, "CreateCommandSignature failed with error " + vformat("0x%08ux", (uint64_t)res) + ".");
return OK;
-};
+}
Error RenderingDeviceDriverD3D12::_initialize_frames(uint32_t p_frame_count) {
Error err;
diff --git a/drivers/gles3/storage/config.h b/drivers/gles3/storage/config.h
index e18befc530..25f5ff3370 100644
--- a/drivers/gles3/storage/config.h
+++ b/drivers/gles3/storage/config.h
@@ -112,7 +112,7 @@ public:
PFNEGLIMAGETARGETTEXTURE2DOESPROC eglEGLImageTargetTexture2DOES = nullptr;
#endif
- static Config *get_singleton() { return singleton; };
+ static Config *get_singleton() { return singleton; }
Config();
~Config();
diff --git a/drivers/gles3/storage/light_storage.h b/drivers/gles3/storage/light_storage.h
index 16c9fb5371..05c680e7ca 100644
--- a/drivers/gles3/storage/light_storage.h
+++ b/drivers/gles3/storage/light_storage.h
@@ -308,8 +308,8 @@ public:
/* Light API */
- Light *get_light(RID p_rid) { return light_owner.get_or_null(p_rid); };
- bool owns_light(RID p_rid) { return light_owner.owns(p_rid); };
+ Light *get_light(RID p_rid) { return light_owner.get_or_null(p_rid); }
+ bool owns_light(RID p_rid) { return light_owner.owns(p_rid); }
void _light_initialize(RID p_rid, RS::LightType p_type);
@@ -436,8 +436,8 @@ public:
/* LIGHT INSTANCE API */
- LightInstance *get_light_instance(RID p_rid) { return light_instance_owner.get_or_null(p_rid); };
- bool owns_light_instance(RID p_rid) { return light_instance_owner.owns(p_rid); };
+ LightInstance *get_light_instance(RID p_rid) { return light_instance_owner.get_or_null(p_rid); }
+ bool owns_light_instance(RID p_rid) { return light_instance_owner.owns(p_rid); }
virtual RID light_instance_create(RID p_light) override;
virtual void light_instance_free(RID p_light_instance) override;
@@ -635,8 +635,8 @@ public:
/* PROBE API */
- ReflectionProbe *get_reflection_probe(RID p_rid) { return reflection_probe_owner.get_or_null(p_rid); };
- bool owns_reflection_probe(RID p_rid) { return reflection_probe_owner.owns(p_rid); };
+ ReflectionProbe *get_reflection_probe(RID p_rid) { return reflection_probe_owner.get_or_null(p_rid); }
+ bool owns_reflection_probe(RID p_rid) { return reflection_probe_owner.owns(p_rid); }
virtual RID reflection_probe_allocate() override;
virtual void reflection_probe_initialize(RID p_rid) override;
@@ -717,8 +717,8 @@ public:
/* LIGHTMAP CAPTURE */
- Lightmap *get_lightmap(RID p_rid) { return lightmap_owner.get_or_null(p_rid); };
- bool owns_lightmap(RID p_rid) { return lightmap_owner.owns(p_rid); };
+ Lightmap *get_lightmap(RID p_rid) { return lightmap_owner.get_or_null(p_rid); }
+ bool owns_lightmap(RID p_rid) { return lightmap_owner.owns(p_rid); }
virtual RID lightmap_allocate() override;
virtual void lightmap_initialize(RID p_rid) override;
@@ -741,15 +741,15 @@ public:
/* LIGHTMAP INSTANCE */
- LightmapInstance *get_lightmap_instance(RID p_rid) { return lightmap_instance_owner.get_or_null(p_rid); };
- bool owns_lightmap_instance(RID p_rid) { return lightmap_instance_owner.owns(p_rid); };
+ LightmapInstance *get_lightmap_instance(RID p_rid) { return lightmap_instance_owner.get_or_null(p_rid); }
+ bool owns_lightmap_instance(RID p_rid) { return lightmap_instance_owner.owns(p_rid); }
virtual RID lightmap_instance_create(RID p_lightmap) override;
virtual void lightmap_instance_free(RID p_lightmap) override;
virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) override;
/* SHADOW ATLAS API */
- bool owns_shadow_atlas(RID p_rid) { return shadow_atlas_owner.owns(p_rid); };
+ bool owns_shadow_atlas(RID p_rid) { return shadow_atlas_owner.owns(p_rid); }
virtual RID shadow_atlas_create() override;
virtual void shadow_atlas_free(RID p_atlas) override;
diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h
index 2d290d7ae8..eb141a87fc 100644
--- a/drivers/gles3/storage/material_storage.h
+++ b/drivers/gles3/storage/material_storage.h
@@ -578,8 +578,8 @@ public:
/* SHADER API */
- Shader *get_shader(RID p_rid) { return shader_owner.get_or_null(p_rid); };
- bool owns_shader(RID p_rid) { return shader_owner.owns(p_rid); };
+ Shader *get_shader(RID p_rid) { return shader_owner.get_or_null(p_rid); }
+ bool owns_shader(RID p_rid) { return shader_owner.owns(p_rid); }
void _shader_make_dirty(Shader *p_shader);
@@ -600,8 +600,8 @@ public:
/* MATERIAL API */
- Material *get_material(RID p_rid) { return material_owner.get_or_null(p_rid); };
- bool owns_material(RID p_rid) { return material_owner.owns(p_rid); };
+ Material *get_material(RID p_rid) { return material_owner.get_or_null(p_rid); }
+ bool owns_material(RID p_rid) { return material_owner.owns(p_rid); }
void _material_queue_update(Material *material, bool p_uniform, bool p_texture);
void _update_queued_materials();
diff --git a/drivers/gles3/storage/mesh_storage.h b/drivers/gles3/storage/mesh_storage.h
index c236d395e3..09b7bfd16b 100644
--- a/drivers/gles3/storage/mesh_storage.h
+++ b/drivers/gles3/storage/mesh_storage.h
@@ -282,8 +282,8 @@ public:
/* MESH API */
- Mesh *get_mesh(RID p_rid) { return mesh_owner.get_or_null(p_rid); };
- bool owns_mesh(RID p_rid) { return mesh_owner.owns(p_rid); };
+ Mesh *get_mesh(RID p_rid) { return mesh_owner.get_or_null(p_rid); }
+ bool owns_mesh(RID p_rid) { return mesh_owner.owns(p_rid); }
virtual RID mesh_allocate() override;
virtual void mesh_initialize(RID p_rid) override;
@@ -445,8 +445,8 @@ public:
/* MESH INSTANCE API */
- MeshInstance *get_mesh_instance(RID p_rid) { return mesh_instance_owner.get_or_null(p_rid); };
- bool owns_mesh_instance(RID p_rid) { return mesh_instance_owner.owns(p_rid); };
+ MeshInstance *get_mesh_instance(RID p_rid) { return mesh_instance_owner.get_or_null(p_rid); }
+ bool owns_mesh_instance(RID p_rid) { return mesh_instance_owner.owns(p_rid); }
virtual RID mesh_instance_create(RID p_base) override;
virtual void mesh_instance_free(RID p_rid) override;
@@ -494,8 +494,8 @@ public:
/* MULTIMESH API */
- MultiMesh *get_multimesh(RID p_rid) { return multimesh_owner.get_or_null(p_rid); };
- bool owns_multimesh(RID p_rid) { return multimesh_owner.owns(p_rid); };
+ MultiMesh *get_multimesh(RID p_rid) { return multimesh_owner.get_or_null(p_rid); }
+ bool owns_multimesh(RID p_rid) { return multimesh_owner.owns(p_rid); }
virtual RID _multimesh_allocate() override;
virtual void _multimesh_initialize(RID p_rid) override;
@@ -573,8 +573,8 @@ public:
/* SKELETON API */
- Skeleton *get_skeleton(RID p_rid) { return skeleton_owner.get_or_null(p_rid); };
- bool owns_skeleton(RID p_rid) { return skeleton_owner.owns(p_rid); };
+ Skeleton *get_skeleton(RID p_rid) { return skeleton_owner.get_or_null(p_rid); }
+ bool owns_skeleton(RID p_rid) { return skeleton_owner.owns(p_rid); }
virtual RID skeleton_allocate() override;
virtual void skeleton_initialize(RID p_rid) override;
diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp
index 924bfff271..e123653f91 100644
--- a/drivers/gles3/storage/texture_storage.cpp
+++ b/drivers/gles3/storage/texture_storage.cpp
@@ -2454,7 +2454,7 @@ Point2i TextureStorage::render_target_get_position(RID p_render_target) const {
ERR_FAIL_NULL_V(rt, Point2i());
return rt->position;
-};
+}
void TextureStorage::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h
index 95c49da7bb..5c00701346 100644
--- a/drivers/gles3/storage/texture_storage.h
+++ b/drivers/gles3/storage/texture_storage.h
@@ -480,8 +480,8 @@ public:
/* Canvas Texture API */
- CanvasTexture *get_canvas_texture(RID p_rid) { return canvas_texture_owner.get_or_null(p_rid); };
- bool owns_canvas_texture(RID p_rid) { return canvas_texture_owner.owns(p_rid); };
+ CanvasTexture *get_canvas_texture(RID p_rid) { return canvas_texture_owner.get_or_null(p_rid); }
+ bool owns_canvas_texture(RID p_rid) { return canvas_texture_owner.owns(p_rid); }
virtual RID canvas_texture_allocate() override;
virtual void canvas_texture_initialize(RID p_rid) override;
@@ -501,8 +501,8 @@ public:
return texture_owner.get_or_null(texture->proxy_to);
}
return texture;
- };
- bool owns_texture(RID p_rid) { return texture_owner.owns(p_rid); };
+ }
+ bool owns_texture(RID p_rid) { return texture_owner.owns(p_rid); }
void texture_2d_initialize_from_texture(RID p_texture, Texture &p_tex) {
texture_owner.initialize_rid(p_texture, p_tex);
@@ -620,8 +620,8 @@ public:
static GLuint system_fbo;
- RenderTarget *get_render_target(RID p_rid) { return render_target_owner.get_or_null(p_rid); };
- bool owns_render_target(RID p_rid) { return render_target_owner.owns(p_rid); };
+ RenderTarget *get_render_target(RID p_rid) { return render_target_owner.get_or_null(p_rid); }
+ bool owns_render_target(RID p_rid) { return render_target_owner.owns(p_rid); }
void check_backbuffer(RenderTarget *rt, const bool uses_screen_texture, const bool uses_depth_texture);
diff --git a/drivers/gles3/storage/utilities.h b/drivers/gles3/storage/utilities.h
index 39170c2dd1..e25f1a3221 100644
--- a/drivers/gles3/storage/utilities.h
+++ b/drivers/gles3/storage/utilities.h
@@ -167,8 +167,8 @@ public:
/* VISIBILITY NOTIFIER */
- VisibilityNotifier *get_visibility_notifier(RID p_rid) { return visibility_notifier_owner.get_or_null(p_rid); };
- bool owns_visibility_notifier(RID p_rid) const { return visibility_notifier_owner.owns(p_rid); };
+ VisibilityNotifier *get_visibility_notifier(RID p_rid) { return visibility_notifier_owner.get_or_null(p_rid); }
+ bool owns_visibility_notifier(RID p_rid) const { return visibility_notifier_owner.owns(p_rid); }
virtual RID visibility_notifier_allocate() override;
virtual void visibility_notifier_initialize(RID p_notifier) override;
diff --git a/drivers/metal/metal_objects.h b/drivers/metal/metal_objects.h
index 000c29ad19..cf21fef3c7 100644
--- a/drivers/metal/metal_objects.h
+++ b/drivers/metal/metal_objects.h
@@ -843,7 +843,7 @@ public:
if (!enabled)
return;
[p_enc setStencilFrontReferenceValue:front_reference backReferenceValue:back_reference];
- };
+ }
} stencil;
struct {
@@ -857,7 +857,7 @@ public:
//if (!enabled)
// return;
[p_enc setBlendColorRed:r green:g blue:b alpha:a];
- };
+ }
} blend;
_FORCE_INLINE_ void apply(id<MTLRenderCommandEncoder> __unsafe_unretained p_enc) const {
diff --git a/drivers/metal/rendering_device_driver_metal.h b/drivers/metal/rendering_device_driver_metal.h
index 977dd8e8aa..1f752811ee 100644
--- a/drivers/metal/rendering_device_driver_metal.h
+++ b/drivers/metal/rendering_device_driver_metal.h
@@ -412,7 +412,7 @@ 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 String get_api_name() const override final { return "Metal"; };
+ 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;
virtual const Capabilities &get_capabilities() const override final;
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h
index df4e6f5bbf..828557c3a5 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.h
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.h
@@ -102,7 +102,7 @@ class AudioDriverPulseAudio : public AudioDriver {
public:
virtual const char *get_name() const override {
return "PulseAudio";
- };
+ }
virtual Error init() override;
virtual void start() override;
diff --git a/drivers/vulkan/rendering_device_driver_vulkan.cpp b/drivers/vulkan/rendering_device_driver_vulkan.cpp
index 8c0b21e868..2b537a6720 100644
--- a/drivers/vulkan/rendering_device_driver_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_driver_vulkan.cpp
@@ -37,6 +37,16 @@
#include "thirdparty/misc/smolv.h"
#include "vulkan_hooks.h"
+#if defined(ANDROID_ENABLED)
+#include "platform/android/java_godot_wrapper.h"
+#include "platform/android/os_android.h"
+#include "platform/android/thread_jandroid.h"
+#endif
+
+#if defined(SWAPPY_FRAME_PACING_ENABLED)
+#include "thirdparty/swappy-frame-pacing/swappyVk.h"
+#endif
+
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#define PRINT_NATIVE_COMMANDS 0
@@ -540,6 +550,37 @@ Error RenderingDeviceDriverVulkan::_initialize_device_extensions() {
err = vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &device_extension_count, device_extensions.ptr());
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
+#if defined(SWAPPY_FRAME_PACING_ENABLED)
+ if (swappy_frame_pacer_enable) {
+ char **swappy_required_extensions;
+ uint32_t swappy_required_extensions_count = 0;
+ // Determine number of extensions required by Swappy frame pacer.
+ SwappyVk_determineDeviceExtensions(physical_device, device_extension_count, device_extensions.ptr(), &swappy_required_extensions_count, nullptr);
+
+ if (swappy_required_extensions_count < device_extension_count) {
+ // Determine the actual extensions.
+ swappy_required_extensions = (char **)malloc(swappy_required_extensions_count * sizeof(char *));
+ char *pRequiredExtensionsData = (char *)malloc(swappy_required_extensions_count * (VK_MAX_EXTENSION_NAME_SIZE + 1));
+ for (uint32_t i = 0; i < swappy_required_extensions_count; i++) {
+ swappy_required_extensions[i] = &pRequiredExtensionsData[i * (VK_MAX_EXTENSION_NAME_SIZE + 1)];
+ }
+ SwappyVk_determineDeviceExtensions(physical_device, device_extension_count,
+ device_extensions.ptr(), &swappy_required_extensions_count, swappy_required_extensions);
+
+ // Enable extensions requested by Swappy.
+ for (uint32_t i = 0; i < swappy_required_extensions_count; i++) {
+ CharString extension_name(swappy_required_extensions[i]);
+ if (requested_device_extensions.has(extension_name)) {
+ enabled_device_extension_names.insert(extension_name);
+ }
+ }
+
+ free(pRequiredExtensionsData);
+ free(swappy_required_extensions);
+ }
+ }
+#endif
+
#ifdef DEV_ENABLED
for (uint32_t i = 0; i < device_extension_count; i++) {
print_verbose(String("VULKAN: Found device extension ") + String::utf8(device_extensions[i].extensionName));
@@ -1381,6 +1422,18 @@ Error RenderingDeviceDriverVulkan::initialize(uint32_t p_device_index, uint32_t
breadcrumb_buffer = buffer_create(2u * sizeof(uint32_t) * BREADCRUMB_BUFFER_ENTRIES, BufferUsageBits::BUFFER_USAGE_TRANSFER_TO_BIT, MemoryAllocationType::MEMORY_ALLOCATION_TYPE_CPU);
#endif
+#if defined(SWAPPY_FRAME_PACING_ENABLED)
+ swappy_frame_pacer_enable = GLOBAL_GET("display/window/frame_pacing/android/enable_frame_pacing");
+ swappy_mode = GLOBAL_GET("display/window/frame_pacing/android/swappy_mode");
+
+ if (VulkanHooks::get_singleton() != nullptr) {
+ // Hooks control device creation & possibly presentation
+ // (e.g. OpenXR) thus it's too risky to use Swappy.
+ swappy_frame_pacer_enable = false;
+ OS::get_singleton()->print("VulkanHooks detected (e.g. OpenXR): Force-disabling Swappy Frame Pacing.\n");
+ }
+#endif
+
return OK;
}
@@ -2366,6 +2419,14 @@ RDD::CommandQueueID RenderingDeviceDriverVulkan::command_queue_create(CommandQue
ERR_FAIL_COND_V_MSG(picked_queue_index >= queue_family.size(), CommandQueueID(), "A queue in the picked family could not be found.");
+#if defined(SWAPPY_FRAME_PACING_ENABLED)
+ if (swappy_frame_pacer_enable) {
+ VkQueue selected_queue;
+ vkGetDeviceQueue(vk_device, family_index, picked_queue_index, &selected_queue);
+ SwappyVk_setQueueFamilyIndex(vk_device, selected_queue, family_index);
+ }
+#endif
+
// Create the virtual queue.
CommandQueue *command_queue = memnew(CommandQueue);
command_queue->queue_family = family_index;
@@ -2511,7 +2572,16 @@ Error RenderingDeviceDriverVulkan::command_queue_execute_and_present(CommandQueu
present_info.pResults = results.ptr();
device_queue.submit_mutex.lock();
+#if defined(SWAPPY_FRAME_PACING_ENABLED)
+ if (swappy_frame_pacer_enable) {
+ err = SwappyVk_queuePresent(device_queue.queue, &present_info);
+ } else {
+ err = device_functions.QueuePresentKHR(device_queue.queue, &present_info);
+ }
+#else
err = device_functions.QueuePresentKHR(device_queue.queue, &present_info);
+#endif
+
device_queue.submit_mutex.unlock();
// Set the index to an invalid value. If any of the swap chains returned out of date, indicate it should be resized the next time it's acquired.
@@ -2693,6 +2763,14 @@ void RenderingDeviceDriverVulkan::_swap_chain_release(SwapChain *swap_chain) {
swap_chain->framebuffers.clear();
if (swap_chain->vk_swapchain != VK_NULL_HANDLE) {
+#if defined(SWAPPY_FRAME_PACING_ENABLED)
+ if (swappy_frame_pacer_enable) {
+ // Swappy has a bug where the ANativeWindow will be leaked if we call
+ // SwappyVk_destroySwapchain, so we must release it by hand.
+ SwappyVk_setWindow(vk_device, swap_chain->vk_swapchain, nullptr);
+ SwappyVk_destroySwapchain(vk_device, swap_chain->vk_swapchain);
+ }
+#endif
device_functions.DestroySwapchainKHR(vk_device, swap_chain->vk_swapchain, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SWAPCHAIN_KHR));
swap_chain->vk_swapchain = VK_NULL_HANDLE;
}
@@ -2809,6 +2887,20 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
VkResult err = functions.GetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, surface->vk_surface, &surface_capabilities);
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
+ // No swapchain yet, this is the first time we're creating it.
+ if (!swap_chain->vk_swapchain) {
+ uint32_t width = surface_capabilities.currentExtent.width;
+ uint32_t height = surface_capabilities.currentExtent.height;
+ if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR ||
+ surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) {
+ // Swap to get identity width and height.
+ surface_capabilities.currentExtent.height = width;
+ surface_capabilities.currentExtent.width = height;
+ }
+
+ native_display_size = surface_capabilities.currentExtent;
+ }
+
VkExtent2D extent;
if (surface_capabilities.currentExtent.width == 0xFFFFFFFF) {
// The current extent is currently undefined, so the current surface width and height will be clamped to the surface's capabilities.
@@ -2859,9 +2951,7 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
}
bool present_mode_available = present_modes.has(present_mode);
- if (present_mode_available) {
- print_verbose("Using present mode: " + present_mode_name);
- } else {
+ if (!present_mode_available) {
// Present mode is not available, fall back to FIFO which is guaranteed to be supported.
WARN_PRINT(vformat("The requested V-Sync mode %s is not available. Falling back to V-Sync mode Enabled.", present_mode_name));
surface->vsync_mode = DisplayServer::VSYNC_ENABLED;
@@ -2875,15 +2965,8 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
desired_swapchain_images = MIN(desired_swapchain_images, surface_capabilities.maxImageCount);
}
- // Prefer identity transform if it's supported, use the current transform otherwise.
- // This behavior is intended as Redot does not supported native rotation in platforms that use these bits.
// Refer to the comment in command_queue_present() for more details.
- VkSurfaceTransformFlagBitsKHR surface_transform_bits;
- if (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
- surface_transform_bits = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
- } else {
- surface_transform_bits = surface_capabilities.currentTransform;
- }
+ VkSurfaceTransformFlagBitsKHR surface_transform_bits = surface_capabilities.currentTransform;
VkCompositeAlphaFlagBitsKHR composite_alpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
if (OS::get_singleton()->is_layered_allowed() || !(surface_capabilities.supportedCompositeAlpha & composite_alpha)) {
@@ -2910,7 +2993,7 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
swap_create_info.minImageCount = desired_swapchain_images;
swap_create_info.imageFormat = swap_chain->format;
swap_create_info.imageColorSpace = swap_chain->color_space;
- swap_create_info.imageExtent = extent;
+ swap_create_info.imageExtent = native_display_size;
swap_create_info.imageArrayLayers = 1;
swap_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
swap_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
@@ -2921,6 +3004,39 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
err = device_functions.CreateSwapchainKHR(vk_device, &swap_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SWAPCHAIN_KHR), &swap_chain->vk_swapchain);
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
+#if defined(SWAPPY_FRAME_PACING_ENABLED)
+ if (swappy_frame_pacer_enable) {
+ const double max_fps = Engine::get_singleton()->get_max_fps();
+ const uint64_t max_time = max_fps > 0 ? uint64_t((1000.0 * 1000.0 * 1000.0) / max_fps) : 0;
+
+ SwappyVk_initAndGetRefreshCycleDuration(get_jni_env(), static_cast<OS_Android *>(OS::get_singleton())->get_godot_java()->get_activity(), physical_device,
+ vk_device, swap_chain->vk_swapchain, &swap_chain->refresh_duration);
+ SwappyVk_setWindow(vk_device, swap_chain->vk_swapchain, static_cast<OS_Android *>(OS::get_singleton())->get_native_window());
+ SwappyVk_setSwapIntervalNS(vk_device, swap_chain->vk_swapchain, MAX(swap_chain->refresh_duration, max_time));
+
+ enum SwappyModes {
+ PIPELINE_FORCED_ON,
+ AUTO_FPS_PIPELINE_FORCED_ON,
+ AUTO_FPS_AUTO_PIPELINE,
+ };
+
+ switch (swappy_mode) {
+ case PIPELINE_FORCED_ON:
+ SwappyVk_setAutoSwapInterval(true);
+ SwappyVk_setAutoPipelineMode(true);
+ break;
+ case AUTO_FPS_PIPELINE_FORCED_ON:
+ SwappyVk_setAutoSwapInterval(true);
+ SwappyVk_setAutoPipelineMode(false);
+ break;
+ case AUTO_FPS_AUTO_PIPELINE:
+ SwappyVk_setAutoSwapInterval(false);
+ SwappyVk_setAutoPipelineMode(false);
+ break;
+ }
+ }
+#endif
+
uint32_t image_count = 0;
err = device_functions.GetSwapchainImagesKHR(vk_device, swap_chain->vk_swapchain, &image_count, nullptr);
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
@@ -3068,6 +3184,22 @@ RDD::DataFormat RenderingDeviceDriverVulkan::swap_chain_get_format(SwapChainID p
}
}
+void RenderingDeviceDriverVulkan::swap_chain_set_max_fps(SwapChainID p_swap_chain, int p_max_fps) {
+ DEV_ASSERT(p_swap_chain.id != 0);
+
+#ifdef SWAPPY_FRAME_PACING_ENABLED
+ if (!swappy_frame_pacer_enable) {
+ return;
+ }
+
+ SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id);
+ if (swap_chain->vk_swapchain != VK_NULL_HANDLE) {
+ const uint64_t max_time = p_max_fps > 0 ? uint64_t((1000.0 * 1000.0 * 1000.0) / p_max_fps) : 0;
+ SwappyVk_setSwapIntervalNS(vk_device, swap_chain->vk_swapchain, MAX(swap_chain->refresh_duration, max_time));
+ }
+#endif
+}
+
void RenderingDeviceDriverVulkan::swap_chain_free(SwapChainID p_swap_chain) {
DEV_ASSERT(p_swap_chain.id != 0);
diff --git a/drivers/vulkan/rendering_device_driver_vulkan.h b/drivers/vulkan/rendering_device_driver_vulkan.h
index c512d012fe..63c5396cfa 100644
--- a/drivers/vulkan/rendering_device_driver_vulkan.h
+++ b/drivers/vulkan/rendering_device_driver_vulkan.h
@@ -145,6 +145,11 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver {
#if defined(VK_TRACK_DEVICE_MEMORY)
bool device_memory_report_support = false;
#endif
+#if defined(SWAPPY_FRAME_PACING_ENABLED)
+ // Swappy frame pacer for Android.
+ bool swappy_frame_pacer_enable = false;
+ uint8_t swappy_mode = 2; // See default value for display/window/frame_pacing/android/swappy_mode.
+#endif
DeviceFunctions device_functions;
void _register_requested_device_extension(const CharString &p_extension_name, bool p_required);
@@ -357,9 +362,13 @@ private:
LocalVector<uint32_t> command_queues_acquired_semaphores;
RenderPassID render_pass;
uint32_t image_index = 0;
+#ifdef ANDROID_ENABLED
+ uint64_t refresh_duration = 0;
+#endif
};
void _swap_chain_release(SwapChain *p_swap_chain);
+ VkExtent2D native_display_size;
public:
virtual SwapChainID swap_chain_create(RenderingContextDriver::SurfaceID p_surface) override final;
@@ -367,6 +376,7 @@ public:
virtual FramebufferID swap_chain_acquire_framebuffer(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, bool &r_resize_required) override final;
virtual RenderPassID swap_chain_get_render_pass(SwapChainID p_swap_chain) override final;
virtual DataFormat swap_chain_get_format(SwapChainID p_swap_chain) override final;
+ virtual void swap_chain_set_max_fps(SwapChainID p_swap_chain, int p_max_fps) override final;
virtual void swap_chain_free(SwapChainID p_swap_chain) override final;
/*********************/
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp
index b020bf4eb3..5e3b0644fd 100644
--- a/drivers/wasapi/audio_driver_wasapi.cpp
+++ b/drivers/wasapi/audio_driver_wasapi.cpp
@@ -87,7 +87,7 @@ public:
_In_ const WAVEFORMATEX *pFormat,
/* [annotation][in] */
_In_opt_ LPCGUID AudioSessionGuid) = 0;
-};
+}
__CRT_UUID_DECL(IAudioClient3, 0x7ED4EE07, 0x8E67, 0x4CD4, 0x8C, 0x1A, 0x2B, 0x7A, 0x59, 0x87, 0xAD, 0x42)
#endif // __IAudioClient3_INTERFACE_DEFINED__