diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/d3d12/rendering_context_driver_d3d12.cpp | 1 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 10 | ||||
-rw-r--r-- | drivers/gles3/storage/mesh_storage.cpp | 19 | ||||
-rw-r--r-- | drivers/gles3/storage/texture_storage.cpp | 2 | ||||
-rw-r--r-- | drivers/vulkan/rendering_context_driver_vulkan.cpp | 28 | ||||
-rw-r--r-- | drivers/vulkan/rendering_context_driver_vulkan.h | 1 | ||||
-rw-r--r-- | drivers/wasapi/audio_driver_wasapi.cpp | 55 | ||||
-rw-r--r-- | drivers/wasapi/audio_driver_wasapi.h | 9 |
8 files changed, 68 insertions, 57 deletions
diff --git a/drivers/d3d12/rendering_context_driver_d3d12.cpp b/drivers/d3d12/rendering_context_driver_d3d12.cpp index 726be064bd..128b8bcd03 100644 --- a/drivers/d3d12/rendering_context_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_context_driver_d3d12.cpp @@ -173,6 +173,7 @@ Error RenderingContextDriverD3D12::_initialize_devices() { Device &device = driver_devices[i]; device.name = desc.Description; device.vendor = Vendor(desc.VendorId); + device.workarounds = Workarounds(); if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { device.type = DEVICE_TYPE_CPU; diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 7048301e57..03f947cd05 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -2394,6 +2394,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ RS::EnvironmentBG bg_mode = environment_get_background(render_data.environment); float bg_energy_multiplier = environment_get_bg_energy_multiplier(render_data.environment); bg_energy_multiplier *= environment_get_bg_intensity(render_data.environment); + RS::EnvironmentReflectionSource reflection_source = environment_get_reflection_source(render_data.environment); if (render_data.camera_attributes.is_valid()) { bg_energy_multiplier *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(render_data.camera_attributes); @@ -2404,7 +2405,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ clear_color.r *= bg_energy_multiplier; clear_color.g *= bg_energy_multiplier; clear_color.b *= bg_energy_multiplier; - if (environment_get_fog_enabled(render_data.environment)) { + if (!render_data.transparent_bg && environment_get_fog_enabled(render_data.environment)) { draw_sky_fog_only = true; GLES3::MaterialStorage::get_singleton()->material_set_param(sky_globals.fog_material, "clear_color", Variant(clear_color)); } @@ -2414,13 +2415,13 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ clear_color.r *= bg_energy_multiplier; clear_color.g *= bg_energy_multiplier; clear_color.b *= bg_energy_multiplier; - if (environment_get_fog_enabled(render_data.environment)) { + if (!render_data.transparent_bg && environment_get_fog_enabled(render_data.environment)) { draw_sky_fog_only = true; GLES3::MaterialStorage::get_singleton()->material_set_param(sky_globals.fog_material, "clear_color", Variant(clear_color)); } } break; case RS::ENV_BG_SKY: { - draw_sky = true; + draw_sky = !render_data.transparent_bg; } break; case RS::ENV_BG_CANVAS: { keep_color = true; @@ -2433,8 +2434,9 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ default: { } } + // setup sky if used for ambient, reflections, or background - if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(render_data.environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(render_data.environment) == RS::ENV_AMBIENT_SOURCE_SKY) { + if (draw_sky || draw_sky_fog_only || (reflection_source == RS::ENV_REFLECTION_SOURCE_BG && bg_mode == RS::ENV_BG_SKY) || reflection_source == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(render_data.environment) == RS::ENV_AMBIENT_SOURCE_SKY) { RENDER_TIMESTAMP("Setup Sky"); Projection projection = render_data.cam_projection; if (is_reflection_probe) { diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp index e073db3cfd..d8a5b960b8 100644 --- a/drivers/gles3/storage/mesh_storage.cpp +++ b/drivers/gles3/storage/mesh_storage.cpp @@ -1936,6 +1936,11 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_b glBindBuffer(GL_ARRAY_BUFFER, 0); } else { + // If we have a data cache, just update it. + if (multimesh->data_cache.size()) { + multimesh->data_cache = p_buffer; + } + // Only Transform is being used, so we can upload directly. ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)multimesh->stride_cache)); const float *r = p_buffer.ptr(); @@ -1947,16 +1952,12 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_b multimesh->buffer_set = true; if (multimesh->data_cache.size() || multimesh->uses_colors || multimesh->uses_custom_data) { - //if we have a data cache, just update it - multimesh->data_cache = multimesh->data_cache; - { - //clear dirty since nothing will be dirty anymore - uint32_t data_cache_dirty_region_count = Math::division_round_up(multimesh->instances, MULTIMESH_DIRTY_REGION_SIZE); - for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) { - multimesh->data_cache_dirty_regions[i] = false; - } - multimesh->data_cache_used_dirty_regions = 0; + // Clear dirty since nothing will be dirty anymore. + uint32_t data_cache_dirty_region_count = Math::division_round_up(multimesh->instances, MULTIMESH_DIRTY_REGION_SIZE); + for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) { + multimesh->data_cache_dirty_regions[i] = false; } + multimesh->data_cache_used_dirty_regions = 0; _multimesh_mark_all_dirty(multimesh, false, true); //update AABB } else if (multimesh->mesh.is_valid()) { diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index 68d10b0c39..2dcf623995 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/drivers/gles3/storage/texture_storage.cpp @@ -1391,7 +1391,7 @@ void TextureStorage::texture_debug_usage(List<RS::TextureInfo> *r_info) { tinfo.format = t->format; tinfo.width = t->alloc_width; tinfo.height = t->alloc_height; - tinfo.depth = 0; + tinfo.depth = t->depth; tinfo.bytes = t->total_data_size; r_info->push_back(tinfo); } diff --git a/drivers/vulkan/rendering_context_driver_vulkan.cpp b/drivers/vulkan/rendering_context_driver_vulkan.cpp index 6eb25743f9..7cba820978 100644 --- a/drivers/vulkan/rendering_context_driver_vulkan.cpp +++ b/drivers/vulkan/rendering_context_driver_vulkan.cpp @@ -502,6 +502,9 @@ Error RenderingContextDriverVulkan::_initialize_devices() { driver_device.name = String::utf8(props.deviceName); driver_device.vendor = Vendor(props.vendorID); driver_device.type = DeviceType(props.deviceType); + driver_device.workarounds = Workarounds(); + + _check_driver_workarounds(props, driver_device); uint32_t queue_family_properties_count = 0; vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &queue_family_properties_count, nullptr); @@ -515,6 +518,31 @@ Error RenderingContextDriverVulkan::_initialize_devices() { return OK; } +void RenderingContextDriverVulkan::_check_driver_workarounds(const VkPhysicalDeviceProperties &p_device_properties, Device &r_device) { + // Workaround for the Adreno 6XX family of devices. + // + // There's a known issue with the Vulkan driver in this family of devices where it'll crash if a dynamic state for drawing is + // used in a command buffer before a dispatch call is issued. As both dynamic scissor and viewport are basic requirements for + // the engine to not bake this state into the PSO, the only known way to fix this issue is to reset the command buffer entirely. + // + // As the render graph has no built in limitations of whether it'll issue compute work before anything needs to draw on the + // frame, and there's no guarantee that compute work will never be dependent on rasterization in the future, this workaround + // will end recording on the current command buffer any time a compute list is encountered after a draw list was executed. + // A new command buffer will be created afterwards and the appropriate synchronization primitives will be inserted. + // + // Executing this workaround has the added cost of synchronization between all the command buffers that are created as well as + // all the individual submissions. This performance hit is accepted for the sake of being able to support these devices without + // limiting the design of the renderer. + // + // This bug was fixed in driver version 512.503.0, so we only enabled it on devices older than this. + // + r_device.workarounds.avoid_compute_after_draw = + r_device.vendor == VENDOR_QUALCOMM && + p_device_properties.deviceID >= 0x6000000 && // Adreno 6xx + p_device_properties.driverVersion < VK_MAKE_VERSION(512, 503, 0) && + r_device.name.find("Turnip") < 0; +} + bool RenderingContextDriverVulkan::_use_validation_layers() const { return Engine::get_singleton()->is_validation_layers_enabled(); } diff --git a/drivers/vulkan/rendering_context_driver_vulkan.h b/drivers/vulkan/rendering_context_driver_vulkan.h index 6348f90d55..f1d4021e32 100644 --- a/drivers/vulkan/rendering_context_driver_vulkan.h +++ b/drivers/vulkan/rendering_context_driver_vulkan.h @@ -105,6 +105,7 @@ private: Error _initialize_instance_extensions(); Error _initialize_instance(); Error _initialize_devices(); + void _check_driver_workarounds(const VkPhysicalDeviceProperties &p_device_properties, Device &r_device); // Static callbacks. static VKAPI_ATTR VkBool32 VKAPI_CALL _debug_messenger_callback(VkDebugUtilsMessageSeverityFlagBitsEXT p_message_severity, VkDebugUtilsMessageTypeFlagsEXT p_message_type, const VkDebugUtilsMessengerCallbackDataEXT *p_callback_data, void *p_user_data); diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index 8ea1f52d15..a349a66f75 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -107,12 +107,6 @@ const IID IID_IAudioClient3 = __uuidof(IAudioClient3); const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient); const IID IID_IAudioCaptureClient = __uuidof(IAudioCaptureClient); -#define SAFE_RELEASE(memory) \ - if ((memory) != nullptr) { \ - (memory)->Release(); \ - (memory) = nullptr; \ - } - #define REFTIMES_PER_SEC 10000000 #define REFTIMES_PER_MILLISEC 10000 @@ -129,16 +123,10 @@ static bool default_input_device_changed = false; class CMMNotificationClient : public IMMNotificationClient { LONG _cRef = 1; - IMMDeviceEnumerator *_pEnumerator = nullptr; public: CMMNotificationClient() {} - virtual ~CMMNotificationClient() { - if ((_pEnumerator) != nullptr) { - (_pEnumerator)->Release(); - (_pEnumerator) = nullptr; - } - } + virtual ~CMMNotificationClient() {} ULONG STDMETHODCALLTYPE AddRef() { return InterlockedIncrement(&_cRef); @@ -203,8 +191,8 @@ static CMMNotificationClient notif_client; Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_input, bool p_reinit, bool p_no_audio_client_3) { WAVEFORMATEX *pwfex; - IMMDeviceEnumerator *enumerator = nullptr; - IMMDevice *output_device = nullptr; + ComPtr<IMMDeviceEnumerator> enumerator = nullptr; + ComPtr<IMMDevice> output_device = nullptr; HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void **)&enumerator); ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN); @@ -212,7 +200,7 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_i if (p_device->device_name == "Default") { hr = enumerator->GetDefaultAudioEndpoint(p_input ? eCapture : eRender, eConsole, &output_device); } else { - IMMDeviceCollection *devices = nullptr; + ComPtr<IMMDeviceCollection> devices = nullptr; hr = enumerator->EnumAudioEndpoints(p_input ? eCapture : eRender, DEVICE_STATE_ACTIVE, &devices); ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN); @@ -225,12 +213,12 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_i ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN); for (ULONG i = 0; i < count && !found; i++) { - IMMDevice *tmp_device = nullptr; + ComPtr<IMMDevice> tmp_device = nullptr; hr = devices->Item(i, &tmp_device); ERR_BREAK(hr != S_OK); - IPropertyStore *props = nullptr; + ComPtr<IPropertyStore> props = nullptr; hr = tmp_device->OpenPropertyStore(STGM_READ, &props); ERR_BREAK(hr != S_OK); @@ -248,8 +236,6 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_i } PropVariantClear(&propvar); - props->Release(); - tmp_device->Release(); } if (found) { @@ -276,7 +262,6 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_i } hr = enumerator->RegisterEndpointNotificationCallback(¬if_client); - SAFE_RELEASE(enumerator) if (hr != S_OK) { ERR_PRINT("WASAPI: RegisterEndpointNotificationCallback error"); @@ -303,8 +288,6 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_i hr = output_device->Activate(IID_IAudioClient, CLSCTX_ALL, nullptr, (void **)&p_device->audio_client); } - SAFE_RELEASE(output_device) - if (p_reinit) { if (hr != S_OK) { return ERR_CANT_OPEN; @@ -319,7 +302,7 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_i audioProps.bIsOffload = FALSE; audioProps.eCategory = AudioCategory_GameEffects; - hr = ((IAudioClient3 *)p_device->audio_client)->SetClientProperties(&audioProps); + hr = ((IAudioClient3 *)p_device->audio_client.Get())->SetClientProperties(&audioProps); ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_CANT_OPEN, "WASAPI: SetClientProperties failed with error 0x" + String::num_uint64(hr, 16) + "."); } @@ -402,7 +385,7 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_i } } else { - IAudioClient3 *device_audio_client_3 = (IAudioClient3 *)p_device->audio_client; + IAudioClient3 *device_audio_client_3 = (IAudioClient3 *)p_device->audio_client.Get(); // AUDCLNT_STREAMFLAGS_RATEADJUST is an invalid flag with IAudioClient3, therefore we have to use // the closest supported mix rate supported by the audio driver. @@ -419,7 +402,6 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_i if (hr != S_OK) { print_verbose("WASAPI: GetSharedModeEnginePeriod failed with error 0x" + String::num_uint64(hr, 16) + ", falling back to IAudioClient."); CoTaskMemFree(pwfex); - SAFE_RELEASE(output_device) return audio_device_init(p_device, p_input, p_reinit, true); } @@ -441,7 +423,6 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_i if (hr != S_OK) { print_verbose("WASAPI: InitializeSharedAudioStream failed with error 0x" + String::num_uint64(hr, 16) + ", falling back to IAudioClient."); CoTaskMemFree(pwfex); - SAFE_RELEASE(output_device); return audio_device_init(p_device, p_input, p_reinit, true); } else { uint32_t output_latency_in_frames; @@ -453,7 +434,6 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_i } else { print_verbose("WASAPI: GetCurrentSharedModeEnginePeriod failed with error 0x" + String::num_uint64(hr, 16) + ", falling back to IAudioClient."); CoTaskMemFree(pwfex); - SAFE_RELEASE(output_device); return audio_device_init(p_device, p_input, p_reinit, true); } } @@ -468,7 +448,6 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_i // Free memory CoTaskMemFree(pwfex); - SAFE_RELEASE(output_device) return OK; } @@ -537,9 +516,9 @@ Error AudioDriverWASAPI::audio_device_finish(AudioDeviceWASAPI *p_device) { p_device->active.clear(); } - SAFE_RELEASE(p_device->audio_client) - SAFE_RELEASE(p_device->render_client) - SAFE_RELEASE(p_device->capture_client) + p_device->audio_client.Reset(); + p_device->render_client.Reset(); + p_device->capture_client.Reset(); return OK; } @@ -581,8 +560,8 @@ AudioDriver::SpeakerMode AudioDriverWASAPI::get_speaker_mode() const { PackedStringArray AudioDriverWASAPI::audio_device_get_list(bool p_input) { PackedStringArray list; - IMMDeviceCollection *devices = nullptr; - IMMDeviceEnumerator *enumerator = nullptr; + ComPtr<IMMDeviceCollection> devices = nullptr; + ComPtr<IMMDeviceEnumerator> enumerator = nullptr; list.push_back(String("Default")); @@ -597,12 +576,12 @@ PackedStringArray AudioDriverWASAPI::audio_device_get_list(bool p_input) { ERR_FAIL_COND_V(hr != S_OK, PackedStringArray()); for (ULONG i = 0; i < count; i++) { - IMMDevice *output_device = nullptr; + ComPtr<IMMDevice> output_device = nullptr; hr = devices->Item(i, &output_device); ERR_BREAK(hr != S_OK); - IPropertyStore *props = nullptr; + ComPtr<IPropertyStore> props = nullptr; hr = output_device->OpenPropertyStore(STGM_READ, &props); ERR_BREAK(hr != S_OK); @@ -615,12 +594,8 @@ PackedStringArray AudioDriverWASAPI::audio_device_get_list(bool p_input) { list.push_back(String(propvar.pwszVal)); PropVariantClear(&propvar); - props->Release(); - output_device->Release(); } - devices->Release(); - enumerator->Release(); return list; } diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h index 367c30607a..d73cbf4a8a 100644 --- a/drivers/wasapi/audio_driver_wasapi.h +++ b/drivers/wasapi/audio_driver_wasapi.h @@ -40,15 +40,18 @@ #include <audioclient.h> #include <mmdeviceapi.h> +#include <wrl/client.h> #define WIN32_LEAN_AND_MEAN #include <windows.h> +using Microsoft::WRL::ComPtr; + class AudioDriverWASAPI : public AudioDriver { class AudioDeviceWASAPI { public: - IAudioClient *audio_client = nullptr; - IAudioRenderClient *render_client = nullptr; // Output - IAudioCaptureClient *capture_client = nullptr; // Input + ComPtr<IAudioClient> audio_client = nullptr; + ComPtr<IAudioRenderClient> render_client = nullptr; // Output + ComPtr<IAudioCaptureClient> capture_client = nullptr; // Input SafeFlag active; WORD format_tag = 0; |