Skip to content

Commit

Permalink
CD3D11VP::SetSuperRes: allows enabling NVIDIA/Intel superres
Browse files Browse the repository at this point in the history
  • Loading branch information
emoose committed Feb 28, 2023
1 parent e02eecc commit a684e0a
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 0 deletions.
95 changes: 95 additions & 0 deletions Source/D3D11VP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,101 @@ void CD3D11VP::GetVPParams(D3D11_VIDEO_PROCESSOR_CAPS& caps, UINT& rateConvIndex
rateConvCaps = m_RateConvCaps;
}

HRESULT CD3D11VP::SetSuperRes(const int iType)
{
// This func calls into both Intel & NV functions, so that we can tell Intel to disable itself if only NV was picked, or vice-versa

// Intel VP SuperRes
HRESULT hr;
{
constexpr GUID GUID_INTEL_VPE_INTERFACE = {
0xedd1d4b9,
0x8659,
0x4cbc,
{0xa4, 0xd6, 0x98, 0x31, 0xa2, 0x16, 0x3a, 0xc3} };

enum : UINT {
kIntelVpeFnVersion = 0x01,
kIntelVpeFnMode = 0x20,
kIntelVpeFnScaling = 0x37,
};

enum : UINT {
kIntelVpeVersion3 = 0x0003,
};

enum : UINT {
kIntelVpeModeNone = 0x0,
kIntelVpeModePreproc = 0x01,
};

enum : UINT {
kIntelVpeScalingDefault = 0x0,
kIntelVpeScalingSuperResolution = 0x2,
};

struct IntelVpeExt {
UINT function;
void* param;
};

IntelVpeExt ext = {};
UINT param = 0;
ext.param = &param;

ext.function = kIntelVpeFnVersion;
param = kIntelVpeVersion3;
hr = m_pVideoContext->VideoProcessorSetOutputExtension(
m_pVideoProcessor, &GUID_INTEL_VPE_INTERFACE, sizeof(ext), &ext);
if (!SUCCEEDED(hr)) {
return hr;
}

ext.function = kIntelVpeFnMode;
param = (iType == SUPERRES_Intel) ? kIntelVpeModePreproc : kIntelVpeModeNone;
hr = m_pVideoContext->VideoProcessorSetOutputExtension(
m_pVideoProcessor, &GUID_INTEL_VPE_INTERFACE, sizeof(ext), &ext);
if (!SUCCEEDED(hr)) {
return hr;
}

ext.function = kIntelVpeFnScaling;
param = (iType == SUPERRES_Intel) ? kIntelVpeScalingSuperResolution : kIntelVpeScalingDefault;

hr = m_pVideoContext->VideoProcessorSetStreamExtension(
m_pVideoProcessor, 0, &GUID_INTEL_VPE_INTERFACE, sizeof(ext), &ext);
if (!SUCCEEDED(hr)) {
return hr;
}
}

// NVIDIA RTX Super Resolution
{
constexpr GUID kNvidiaPPEInterfaceGUID = {
0xd43ce1b3,
0x1f4b,
0x48ac,
{0xba, 0xee, 0xc3, 0xc2, 0x53, 0x75, 0xe6, 0xf7} };
constexpr UINT kStreamExtensionVersionV1 = 0x1;
constexpr UINT kStreamExtensionMethodSuperResolution = 0x2;

struct {
UINT version;
UINT method;
UINT enable;
} stream_extension_info = { kStreamExtensionVersionV1,
kStreamExtensionMethodSuperResolution, iType == SUPERRES_Nvidia ? 1 : 0 };

hr = m_pVideoContext->VideoProcessorSetStreamExtension(m_pVideoProcessor, 0, &kNvidiaPPEInterfaceGUID,
sizeof(stream_extension_info), &stream_extension_info);
if (!SUCCEEDED(hr)) {
return hr;
}
}

return hr;
}

HRESULT CD3D11VP::SetRectangles(const RECT* pSrcRect, const RECT* pDstRect)
{
CheckPointer(m_pVideoContext, E_ABORT);
Expand Down
8 changes: 8 additions & 0 deletions Source/D3D11VP.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@

#include <d3d11.h>

// TODO: move this somewhere better?
enum :int {
SUPERRES_None = 0,
SUPERRES_Intel = 1,
SUPERRES_Nvidia = 2
};

class VideoTextureBuffer
{
private:
Expand Down Expand Up @@ -163,6 +170,7 @@ class CD3D11VP
ID3D11Texture2D* GetNextInputTexture(const D3D11_VIDEO_FRAME_FORMAT vframeFormat);
void ResetFrameOrder();

HRESULT SetSuperRes(const int iType);
HRESULT SetRectangles(const RECT * pSrcRect, const RECT* pDstRect);
HRESULT SetColorSpace(const DXVA2_ExtendedFormat exFmt, const bool bHdrPassthrough);
void SetRotation(D3D11_VIDEO_PROCESSOR_ROTATION rotation);
Expand Down
7 changes: 7 additions & 0 deletions Source/DX11VideoProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1585,6 +1585,13 @@ HRESULT CDX11VideoProcessor::InitializeD3D11VP(const FmtConvParams_t& params, co
return hr;
}

// TODO: SetSuperRes can enable Intel superres too, but this only calls with SUPERRES_Nvidia atm
hr = m_D3D11VP.SetSuperRes(SUPERRES_Nvidia);
if (FAILED(hr)) {
DLog(L"CDX11VideoProcessor::InitializeD3D11VP() : SetSuperRes() failed with error {}", HR2Str(hr));
return hr;
}

hr = m_D3D11VP.SetColorSpace(m_srcExFmt, m_bHdrDisplayModeEnabled && SourceIsHDR());

hr = m_TexSrcVideo.Create(m_pDevice, dxgiFormat, width, height, Tex2D_DynamicShaderWriteNoSRV);
Expand Down

3 comments on commit a684e0a

@v0lt
Copy link

@v0lt v0lt commented on a684e0a Mar 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job.
https://disk.yandex.ru/d/WoH6AFKzmEejEA
My quick implementation of the option.
Only for Nvidia. To apply the option, you must restart playback.

@emoose
Copy link
Owner Author

@emoose emoose commented on a684e0a Mar 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@v0lt

To apply the option, you must restart playback.

I found in d56bcfa that after enabling SuperRes during init I could then disable/enable it any time after and it seems to apply change fine.
There I have it checking in UpdateRenderRect and disabling if too small, or enabling again when it's upscaling, seemed to save a few watts being wasted since VSR doesn't do anything for downscaling.

If I remove the super-res enable during InitializeD3D11VP then the enable/disable calls during resize didn't have any effect though, I guess after some point in D3D11 init SuperRes maybe checks if it was turned on before, if it wasn't then it prevents working (maybe unloads itself or something).

You might want to add check for P010/P016 and prevent it for that too, there's a bad memory leak in VSR for those right now: #1
It looks like only CF_NV12 is working with it properly really, at least for the NV scaler anyway, not sure what Intel works with.

@v0lt
Copy link

@v0lt v0lt commented on a684e0a Mar 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.