mirror of
https://github.com/NVIDIA/open-gpu-kernel-modules.git
synced 2026-02-01 14:09:47 +00:00
560.28.03
This commit is contained in:
@@ -200,6 +200,7 @@ SHADER_OBJS =
|
||||
$(eval $(call COMPRESS_SHADERS,turing))
|
||||
$(eval $(call COMPRESS_SHADERS,ampere))
|
||||
$(eval $(call COMPRESS_SHADERS,hopper))
|
||||
$(eval $(call COMPRESS_SHADERS,blackwell))
|
||||
|
||||
OBJS = $(call BUILD_OBJECT_LIST,$(ALL_SRCS))
|
||||
OBJS += $(SHADER_OBJS)
|
||||
|
||||
@@ -83,7 +83,8 @@ NvBool nvDpyIsAdaptiveSyncDefaultlisted(const NVDpyEvoRec *pDpyEvo);
|
||||
enum NvKmsDpyAttributeDigitalSignalValue
|
||||
nvGetDefaultDpyAttributeDigitalSignalValue(const NVConnectorEvoRec *pConnectorEvo);
|
||||
|
||||
NVColorFormatInfoRec nvGetColorFormatInfo(const NVDpyEvoRec *pDpyEvo);
|
||||
NvKmsDpyOutputColorFormatInfo nvDpyGetOutputColorFormatInfo(
|
||||
const NVDpyEvoRec *pDpyEvo);
|
||||
|
||||
NvU32 nvDpyGetPossibleApiHeadsMask(const NVDpyEvoRec *pDpyEvo);
|
||||
|
||||
|
||||
@@ -180,10 +180,12 @@ NvBool nvConstructHwModeTimingsImpCheckEvo(
|
||||
NvU32 *pNumHeads,
|
||||
NVEvoInfoStringPtr pInfoString);
|
||||
|
||||
NvBool nvDowngradeColorBpc(NVDpyAttributeColor *pDpyColor);
|
||||
NvBool nvDowngradeColorBpc(
|
||||
const NvKmsDpyOutputColorFormatInfo *pSupportedColorFormats,
|
||||
NVDpyAttributeColor *pDpyColor);
|
||||
|
||||
NvBool nvDowngradeColorSpaceAndBpc(
|
||||
const NVColorFormatInfoRec *pSupportedColorFormats,
|
||||
const NvKmsDpyOutputColorFormatInfo *pSupportedColorFormats,
|
||||
NVDpyAttributeColor *pDpyColor);
|
||||
|
||||
NvBool nvDPValidateModeEvo(NVDpyEvoPtr pDpyEvo,
|
||||
@@ -259,6 +261,7 @@ NvBool nvChooseCurrentColorSpaceAndRangeEvo(
|
||||
const enum NvYuv420Mode yuv420Mode,
|
||||
enum NvKmsOutputColorimetry colorimetry,
|
||||
const enum NvKmsDpyAttributeRequestedColorSpaceValue requestedColorSpace,
|
||||
const enum NvKmsDpyAttributeColorBpcValue requestedColorBpc,
|
||||
const enum NvKmsDpyAttributeColorRangeValue requestedColorRange,
|
||||
enum NvKmsDpyAttributeCurrentColorSpaceValue *pCurrentColorSpace,
|
||||
enum NvKmsDpyAttributeColorBpcValue *pCurrentColorBpc,
|
||||
@@ -347,8 +350,9 @@ enum nvKmsPixelDepth nvEvoDpyColorToPixelDepth(
|
||||
void nvSuspendDevEvo(NVDevEvoRec *pDevEvo);
|
||||
NvBool nvResumeDevEvo(NVDevEvoRec *pDevEvo);
|
||||
|
||||
NvBool nvGetDefaultDpyColor(const NVColorFormatInfoRec *pColorFormatsInfo,
|
||||
NVDpyAttributeColor *pDpyColor);
|
||||
NvBool nvGetDefaultDpyColor(
|
||||
const NvKmsDpyOutputColorFormatInfo *pColorFormatsInfo,
|
||||
NVDpyAttributeColor *pDpyColor);
|
||||
|
||||
static inline void nvEvoSetFlipOccurredEvent(const NVDispEvoRec *pDispEvo,
|
||||
const NvU32 head,
|
||||
|
||||
@@ -44,6 +44,7 @@ typedef struct {
|
||||
NvBool hdrInfoFrameOverride;
|
||||
NvU32 hdrStaticMetadataLayerMask;
|
||||
NvBool colorSpaceSpecified : 1;
|
||||
NvBool colorBpcSpecified : 1;
|
||||
NvBool colorRangeSpecified : 1;
|
||||
NvBool hs10bpcHint : 1;
|
||||
NvBool changed : 1;
|
||||
|
||||
@@ -680,19 +680,6 @@ typedef struct {
|
||||
} maxDownscaleFactors;
|
||||
} NVFlipChannelEvoHwState;
|
||||
|
||||
enum NvKmsDpyAttributeColorBpcValue {
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_UNKNOWN = 0,
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10 = 10,
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8 = 8,
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_6 = 6,
|
||||
};
|
||||
|
||||
typedef struct _NVColorFormatInfoRec {
|
||||
struct {
|
||||
enum NvKmsDpyAttributeColorBpcValue maxBpc;
|
||||
} rgb444, yuv444, yuv422;
|
||||
} NVColorFormatInfoRec;
|
||||
|
||||
typedef struct {
|
||||
struct NvKmsPoint viewPortPointIn;
|
||||
NVFlipCursorEvoHwState cursor;
|
||||
@@ -1961,6 +1948,9 @@ typedef struct _NVDispEvoRec {
|
||||
NVDpyIdList muxDisplays;
|
||||
|
||||
struct {
|
||||
// Indicates whether a VRR cookie was detected
|
||||
NvBool hasPlatformCookie;
|
||||
|
||||
nvkms_timer_handle_t *unstallTimer;
|
||||
} vrr;
|
||||
|
||||
@@ -2151,6 +2141,7 @@ typedef struct _NVDpyEvoRec {
|
||||
|
||||
NvU8 laneCount; // NV0073_CTRL_DP_DATA_SET_LANE_COUNT
|
||||
NvU8 linkRate; // NV0073_CTRL_DP_DATA_SET_LINK_BW
|
||||
NvU32 linkRate10MHz;
|
||||
enum NvKmsDpyAttributeDisplayportConnectorTypeValue connectorType;
|
||||
NvBool sinkIsAudioCapable;
|
||||
|
||||
@@ -2192,7 +2183,6 @@ typedef struct _NVDpyEvoRec {
|
||||
|
||||
struct {
|
||||
enum NvKmsDpyVRRType type;
|
||||
NvU32 edidTimeoutMicroseconds;
|
||||
NvBool needsSwFramePacing;
|
||||
} vrr;
|
||||
} NVDpyEvoRec;
|
||||
@@ -2433,6 +2423,12 @@ static inline NvBool nvIsEmulationEvo(const NVDevEvoRec *pDevEvo)
|
||||
NV2080_CTRL_GPU_GET_SIMULATION_INFO_TYPE_NONE;
|
||||
}
|
||||
|
||||
static inline NvBool nvIsDfpgaEvo(const NVDevEvoRec *pDevEvo)
|
||||
{
|
||||
return pDevEvo->simulationType ==
|
||||
NV2080_CTRL_GPU_GET_SIMULATION_INFO_TYPE_DFPGA;
|
||||
}
|
||||
|
||||
static inline NvBool nvIs3DVisionStereoEvo(const enum NvKmsStereoMode stereo)
|
||||
{
|
||||
return (stereo == NVKMS_STEREO_NVIDIA_3D_VISION ||
|
||||
|
||||
@@ -118,8 +118,8 @@ static inline NvBool nvExceedsTimeoutUSec(
|
||||
{
|
||||
const NvU64 currentTime = nvkms_get_usec();
|
||||
|
||||
if (nvIsEmulationEvo(pDevEvo)) {
|
||||
return FALSE;
|
||||
if (nvIsEmulationEvo(pDevEvo) && !nvIsDfpgaEvo(pDevEvo)) {
|
||||
timeoutPeriod *= 100;
|
||||
}
|
||||
|
||||
if (*pStartTime == 0) {
|
||||
|
||||
@@ -36,11 +36,12 @@ nvGetAllowedDpyVrrType(const NVDpyEvoRec *pDpyEvo,
|
||||
enum NvKmsStereoMode stereoMode,
|
||||
const NvBool allowGsync,
|
||||
const enum NvKmsAllowAdaptiveSync allowAdaptiveSync);
|
||||
void nvAdjustHwModeTimingsForVrrEvo(NVHwModeTimingsEvoPtr pTimings,
|
||||
const enum NvKmsDpyVRRType vrrType,
|
||||
const NvU32 edidTimeoutMicroseconds,
|
||||
const NvU32 vrrOverrideMinRefreshRate,
|
||||
const NvBool needsSwFramePacing);
|
||||
void nvAdjustHwModeTimingsForVrrEvo(
|
||||
const NVDpyEvoRec *pDpyEvo,
|
||||
const enum NvKmsDpyVRRType vrrType,
|
||||
const NvU32 vrrOverrideMinRefreshRate,
|
||||
const NvBool needsSwFramePacing,
|
||||
NVHwModeTimingsEvoPtr pTimings);
|
||||
NvU16 nvPrepareNextVrrNotifier(NVEvoChannelPtr pChannel, NvU32 sd, NvU32 head);
|
||||
void nvTrackAndDelayFlipForVrrSwFramePacing(NVDispEvoPtr pDispEvo,
|
||||
const struct NvKmsVrrFramePacingInfo *pVrrFramePacingInfo,
|
||||
@@ -71,6 +72,8 @@ NvBool nvDispSupportsVrr(const NVDispEvoRec *pDispEvo);
|
||||
|
||||
NvBool nvExportVrrSemaphoreSurface(const NVDevEvoRec *pDevEvo, int fd);
|
||||
|
||||
void nvVrrSignalSemaphore(NVDevEvoPtr pDevEvo, NvS32 vrrSemaphoreIndex);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -440,9 +440,9 @@ struct NvKmsLayerCapabilities {
|
||||
NvBool supportsWindowMode :1;
|
||||
|
||||
/*!
|
||||
* Whether layer supports HDR pipe.
|
||||
* Whether layer supports ICtCp pipe.
|
||||
*/
|
||||
NvBool supportsHDR :1;
|
||||
NvBool supportsICtCp :1;
|
||||
|
||||
|
||||
/*!
|
||||
|
||||
@@ -271,6 +271,7 @@ enum NvKmsIoctlCommand {
|
||||
NVKMS_IOCTL_ENABLE_VBLANK_SEM_CONTROL,
|
||||
NVKMS_IOCTL_DISABLE_VBLANK_SEM_CONTROL,
|
||||
NVKMS_IOCTL_ACCEL_VBLANK_SEM_CONTROLS,
|
||||
NVKMS_IOCTL_VRR_SIGNAL_SEMAPHORE,
|
||||
};
|
||||
|
||||
|
||||
@@ -295,7 +296,8 @@ enum NvKmsIoctlCommand {
|
||||
#define NVKMS_3DVISION_DONGLE_PARAM_BYTES 20
|
||||
#define NVKMS_GPU_STRING_SIZE 80
|
||||
|
||||
#define NVKMS_VRR_SEMAPHORE_SURFACE_SIZE 1024
|
||||
#define NVKMS_VRR_SEMAPHORE_SURFACE_COUNT 256
|
||||
#define NVKMS_VRR_SEMAPHORE_SURFACE_SIZE (sizeof(NvU32) * NVKMS_VRR_SEMAPHORE_SURFACE_COUNT)
|
||||
|
||||
/*
|
||||
* The GUID string has the form:
|
||||
@@ -416,6 +418,12 @@ enum NvKmsStereoMode {
|
||||
NVKMS_STEREO_OTHER,
|
||||
};
|
||||
|
||||
enum NvKmsDscMode {
|
||||
NVKMS_DSC_MODE_DEFAULT = 0,
|
||||
NVKMS_DSC_MODE_FORCE_ENABLE,
|
||||
NVKMS_DSC_MODE_FORCE_DISABLE,
|
||||
};
|
||||
|
||||
struct NvKmsModeValidationParams {
|
||||
NvBool verboseModeValidation;
|
||||
NvBool moreVerboseModeValidation;
|
||||
@@ -433,11 +441,11 @@ struct NvKmsModeValidationParams {
|
||||
struct NvKmsModeValidationValidSyncs validSyncs;
|
||||
|
||||
/*!
|
||||
* Normally, NVKMS will determine on its own whether to use Display
|
||||
* Stream Compression (DSC). Use forceDsc to force NVKMS to use DSC,
|
||||
* when the GPU supports it.
|
||||
* Normally, NVKMS will determine on its own whether to enable/disable
|
||||
* Display Stream Compression (DSC). Use dscMode to force NVKMS to
|
||||
* enable/disable DSC, when both the GPU and display supports it.
|
||||
*/
|
||||
NvBool forceDsc;
|
||||
enum NvKmsDscMode dscMode;
|
||||
|
||||
/*!
|
||||
* When enabled, Display Stream Compression (DSC) has an
|
||||
@@ -908,7 +916,7 @@ struct NvKmsFlipCommonParams {
|
||||
|
||||
/*
|
||||
* This field can be used when
|
||||
* NvKmsAllocDeviceReply::layerCaps[layer].supportsHDR = TRUE.
|
||||
* NvKmsAllocDeviceReply::layerCaps[layer].supportsICtCp = TRUE.
|
||||
*
|
||||
* If staticMetadata is enabled for multiple layers, flip request
|
||||
* will be rejected.
|
||||
@@ -1413,6 +1421,23 @@ struct NvKmsQueryDpyDynamicDataRequest {
|
||||
} edid;
|
||||
};
|
||||
|
||||
/*! Values for the NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC attributes. */
|
||||
enum NvKmsDpyAttributeColorBpcValue {
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_UNKNOWN = 0,
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_6 = 6,
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8 = 8,
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10 = 10,
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_MAX =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10,
|
||||
};
|
||||
|
||||
typedef struct _NvKmsDpyOutputColorFormatInfo {
|
||||
struct {
|
||||
enum NvKmsDpyAttributeColorBpcValue maxBpc;
|
||||
enum NvKmsDpyAttributeColorBpcValue minBpc;
|
||||
} rgb444, yuv444, yuv422;
|
||||
} NvKmsDpyOutputColorFormatInfo;
|
||||
|
||||
enum NvKmsDpyVRRType {
|
||||
NVKMS_DPY_VRR_TYPE_NONE,
|
||||
NVKMS_DPY_VRR_TYPE_GSYNC,
|
||||
@@ -1480,6 +1505,8 @@ struct NvKmsQueryDpyDynamicDataReply {
|
||||
char infoString[NVKMS_EDID_INFO_STRING_LENGTH];
|
||||
} edid;
|
||||
|
||||
NvKmsDpyOutputColorFormatInfo supportedOutputColorFormats;
|
||||
|
||||
struct NvKmsSuperframeInfo superframeInfo;
|
||||
};
|
||||
|
||||
@@ -1874,6 +1901,12 @@ struct NvKmsSetModeOneHeadRequest {
|
||||
enum NvKmsDpyAttributeRequestedColorSpaceValue colorSpace;
|
||||
NvBool colorSpaceSpecified;
|
||||
|
||||
/*!
|
||||
* Output color bpc. Valid only when colorBpcSpecified is true.
|
||||
*/
|
||||
enum NvKmsDpyAttributeColorBpcValue colorBpc;
|
||||
NvBool colorBpcSpecified;
|
||||
|
||||
/*!
|
||||
* Output color range. Valid only when colorRangeSpecified is true.
|
||||
*/
|
||||
@@ -2558,9 +2591,11 @@ enum NvKmsDpyAttribute {
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE,
|
||||
NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_RANGE,
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_RANGE,
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC,
|
||||
NV_KMS_DPY_ATTRIBUTE_DIGITAL_SIGNAL,
|
||||
NV_KMS_DPY_ATTRIBUTE_DIGITAL_LINK_TYPE,
|
||||
NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_LINK_RATE,
|
||||
NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_LINK_RATE_10MHZ,
|
||||
NV_KMS_DPY_ATTRIBUTE_FRAMELOCK_DISPLAY_CONFIG,
|
||||
/*
|
||||
* XXX NVKMS TODO: Delete UPDATE_GLS_FRAMELOCK; this event-only
|
||||
@@ -4168,4 +4203,25 @@ struct NvKmsAccelVblankSemControlsParams {
|
||||
struct NvKmsAccelVblankSemControlsReply reply;
|
||||
};
|
||||
|
||||
/*!
|
||||
* NVKMS_IOCTL_VRR_SIGNAL_SEMAPHORE
|
||||
*
|
||||
* This IOCTL is used to signal a semaphore from VRR semaphore surface.
|
||||
* It should be invoked after flip if needed. If device does not supports
|
||||
* VRR semaphores, then this is a no-op action for compatibility.
|
||||
*/
|
||||
struct NvKmsVrrSignalSemaphoreRequest {
|
||||
NvKmsDeviceHandle deviceHandle;
|
||||
NvS32 vrrSemaphoreIndex;
|
||||
};
|
||||
|
||||
struct NvKmsVrrSignalSemaphoreReply {
|
||||
NvU32 padding;
|
||||
};
|
||||
|
||||
struct NvKmsVrrSignalSemaphoreParams {
|
||||
struct NvKmsVrrSignalSemaphoreRequest request; /*! in */
|
||||
struct NvKmsVrrSignalSemaphoreReply reply; /*! out */
|
||||
};
|
||||
|
||||
#endif /* NVKMS_API_H */
|
||||
|
||||
@@ -41,6 +41,41 @@
|
||||
nvEvoLogDebug(EVO_LOG_INFO, "[kapi][GPU Id 0x%08x] "__format, \
|
||||
device->gpuId, ##__VA_ARGS__)
|
||||
|
||||
/*
|
||||
* Semaphore values used when using semaphore-based synchronization between
|
||||
* userspace rendering and flips.
|
||||
*/
|
||||
enum NvKmsKapiSemaphoreValues {
|
||||
/*
|
||||
* Initial state on driver init, and the value written by the hardware when
|
||||
* it has completed processing of a frame using this semaphore.
|
||||
*/
|
||||
NVKMS_KAPI_SEMAPHORE_VALUE_DONE = 0xd00dd00d,
|
||||
|
||||
/*
|
||||
* Value of the semaphore when a flip is pending in the display pushbuffer,
|
||||
* but userspace rendering is not yet complete.
|
||||
*/
|
||||
NVKMS_KAPI_SEMAPHORE_VALUE_NOT_READY = 0x13371337,
|
||||
|
||||
/*
|
||||
* Value of the semaphore when userspace rendering is complete and the
|
||||
* pending flip may proceed.
|
||||
*/
|
||||
NVKMS_KAPI_SEMAPHORE_VALUE_READY = 0xf473f473,
|
||||
};
|
||||
|
||||
struct NvKmsKapiNisoSurface {
|
||||
NvU32 hRmHandle;
|
||||
NvKmsSurfaceHandle hKmsHandle;
|
||||
|
||||
NvBool mapped;
|
||||
void *pLinearAddress;
|
||||
|
||||
enum NvKmsNIsoFormat format;
|
||||
|
||||
};
|
||||
|
||||
struct NvKmsKapiDevice {
|
||||
|
||||
NvU32 gpuId;
|
||||
@@ -87,20 +122,15 @@ struct NvKmsKapiDevice {
|
||||
} caps;
|
||||
|
||||
NvU64 supportedSurfaceMemoryFormats[NVKMS_KAPI_LAYER_MAX];
|
||||
NvBool supportsHDR[NVKMS_KAPI_LAYER_MAX];
|
||||
NvBool supportsICtCp[NVKMS_KAPI_LAYER_MAX];
|
||||
|
||||
NvU32 numHeads;
|
||||
NvU32 numLayers[NVKMS_KAPI_MAX_HEADS];
|
||||
|
||||
struct {
|
||||
NvU32 hRmHandle;
|
||||
NvKmsSurfaceHandle hKmsHandle;
|
||||
struct NvKmsKapiNisoSurface notifier;
|
||||
struct NvKmsKapiNisoSurface semaphore;
|
||||
|
||||
NvBool mapped;
|
||||
void *pLinearAddress;
|
||||
|
||||
enum NvKmsNIsoFormat format;
|
||||
} notifier;
|
||||
NvU32 numDisplaySemaphores;
|
||||
|
||||
struct {
|
||||
NvU32 currFlipNotifierIndex;
|
||||
|
||||
@@ -72,8 +72,10 @@ static inline NvU32 NVKMS_KAPI_NOTIFIER_OFFSET(NvU32 head,
|
||||
}
|
||||
|
||||
NvBool nvKmsKapiAllocateNotifiers(struct NvKmsKapiDevice *device, NvBool inVideoMemory);
|
||||
NvBool nvKmsKapiAllocateSemaphores(struct NvKmsKapiDevice *device, NvBool inVideoMemory);
|
||||
|
||||
void nvKmsKapiFreeNotifiers(struct NvKmsKapiDevice *device);
|
||||
void nvKmsKapiFreeNisoSurface(struct NvKmsKapiDevice *device,
|
||||
struct NvKmsKapiNisoSurface *surf);
|
||||
|
||||
NvBool nvKmsKapiIsNotifierFinish(const struct NvKmsKapiDevice *device,
|
||||
const NvU32 head, const NvU32 layer,
|
||||
@@ -82,4 +84,16 @@ NvBool nvKmsKapiIsNotifierFinish(const struct NvKmsKapiDevice *device,
|
||||
void nvKmsKapiNotifierSetNotBegun(struct NvKmsKapiDevice *device,
|
||||
NvU32 head, NvU32 layer, NvU32 index);
|
||||
|
||||
NvBool nvKmsKapiResetDisplaySemaphore(struct NvKmsKapiDevice *device,
|
||||
NvU32 index);
|
||||
|
||||
void nvKmsKapiSignalDisplaySemaphore(struct NvKmsKapiDevice *device,
|
||||
NvU32 index);
|
||||
|
||||
void nvKmsKapiCancelDisplaySemaphore(struct NvKmsKapiDevice *device,
|
||||
NvU32 index);
|
||||
|
||||
NvU32 nvKmsKapiGetDisplaySemaphoreOffset(struct NvKmsKapiDevice *device,
|
||||
NvU32 index);
|
||||
|
||||
#endif /* __NVKMS_KAPI_NOTIFIERS_H__ */
|
||||
|
||||
@@ -158,13 +158,17 @@ struct NvKmsKapiDeviceResourcesInfo {
|
||||
|
||||
NvU32 hasVideoMemory;
|
||||
|
||||
NvU32 numDisplaySemaphores;
|
||||
|
||||
NvU8 genericPageKind;
|
||||
|
||||
NvBool supportsSyncpts;
|
||||
|
||||
NvBool requiresVrrSemaphores;
|
||||
} caps;
|
||||
|
||||
NvU64 supportedSurfaceMemoryFormats[NVKMS_KAPI_LAYER_MAX];
|
||||
NvBool supportsHDR[NVKMS_KAPI_LAYER_MAX];
|
||||
NvBool supportsICtCp[NVKMS_KAPI_LAYER_MAX];
|
||||
};
|
||||
|
||||
#define NVKMS_KAPI_LAYER_MASK(layerType) (1 << (layerType))
|
||||
@@ -210,18 +214,26 @@ struct NvKmsKapiStaticDisplayInfo {
|
||||
NvU32 headMask;
|
||||
};
|
||||
|
||||
struct NvKmsKapiSyncpt {
|
||||
struct NvKmsKapiSyncParams {
|
||||
union {
|
||||
struct {
|
||||
/*!
|
||||
* Possible syncpt use case in kapi.
|
||||
* For pre-syncpt, use only id and value
|
||||
* and for post-syncpt, use only fd.
|
||||
*/
|
||||
NvU32 preSyncptId;
|
||||
NvU32 preSyncptValue;
|
||||
} syncpt;
|
||||
|
||||
/*!
|
||||
* Possible syncpt use case in kapi.
|
||||
* For pre-syncpt, use only id and value
|
||||
* and for post-syncpt, use only fd.
|
||||
*/
|
||||
NvBool preSyncptSpecified;
|
||||
NvU32 preSyncptId;
|
||||
NvU32 preSyncptValue;
|
||||
struct {
|
||||
NvU32 index;
|
||||
} semaphore;
|
||||
} u;
|
||||
|
||||
NvBool postSyncptRequested;
|
||||
NvBool preSyncptSpecified;
|
||||
NvBool postSyncptRequested;
|
||||
NvBool semaphoreSpecified;
|
||||
};
|
||||
|
||||
struct NvKmsKapiLayerConfig {
|
||||
@@ -231,7 +243,7 @@ struct NvKmsKapiLayerConfig {
|
||||
NvU8 surfaceAlpha;
|
||||
} compParams;
|
||||
struct NvKmsRRParams rrParams;
|
||||
struct NvKmsKapiSyncpt syncptParams;
|
||||
struct NvKmsKapiSyncParams syncParams;
|
||||
|
||||
struct {
|
||||
struct NvKmsHDRStaticMetadata val;
|
||||
@@ -319,7 +331,6 @@ struct NvKmsKapiHeadModeSetConfig {
|
||||
|
||||
struct {
|
||||
struct {
|
||||
NvBool specified;
|
||||
NvU32 depth;
|
||||
NvU32 start;
|
||||
NvU32 end;
|
||||
@@ -327,7 +338,6 @@ struct NvKmsKapiHeadModeSetConfig {
|
||||
} input;
|
||||
|
||||
struct {
|
||||
NvBool specified;
|
||||
NvBool enabled;
|
||||
struct NvKmsLutRamps *pRamps;
|
||||
} output;
|
||||
@@ -342,7 +352,8 @@ struct NvKmsKapiHeadRequestedConfig {
|
||||
NvBool modeChanged : 1;
|
||||
NvBool hdrInfoFrameChanged : 1;
|
||||
NvBool colorimetryChanged : 1;
|
||||
NvBool lutChanged : 1;
|
||||
NvBool ilutChanged : 1;
|
||||
NvBool olutChanged : 1;
|
||||
} flags;
|
||||
|
||||
struct NvKmsKapiCursorRequestedConfig cursorRequestedConfig;
|
||||
@@ -368,6 +379,8 @@ struct NvKmsKapiHeadReplyConfig {
|
||||
|
||||
struct NvKmsKapiModeSetReplyConfig {
|
||||
enum NvKmsFlipResult flipResult;
|
||||
NvBool vrrFlip;
|
||||
NvS32 vrrSemaphoreIndex;
|
||||
struct NvKmsKapiHeadReplyConfig
|
||||
headReplyConfig[NVKMS_KAPI_MAX_HEADS];
|
||||
};
|
||||
@@ -1410,6 +1423,87 @@ struct NvKmsKapiFunctionsTable {
|
||||
(
|
||||
NvKmsKapiSuspendResumeCallbackFunc *function
|
||||
);
|
||||
|
||||
/*!
|
||||
* Immediately reset the specified display semaphore to the pending state.
|
||||
*
|
||||
* Must be called prior to applying a mode set that utilizes the specified
|
||||
* display semaphore for synchronization.
|
||||
*
|
||||
* \param [in] device The device which will utilize the semaphore.
|
||||
*
|
||||
* \param [in] semaphoreIndex Index of the desired semaphore within the
|
||||
* NVKMS semaphore pool. Must be less than
|
||||
* NvKmsKapiDeviceResourcesInfo::caps::numDisplaySemaphores
|
||||
* for the specified device.
|
||||
*/
|
||||
NvBool
|
||||
(*resetDisplaySemaphore)
|
||||
(
|
||||
struct NvKmsKapiDevice *device,
|
||||
NvU32 semaphoreIndex
|
||||
);
|
||||
|
||||
/*!
|
||||
* Immediately set the specified display semaphore to the displayable state.
|
||||
*
|
||||
* Must be called after \ref resetDisplaySemaphore to indicate a mode
|
||||
* configuration change that utilizes the specified display semaphore for
|
||||
* synchronization may proceed.
|
||||
*
|
||||
* \param [in] device The device which will utilize the semaphore.
|
||||
*
|
||||
* \param [in] semaphoreIndex Index of the desired semaphore within the
|
||||
* NVKMS semaphore pool. Must be less than
|
||||
* NvKmsKapiDeviceResourcesInfo::caps::numDisplaySemaphores
|
||||
* for the specified device.
|
||||
*/
|
||||
void
|
||||
(*signalDisplaySemaphore)
|
||||
(
|
||||
struct NvKmsKapiDevice *device,
|
||||
NvU32 semaphoreIndex
|
||||
);
|
||||
|
||||
/*!
|
||||
* Immediately cancel use of a display semaphore by resetting its value to
|
||||
* its initial state.
|
||||
*
|
||||
* This can be used by clients to restore a semaphore to a consistent state
|
||||
* when they have prepared it for use by previously calling
|
||||
* \ref resetDisplaySemaphore() on it, but are then prevented from
|
||||
* submitting the associated hardware operations to consume it due to the
|
||||
* subsequent failure of some software or hardware operation.
|
||||
*
|
||||
* \param [in] device The device which will utilize the semaphore.
|
||||
*
|
||||
* \param [in] semaphoreIndex Index of the desired semaphore within the
|
||||
* NVKMS semaphore pool. Must be less than
|
||||
* NvKmsKapiDeviceResourcesInfo::caps::numDisplaySemaphores
|
||||
* for the specified device.
|
||||
*/
|
||||
void
|
||||
(*cancelDisplaySemaphore)
|
||||
(
|
||||
struct NvKmsKapiDevice *device,
|
||||
NvU32 semaphoreIndex
|
||||
);
|
||||
|
||||
/*!
|
||||
* Signal the VRR semaphore at the specified index from the CPU.
|
||||
* If device does not support VRR semaphores, this is a no-op.
|
||||
* Returns true if signal is success or no-op, otherwise returns false.
|
||||
*
|
||||
* \param [in] device A device allocated using allocateDevice().
|
||||
*
|
||||
* \param [in] index The VRR semaphore index to be signalled.
|
||||
*/
|
||||
NvBool
|
||||
(*signalVrrSemaphore)
|
||||
(
|
||||
struct NvKmsKapiDevice *device,
|
||||
NvS32 index
|
||||
);
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -33,14 +33,15 @@
|
||||
NVKMS_MAX_LAYERS_PER_HEAD * \
|
||||
NVKMS_KAPI_MAX_NOTIFERS_PER_LAYER)
|
||||
|
||||
void nvKmsKapiFreeNotifiers(struct NvKmsKapiDevice *device)
|
||||
void nvKmsKapiFreeNisoSurface(struct NvKmsKapiDevice *device,
|
||||
struct NvKmsKapiNisoSurface *surface)
|
||||
{
|
||||
if (device->notifier.hKmsHandle != 0) {
|
||||
if (surface->hKmsHandle != 0) {
|
||||
struct NvKmsUnregisterSurfaceParams paramsUnreg = { };
|
||||
NvBool status;
|
||||
|
||||
paramsUnreg.request.deviceHandle = device->hKmsDevice;
|
||||
paramsUnreg.request.surfaceHandle = device->notifier.hKmsHandle;
|
||||
paramsUnreg.request.surfaceHandle = surface->hKmsHandle;
|
||||
|
||||
status = nvkms_ioctl_from_kapi(device->pKmsOpen,
|
||||
NVKMS_IOCTL_UNREGISTER_SURFACE,
|
||||
@@ -55,13 +56,13 @@ void nvKmsKapiFreeNotifiers(struct NvKmsKapiDevice *device)
|
||||
device->notifier.hKmsHandle = 0;
|
||||
}
|
||||
|
||||
if (device->notifier.mapped) {
|
||||
if (surface->mapped) {
|
||||
NV_STATUS status;
|
||||
|
||||
status = nvRmApiUnmapMemory(device->hRmClient,
|
||||
device->hRmSubDevice,
|
||||
device->notifier.hRmHandle,
|
||||
device->notifier.pLinearAddress,
|
||||
surface->hRmHandle,
|
||||
surface->pLinearAddress,
|
||||
0);
|
||||
|
||||
if (status != NV_OK) {
|
||||
@@ -74,12 +75,12 @@ void nvKmsKapiFreeNotifiers(struct NvKmsKapiDevice *device)
|
||||
device->notifier.mapped = NV_FALSE;
|
||||
}
|
||||
|
||||
if (device->notifier.hRmHandle != 0) {
|
||||
if (surface->hRmHandle != 0) {
|
||||
NvU32 status;
|
||||
|
||||
status = nvRmApiFree(device->hRmClient,
|
||||
device->hRmDevice,
|
||||
device->notifier.hRmHandle);
|
||||
surface->hRmHandle);
|
||||
|
||||
if (status != NVOS_STATUS_SUCCESS) {
|
||||
nvKmsKapiLogDeviceDebug(
|
||||
@@ -88,8 +89,8 @@ void nvKmsKapiFreeNotifiers(struct NvKmsKapiDevice *device)
|
||||
status);
|
||||
}
|
||||
|
||||
nvFreeUnixRmHandle(&device->handleAllocator, device->notifier.hRmHandle);
|
||||
device->notifier.hRmHandle = 0;
|
||||
nvFreeUnixRmHandle(&device->handleAllocator, surface->hRmHandle);
|
||||
surface->hRmHandle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,9 +103,9 @@ static void InitNotifier(struct NvKmsKapiDevice *device,
|
||||
device->notifier.pLinearAddress);
|
||||
}
|
||||
|
||||
#define NVKMS_KAPI_NOTIFIERS_SURFACE_SIZE 0x1000
|
||||
|
||||
NvBool nvKmsKapiAllocateNotifiers(struct NvKmsKapiDevice *device,
|
||||
static NvBool AllocateNisoSurface(struct NvKmsKapiDevice *device,
|
||||
struct NvKmsKapiNisoSurface *surface,
|
||||
NvU64 size,
|
||||
NvBool inVideoMemory)
|
||||
{
|
||||
struct NvKmsRegisterSurfaceParams surfParams = {};
|
||||
@@ -112,19 +113,10 @@ NvBool nvKmsKapiAllocateNotifiers(struct NvKmsKapiDevice *device,
|
||||
NvU8 compressible = 0;
|
||||
NvBool ret;
|
||||
|
||||
ct_assert((NVKMS_KAPI_MAX_NOTIFIERS * NVKMS_KAPI_NOTIFIER_SIZE) <=
|
||||
(NVKMS_KAPI_NOTIFIERS_SURFACE_SIZE));
|
||||
|
||||
ct_assert(NVKMS_KAPI_NOTIFIER_SIZE >= sizeof(NvNotification));
|
||||
nvAssert(NVKMS_KAPI_NOTIFIER_SIZE >=
|
||||
nvKmsSizeOfNotifier(device->notifier.format, TRUE /* overlay */));
|
||||
nvAssert(NVKMS_KAPI_NOTIFIER_SIZE >=
|
||||
nvKmsSizeOfNotifier(device->notifier.format, FALSE /* overlay */));
|
||||
|
||||
device->notifier.hRmHandle =
|
||||
surface->hRmHandle =
|
||||
nvGenerateUnixRmHandle(&device->handleAllocator);
|
||||
|
||||
if (device->notifier.hRmHandle == 0x0) {
|
||||
if (surface->hRmHandle == 0x0) {
|
||||
nvKmsKapiLogDeviceDebug(
|
||||
device,
|
||||
"nvGenerateUnixRmHandle() failed");
|
||||
@@ -133,32 +125,32 @@ NvBool nvKmsKapiAllocateNotifiers(struct NvKmsKapiDevice *device,
|
||||
|
||||
if (inVideoMemory) {
|
||||
ret = nvKmsKapiAllocateVideoMemory(device,
|
||||
device->notifier.hRmHandle,
|
||||
surface->hRmHandle,
|
||||
NvKmsSurfaceMemoryLayoutPitch,
|
||||
NVKMS_KAPI_NOTIFIERS_SURFACE_SIZE,
|
||||
size,
|
||||
NVKMS_KAPI_ALLOCATION_TYPE_NOTIFIER,
|
||||
&compressible);
|
||||
} else {
|
||||
ret = nvKmsKapiAllocateSystemMemory(device,
|
||||
device->notifier.hRmHandle,
|
||||
NvKmsSurfaceMemoryLayoutPitch,
|
||||
NVKMS_KAPI_NOTIFIERS_SURFACE_SIZE,
|
||||
surface->hRmHandle,
|
||||
NvKmsSurfaceMemoryLayoutPitch,
|
||||
size,
|
||||
NVKMS_KAPI_ALLOCATION_TYPE_NOTIFIER,
|
||||
&compressible);
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
nvFreeUnixRmHandle(&device->handleAllocator, device->notifier.hRmHandle);
|
||||
device->notifier.hRmHandle = 0x0;
|
||||
nvFreeUnixRmHandle(&device->handleAllocator, surface->hRmHandle);
|
||||
surface->hRmHandle = 0x0;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
status = nvRmApiMapMemory(device->hRmClient,
|
||||
device->hRmSubDevice,
|
||||
device->notifier.hRmHandle,
|
||||
surface->hRmHandle,
|
||||
0,
|
||||
NVKMS_KAPI_NOTIFIERS_SURFACE_SIZE,
|
||||
&device->notifier.pLinearAddress,
|
||||
size,
|
||||
&surface->pLinearAddress,
|
||||
0);
|
||||
|
||||
if (status != NV_OK) {
|
||||
@@ -169,23 +161,22 @@ NvBool nvKmsKapiAllocateNotifiers(struct NvKmsKapiDevice *device,
|
||||
goto failed;
|
||||
}
|
||||
|
||||
device->notifier.mapped = NV_TRUE;
|
||||
surface->mapped = NV_TRUE;
|
||||
|
||||
surfParams.request.deviceHandle = device->hKmsDevice;
|
||||
surfParams.request.useFd = FALSE;
|
||||
surfParams.request.rmClient = device->hRmClient;
|
||||
|
||||
surfParams.request.widthInPixels = NVKMS_KAPI_NOTIFIERS_SURFACE_SIZE;
|
||||
surfParams.request.widthInPixels = size;
|
||||
surfParams.request.heightInPixels = 1;
|
||||
surfParams.request.layout = NvKmsSurfaceMemoryLayoutPitch;
|
||||
surfParams.request.format = NvKmsSurfaceMemoryFormatI8;
|
||||
surfParams.request.log2GobsPerBlockY = 0;
|
||||
surfParams.request.isoType = NVKMS_MEMORY_NISO;
|
||||
|
||||
surfParams.request.planes[0].u.rmObject = device->notifier.hRmHandle;
|
||||
surfParams.request.planes[0].pitch = NVKMS_KAPI_NOTIFIERS_SURFACE_SIZE;
|
||||
surfParams.request.planes[0].rmObjectSizeInBytes =
|
||||
NVKMS_KAPI_NOTIFIERS_SURFACE_SIZE;
|
||||
surfParams.request.planes[0].u.rmObject = surface->hRmHandle;
|
||||
surfParams.request.planes[0].pitch = size;
|
||||
surfParams.request.planes[0].rmObjectSizeInBytes = size;
|
||||
|
||||
if (!nvkms_ioctl_from_kapi(device->pKmsOpen,
|
||||
NVKMS_IOCTL_REGISTER_SURFACE,
|
||||
@@ -196,7 +187,37 @@ NvBool nvKmsKapiAllocateNotifiers(struct NvKmsKapiDevice *device,
|
||||
goto failed;
|
||||
}
|
||||
|
||||
device->notifier.hKmsHandle = surfParams.reply.surfaceHandle;
|
||||
surface->hKmsHandle = surfParams.reply.surfaceHandle;
|
||||
|
||||
return NV_TRUE;
|
||||
|
||||
failed:
|
||||
|
||||
nvKmsKapiFreeNisoSurface(device, surface);
|
||||
|
||||
return NV_FALSE;
|
||||
}
|
||||
|
||||
#define NVKMS_KAPI_NOTIFIERS_SURFACE_SIZE 0x1000
|
||||
|
||||
NvBool nvKmsKapiAllocateNotifiers(struct NvKmsKapiDevice *device,
|
||||
NvBool inVideoMemory)
|
||||
{
|
||||
ct_assert((NVKMS_KAPI_MAX_NOTIFIERS * NVKMS_KAPI_NOTIFIER_SIZE) <=
|
||||
NVKMS_KAPI_NOTIFIERS_SURFACE_SIZE);
|
||||
|
||||
ct_assert(NVKMS_KAPI_NOTIFIER_SIZE >= sizeof(NvNotification));
|
||||
nvAssert(NVKMS_KAPI_NOTIFIER_SIZE >=
|
||||
nvKmsSizeOfNotifier(device->notifier.format, TRUE /* overlay */));
|
||||
nvAssert(NVKMS_KAPI_NOTIFIER_SIZE >=
|
||||
nvKmsSizeOfNotifier(device->notifier.format, FALSE /* overlay */));
|
||||
|
||||
if (!AllocateNisoSurface(device,
|
||||
&device->notifier,
|
||||
NVKMS_KAPI_NOTIFIERS_SURFACE_SIZE,
|
||||
inVideoMemory)) {
|
||||
return NV_FALSE;
|
||||
}
|
||||
|
||||
/* Init Notifiers */
|
||||
|
||||
@@ -218,10 +239,117 @@ NvBool nvKmsKapiAllocateNotifiers(struct NvKmsKapiDevice *device,
|
||||
}
|
||||
|
||||
return NV_TRUE;
|
||||
|
||||
failed:
|
||||
|
||||
nvKmsKapiFreeNotifiers(device);
|
||||
|
||||
return NV_FALSE;
|
||||
}
|
||||
|
||||
static void ResetSemaphore(struct NvKmsKapiDevice *device,
|
||||
NvU32 index,
|
||||
NvU32 payload)
|
||||
{
|
||||
nvKmsResetSemaphore(device->semaphore.format,
|
||||
index,
|
||||
device->semaphore.pLinearAddress,
|
||||
payload);
|
||||
}
|
||||
|
||||
#define NVKMS_KAPI_SEMAPHORE_SURFACE_SIZE 0x1000
|
||||
|
||||
NvBool nvKmsKapiAllocateSemaphores(struct NvKmsKapiDevice *device,
|
||||
NvBool inVideoMemory)
|
||||
{
|
||||
NvU32 index;
|
||||
|
||||
if (!AllocateNisoSurface(device,
|
||||
&device->semaphore,
|
||||
NVKMS_KAPI_SEMAPHORE_SURFACE_SIZE,
|
||||
inVideoMemory)) {
|
||||
return NV_FALSE;
|
||||
}
|
||||
|
||||
/* Init Semaphores */
|
||||
|
||||
device->numDisplaySemaphores = NVKMS_KAPI_SEMAPHORE_SURFACE_SIZE /
|
||||
nvKmsSizeOfSemaphore(device->semaphore.format);
|
||||
|
||||
/*
|
||||
* See the comment in nvKmsKapiSignalDisplaySemaphore() for the full
|
||||
* justification of this requirement. The current implementation requires
|
||||
* only 16 semaphores (2 per window) given a maximum of one outstanding
|
||||
* flip, but this value allows up to 32 outstanding flips, as recommended
|
||||
* by the architecture team in an old hardware bug.
|
||||
*/
|
||||
nvAssert(device->numDisplaySemaphores >= 256);
|
||||
|
||||
for (index = 0; index < device->numDisplaySemaphores; index++) {
|
||||
ResetSemaphore(device, index, NVKMS_KAPI_SEMAPHORE_VALUE_DONE);
|
||||
}
|
||||
|
||||
return NV_TRUE;
|
||||
}
|
||||
|
||||
NvBool nvKmsKapiResetDisplaySemaphore(struct NvKmsKapiDevice *device,
|
||||
NvU32 index)
|
||||
{
|
||||
struct nvKmsParsedSemaphore semParsed;
|
||||
|
||||
nvKmsParseSemaphore(device->semaphore.format,
|
||||
index,
|
||||
device->semaphore.pLinearAddress,
|
||||
&semParsed);
|
||||
|
||||
if (semParsed.payload != NVKMS_KAPI_SEMAPHORE_VALUE_DONE) {
|
||||
nvKmsKapiLogDeviceDebug(
|
||||
device,
|
||||
"Attempt to reuse semaphore at index %u with pending status 0x%08x",
|
||||
index,
|
||||
semParsed.payload);
|
||||
|
||||
return NV_FALSE;
|
||||
}
|
||||
|
||||
ResetSemaphore(device, index, NVKMS_KAPI_SEMAPHORE_VALUE_NOT_READY);
|
||||
|
||||
return NV_TRUE;
|
||||
}
|
||||
|
||||
void nvKmsKapiSignalDisplaySemaphore(struct NvKmsKapiDevice *device,
|
||||
NvU32 index)
|
||||
{
|
||||
/*
|
||||
* Note most users of semaphores use a "ready" value that varies from
|
||||
* frame to frame, citing bug 194936. However, this "bug" simply
|
||||
* notes that the hardware may read ahead and grab semaphore values for
|
||||
* pending semaphore acquires such that two pending frames using the
|
||||
* same semaphore might be signaled "ready" by the same semaphore write.
|
||||
* Given this implementation cycles through at least 256 semaphores,
|
||||
* meaning if all 8 hardware windows were programmed in every flip, there
|
||||
* could be at least 32 frames in-flight without re-using a semaphore
|
||||
* slot, and the code above that initializes a semaphore for each frame
|
||||
* first ensures the prior frame using that semaphore has completed,
|
||||
* this approach is not necessary here. There should be no opportunity
|
||||
* for the hardware to "pre-fetch" a prior frame's semaphore acquire
|
||||
* value from the semaphore here, and hence a constant value is sufficient.
|
||||
*/
|
||||
ResetSemaphore(device, index, NVKMS_KAPI_SEMAPHORE_VALUE_READY);
|
||||
}
|
||||
|
||||
void nvKmsKapiCancelDisplaySemaphore(struct NvKmsKapiDevice *device,
|
||||
NvU32 index)
|
||||
{
|
||||
struct nvKmsParsedSemaphore semParsed;
|
||||
|
||||
nvKmsParseSemaphore(device->semaphore.format,
|
||||
index,
|
||||
device->semaphore.pLinearAddress,
|
||||
&semParsed);
|
||||
|
||||
if (semParsed.payload != NVKMS_KAPI_SEMAPHORE_VALUE_DONE) {
|
||||
nvAssert(semParsed.payload == NVKMS_KAPI_SEMAPHORE_VALUE_NOT_READY);
|
||||
ResetSemaphore(device, index, NVKMS_KAPI_SEMAPHORE_VALUE_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
NvU32 nvKmsKapiGetDisplaySemaphoreOffset(struct NvKmsKapiDevice *device,
|
||||
NvU32 index)
|
||||
{
|
||||
return nvKmsSizeOfSemaphore(device->semaphore.format) * index;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "nvidia-modeset-os-interface.h"
|
||||
|
||||
#include "nvkms-api.h"
|
||||
#include "nvkms-sync.h"
|
||||
#include "nvkms-rmapi.h"
|
||||
#include "nvkms-vrr.h"
|
||||
|
||||
@@ -272,9 +273,10 @@ failed:
|
||||
*/
|
||||
static void KmsFreeDevice(struct NvKmsKapiDevice *device)
|
||||
{
|
||||
/* Free notifier memory */
|
||||
/* Free notifier and semaphore memory */
|
||||
|
||||
nvKmsKapiFreeNotifiers(device);
|
||||
nvKmsKapiFreeNisoSurface(device, &device->semaphore);
|
||||
nvKmsKapiFreeNisoSurface(device, &device->notifier);
|
||||
|
||||
/* Free NVKMS device */
|
||||
|
||||
@@ -398,7 +400,7 @@ static NvBool KmsAllocateDevice(struct NvKmsKapiDevice *device)
|
||||
for (layer = 0; layer < NVKMS_KAPI_LAYER_MAX; layer++) {
|
||||
device->supportedSurfaceMemoryFormats[layer] =
|
||||
paramsAlloc->reply.layerCaps[layer].supportedSurfaceMemoryFormats;
|
||||
device->supportsHDR[layer] = paramsAlloc->reply.layerCaps[layer].supportsHDR;
|
||||
device->supportsICtCp[layer] = paramsAlloc->reply.layerCaps[layer].supportsICtCp;
|
||||
}
|
||||
|
||||
if (paramsAlloc->reply.validNIsoFormatMask &
|
||||
@@ -413,6 +415,15 @@ static NvBool KmsAllocateDevice(struct NvKmsKapiDevice *device)
|
||||
device->notifier.format = NVKMS_NISO_FORMAT_LEGACY;
|
||||
}
|
||||
|
||||
if (paramsAlloc->reply.validNIsoFormatMask &
|
||||
(1 << NVKMS_NISO_FORMAT_FOUR_WORD_NVDISPLAY)) {
|
||||
device->semaphore.format = NVKMS_NISO_FORMAT_FOUR_WORD_NVDISPLAY;
|
||||
} else {
|
||||
nvAssert(paramsAlloc->reply.validNIsoFormatMask &
|
||||
(1 << NVKMS_NISO_FORMAT_LEGACY));
|
||||
device->semaphore.format = NVKMS_NISO_FORMAT_LEGACY;
|
||||
}
|
||||
|
||||
/* XXX Add support for SLI/multiple display engines per device */
|
||||
if (paramsAlloc->reply.numDisps != 1)
|
||||
{
|
||||
@@ -442,6 +453,14 @@ static NvBool KmsAllocateDevice(struct NvKmsKapiDevice *device)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Allocate semaphore memory in video memory whenever available */
|
||||
if (!nvKmsKapiAllocateSemaphores(device, !device->isSOC)) {
|
||||
nvKmsKapiLogDebug(
|
||||
"Failed to allocate Semaphore objects for GPU ID 0x%08x",
|
||||
device->gpuId);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = NV_TRUE;
|
||||
|
||||
done:
|
||||
@@ -1010,6 +1029,7 @@ static NvBool GetDeviceResourcesInfo
|
||||
|
||||
info->caps.hasVideoMemory = !device->isSOC;
|
||||
info->caps.genericPageKind = device->caps.genericPageKind;
|
||||
info->caps.requiresVrrSemaphores = device->caps.requiresVrrSemaphores;
|
||||
|
||||
if (device->hKmsDevice == 0x0) {
|
||||
info->caps.pitchAlignment = 0x1;
|
||||
@@ -1085,6 +1105,8 @@ static NvBool GetDeviceResourcesInfo
|
||||
info->caps.supportedCursorSurfaceMemoryFormats =
|
||||
NVBIT(NvKmsSurfaceMemoryFormatA8R8G8B8);
|
||||
|
||||
info->caps.numDisplaySemaphores = device->numDisplaySemaphores;
|
||||
|
||||
ct_assert(sizeof(info->supportedSurfaceMemoryFormats) ==
|
||||
sizeof(device->supportedSurfaceMemoryFormats));
|
||||
|
||||
@@ -1092,12 +1114,12 @@ static NvBool GetDeviceResourcesInfo
|
||||
device->supportedSurfaceMemoryFormats,
|
||||
sizeof(device->supportedSurfaceMemoryFormats));
|
||||
|
||||
ct_assert(sizeof(info->supportsHDR) ==
|
||||
sizeof(device->supportsHDR));
|
||||
ct_assert(sizeof(info->supportsICtCp) ==
|
||||
sizeof(device->supportsICtCp));
|
||||
|
||||
nvkms_memcpy(info->supportsHDR,
|
||||
device->supportsHDR,
|
||||
sizeof(device->supportsHDR));
|
||||
nvkms_memcpy(info->supportsICtCp,
|
||||
device->supportsICtCp,
|
||||
sizeof(device->supportsICtCp));
|
||||
done:
|
||||
|
||||
return status;
|
||||
@@ -1319,7 +1341,7 @@ static NvBool GetDynamicDisplayInfo(
|
||||
sizeof(params->edid.buffer));
|
||||
|
||||
params->edid.bufferSize = pParamsDpyDynamic->reply.edid.bufferSize;
|
||||
params->vrrSupported = (vrrSupported && !device->caps.requiresVrrSemaphores) ? NV_TRUE : NV_FALSE;
|
||||
params->vrrSupported = vrrSupported;
|
||||
}
|
||||
|
||||
done:
|
||||
@@ -2471,25 +2493,48 @@ static NvBool AssignSyncObjectConfig(
|
||||
struct NvKmsChannelSyncObjects *pSyncObject)
|
||||
{
|
||||
if (!device->supportsSyncpts) {
|
||||
if (pLayerConfig->syncptParams.preSyncptSpecified ||
|
||||
pLayerConfig->syncptParams.postSyncptRequested) {
|
||||
if (pLayerConfig->syncParams.preSyncptSpecified ||
|
||||
pLayerConfig->syncParams.postSyncptRequested) {
|
||||
return NV_FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Syncpt and Semaphore usage are mutually exclusive. */
|
||||
if (pLayerConfig->syncParams.semaphoreSpecified &&
|
||||
(pLayerConfig->syncParams.preSyncptSpecified ||
|
||||
pLayerConfig->syncParams.postSyncptRequested)) {
|
||||
return NV_FALSE;
|
||||
}
|
||||
|
||||
pSyncObject->useSyncpt = FALSE;
|
||||
|
||||
if (pLayerConfig->syncptParams.preSyncptSpecified) {
|
||||
if (pLayerConfig->syncParams.preSyncptSpecified) {
|
||||
pSyncObject->useSyncpt = TRUE;
|
||||
|
||||
pSyncObject->u.syncpts.pre.type = NVKMS_SYNCPT_TYPE_RAW;
|
||||
pSyncObject->u.syncpts.pre.u.raw.id = pLayerConfig->syncptParams.preSyncptId;
|
||||
pSyncObject->u.syncpts.pre.u.raw.value = pLayerConfig->syncptParams.preSyncptValue;
|
||||
pSyncObject->u.syncpts.pre.u.raw.id = pLayerConfig->syncParams.u.syncpt.preSyncptId;
|
||||
pSyncObject->u.syncpts.pre.u.raw.value = pLayerConfig->syncParams.u.syncpt.preSyncptValue;
|
||||
} else if (pLayerConfig->syncParams.semaphoreSpecified) {
|
||||
pSyncObject->u.semaphores.release.surface.surfaceHandle =
|
||||
pSyncObject->u.semaphores.acquire.surface.surfaceHandle =
|
||||
device->semaphore.hKmsHandle;
|
||||
pSyncObject->u.semaphores.release.surface.format =
|
||||
pSyncObject->u.semaphores.acquire.surface.format =
|
||||
device->semaphore.format;
|
||||
pSyncObject->u.semaphores.release.surface.offsetInWords =
|
||||
pSyncObject->u.semaphores.acquire.surface.offsetInWords =
|
||||
nvKmsKapiGetDisplaySemaphoreOffset(
|
||||
device,
|
||||
pLayerConfig->syncParams.u.semaphore.index) >> 2;
|
||||
pSyncObject->u.semaphores.acquire.value =
|
||||
NVKMS_KAPI_SEMAPHORE_VALUE_READY;
|
||||
pSyncObject->u.semaphores.release.value =
|
||||
NVKMS_KAPI_SEMAPHORE_VALUE_DONE;
|
||||
}
|
||||
|
||||
if (pLayerConfig->syncptParams.postSyncptRequested) {
|
||||
if (pLayerConfig->syncParams.postSyncptRequested) {
|
||||
pSyncObject->useSyncpt = TRUE;
|
||||
|
||||
pSyncObject->u.syncpts.requestedPostType = NVKMS_SYNCPT_TYPE_FD;
|
||||
}
|
||||
return NV_TRUE;
|
||||
@@ -2581,7 +2626,7 @@ static NvBool NvKmsKapiOverlayLayerConfigToKms(
|
||||
params->layer[layer].colorSpace.specified = TRUE;
|
||||
}
|
||||
|
||||
if (layerRequestedConfig->flags.cscChanged) {
|
||||
if (layerRequestedConfig->flags.cscChanged || bFromKmsSetMode) {
|
||||
params->layer[layer].csc.specified = NV_TRUE;
|
||||
params->layer[layer].csc.useMain = layerConfig->cscUseMain;
|
||||
if (!layerConfig->cscUseMain) {
|
||||
@@ -2709,7 +2754,7 @@ static NvBool NvKmsKapiPrimaryLayerConfigToKms(
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (layerRequestedConfig->flags.cscChanged) {
|
||||
if (layerRequestedConfig->flags.cscChanged || bFromKmsSetMode) {
|
||||
nvAssert(!layerConfig->cscUseMain);
|
||||
|
||||
params->layer[NVKMS_MAIN_LAYER].csc.specified = NV_TRUE;
|
||||
@@ -2795,25 +2840,32 @@ static NvBool NvKmsKapiLayerConfigToKms(
|
||||
}
|
||||
|
||||
static void NvKmsKapiHeadLutConfigToKms(
|
||||
const struct NvKmsKapiHeadModeSetConfig *modeSetConfig,
|
||||
struct NvKmsSetLutCommonParams *lutParams)
|
||||
const struct NvKmsKapiHeadRequestedConfig *headRequestedConfig,
|
||||
struct NvKmsSetLutCommonParams *lutParams,
|
||||
NvBool bFromKmsSetMode)
|
||||
{
|
||||
const struct NvKmsKapiHeadModeSetConfig *modeSetConfig =
|
||||
&headRequestedConfig->modeSetConfig;
|
||||
struct NvKmsSetInputLutParams *input = &lutParams->input;
|
||||
struct NvKmsSetOutputLutParams *output = &lutParams->output;
|
||||
|
||||
/* input LUT */
|
||||
input->specified = modeSetConfig->lut.input.specified;
|
||||
input->depth = modeSetConfig->lut.input.depth;
|
||||
input->start = modeSetConfig->lut.input.start;
|
||||
input->end = modeSetConfig->lut.input.end;
|
||||
if (headRequestedConfig->flags.ilutChanged || bFromKmsSetMode) {
|
||||
input->specified = NV_TRUE;
|
||||
input->depth = modeSetConfig->lut.input.depth;
|
||||
input->start = modeSetConfig->lut.input.start;
|
||||
input->end = modeSetConfig->lut.input.end;
|
||||
|
||||
input->pRamps = nvKmsPointerToNvU64(modeSetConfig->lut.input.pRamps);
|
||||
input->pRamps = nvKmsPointerToNvU64(modeSetConfig->lut.input.pRamps);
|
||||
}
|
||||
|
||||
/* output LUT */
|
||||
output->specified = modeSetConfig->lut.output.specified;
|
||||
output->enabled = modeSetConfig->lut.output.enabled;
|
||||
if (headRequestedConfig->flags.olutChanged || bFromKmsSetMode) {
|
||||
output->specified = NV_TRUE;
|
||||
output->enabled = modeSetConfig->lut.output.enabled;
|
||||
|
||||
output->pRamps = nvKmsPointerToNvU64(modeSetConfig->lut.output.pRamps);
|
||||
output->pRamps = nvKmsPointerToNvU64(modeSetConfig->lut.output.pRamps);
|
||||
}
|
||||
}
|
||||
|
||||
static NvBool AnyLayerTransferFunctionChanged(
|
||||
@@ -2925,9 +2977,9 @@ static NvBool NvKmsKapiRequestedModeSetConfigToKms(
|
||||
|
||||
NvKmsKapiDisplayModeToKapi(&headModeSetConfig->mode, ¶msHead->mode);
|
||||
|
||||
if (headRequestedConfig->flags.lutChanged) {
|
||||
NvKmsKapiHeadLutConfigToKms(headModeSetConfig, ¶msHead->flip.lut);
|
||||
}
|
||||
NvKmsKapiHeadLutConfigToKms(headRequestedConfig,
|
||||
¶msHead->flip.lut,
|
||||
NV_TRUE /* bFromKmsSetMode */);
|
||||
|
||||
NvKmsKapiCursorConfigToKms(&headRequestedConfig->cursorRequestedConfig,
|
||||
¶msHead->flip,
|
||||
@@ -2975,13 +3027,8 @@ static NvBool NvKmsKapiRequestedModeSetConfigToKms(
|
||||
paramsHead->viewPortSizeIn.height =
|
||||
headModeSetConfig->mode.timings.vVisible;
|
||||
|
||||
if (device->caps.requiresVrrSemaphores) {
|
||||
paramsHead->allowGsync = NV_FALSE;
|
||||
paramsHead->allowAdaptiveSync = NVKMS_ALLOW_ADAPTIVE_SYNC_DISABLED;
|
||||
} else {
|
||||
paramsHead->allowGsync = NV_TRUE;
|
||||
paramsHead->allowAdaptiveSync = NVKMS_ALLOW_ADAPTIVE_SYNC_ALL;
|
||||
}
|
||||
paramsHead->allowGsync = NV_TRUE;
|
||||
paramsHead->allowAdaptiveSync = NVKMS_ALLOW_ADAPTIVE_SYNC_ALL;
|
||||
}
|
||||
|
||||
return NV_TRUE;
|
||||
@@ -3189,9 +3236,10 @@ static NvBool KmsFlip(
|
||||
if (headModeSetConfig->vrrEnabled) {
|
||||
params->request.allowVrr = NV_TRUE;
|
||||
}
|
||||
if (headRequestedConfig->flags.lutChanged) {
|
||||
NvKmsKapiHeadLutConfigToKms(headModeSetConfig, &flipParams->lut);
|
||||
}
|
||||
|
||||
NvKmsKapiHeadLutConfigToKms(headRequestedConfig,
|
||||
&flipParams->lut,
|
||||
NV_FALSE /* bFromKmsSetMode */);
|
||||
}
|
||||
|
||||
if (params->request.numFlipHeads == 0) {
|
||||
@@ -3216,6 +3264,9 @@ static NvBool KmsFlip(
|
||||
}
|
||||
|
||||
/*! fill back flip reply */
|
||||
replyConfig->vrrFlip = params->reply.vrrFlipType;
|
||||
replyConfig->vrrSemaphoreIndex = params->reply.vrrSemaphoreIndex;
|
||||
|
||||
for (i = 0; i < params->request.numFlipHeads; i++) {
|
||||
const struct NvKmsKapiHeadRequestedConfig *headRequestedConfig =
|
||||
&requestedConfig->headRequestedConfig[pFlipHead[i].head];
|
||||
@@ -3246,7 +3297,7 @@ static NvBool KmsFlip(
|
||||
|
||||
/*! initialize explicitly to -1 as 0 is valid file descriptor */
|
||||
layerReplyConfig->postSyncptFd = -1;
|
||||
if (layerRequestedConfig->syncptParams.postSyncptRequested) {
|
||||
if (layerRequestedConfig->syncParams.postSyncptRequested) {
|
||||
layerReplyConfig->postSyncptFd =
|
||||
flipParams->layer[layer].postSyncpt.u.fd;
|
||||
}
|
||||
@@ -3457,6 +3508,25 @@ static void nvKmsKapiSetSuspendResumeCallback
|
||||
pSuspendResumeFunc = function;
|
||||
}
|
||||
|
||||
static NvBool SignalVrrSemaphore
|
||||
(
|
||||
struct NvKmsKapiDevice *device,
|
||||
NvS32 index
|
||||
)
|
||||
{
|
||||
NvBool status = NV_TRUE;
|
||||
struct NvKmsVrrSignalSemaphoreParams params = { };
|
||||
params.request.deviceHandle = device->hKmsDevice;
|
||||
params.request.vrrSemaphoreIndex = index;
|
||||
status = nvkms_ioctl_from_kapi(device->pKmsOpen,
|
||||
NVKMS_IOCTL_VRR_SIGNAL_SEMAPHORE,
|
||||
¶ms, sizeof(params));
|
||||
if (!status) {
|
||||
nvKmsKapiLogDeviceDebug(device, "NVKMS VrrSignalSemaphore failed");
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
NvBool nvKmsKapiGetFunctionsTableInternal
|
||||
(
|
||||
struct NvKmsKapiFunctionsTable *funcsTable
|
||||
@@ -3537,5 +3607,10 @@ NvBool nvKmsKapiGetFunctionsTableInternal
|
||||
nvKmsKapiSetSemaphoreSurfaceValue;
|
||||
funcsTable->setSuspendResumeCallback = nvKmsKapiSetSuspendResumeCallback;
|
||||
|
||||
funcsTable->resetDisplaySemaphore = nvKmsKapiResetDisplaySemaphore;
|
||||
funcsTable->signalDisplaySemaphore = nvKmsKapiSignalDisplaySemaphore;
|
||||
funcsTable->cancelDisplaySemaphore = nvKmsKapiCancelDisplaySemaphore;
|
||||
funcsTable->signalVrrSemaphore = SignalVrrSemaphore;
|
||||
|
||||
return NV_TRUE;
|
||||
}
|
||||
|
||||
@@ -238,9 +238,17 @@ static void EnableVRR(NVDpyEvoPtr pDpyEvo)
|
||||
DisplayPort::Device *device = pDpyEvo->dp.pDpLibDevice->device;
|
||||
const NvBool dispSupportsVrr = nvDispSupportsVrr(pDispEvo);
|
||||
|
||||
if (pDpyEvo->internal) {
|
||||
// VRR + notebooks not supported, yet
|
||||
pDpyEvo->vrr.type = NVKMS_DPY_VRR_TYPE_NONE;
|
||||
// If the dpy is a laptop internal panel and an SBIOS cookie indicates that
|
||||
// it supports VRR, override its enable flag and timeout. Note that in the
|
||||
// internal panel scenario, the EDID may not claim VRR support, so honor
|
||||
// hasPlatformCookie even if DpyHasVRREDID() reports FALSE.
|
||||
if (pDpyEvo->internal && pDispEvo->vrr.hasPlatformCookie) {
|
||||
|
||||
if (pDispEvo->pDevEvo->hal->caps.supportsDisplayRate) {
|
||||
pDpyEvo->vrr.needsSwFramePacing = TRUE;
|
||||
}
|
||||
|
||||
pDpyEvo->vrr.type = NVKMS_DPY_VRR_TYPE_GSYNC;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -299,53 +307,6 @@ static void EnableVRR(NVDpyEvoPtr pDpyEvo)
|
||||
pDpyEvo->vrr.type = NVKMS_DPY_VRR_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (pDpyEvo->parsedEdid.valid && nvDpyIsAdaptiveSync(pDpyEvo)) {
|
||||
// Adaptive-Sync minimum refresh rate is either in DisplayID (Display
|
||||
// ID spec 1.3 section 4.6 Video Timing Range Limits) or EDID (EDID
|
||||
// spec 1.4 section 3.10.3.3 Display Range Limits & Additional Timing
|
||||
// Descriptor Definition)
|
||||
int minRR = 0;
|
||||
if (pDpyEvo->parsedEdid.info.ext_displayid.version) {
|
||||
minRR = pDpyEvo->parsedEdid.info.ext_displayid.range_limits[0].vfreq_min;
|
||||
}
|
||||
|
||||
if (minRR == 0) {
|
||||
NvU32 i;
|
||||
for (i = 0; i < NVT_EDID_MAX_LONG_DISPLAY_DESCRIPTOR; i++) {
|
||||
if (pDpyEvo->parsedEdid.info.ldd[i].tag ==
|
||||
NVT_EDID_DISPLAY_DESCRIPTOR_DRL) {
|
||||
minRR = pDpyEvo->parsedEdid.info.ldd[i].u.range_limit.min_v_rate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (minRR == 0) {
|
||||
// Adaptive sync does not support self refresh (zero timeout)
|
||||
nvEvoLogDisp(pDispEvo, EVO_LOG_WARN,
|
||||
"%s: G-SYNC Compatible: EDID min refresh rate "
|
||||
"invalid, disabling G-SYNC Compatible.",
|
||||
pDpyEvo->name);
|
||||
pDpyEvo->vrr.type = NVKMS_DPY_VRR_TYPE_NONE;
|
||||
pDpyEvo->vrr.needsSwFramePacing = FALSE;
|
||||
} else {
|
||||
pDpyEvo->vrr.edidTimeoutMicroseconds = 1000000 / minRR;
|
||||
}
|
||||
} else if (DpyHasVRREDID(pDpyEvo)) {
|
||||
// Update the minimum refresh rate if a VRR EDID block is present.
|
||||
const int minRR =
|
||||
pDpyEvo->parsedEdid.info.nvdaVsdbInfo.vrrData.v1.minRefreshRate;
|
||||
|
||||
if (minRR == 0) {
|
||||
// Zero indicates that no refreshes are required (i.e. the panel is
|
||||
// self-refreshing).
|
||||
pDpyEvo->vrr.edidTimeoutMicroseconds = 0;
|
||||
} else {
|
||||
// Round the timeout down. It's better to refresh the panel too soon
|
||||
// than too late.
|
||||
pDpyEvo->vrr.edidTimeoutMicroseconds = 1000000 / minRR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// when we get this event, the DP lib has done link training and the
|
||||
@@ -604,11 +565,13 @@ void nvDPLibUpdateDpyLinkConfiguration(NVDpyEvoPtr pDpyEvo)
|
||||
pDpyEvo->pConnectorEvo->pDpLibConnector->connector;
|
||||
unsigned laneCount;
|
||||
NvU64 linkRate;
|
||||
NvU64 linkRate10MHz;
|
||||
enum NvKmsDpyAttributeDisplayportConnectorTypeValue connectorType;
|
||||
NvBool sinkIsAudioCapable;
|
||||
|
||||
if (!dev || !pDpLibDevice->isPlugged) {
|
||||
linkRate = 0;
|
||||
linkRate10MHz = 0;
|
||||
laneCount = NV0073_CTRL_CMD_DP_GET_LINK_CONFIG_LANE_COUNT_1;
|
||||
connectorType = NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_CONNECTOR_TYPE_UNKNOWN;
|
||||
sinkIsAudioCapable = FALSE;
|
||||
@@ -620,6 +583,7 @@ void nvDPLibUpdateDpyLinkConfiguration(NVDpyEvoPtr pDpyEvo)
|
||||
// The DisplayPort library multiplies the link rate enum value by
|
||||
// 27000000. Convert back to NV-CONTROL's defines.
|
||||
linkRate /= 27000000;
|
||||
linkRate10MHz = linkRate * 27;
|
||||
|
||||
nvkmsDisplayPort::EnableVRR(pDpyEvo);
|
||||
|
||||
@@ -667,6 +631,13 @@ void nvDPLibUpdateDpyLinkConfiguration(NVDpyEvoPtr pDpyEvo)
|
||||
linkRate);
|
||||
}
|
||||
|
||||
if (linkRate10MHz != pDpyEvo->dp.linkRate10MHz) {
|
||||
pDpyEvo->dp.linkRate10MHz = linkRate10MHz;
|
||||
nvSendDpyAttributeChangedEventEvo(pDpyEvo,
|
||||
NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_LINK_RATE_10MHZ,
|
||||
linkRate10MHz);
|
||||
}
|
||||
|
||||
if (connectorType != pDpyEvo->dp.connectorType) {
|
||||
pDpyEvo->dp.connectorType = connectorType;
|
||||
nvSendDpyAttributeChangedEventEvo(pDpyEvo,
|
||||
|
||||
@@ -468,14 +468,30 @@ static NvBool ConstructDpLibIsModesetPossibleParamsOneHead(
|
||||
}
|
||||
|
||||
pParams->head[head].pDscParams->bCheckWithDsc = true;
|
||||
pParams->head[head].pDscParams->forceDsc = pModeValidationParams->forceDsc ?
|
||||
DisplayPort::DSC_FORCE_ENABLE :
|
||||
DisplayPort::DSC_DEFAULT;
|
||||
pParams->head[head].pDscParams->forceDsc = DisplayPort::DSC_DEFAULT;
|
||||
switch (pModeValidationParams->dscMode) {
|
||||
case NVKMS_DSC_MODE_FORCE_ENABLE:
|
||||
pParams->head[head].pDscParams->forceDsc =
|
||||
DisplayPort::DSC_FORCE_ENABLE;
|
||||
break;
|
||||
case NVKMS_DSC_MODE_FORCE_DISABLE:
|
||||
pParams->head[head].pDscParams->forceDsc =
|
||||
DisplayPort::DSC_FORCE_DISABLE;
|
||||
break;
|
||||
default:
|
||||
pParams->head[head].pDscParams->forceDsc =
|
||||
DisplayPort::DSC_DEFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* 2Heads1Or requires either YUV420 or DSC; if b2Heads1Or is enabled
|
||||
* but YUV420 is not, force DSC.
|
||||
*/
|
||||
if (b2Heads1Or && (pTimings->yuv420Mode != NV_YUV420_MODE_HW)) {
|
||||
if (pModeValidationParams->dscMode == NVKMS_DSC_MODE_FORCE_DISABLE) {
|
||||
goto failed;
|
||||
}
|
||||
pParams->head[head].pDscParams->forceDsc = DisplayPort::DSC_FORCE_ENABLE;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,14 +46,6 @@ static NVEvoLogType dpSeverityToNvkmsMap(DP_LOG_LEVEL severity)
|
||||
return level;
|
||||
}
|
||||
|
||||
void dpPrint(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
nvVEvoLog(EVO_LOG_INFO, NV_INVALID_GPU_LOG_INDEX, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void dpPrintf(DP_LOG_LEVEL severity, const char *format, ...)
|
||||
{
|
||||
if (severity == DP_SILENT) return;
|
||||
|
||||
@@ -628,6 +628,7 @@ static void DpyPostColorSpaceOrRangeSetEvo(NVDpyEvoPtr pDpyEvo)
|
||||
pApiHeadState->timings.yuv420Mode,
|
||||
pApiHeadState->attributes.color.colorimetry,
|
||||
pDpyEvo->requestedColorSpace,
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_UNKNOWN,
|
||||
pDpyEvo->requestedColorRange,
|
||||
&colorSpace,
|
||||
&colorBpc,
|
||||
@@ -668,8 +669,8 @@ static void DpyPostColorSpaceOrRangeSetEvo(NVDpyEvoPtr pDpyEvo)
|
||||
if (pApiHeadState->timings.protocol == NVKMS_PROTOCOL_SOR_HDMI_FRL) {
|
||||
tmpDpyColor.bpc = pApiHeadState->attributes.color.bpc;
|
||||
} else {
|
||||
const NVColorFormatInfoRec colorFormatsInfo =
|
||||
nvGetColorFormatInfo(pDpyEvo);
|
||||
const NvKmsDpyOutputColorFormatInfo colorFormatsInfo =
|
||||
nvDpyGetOutputColorFormatInfo(pDpyEvo);
|
||||
|
||||
while (nvHdmiGetEffectivePixelClockKHz(pDpyEvo,
|
||||
&pApiHeadState->timings,
|
||||
@@ -878,6 +879,30 @@ static NvBool GetColorRangeValidValues(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NvBool GetCurrentColorBpc(const NVDpyEvoRec *pDpyEvo, NvS64 *pValue)
|
||||
{
|
||||
*pValue = pDpyEvo->currentAttributes.color.bpc;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NvBool GetColorBpcValidValues(
|
||||
const NVDpyEvoRec *pDpyEvo,
|
||||
struct NvKmsAttributeValidValuesCommonReply *pValidValues)
|
||||
{
|
||||
nvAssert(pValidValues->type == NV_KMS_ATTRIBUTE_TYPE_INTBITS);
|
||||
|
||||
/* If new enum values are added, update the u.bits.ints assignment. */
|
||||
ct_assert(NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_MAX ==
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10);
|
||||
|
||||
pValidValues->u.bits.ints =
|
||||
NVBIT(NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_6) |
|
||||
NVBIT(NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8) |
|
||||
NVBIT(NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NvBool DigitalSignalAvailable(const NVDpyEvoRec *pDpyEvo)
|
||||
{
|
||||
return pDpyEvo->pConnectorEvo->legacyType ==
|
||||
@@ -991,6 +1016,30 @@ static NvBool GetDisplayportLinkRateValidValues(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NvBool GetDisplayportLinkRate10MHz(const NVDpyEvoRec *pDpyEvo, NvS64 *pValue)
|
||||
{
|
||||
if (!DisplayportLinkRateAvailable(pDpyEvo)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pValue = pDpyEvo->dp.linkRate10MHz;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NvBool GetDisplayportLinkRate10MHzValidValues(
|
||||
const NVDpyEvoRec *pDpyEvo,
|
||||
struct NvKmsAttributeValidValuesCommonReply *pValidValues)
|
||||
{
|
||||
if (!DisplayportLinkRateAvailable(pDpyEvo)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
nvAssert(pValidValues->type == NV_KMS_ATTRIBUTE_TYPE_INTEGER);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NvBool GetDisplayportConnectorType(const NVDpyEvoRec *pDpyEvo,
|
||||
NvS64 *pValue)
|
||||
{
|
||||
@@ -1139,6 +1188,7 @@ static NvBool GetVrrMinRefreshRateValidValues(
|
||||
struct NvKmsAttributeValidValuesCommonReply *pValidValues)
|
||||
{
|
||||
NvU32 minMinRefreshRate, maxMinRefreshRate;
|
||||
const NVHwModeTimingsEvo *pTimings;
|
||||
const NVDispEvoRec *pDispEvo = pDpyEvo->pDispEvo;
|
||||
NvU32 head;
|
||||
|
||||
@@ -1148,9 +1198,12 @@ static NvBool GetVrrMinRefreshRateValidValues(
|
||||
|
||||
head = nvGetPrimaryHwHead(pDispEvo, pDpyEvo->apiHead);
|
||||
nvAssert(head != NV_INVALID_HEAD);
|
||||
nvGetDpyMinRefreshRateValidValues(&pDispEvo->headState[head].timings,
|
||||
|
||||
pTimings = &pDispEvo->headState[head].timings;
|
||||
|
||||
nvGetDpyMinRefreshRateValidValues(pTimings,
|
||||
pDpyEvo->vrr.type,
|
||||
pDpyEvo->vrr.edidTimeoutMicroseconds,
|
||||
pTimings->vrr.timeoutMicroseconds,
|
||||
&minMinRefreshRate,
|
||||
&maxMinRefreshRate);
|
||||
#if defined(DEBUG)
|
||||
@@ -1159,9 +1212,11 @@ static NvBool GetVrrMinRefreshRateValidValues(
|
||||
FOR_EACH_EVO_HW_HEAD(pDispEvo, pDpyEvo->apiHead, h) {
|
||||
NvU32 tmpMinMinRefreshRate, tmpMaxMinRefreshRate;
|
||||
|
||||
nvGetDpyMinRefreshRateValidValues(&pDispEvo->headState[h].timings,
|
||||
pTimings = &pDispEvo->headState[h].timings;
|
||||
|
||||
nvGetDpyMinRefreshRateValidValues(pTimings,
|
||||
pDpyEvo->vrr.type,
|
||||
pDpyEvo->vrr.edidTimeoutMicroseconds,
|
||||
pTimings->vrr.timeoutMicroseconds,
|
||||
&tmpMinMinRefreshRate,
|
||||
&tmpMaxMinRefreshRate);
|
||||
|
||||
@@ -1302,6 +1357,12 @@ static const struct {
|
||||
.getValidValues = GetColorRangeValidValues,
|
||||
.type = NV_KMS_ATTRIBUTE_TYPE_INTBITS,
|
||||
},
|
||||
[NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC] = {
|
||||
.set = NULL,
|
||||
.get = GetCurrentColorBpc,
|
||||
.getValidValues = GetColorBpcValidValues,
|
||||
.type = NV_KMS_ATTRIBUTE_TYPE_INTBITS,
|
||||
},
|
||||
[NV_KMS_DPY_ATTRIBUTE_DIGITAL_SIGNAL] = {
|
||||
.set = NULL,
|
||||
.get = GetDigitalSignal,
|
||||
@@ -1320,6 +1381,12 @@ static const struct {
|
||||
.getValidValues = GetDisplayportLinkRateValidValues,
|
||||
.type = NV_KMS_ATTRIBUTE_TYPE_INTEGER,
|
||||
},
|
||||
[NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_LINK_RATE_10MHZ] = {
|
||||
.set = NULL,
|
||||
.get = GetDisplayportLinkRate10MHz,
|
||||
.getValidValues = GetDisplayportLinkRate10MHzValidValues,
|
||||
.type = NV_KMS_ATTRIBUTE_TYPE_INTEGER,
|
||||
},
|
||||
[NV_KMS_DPY_ATTRIBUTE_DISPLAYPORT_CONNECTOR_TYPE] = {
|
||||
.set = NULL,
|
||||
.get = GetDisplayportConnectorType,
|
||||
|
||||
@@ -1660,6 +1660,46 @@ static void LogEdid(NVDpyEvoPtr pDpyEvo, NVEvoInfoStringPtr pInfoString)
|
||||
pParsedEdid->info.nvdaVsdbInfo.vrrData.v1.minRefreshRate);
|
||||
}
|
||||
|
||||
if (pParsedEdid->info.ext_displayid.version) {
|
||||
nvEvoLogInfoString(pInfoString,
|
||||
"DisplayID vfreq_min : %d Hz",
|
||||
pParsedEdid->info.ext_displayid.range_limits[0].vfreq_min);
|
||||
}
|
||||
|
||||
if (pParsedEdid->info.ext_displayid20.version &&
|
||||
pParsedEdid->info.ext_displayid20.range_limits.seamless_dynamic_video_timing_change) {
|
||||
nvEvoLogInfoString(pInfoString,
|
||||
"DisplayID 2.0 vfreq_min : %d Hz",
|
||||
pParsedEdid->info.ext_displayid20.range_limits.vfreq_min);
|
||||
}
|
||||
|
||||
if (pParsedEdid->info.ext_displayid20.version &&
|
||||
pParsedEdid->info.ext_displayid20.total_adaptive_sync_descriptor != 0) {
|
||||
for (k = 0;
|
||||
k < pParsedEdid->info.ext_displayid20.total_adaptive_sync_descriptor &&
|
||||
k < ARRAY_LEN(pParsedEdid->info.ext_displayid20.adaptive_sync_descriptor);
|
||||
k++) {
|
||||
nvEvoLogInfoString(pInfoString,
|
||||
"DisplayID 2.0 adaptive sync : %d Hz (max), %d Hz (min)",
|
||||
pParsedEdid->info.ext_displayid20.adaptive_sync_descriptor[k].max_rr,
|
||||
pParsedEdid->info.ext_displayid20.adaptive_sync_descriptor[k].min_rr);
|
||||
}
|
||||
}
|
||||
|
||||
for (k = 0; k < ARRAY_LEN(pParsedEdid->info.ldd); k++) {
|
||||
if (pParsedEdid->info.ldd[k].tag == NVT_EDID_DISPLAY_DESCRIPTOR_DRL) {
|
||||
nvEvoLogInfoString(pInfoString,
|
||||
"min_v_rate : %d Hz",
|
||||
pParsedEdid->info.ldd[k].u.range_limit.min_v_rate);
|
||||
}
|
||||
}
|
||||
|
||||
if (pParsedEdid->info.hdmiForumInfo.vrr_min != 0) {
|
||||
nvEvoLogInfoString(pInfoString,
|
||||
"HDMI Forum vrr_min : %d Hz",
|
||||
pParsedEdid->info.hdmiForumInfo.vrr_min);
|
||||
}
|
||||
|
||||
nvLogEdidCea861InfoEvo(pDpyEvo, pInfoString);
|
||||
|
||||
if (pParsedEdid->info.input.isDigital &&
|
||||
@@ -3014,6 +3054,9 @@ NvBool nvDpyGetDynamicData(
|
||||
nvkms_memcpy(pReply->edid.buffer, pDpyEvo->edid.buffer, pDpyEvo->edid.length);
|
||||
}
|
||||
|
||||
pReply->supportedOutputColorFormats =
|
||||
nvDpyGetOutputColorFormatInfo(pDpyEvo);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -3172,17 +3215,21 @@ static enum NvKmsDpyAttributeColorBpcValue GetYuv422MaxBpc(
|
||||
return NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_UNKNOWN;
|
||||
}
|
||||
|
||||
NVColorFormatInfoRec nvGetColorFormatInfo(const NVDpyEvoRec *pDpyEvo)
|
||||
NvKmsDpyOutputColorFormatInfo nvDpyGetOutputColorFormatInfo(
|
||||
const NVDpyEvoRec *pDpyEvo)
|
||||
{
|
||||
const NVConnectorEvoRec *pConnectorEvo =
|
||||
pDpyEvo->pConnectorEvo;
|
||||
NVColorFormatInfoRec colorFormatsInfo = { };
|
||||
NvKmsDpyOutputColorFormatInfo colorFormatsInfo = { };
|
||||
|
||||
if (pConnectorEvo->legacyType ==
|
||||
NV0073_CTRL_SPECIFIC_DISPLAY_TYPE_CRT) {
|
||||
|
||||
colorFormatsInfo.rgb444.maxBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10;
|
||||
colorFormatsInfo.rgb444.minBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10;
|
||||
|
||||
} else if (pConnectorEvo->legacyType ==
|
||||
NV0073_CTRL_SPECIFIC_DISPLAY_TYPE_DFP) {
|
||||
|
||||
@@ -3207,9 +3254,14 @@ NVColorFormatInfoRec nvGetColorFormatInfo(const NVDpyEvoRec *pDpyEvo)
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
|
||||
break;
|
||||
}
|
||||
|
||||
colorFormatsInfo.rgb444.minBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_6;
|
||||
} else {
|
||||
colorFormatsInfo.rgb444.maxBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
|
||||
colorFormatsInfo.rgb444.minBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
|
||||
}
|
||||
} else if (nvConnectorUsesDPLib(pDpyEvo->pConnectorEvo)) {
|
||||
|
||||
@@ -3219,9 +3271,13 @@ NVColorFormatInfoRec nvGetColorFormatInfo(const NVDpyEvoRec *pDpyEvo)
|
||||
if (pDpyEvo->parsedEdid.info.input.u.digital.bpc >= 10) {
|
||||
colorFormatsInfo.rgb444.maxBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10;
|
||||
colorFormatsInfo.yuv444.maxBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10;
|
||||
} else if (pDpyEvo->parsedEdid.info.input.u.digital.bpc < 8) {
|
||||
colorFormatsInfo.rgb444.maxBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_6;
|
||||
colorFormatsInfo.yuv444.maxBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_UNKNOWN;
|
||||
} else {
|
||||
colorFormatsInfo.rgb444.maxBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
|
||||
@@ -3229,23 +3285,56 @@ NVColorFormatInfoRec nvGetColorFormatInfo(const NVDpyEvoRec *pDpyEvo)
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
|
||||
}
|
||||
|
||||
colorFormatsInfo.rgb444.minBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_6;
|
||||
if (colorFormatsInfo.yuv444.maxBpc !=
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_UNKNOWN) {
|
||||
colorFormatsInfo.yuv444.minBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
|
||||
} else {
|
||||
colorFormatsInfo.yuv444.minBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_UNKNOWN;
|
||||
}
|
||||
|
||||
colorFormatsInfo.yuv422.maxBpc = GetYuv422MaxBpc(pDpyEvo);
|
||||
if (colorFormatsInfo.yuv422.maxBpc !=
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_UNKNOWN) {
|
||||
colorFormatsInfo.yuv422.minBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
|
||||
} else {
|
||||
colorFormatsInfo.yuv422.minBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_UNKNOWN;
|
||||
}
|
||||
} else {
|
||||
colorFormatsInfo.rgb444.maxBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
|
||||
colorFormatsInfo.rgb444.minBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
|
||||
}
|
||||
} else {
|
||||
colorFormatsInfo.rgb444.maxBpc =
|
||||
nvDpyIsHdmiDepth30Evo(pDpyEvo) ?
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10 :
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
|
||||
colorFormatsInfo.rgb444.minBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
|
||||
|
||||
if (nvDpyIsHdmiEvo(pDpyEvo)) {
|
||||
// TODO: Handle depth 30 YUV
|
||||
colorFormatsInfo.yuv444.maxBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
|
||||
colorFormatsInfo.yuv422.maxBpc =
|
||||
GetYuv422MaxBpc(pDpyEvo);
|
||||
colorFormatsInfo.yuv444.minBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
|
||||
|
||||
colorFormatsInfo.yuv422.maxBpc = GetYuv422MaxBpc(pDpyEvo);
|
||||
if (colorFormatsInfo.yuv422.maxBpc !=
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_UNKNOWN) {
|
||||
colorFormatsInfo.yuv422.minBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
|
||||
} else {
|
||||
colorFormatsInfo.yuv422.minBpc =
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2725,7 +2725,7 @@ void nvEnableMidFrameAndDWCFWatermark(NVDevEvoPtr pDevEvo,
|
||||
}
|
||||
|
||||
static NvBool GetDefaultColorSpace(
|
||||
const NVColorFormatInfoRec *pColorFormatsInfo,
|
||||
const NvKmsDpyOutputColorFormatInfo *pColorFormatsInfo,
|
||||
enum NvKmsDpyAttributeCurrentColorSpaceValue *pColorSpace,
|
||||
enum NvKmsDpyAttributeColorBpcValue *pColorBpc)
|
||||
{
|
||||
@@ -2753,8 +2753,9 @@ static NvBool GetDefaultColorSpace(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NvBool nvGetDefaultDpyColor(const NVColorFormatInfoRec *pColorFormatsInfo,
|
||||
NVDpyAttributeColor *pDpyColor)
|
||||
NvBool nvGetDefaultDpyColor(
|
||||
const NvKmsDpyOutputColorFormatInfo *pColorFormatsInfo,
|
||||
NVDpyAttributeColor *pDpyColor)
|
||||
{
|
||||
nvkms_memset(pDpyColor, 0, sizeof(*pDpyColor));
|
||||
|
||||
@@ -2806,6 +2807,23 @@ NvBool nvChooseColorRangeEvo(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static enum NvKmsDpyAttributeColorBpcValue ChooseColorBpc(
|
||||
const enum NvKmsDpyAttributeColorBpcValue requested,
|
||||
const enum NvKmsDpyAttributeColorBpcValue max,
|
||||
const enum NvKmsDpyAttributeColorBpcValue min)
|
||||
{
|
||||
if ((requested == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_UNKNOWN) ||
|
||||
(requested > max)) {
|
||||
return max;
|
||||
}
|
||||
|
||||
if (requested < min) {
|
||||
return min;
|
||||
}
|
||||
|
||||
return requested;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Choose current colorSpace and colorRange for the given dpy based on
|
||||
* the dpy's color format capailities, the given modeset parameters (YUV420
|
||||
@@ -2823,6 +2841,7 @@ NvBool nvChooseCurrentColorSpaceAndRangeEvo(
|
||||
const enum NvYuv420Mode yuv420Mode,
|
||||
enum NvKmsOutputColorimetry colorimetry,
|
||||
const enum NvKmsDpyAttributeRequestedColorSpaceValue requestedColorSpace,
|
||||
const enum NvKmsDpyAttributeColorBpcValue requestedColorBpc,
|
||||
const enum NvKmsDpyAttributeColorRangeValue requestedColorRange,
|
||||
enum NvKmsDpyAttributeCurrentColorSpaceValue *pCurrentColorSpace,
|
||||
enum NvKmsDpyAttributeColorBpcValue *pCurrentColorBpc,
|
||||
@@ -2834,8 +2853,8 @@ NvBool nvChooseCurrentColorSpaceAndRangeEvo(
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10;
|
||||
enum NvKmsDpyAttributeColorRangeValue newColorRange =
|
||||
NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL;
|
||||
const NVColorFormatInfoRec colorFormatsInfo =
|
||||
nvGetColorFormatInfo(pDpyEvo);
|
||||
const NvKmsDpyOutputColorFormatInfo colorFormatsInfo =
|
||||
nvDpyGetOutputColorFormatInfo(pDpyEvo);
|
||||
|
||||
// XXX HDR TODO: Handle other colorimetries
|
||||
// XXX HDR TODO: Handle YUV
|
||||
@@ -2870,15 +2889,21 @@ NvBool nvChooseCurrentColorSpaceAndRangeEvo(
|
||||
switch (requestedColorSpace) {
|
||||
case NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE_RGB:
|
||||
newColorSpace = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB;
|
||||
newColorBpc = colorFormatsInfo.rgb444.maxBpc;
|
||||
newColorBpc = ChooseColorBpc(requestedColorBpc,
|
||||
colorFormatsInfo.rgb444.maxBpc,
|
||||
colorFormatsInfo.rgb444.minBpc);
|
||||
break;
|
||||
case NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE_YCbCr422:
|
||||
newColorSpace = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr422;
|
||||
newColorBpc = colorFormatsInfo.yuv422.maxBpc;
|
||||
newColorBpc = ChooseColorBpc(requestedColorBpc,
|
||||
colorFormatsInfo.yuv422.maxBpc,
|
||||
colorFormatsInfo.yuv422.minBpc);
|
||||
break;
|
||||
case NV_KMS_DPY_ATTRIBUTE_REQUESTED_COLOR_SPACE_YCbCr444:
|
||||
newColorSpace = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr444;
|
||||
newColorBpc = colorFormatsInfo.yuv444.maxBpc;
|
||||
newColorBpc = ChooseColorBpc(requestedColorBpc,
|
||||
colorFormatsInfo.yuv444.maxBpc,
|
||||
colorFormatsInfo.yuv444.minBpc);
|
||||
break;
|
||||
default:
|
||||
nvAssert(!"Invalid Requested ColorSpace");
|
||||
@@ -6653,8 +6678,9 @@ ConstructHwModeTimingsViewPort(const NVDispEvoRec *pDispEvo,
|
||||
}
|
||||
|
||||
|
||||
static NvBool GetDefaultFrlDpyColor(const NVColorFormatInfoRec *pColorFormatsInfo,
|
||||
NVDpyAttributeColor *pDpyColor)
|
||||
static NvBool GetDefaultFrlDpyColor(
|
||||
const NvKmsDpyOutputColorFormatInfo *pColorFormatsInfo,
|
||||
NVDpyAttributeColor *pDpyColor)
|
||||
{
|
||||
nvkms_memset(pDpyColor, 0, sizeof(*pDpyColor));
|
||||
pDpyColor->colorimetry = NVKMS_OUTPUT_COLORIMETRY_DEFAULT;
|
||||
@@ -6686,8 +6712,8 @@ static NvBool GetDfpHdmiProtocol(const NVDpyEvoRec *pDpyEvo,
|
||||
{
|
||||
NVConnectorEvoPtr pConnectorEvo = pDpyEvo->pConnectorEvo;
|
||||
const NvU32 rmProtocol = pConnectorEvo->or.protocol;
|
||||
const NVColorFormatInfoRec colorFormatsInfo =
|
||||
nvGetColorFormatInfo(pDpyEvo);
|
||||
const NvKmsDpyOutputColorFormatInfo colorFormatsInfo =
|
||||
nvDpyGetOutputColorFormatInfo(pDpyEvo);
|
||||
const NvBool forceHdmiFrlIsSupported = FALSE;
|
||||
|
||||
nvAssert(rmProtocol == NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_SINGLE_TMDS_A ||
|
||||
@@ -6888,18 +6914,55 @@ static NvBool ConstructHwModeTimingsEvoDfp(const NVDpyEvoRec *pDpyEvo,
|
||||
pViewPortOut);
|
||||
}
|
||||
|
||||
NvBool nvDowngradeColorBpc(NVDpyAttributeColor *pDpyColor)
|
||||
static NvBool IsColorBpcSupported(
|
||||
const NvKmsDpyOutputColorFormatInfo *pSupportedColorFormats,
|
||||
const enum NvKmsDpyAttributeCurrentColorSpaceValue format,
|
||||
const enum NvKmsDpyAttributeColorBpcValue bpc)
|
||||
{
|
||||
switch (format) {
|
||||
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB:
|
||||
return (bpc <= pSupportedColorFormats->rgb444.maxBpc) &&
|
||||
(bpc >= pSupportedColorFormats->rgb444.minBpc);
|
||||
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr422:
|
||||
return (bpc <= pSupportedColorFormats->yuv422.maxBpc) &&
|
||||
(bpc >= pSupportedColorFormats->yuv422.minBpc);
|
||||
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr444:
|
||||
return (bpc <= pSupportedColorFormats->yuv444.maxBpc) &&
|
||||
(bpc >= pSupportedColorFormats->yuv444.minBpc);
|
||||
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_YCbCr420:
|
||||
return (bpc == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NvBool nvDowngradeColorBpc(
|
||||
const NvKmsDpyOutputColorFormatInfo *pSupportedColorFormats,
|
||||
NVDpyAttributeColor *pDpyColor)
|
||||
{
|
||||
switch (pDpyColor->bpc) {
|
||||
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_10:
|
||||
if (pDpyColor->colorimetry == NVKMS_OUTPUT_COLORIMETRY_BT2100) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!IsColorBpcSupported(pSupportedColorFormats,
|
||||
pDpyColor->format,
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pDpyColor->bpc = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8;
|
||||
break;
|
||||
case NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8:
|
||||
/* At depth 18 only RGB and full range are allowed */
|
||||
if (pDpyColor->format == NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_SPACE_RGB) {
|
||||
if (!IsColorBpcSupported(pSupportedColorFormats,
|
||||
pDpyColor->format,
|
||||
NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_6)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pDpyColor->bpc = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_6;
|
||||
pDpyColor->range = NV_KMS_DPY_ATTRIBUTE_COLOR_RANGE_FULL;
|
||||
} else {
|
||||
@@ -6915,10 +6978,10 @@ NvBool nvDowngradeColorBpc(NVDpyAttributeColor *pDpyColor)
|
||||
}
|
||||
|
||||
NvBool nvDowngradeColorSpaceAndBpc(
|
||||
const NVColorFormatInfoRec *pSupportedColorFormats,
|
||||
const NvKmsDpyOutputColorFormatInfo *pSupportedColorFormats,
|
||||
NVDpyAttributeColor *pDpyColor)
|
||||
{
|
||||
if (nvDowngradeColorBpc(pDpyColor)) {
|
||||
if (nvDowngradeColorBpc(pSupportedColorFormats, pDpyColor)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -6961,8 +7024,8 @@ NvBool nvDPValidateModeEvo(NVDpyEvoPtr pDpyEvo,
|
||||
{
|
||||
NVConnectorEvoPtr pConnectorEvo = pDpyEvo->pConnectorEvo;
|
||||
NVDpyAttributeColor dpyColor = *pDpyColor;
|
||||
const NVColorFormatInfoRec supportedColorFormats =
|
||||
nvGetColorFormatInfo(pDpyEvo);
|
||||
const NvKmsDpyOutputColorFormatInfo supportedColorFormats =
|
||||
nvDpyGetOutputColorFormatInfo(pDpyEvo);
|
||||
|
||||
/* Only do this for DP devices. */
|
||||
if (!nvConnectorUsesDPLib(pConnectorEvo)) {
|
||||
|
||||
@@ -5946,10 +5946,10 @@ static void SetHDRLayerCaps(NVDevEvoPtr pDevEvo)
|
||||
* TODO: Rework API for per-head layerCaps if this assert trips.
|
||||
*/
|
||||
nvAssert(!hdrLayerCapSet[numLayers[head]] ||
|
||||
(pDevEvo->caps.layerCaps[numLayers[head]].supportsHDR ==
|
||||
(pDevEvo->caps.layerCaps[numLayers[head]].supportsICtCp ==
|
||||
pWinCaps->tmoPresent));
|
||||
|
||||
pDevEvo->caps.layerCaps[numLayers[head]].supportsHDR = pWinCaps->tmoPresent;
|
||||
pDevEvo->caps.layerCaps[numLayers[head]].supportsICtCp = pWinCaps->tmoPresent;
|
||||
|
||||
#if defined(DEBUG)
|
||||
hdrLayerCapSet[numLayers[head]] = TRUE;
|
||||
@@ -7042,14 +7042,14 @@ static void ForceFlipToNull(
|
||||
NVDevEvoPtr pDevEvo,
|
||||
NVEvoChannelPtr pChannel,
|
||||
NvU32 sd,
|
||||
NVEvoUpdateState *updateState)
|
||||
NVEvoUpdateState *updateState,
|
||||
const NVFlipChannelEvoHwState *pNullHwState)
|
||||
{
|
||||
NVFlipChannelEvoHwState hwState = { };
|
||||
const NvU32 subDeviceMask = (1 << sd);
|
||||
|
||||
nvPushEvoSubDevMask(pDevEvo, subDeviceMask);
|
||||
|
||||
pDevEvo->hal->Flip(pDevEvo, pChannel, &hwState, updateState,
|
||||
pDevEvo->hal->Flip(pDevEvo, pChannel, pNullHwState, updateState,
|
||||
FALSE /* bypassComposition */);
|
||||
|
||||
nvPopEvoSubDevMask(pDevEvo);
|
||||
@@ -7108,6 +7108,7 @@ typedef struct {
|
||||
NvU32 accelerators;
|
||||
NvBool overridden;
|
||||
} window[NVKMS_MAX_WINDOWS_PER_DISP];
|
||||
NVFlipChannelEvoHwState nullEvoHwState;
|
||||
} EvoIdleChannelAcceleratorState;
|
||||
|
||||
static NvBool EvoForceIdleSatelliteChannelsWithAccel(
|
||||
@@ -7162,8 +7163,16 @@ static NvBool EvoForceIdleSatelliteChannelsWithAccel(
|
||||
}
|
||||
pAcceleratorState[sd].window[window].overridden = TRUE;
|
||||
|
||||
/* Push a flip to null in this channel. */
|
||||
ForceFlipToNull(pDevEvo, pChannel, sd, &updateState);
|
||||
/*
|
||||
* Push a flip to null in this channel.
|
||||
*
|
||||
* XXX nullEvoHwState isn't a valid state for NULL flip, for
|
||||
* example 'csc' will be all 0s instead of the identity. This
|
||||
* will also lead to the HW state being out of sync with the SW
|
||||
* state.
|
||||
*/
|
||||
ForceFlipToNull(pDevEvo, pChannel, sd, &updateState,
|
||||
&pAcceleratorState->nullEvoHwState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1415,8 +1415,6 @@ void nvDpyUpdateHdmiVRRCaps(NVDpyEvoPtr pDpyEvo)
|
||||
}
|
||||
|
||||
pDpyEvo->vrr.needsSwFramePacing = TRUE;
|
||||
|
||||
pDpyEvo->vrr.edidTimeoutMicroseconds = 1000000 / edidVrrMin;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2311,7 +2309,7 @@ static NvBool nvHdmiFrlQueryConfigOneBpc(
|
||||
|
||||
clientControl.option = HDMI_QUERY_FRL_HIGHEST_PIXEL_QUALITY;
|
||||
|
||||
if (pValidationParams->forceDsc) {
|
||||
if (pValidationParams->dscMode == NVKMS_DSC_MODE_FORCE_ENABLE) {
|
||||
clientControl.enableDSC = TRUE;
|
||||
}
|
||||
|
||||
@@ -2320,6 +2318,9 @@ static NvBool nvHdmiFrlQueryConfigOneBpc(
|
||||
* but YUV420 is not, force DSC.
|
||||
*/
|
||||
if (b2Heads1Or && (pHwTimings->yuv420Mode != NV_YUV420_MODE_HW)) {
|
||||
if (pValidationParams->dscMode == NVKMS_DSC_MODE_FORCE_DISABLE) {
|
||||
return FALSE;
|
||||
}
|
||||
clientControl.enableDSC = TRUE;
|
||||
}
|
||||
|
||||
@@ -2357,6 +2358,13 @@ static NvBool nvHdmiFrlQueryConfigOneBpc(
|
||||
if ((pConfig->frlRate != HDMI_FRL_DATA_RATE_NONE) &&
|
||||
pConfig->dscInfo.bEnableDSC &&
|
||||
(hdmiLinkRate != 0)) {
|
||||
|
||||
if (pValidationParams->dscMode ==
|
||||
NVKMS_DSC_MODE_FORCE_DISABLE) {
|
||||
ret = NVHDMIPKT_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
pDscInfo->type = NV_DSC_INFO_EVO_TYPE_HDMI;
|
||||
pDscInfo->hdmi.dscMode = b2Heads1Or ?
|
||||
NV_DSC_EVO_MODE_DUAL : NV_DSC_EVO_MODE_SINGLE;
|
||||
@@ -2385,6 +2393,7 @@ static NvBool nvHdmiFrlQueryConfigOneBpc(
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return ret == NVHDMIPKT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -2410,6 +2419,8 @@ NvBool nvHdmiFrlQueryConfig(
|
||||
HDMI_FRL_CONFIG *pConfig,
|
||||
NVDscInfoEvoRec *pDscInfo)
|
||||
{
|
||||
const NvKmsDpyOutputColorFormatInfo supportedColorFormats =
|
||||
nvDpyGetOutputColorFormatInfo(pDpyEvo);
|
||||
NVDpyAttributeColor dpyColor = *pDpyColor;
|
||||
do {
|
||||
if (nvHdmiFrlQueryConfigOneBpc(pDpyEvo,
|
||||
@@ -2423,7 +2434,7 @@ NvBool nvHdmiFrlQueryConfig(
|
||||
*pDpyColor = dpyColor;
|
||||
return TRUE;
|
||||
}
|
||||
} while(nvDowngradeColorBpc(&dpyColor) &&
|
||||
} while(nvDowngradeColorBpc(&supportedColorFormats, &dpyColor) &&
|
||||
(dpyColor.bpc >= NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_8));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -541,8 +541,8 @@ static NvBool UpdateLayerFlipEvoHwStateHDRStaticMetadata(
|
||||
{
|
||||
if (pParams->layer[layer].hdr.specified) {
|
||||
if (pParams->layer[layer].hdr.enabled) {
|
||||
// Don't allow enabling HDR on a layer that doesn't support it.
|
||||
if (!pDevEvo->caps.layerCaps[layer].supportsHDR) {
|
||||
// Don't allow enabling HDR on a layer that doesn't support ICtCp.
|
||||
if (!pDevEvo->caps.layerCaps[layer].supportsICtCp) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -551,8 +551,8 @@ static NvBool UpdateLayerFlipEvoHwStateHDRStaticMetadata(
|
||||
}
|
||||
pHwState->hdrStaticMetadata.enabled = pParams->layer[layer].hdr.enabled;
|
||||
|
||||
// Only mark dirty if layer supports HDR, otherwise this is a no-op.
|
||||
if (pDevEvo->caps.layerCaps[layer].supportsHDR) {
|
||||
// Only mark dirty if layer supports ICtCp, otherwise this is a no-op.
|
||||
if (pDevEvo->caps.layerCaps[layer].supportsICtCp) {
|
||||
pFlipState->dirty.hdrStaticMetadata = TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1273,7 +1273,7 @@ ValidateHDR(const NVDevEvoRec *pDevEvo,
|
||||
NvU32 layer;
|
||||
|
||||
for (layer = 0; layer < pDevEvo->head[head].numLayers; layer++) {
|
||||
if (pDevEvo->caps.layerCaps[layer].supportsHDR) {
|
||||
if (pDevEvo->caps.layerCaps[layer].supportsICtCp) {
|
||||
layerSupportedCount++;
|
||||
}
|
||||
|
||||
@@ -1291,7 +1291,7 @@ ValidateHDR(const NVDevEvoRec *pDevEvo,
|
||||
}
|
||||
|
||||
// Already checked in UpdateLayerFlipEvoHwStateHDRStaticMetadata()
|
||||
nvAssert(pDevEvo->caps.layerCaps[layer].supportsHDR);
|
||||
nvAssert(pDevEvo->caps.layerCaps[layer].supportsICtCp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1672,7 +1672,8 @@ static NvBool ValidateMode(NVDpyEvoPtr pDpyEvo,
|
||||
NvU32 head;
|
||||
NvBool ret = FALSE;
|
||||
|
||||
const NVColorFormatInfoRec supportedColorFormats = nvGetColorFormatInfo(pDpyEvo);
|
||||
const NvKmsDpyOutputColorFormatInfo supportedColorFormats =
|
||||
nvDpyGetOutputColorFormatInfo(pDpyEvo);
|
||||
NVDpyAttributeColor dpyColor;
|
||||
|
||||
if (modeName[0] == '\0') {
|
||||
|
||||
@@ -247,6 +247,7 @@ GetColorSpaceAndColorRange(
|
||||
{
|
||||
enum NvKmsOutputColorimetry colorimetry;
|
||||
enum NvKmsDpyAttributeColorRangeValue requestedColorRange;
|
||||
enum NvKmsDpyAttributeColorBpcValue requestedColorBpc;
|
||||
enum NvKmsDpyAttributeRequestedColorSpaceValue requestedColorSpace;
|
||||
NVDpyEvoRec *pOneArbitraryDpyEvo =
|
||||
nvGetOneArbitraryDpyEvo(pRequestHead->dpyIdList, pDispEvo);
|
||||
@@ -275,6 +276,12 @@ GetColorSpaceAndColorRange(
|
||||
requestedColorRange = pOneArbitraryDpyEvo->requestedColorRange;
|
||||
}
|
||||
|
||||
if (pRequestHead->colorBpcSpecified) {
|
||||
requestedColorBpc = pRequestHead->colorBpc;
|
||||
} else {
|
||||
requestedColorBpc = NV_KMS_DPY_ATTRIBUTE_CURRENT_COLOR_BPC_UNKNOWN;
|
||||
}
|
||||
|
||||
if (pRequestHead->flip.colorimetry.specified) {
|
||||
colorimetry = pRequestHead->flip.colorimetry.val;
|
||||
} else {
|
||||
@@ -290,6 +297,7 @@ GetColorSpaceAndColorRange(
|
||||
pRequestHead->mode.timings.yuv420Mode,
|
||||
colorimetry,
|
||||
requestedColorSpace,
|
||||
requestedColorBpc,
|
||||
requestedColorRange,
|
||||
&pDpyColor->format,
|
||||
&pDpyColor->bpc,
|
||||
@@ -332,6 +340,15 @@ static NvBool AssignProposedModeSetColorSpaceAndColorRangeSpecified(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* When color bpc is specified in modeset request, it should
|
||||
* match the proposed color bpc.
|
||||
*/
|
||||
if (pRequestHead->colorBpcSpecified &&
|
||||
(pProposedApiHead->attributes.color.bpc != pRequestHead->colorBpc)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* When color range is specified in modeset request, it should
|
||||
* match the proposed color range.
|
||||
@@ -342,6 +359,7 @@ static NvBool AssignProposedModeSetColorSpaceAndColorRangeSpecified(
|
||||
}
|
||||
|
||||
pProposedApiHead->colorSpaceSpecified = pRequestHead->colorSpaceSpecified;
|
||||
pProposedApiHead->colorBpcSpecified = pRequestHead->colorBpcSpecified;
|
||||
pProposedApiHead->colorRangeSpecified = pRequestHead->colorRangeSpecified;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -417,11 +435,11 @@ static void AdjustHwModeTimingsForVrr(const NVDispEvoRec *pDispEvo,
|
||||
allowGsync,
|
||||
allowAdaptiveSync);
|
||||
|
||||
nvAdjustHwModeTimingsForVrrEvo(pTimings,
|
||||
nvAdjustHwModeTimingsForVrrEvo(pDpyEvo,
|
||||
vrrType,
|
||||
pDpyEvo->vrr.edidTimeoutMicroseconds,
|
||||
vrrOverrideMinRefreshRate,
|
||||
pDpyEvo->vrr.needsSwFramePacing);
|
||||
pDpyEvo->vrr.needsSwFramePacing,
|
||||
pTimings);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1539,8 +1557,8 @@ static NvBool DowngradeColorSpaceAndBpcOneHead(
|
||||
NVDpyEvoRec *pDpyEvo =
|
||||
nvGetOneArbitraryDpyEvo(pProposedApiHead->dpyIdList,
|
||||
pDispEvo);
|
||||
const NVColorFormatInfoRec supportedColorFormats =
|
||||
nvGetColorFormatInfo(pDpyEvo);
|
||||
const NvKmsDpyOutputColorFormatInfo supportedColorFormats =
|
||||
nvDpyGetOutputColorFormatInfo(pDpyEvo);
|
||||
|
||||
if (!nvDowngradeColorSpaceAndBpc(&supportedColorFormats, &dpyColor)) {
|
||||
return FALSE;
|
||||
@@ -1551,6 +1569,11 @@ static NvBool DowngradeColorSpaceAndBpcOneHead(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pProposedApiHead->colorBpcSpecified &&
|
||||
(dpyColor.bpc != pProposedApiHead->attributes.color.bpc)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pProposedApiHead->colorSpaceSpecified &&
|
||||
(dpyColor.format != pProposedApiHead->attributes.color.format)) {
|
||||
return FALSE;
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
#include <ctrl/ctrl2080/ctrl2080unix.h> /* NV2080_CTRL_CMD_OS_UNIX_GC6_BLOCKER_REFCNT */
|
||||
#include <ctrl/ctrl5070/ctrl5070chnc.h> /* NV5070_CTRL_CMD_SET_RMFREE_FLAGS */
|
||||
#include <ctrl/ctrl5070/ctrl5070or.h> /* NV5070_CTRL_CMD_SET_DAC_PWR */
|
||||
#include <ctrl/ctrl0000/ctrl0000system.h> /* NV0000_CTRL_CMD_SYSTEM_GET_APPROVAL_COOKIE */
|
||||
|
||||
#include "nvos.h"
|
||||
|
||||
@@ -1291,6 +1292,28 @@ static NvBool ProbeDisplayCommonCaps(NVDevEvoPtr pDevEvo)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Query the variable refresh rate (G-SYNC) capability of a display.
|
||||
*/
|
||||
static void ProbeVRRCaps(NVDispEvoPtr pDispEvo)
|
||||
{
|
||||
NV0000_CTRL_SYSTEM_GET_VRR_COOKIE_PRESENT_PARAMS params = { 0 };
|
||||
NvU32 ret;
|
||||
|
||||
ret = nvRmApiControl(nvEvoGlobal.clientHandle,
|
||||
nvEvoGlobal.clientHandle,
|
||||
NV0000_CTRL_SYSTEM_GET_VRR_COOKIE_PRESENT,
|
||||
¶ms, sizeof(params));
|
||||
if (ret != NVOS_STATUS_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
pDispEvo->vrr.hasPlatformCookie = params.bIsPresent;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static NvBool ReadDPCDReg(NVConnectorEvoPtr pConnectorEvo,
|
||||
NvU32 dpcdAddr,
|
||||
NvU8 *dpcdData)
|
||||
@@ -1766,6 +1789,7 @@ enum NvKmsAllocDeviceStatus nvRmAllocDisplays(NVDevEvoPtr pDevEvo)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ProbeVRRCaps(pDispEvo);
|
||||
}
|
||||
|
||||
nvAllocVrrEvo(pDevEvo);
|
||||
|
||||
@@ -255,19 +255,86 @@ nvGetAllowedDpyVrrType(const NVDpyEvoRec *pDpyEvo,
|
||||
return NVKMS_DPY_VRR_TYPE_NONE;
|
||||
}
|
||||
|
||||
static NvBool GetEdidTimeoutMicroseconds(
|
||||
const NVDpyEvoRec *pDpyEvo,
|
||||
const NVHwModeTimingsEvo *pTimings,
|
||||
NvU32 *pEdidTimeoutMicroseconds)
|
||||
{
|
||||
const NvU32 rr10kHz = nvGetRefreshRate10kHz(pTimings);
|
||||
const NVParsedEdidEvoRec *pParsedEdid = &pDpyEvo->parsedEdid;
|
||||
const NVT_DISPLAYID_2_0_INFO *pDisplayIdInfo = NULL;
|
||||
const NvU32 nominalRefreshRateHz = rr10kHz / 10000; // XXX round?
|
||||
NVT_PROTOCOL sinkProtocol = NVT_PROTOCOL_UNKNOWN;
|
||||
NvU32 fmin;
|
||||
|
||||
if (!pParsedEdid->valid) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// XXX not sufficient; see what DD does in changelist 34157172
|
||||
if (nvDpyUsesDPLib(pDpyEvo)) {
|
||||
sinkProtocol = NVT_PROTOCOL_DP;
|
||||
} else if (nvDpyIsHdmiEvo(pDpyEvo)) {
|
||||
sinkProtocol = NVT_PROTOCOL_HDMI;
|
||||
}
|
||||
|
||||
fmin = NvTiming_GetVrrFmin(&pParsedEdid->info,
|
||||
pDisplayIdInfo,
|
||||
nominalRefreshRateHz,
|
||||
sinkProtocol);
|
||||
|
||||
if (fmin == 0) {
|
||||
if (pDpyEvo->internal && pDpyEvo->pDispEvo->vrr.hasPlatformCookie) {
|
||||
|
||||
/*
|
||||
* An internal notebook VRR panel must have a non-zero fmin. The
|
||||
* recommendation from hardware is to use a default of fmin =
|
||||
* rr/2.4. So, compute timeoutUsec as:
|
||||
*
|
||||
* timeoutUsec = 10^6 / fmin
|
||||
* = 10^6 / (rr/2.4)
|
||||
* = 10^6 * (2.4/rr)
|
||||
* = 10^5 * 24 / rr
|
||||
*/
|
||||
*pEdidTimeoutMicroseconds = 2400000 / nominalRefreshRateHz;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (pDpyEvo->vrr.type == NVKMS_DPY_VRR_TYPE_GSYNC) {
|
||||
/* GSYNC can have fmin==0; i.e., the panel is self-refreshing. */
|
||||
*pEdidTimeoutMicroseconds = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Otherwise, VRR is not possible. */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pEdidTimeoutMicroseconds = 1000000 / fmin;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*! Adjust mode timings as necessary for VRR. */
|
||||
void nvAdjustHwModeTimingsForVrrEvo(NVHwModeTimingsEvoPtr pTimings,
|
||||
void nvAdjustHwModeTimingsForVrrEvo(const NVDpyEvoRec *pDpyEvo,
|
||||
const enum NvKmsDpyVRRType vrrType,
|
||||
const NvU32 edidTimeoutMicroseconds,
|
||||
const NvU32 vrrOverrideMinRefreshRate,
|
||||
const NvBool needsSwFramePacing)
|
||||
const NvBool needsSwFramePacing,
|
||||
NVHwModeTimingsEvoPtr pTimings)
|
||||
{
|
||||
NvU32 timeoutMicroseconds;
|
||||
NvU32 edidTimeoutMicroseconds;
|
||||
|
||||
if (vrrType == NVKMS_DPY_VRR_TYPE_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetEdidTimeoutMicroseconds(pDpyEvo,
|
||||
pTimings,
|
||||
&edidTimeoutMicroseconds)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Allow overriding the EDID min refresh rate on Adaptive-Sync
|
||||
// displays.
|
||||
if (nvIsAdaptiveSyncDpyVrrType(vrrType) && vrrOverrideMinRefreshRate) {
|
||||
@@ -395,7 +462,7 @@ static void SetTimeoutPerFrame(void *dataPtr, NvU32 dataU32)
|
||||
&(pInputHeadState->vrrFramePacingInfo);
|
||||
const NvU32 headsMask = pInputHeadState->mergeModeVrrSecondaryHeadMask |
|
||||
NVBIT(inputHead);
|
||||
volatile NV0073_CTRL_RM_VRR_SHARED_DATA *pData = pInputVrrFramePacingInfo->pData;
|
||||
volatile NV0073_CTRL_RM_VRR_SHARED_DATA *pData = pInputVrrFramePacingInfo->pData;
|
||||
|
||||
/*
|
||||
* XXX[2Heads1OR] Implement per api-head frame pacing and remove this
|
||||
@@ -1078,7 +1145,7 @@ void nvTrackAndDelayFlipForVrrSwFramePacing(NVDispEvoPtr pDispEvo,
|
||||
const struct NvKmsVrrFramePacingInfo *pVrrFramePacingInfo,
|
||||
NVFlipChannelEvoHwState *pFlip)
|
||||
{
|
||||
volatile NV0073_CTRL_RM_VRR_SHARED_DATA *pData = pVrrFramePacingInfo->pData;
|
||||
volatile NV0073_CTRL_RM_VRR_SHARED_DATA *pData = pVrrFramePacingInfo->pData;
|
||||
NvU32 retryCount = MAX_VRR_FLIP_DELAY_TIME_RETRY_COUNT;
|
||||
NvU64 flipTimeStamp = 0;
|
||||
NvU64 dataTimeStamp1 = 0, dataTimeStamp2 = 0;
|
||||
@@ -1216,8 +1283,7 @@ NvS32 nvIncVrrSemaphoreIndex(NVDevEvoPtr pDevEvo)
|
||||
|
||||
if (pDevEvo->vrr.active && !pDevEvo->hal->caps.supportsDisplayRate) {
|
||||
vrrSemaphoreIndex = pDevEvo->vrr.flipCounter++;
|
||||
if (pDevEvo->vrr.flipCounter >=
|
||||
NVKMS_VRR_SEMAPHORE_SURFACE_SIZE / sizeof(NvU32)) {
|
||||
if (pDevEvo->vrr.flipCounter >= NVKMS_VRR_SEMAPHORE_SURFACE_COUNT) {
|
||||
pDevEvo->vrr.flipCounter = 0;
|
||||
}
|
||||
}
|
||||
@@ -1302,3 +1368,21 @@ void nvTriggerVrrUnstallSetCursorImage(NVDispEvoPtr pDispEvo,
|
||||
}
|
||||
}
|
||||
|
||||
void nvVrrSignalSemaphore(NVDevEvoPtr pDevEvo, NvS32 vrrSemaphoreIndex)
|
||||
{
|
||||
NvU32* pVrrSemaphores = (NvU32*)pDevEvo->vrr.pSemaphores;
|
||||
|
||||
if (!pDevEvo->vrr.pSemaphores) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (vrrSemaphoreIndex < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (vrrSemaphoreIndex >= NVKMS_VRR_SEMAPHORE_SURFACE_COUNT) {
|
||||
return;
|
||||
}
|
||||
|
||||
pVrrSemaphores[vrrSemaphoreIndex] = 1;
|
||||
}
|
||||
|
||||
@@ -2694,7 +2694,7 @@ static NvBool RegisterSurface(struct NvKmsPerOpen *pOpen,
|
||||
|
||||
nvEvoRegisterSurface(pOpenDev->pDevEvo, pOpenDev, pParams,
|
||||
NvHsMapPermissionsReadOnly);
|
||||
return TRUE;
|
||||
return pParams->reply.surfaceHandle != 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -4899,6 +4899,24 @@ static NvBool AccelVblankSemControls(
|
||||
hwHeadMask);
|
||||
}
|
||||
|
||||
static NvBool VrrSignalSemaphore(
|
||||
struct NvKmsPerOpen *pOpen,
|
||||
void *pParamsVoid)
|
||||
{
|
||||
struct NvKmsPerOpenDev *pOpenDev;
|
||||
|
||||
const struct NvKmsVrrSignalSemaphoreParams *pParams = pParamsVoid;
|
||||
NvS32 vrrSemaphoreIndex = pParams->request.vrrSemaphoreIndex;
|
||||
|
||||
pOpenDev = GetPerOpenDev(pOpen, pParams->request.deviceHandle);
|
||||
if (pOpenDev == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
nvVrrSignalSemaphore(pOpenDev->pDevEvo, vrrSemaphoreIndex);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Perform the ioctl operation requested by the client.
|
||||
*
|
||||
@@ -5024,6 +5042,7 @@ NvBool nvKmsIoctl(
|
||||
ENTRY(NVKMS_IOCTL_ENABLE_VBLANK_SEM_CONTROL, EnableVblankSemControl),
|
||||
ENTRY(NVKMS_IOCTL_DISABLE_VBLANK_SEM_CONTROL, DisableVblankSemControl),
|
||||
ENTRY(NVKMS_IOCTL_ACCEL_VBLANK_SEM_CONTROLS, AccelVblankSemControls),
|
||||
ENTRY(NVKMS_IOCTL_VRR_SIGNAL_SEMAPHORE, VrrSignalSemaphore),
|
||||
};
|
||||
|
||||
struct NvKmsPerOpen *pOpen = pOpenVoid;
|
||||
|
||||
328
src/nvidia-modeset/src/shaders/g_blackwell_shader_info.h
Normal file
328
src/nvidia-modeset/src/shaders/g_blackwell_shader_info.h
Normal file
@@ -0,0 +1,328 @@
|
||||
// Generated using 'Offline GLSL Shader Compiler Version 13.0.0.0.545.00.dev/gpu_drv/dev_a-16109'
|
||||
// WARNING: This file is auto-generated! Do not hand-edit!
|
||||
// Instead, edit the GLSL shaders and run 'unix-build nvmake @generate'.
|
||||
|
||||
#include "nvidia-3d-shaders.h"
|
||||
#include "g_shader_names.h"
|
||||
|
||||
ct_assert(NUM_PROGRAMS == 34);
|
||||
static const Nv3dProgramInfo BlackwellProgramInfo[NUM_PROGRAMS] = {
|
||||
// nvidia_headsurface_vertex
|
||||
{ .offset = 0x00000000,
|
||||
.registerCount = 15,
|
||||
.type = NV3D_SHADER_TYPE_VERTEX,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_VERTEX_B,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_VERTEX,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment
|
||||
{ .offset = 0x00000300,
|
||||
.registerCount = 13,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_customSampling
|
||||
{ .offset = 0x00000580,
|
||||
.registerCount = 40,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_overlay
|
||||
{ .offset = 0x00004680,
|
||||
.registerCount = 31,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_overlay_customSampling
|
||||
{ .offset = 0x00005480,
|
||||
.registerCount = 32,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_offset
|
||||
{ .offset = 0x00008280,
|
||||
.registerCount = 15,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_offset_customSampling
|
||||
{ .offset = 0x00008600,
|
||||
.registerCount = 40,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_offset_swapped
|
||||
{ .offset = 0x0000c800,
|
||||
.registerCount = 16,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_offset_swapped_customSampling
|
||||
{ .offset = 0x0000cb80,
|
||||
.registerCount = 40,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_offset_overlay
|
||||
{ .offset = 0x00010d80,
|
||||
.registerCount = 32,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_offset_overlay_customSampling
|
||||
{ .offset = 0x00011c00,
|
||||
.registerCount = 32,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_offset_overlay_swapped
|
||||
{ .offset = 0x00014b00,
|
||||
.registerCount = 31,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_offset_overlay_swapped_customSampling
|
||||
{ .offset = 0x00015980,
|
||||
.registerCount = 32,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_blend
|
||||
{ .offset = 0x00018880,
|
||||
.registerCount = 15,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_blend_customSampling
|
||||
{ .offset = 0x00018b80,
|
||||
.registerCount = 40,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_blend_swapped
|
||||
{ .offset = 0x0001cd00,
|
||||
.registerCount = 17,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_blend_swapped_customSampling
|
||||
{ .offset = 0x0001d080,
|
||||
.registerCount = 40,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_blend_overlay
|
||||
{ .offset = 0x00021280,
|
||||
.registerCount = 32,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_blend_overlay_customSampling
|
||||
{ .offset = 0x00022100,
|
||||
.registerCount = 32,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_blend_overlay_swapped
|
||||
{ .offset = 0x00024f80,
|
||||
.registerCount = 31,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_blend_overlay_swapped_customSampling
|
||||
{ .offset = 0x00025e00,
|
||||
.registerCount = 32,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_blend_offset
|
||||
{ .offset = 0x00028d00,
|
||||
.registerCount = 20,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_blend_offset_customSampling
|
||||
{ .offset = 0x00029100,
|
||||
.registerCount = 40,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_blend_offset_swapped
|
||||
{ .offset = 0x0002d380,
|
||||
.registerCount = 20,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_blend_offset_swapped_customSampling
|
||||
{ .offset = 0x0002d780,
|
||||
.registerCount = 40,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_blend_offset_overlay
|
||||
{ .offset = 0x00031a00,
|
||||
.registerCount = 35,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_blend_offset_overlay_customSampling
|
||||
{ .offset = 0x00032880,
|
||||
.registerCount = 37,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_blend_offset_overlay_swapped
|
||||
{ .offset = 0x00035780,
|
||||
.registerCount = 36,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_blend_offset_overlay_swapped_customSampling
|
||||
{ .offset = 0x00036680,
|
||||
.registerCount = 37,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_yuv420
|
||||
{ .offset = 0x00039600,
|
||||
.registerCount = 56,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_yuv420_overlay
|
||||
{ .offset = 0x0003b180,
|
||||
.registerCount = 38,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_pixelShift
|
||||
{ .offset = 0x0003dc80,
|
||||
.registerCount = 32,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_overlay_pixelShift
|
||||
{ .offset = 0x0003e880,
|
||||
.registerCount = 31,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
// nvidia_headsurface_fragment_reversePrime
|
||||
{ .offset = 0x0003f780,
|
||||
.registerCount = 13,
|
||||
.type = NV3D_SHADER_TYPE_PIXEL,
|
||||
.constIndex = -1,
|
||||
.stage = NV3D_HW_SHADER_STAGE_PIXEL,
|
||||
.bindGroup = NV3D_HW_BIND_GROUP_FRAGMENT,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
|
||||
static const Nv3dShaderConstBufInfo BlackwellConstBufInfo[] = {
|
||||
};
|
||||
|
||||
static const size_t BlackwellConstBufSize = 0;
|
||||
static const NvU32 BlackwellConstBufSizeAlign = 256;
|
||||
|
||||
// Total shader code size: 254.5 KB
|
||||
static const size_t BlackwellProgramHeapSize = 260608;
|
||||
static const size_t BlackwellShaderMaxLocalBytes = 0;
|
||||
static const size_t BlackwellShaderMaxStackBytes = 0;
|
||||
BIN
src/nvidia-modeset/src/shaders/g_blackwell_shaders
Normal file
BIN
src/nvidia-modeset/src/shaders/g_blackwell_shaders
Normal file
Binary file not shown.
Reference in New Issue
Block a user