From c32515c11a2f18531cb8ba67a024c1a7255d1462 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Wed, 18 May 2022 03:27:43 +0000 Subject: [PATCH] nvkms: Implement CRTC_X/Y for primary planes This is used by Gamescope for centring the game's buffer. Adds a check to see if the `supportsWindowMode` cap is supported for the main plane (EVO3+) and implements CRTC_X/Y for NVKMS_MAIN_LAYER if it is supported. This was not checked before, so CRTC_X could be specified on the main layer, and the atomic commit would succeed, resulting in incorrect output. --- .../kapi/include/nvkms-kapi-internal.h | 2 ++ src/nvidia-modeset/kapi/src/nvkms-kapi.c | 15 +++++++++++++++ src/nvidia-modeset/src/nvkms-console-restore.c | 4 ++++ 3 files changed, 21 insertions(+) diff --git a/src/nvidia-modeset/kapi/include/nvkms-kapi-internal.h b/src/nvidia-modeset/kapi/include/nvkms-kapi-internal.h index e37cb9598..d5b0e2f5c 100644 --- a/src/nvidia-modeset/kapi/include/nvkms-kapi-internal.h +++ b/src/nvidia-modeset/kapi/include/nvkms-kapi-internal.h @@ -71,6 +71,8 @@ struct NvKmsKapiDevice { /* Device capabilities */ struct { + NvBool mainLayerSupportsWindowMode; + struct NvKmsCompositionCapabilities cursorCompositionCaps; struct NvKmsCompositionCapabilities overlayCompositionCaps; diff --git a/src/nvidia-modeset/kapi/src/nvkms-kapi.c b/src/nvidia-modeset/kapi/src/nvkms-kapi.c index 4c6100cc9..43e8ae488 100644 --- a/src/nvidia-modeset/kapi/src/nvkms-kapi.c +++ b/src/nvidia-modeset/kapi/src/nvkms-kapi.c @@ -339,6 +339,9 @@ static NvBool KmsAllocateDevice(struct NvKmsKapiDevice *device) device->hKmsDevice = paramsAlloc->reply.deviceHandle; + device->caps.mainLayerSupportsWindowMode = + paramsAlloc->reply.layerCaps[NVKMS_MAIN_LAYER].supportsWindowMode; + device->caps.cursorCompositionCaps = paramsAlloc->reply.cursorCompositionCaps; @@ -2432,6 +2435,18 @@ static NvBool NvKmsKapiPrimaryLayerConfigToKms( changed = TRUE; } + if (layerRequestedConfig->flags.dstXYChanged || bFromKmsSetMode) { + /* If the main layer doesn't support window mode, + * then return false here to fail the commit/test. */ + if (!device->caps.mainLayerSupportsWindowMode && + (layerConfig->dstX != 0 || layerConfig->dstY != 0)) + return NV_FALSE; + + params->layer[NVKMS_MAIN_LAYER].outputPosition.val.x = layerConfig->dstX; + params->layer[NVKMS_MAIN_LAYER].outputPosition.val.y = layerConfig->dstY; + params->layer[NVKMS_MAIN_LAYER].outputPosition.specified = TRUE; + } + if (layerRequestedConfig->flags.srcXYChanged || bFromKmsSetMode) { params->viewPortIn.point.x = layerConfig->srcX; params->viewPortIn.point.y = layerConfig->srcY; diff --git a/src/nvidia-modeset/src/nvkms-console-restore.c b/src/nvidia-modeset/src/nvkms-console-restore.c index 891fdbd61..65a76830a 100644 --- a/src/nvidia-modeset/src/nvkms-console-restore.c +++ b/src/nvidia-modeset/src/nvkms-console-restore.c @@ -232,6 +232,10 @@ static NvBool InitModeOneHeadRequest( pFlip->layer[NVKMS_MAIN_LAYER].sizeOut.val = pFlip->layer[NVKMS_MAIN_LAYER].sizeIn.val; + pFlip->layer[NVKMS_MAIN_LAYER].outputPosition.specified = TRUE; + pFlip->layer[NVKMS_MAIN_LAYER].outputPosition.val.x = 0; + pFlip->layer[NVKMS_MAIN_LAYER].outputPosition.val.y = 0; + /* Disable other layers except Main */ for (layer = 0; layer < pDevEvo->head[head].numLayers; layer++) {