diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/SCsub | 3 | ||||
-rw-r--r-- | drivers/coreaudio/SCsub | 2 | ||||
-rw-r--r-- | drivers/coreaudio/audio_driver_coreaudio.h | 7 | ||||
-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.cpp | 4 | ||||
-rw-r--r-- | drivers/gles3/storage/config.h | 2 | ||||
-rw-r--r-- | drivers/gles3/storage/light_storage.h | 22 | ||||
-rw-r--r-- | drivers/gles3/storage/material_storage.h | 8 | ||||
-rw-r--r-- | drivers/gles3/storage/mesh_storage.h | 16 | ||||
-rw-r--r-- | drivers/gles3/storage/texture_storage.cpp | 2 | ||||
-rw-r--r-- | drivers/gles3/storage/texture_storage.h | 12 | ||||
-rw-r--r-- | drivers/gles3/storage/utilities.h | 4 | ||||
-rw-r--r-- | drivers/metal/metal_objects.h | 4 | ||||
-rw-r--r-- | drivers/metal/rendering_device_driver_metal.h | 2 | ||||
-rw-r--r-- | drivers/pulseaudio/audio_driver_pulseaudio.h | 2 | ||||
-rw-r--r-- | drivers/vulkan/rendering_device_driver_vulkan.cpp | 156 | ||||
-rw-r--r-- | drivers/vulkan/rendering_device_driver_vulkan.h | 10 | ||||
-rw-r--r-- | drivers/wasapi/audio_driver_wasapi.cpp | 2 |
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__ |