summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/d3d12/rendering_context_driver_d3d12.cpp1
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp10
-rw-r--r--drivers/vulkan/rendering_context_driver_vulkan.cpp28
-rw-r--r--drivers/vulkan/rendering_context_driver_vulkan.h1
4 files changed, 36 insertions, 4 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/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);