From 99297ff02bec82bd6c00732e35b8c52a3e41339f Mon Sep 17 00:00:00 2001 From: LavaDesu Date: Sun, 9 Oct 2022 21:49:26 +0700 Subject: [PATCH] packages/linux-lava: add atomic async page flips --- .../linux-lava/atomic-async-page-flips.patch | 227 ++++++++++++++++++ packages/linux-lava/sources.nix | 1 + 2 files changed, 228 insertions(+) create mode 100644 packages/linux-lava/atomic-async-page-flips.patch diff --git a/packages/linux-lava/atomic-async-page-flips.patch b/packages/linux-lava/atomic-async-page-flips.patch new file mode 100644 index 0000000..9c41421 --- /dev/null +++ b/packages/linux-lava/atomic-async-page-flips.patch @@ -0,0 +1,227 @@ +diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +index 288fce7dc0e..ad0341d89ec 100644 +--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +@@ -2791,6 +2791,7 @@ static int dce_v10_0_sw_init(void *handle) + adev_to_drm(adev)->mode_config.funcs = &amdgpu_mode_funcs; + + adev_to_drm(adev)->mode_config.async_page_flip = true; ++ adev_to_drm(adev)->mode_config.atomic_async_page_flip_not_supported = true; + + adev_to_drm(adev)->mode_config.max_width = 16384; + adev_to_drm(adev)->mode_config.max_height = 16384; +diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +index cbe5250b31c..dda923cc908 100644 +--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +@@ -2909,6 +2909,7 @@ static int dce_v11_0_sw_init(void *handle) + adev_to_drm(adev)->mode_config.funcs = &amdgpu_mode_funcs; + + adev_to_drm(adev)->mode_config.async_page_flip = true; ++ adev_to_drm(adev)->mode_config.atomic_async_page_flip_not_supported = true; + + adev_to_drm(adev)->mode_config.max_width = 16384; + adev_to_drm(adev)->mode_config.max_height = 16384; +diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c +index b1c44fab074..dcef4f873b6 100644 +--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c +@@ -2670,6 +2670,7 @@ static int dce_v6_0_sw_init(void *handle) + + adev_to_drm(adev)->mode_config.funcs = &amdgpu_mode_funcs; + adev_to_drm(adev)->mode_config.async_page_flip = true; ++ adev_to_drm(adev)->mode_config.atomic_async_page_flip_not_supported = true; + adev_to_drm(adev)->mode_config.max_width = 16384; + adev_to_drm(adev)->mode_config.max_height = 16384; + adev_to_drm(adev)->mode_config.preferred_depth = 24; +diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +index a22b45c9279..569bd11532e 100644 +--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +@@ -2688,6 +2688,7 @@ static int dce_v8_0_sw_init(void *handle) + adev_to_drm(adev)->mode_config.funcs = &amdgpu_mode_funcs; + + adev_to_drm(adev)->mode_config.async_page_flip = true; ++ adev_to_drm(adev)->mode_config.atomic_async_page_flip_not_supported = true; + + adev_to_drm(adev)->mode_config.max_width = 16384; + adev_to_drm(adev)->mode_config.max_height = 16384; +diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c +index 651e3c10936..831923c468d 100644 +--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c ++++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c +@@ -639,6 +639,7 @@ static int atmel_hlcdc_dc_modeset_init(struct drm_device *dev) + dev->mode_config.max_height = dc->desc->max_height; + dev->mode_config.funcs = &mode_config_funcs; + dev->mode_config.async_page_flip = true; ++ dev->mode_config.atomic_async_page_flip_not_supported = true; + + return 0; + } +diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c +index 79730fa1dd8..ee24ed7e2ed 100644 +--- a/drivers/gpu/drm/drm_atomic_uapi.c ++++ b/drivers/gpu/drm/drm_atomic_uapi.c +@@ -1278,6 +1278,18 @@ static void complete_signaling(struct drm_device *dev, + kfree(fence_state); + } + ++static void ++set_async_flip(struct drm_atomic_state *state) ++{ ++ struct drm_crtc *crtc; ++ struct drm_crtc_state *crtc_state; ++ int i; ++ ++ for_each_new_crtc_in_state(state, crtc, crtc_state, i) { ++ crtc_state->async_flip = true; ++ } ++} ++ + int drm_mode_atomic_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv) + { +@@ -1318,9 +1330,16 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, + } + + if (arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) { +- drm_dbg_atomic(dev, +- "commit failed: invalid flag DRM_MODE_PAGE_FLIP_ASYNC\n"); +- return -EINVAL; ++ if (!dev->mode_config.async_page_flip) { ++ drm_dbg_atomic(dev, ++ "commit failed: DRM_MODE_PAGE_FLIP_ASYNC not supported\n"); ++ return -EINVAL; ++ } ++ if (dev->mode_config.atomic_async_page_flip_not_supported) { ++ drm_dbg_atomic(dev, ++ "commit failed: DRM_MODE_PAGE_FLIP_ASYNC not supported with atomic\n"); ++ return -EINVAL; ++ } + } + + /* can't test and expect an event at the same time. */ +@@ -1418,6 +1437,9 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, + if (ret) + goto out; + ++ if (arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) ++ set_async_flip(state); ++ + if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) { + ret = drm_atomic_check_only(state); + } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) { +diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c +index 8faad23dc1d..6c399e50e40 100644 +--- a/drivers/gpu/drm/drm_ioctl.c ++++ b/drivers/gpu/drm/drm_ioctl.c +@@ -302,6 +302,11 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_ + case DRM_CAP_CRTC_IN_VBLANK_EVENT: + req->value = 1; + break; ++ case DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP: ++ req->value = drm_core_check_feature(dev, DRIVER_ATOMIC) && ++ dev->mode_config.async_page_flip && ++ !dev->mode_config.atomic_async_page_flip_not_supported; ++ break; + default: + return -EINVAL; + } +diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c +index fc5d94862ef..8793efbc049 100644 +--- a/drivers/gpu/drm/i915/display/intel_display.c ++++ b/drivers/gpu/drm/i915/display/intel_display.c +@@ -8616,6 +8616,7 @@ static void intel_mode_config_init(struct drm_i915_private *i915) + mode_config->funcs = &intel_mode_funcs; + + mode_config->async_page_flip = HAS_ASYNC_FLIPS(i915); ++ mode_config->atomic_async_page_flip_not_supported = true; + + /* + * Maximum framebuffer dimensions, chosen to match +diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c +index a2f5df568ca..2b5c4f24aed 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_display.c ++++ b/drivers/gpu/drm/nouveau/nouveau_display.c +@@ -699,6 +699,7 @@ nouveau_display_create(struct drm_device *dev) + dev->mode_config.async_page_flip = false; + else + dev->mode_config.async_page_flip = true; ++ dev->mode_config.atomic_async_page_flip_not_supported = true; + + drm_kms_helper_poll_init(dev); + drm_kms_helper_poll_disable(dev); +diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c +index f12675e3d26..1185275c3f8 100644 +--- a/drivers/gpu/drm/radeon/radeon_display.c ++++ b/drivers/gpu/drm/radeon/radeon_display.c +@@ -1588,6 +1588,7 @@ int radeon_modeset_init(struct radeon_device *rdev) + + if (radeon_use_pflipirq == 2 && rdev->family >= CHIP_R600) + rdev->ddev->mode_config.async_page_flip = true; ++ rdev->ddev->mode_config.atomic_async_page_flip_not_supported = true; + + if (ASIC_IS_DCE5(rdev)) { + rdev->ddev->mode_config.max_width = 16384; +diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c +index b45dcdfd730..44102b80eb6 100644 +--- a/drivers/gpu/drm/vc4/vc4_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_kms.c +@@ -1048,6 +1048,7 @@ int vc4_kms_load(struct drm_device *dev) + dev->mode_config.helper_private = &vc4_mode_config_helpers; + dev->mode_config.preferred_depth = 24; + dev->mode_config.async_page_flip = true; ++ dev->mode_config.atomic_async_page_flip_not_supported = true; + + ret = vc4_ctm_obj_init(vc4); + if (ret) +diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h +index 6b5e0129534..1b535d94f2f 100644 +--- a/include/drm/drm_mode_config.h ++++ b/include/drm/drm_mode_config.h +@@ -917,6 +917,17 @@ struct drm_mode_config { + */ + bool async_page_flip; + ++ /** ++ * @atomic_async_page_flip_not_supported: ++ * ++ * If true, the driver does not support async page-flips with the ++ * atomic uAPI. This is only used by old drivers which haven't yet ++ * accomodated for &drm_crtc_state.async_flip in their atomic logic, ++ * even if they have &drm_mode_config.async_page_flip set to true. ++ * New drivers shall not set this flag. ++ */ ++ bool atomic_async_page_flip_not_supported; ++ + /** + * @fb_modifiers_not_supported: + * +diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h +index 642808520d9..b1962628ecd 100644 +--- a/include/uapi/drm/drm.h ++++ b/include/uapi/drm/drm.h +@@ -706,7 +706,8 @@ struct drm_gem_open { + /** + * DRM_CAP_ASYNC_PAGE_FLIP + * +- * If set to 1, the driver supports &DRM_MODE_PAGE_FLIP_ASYNC. ++ * If set to 1, the driver supports &DRM_MODE_PAGE_FLIP_ASYNC for legacy ++ * page-flips. + */ + #define DRM_CAP_ASYNC_PAGE_FLIP 0x7 + /** +@@ -767,6 +768,13 @@ struct drm_gem_open { + * Documentation/gpu/drm-mm.rst, section "DRM Sync Objects". + */ + #define DRM_CAP_SYNCOBJ_TIMELINE 0x14 ++/** ++ * DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP ++ * ++ * If set to 1, the driver supports &DRM_MODE_PAGE_FLIP_ASYNC for atomic ++ * commits. ++ */ ++#define DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP 0x15 + + /* DRM_IOCTL_GET_CAP ioctl argument type */ + struct drm_get_cap { diff --git a/packages/linux-lava/sources.nix b/packages/linux-lava/sources.nix index c63f093..66636ce 100644 --- a/packages/linux-lava/sources.nix +++ b/packages/linux-lava/sources.nix @@ -53,6 +53,7 @@ in { #kernelPatchSrc borePatch (patch ./si-manual-clocking.patch) + (patch ./atomic-async-page-flips.patch) (patch ./winesync-hotfix.patch) ] ++ builtins.map (name: {