mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-07-20 14:22:00 +00:00
[idd] disable HDR and post-processing when in software mode
This commit is contained in:
@@ -60,10 +60,13 @@ static void CALLBACK _D3D12DebugCallback(
|
||||
description);
|
||||
}
|
||||
|
||||
CD3D12Device::InitResult CD3D12Device::Init(CIVSHMEM &ivshmem, UINT64 &alignSize)
|
||||
CD3D12Device::InitResult CD3D12Device::Init(CIVSHMEM &ivshmem,
|
||||
UINT64 &alignSize, bool enableCompute)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
m_computeEnabled = enableCompute;
|
||||
|
||||
hr = CreateDXGIFactory2(m_debug ? DXGI_CREATE_FACTORY_DEBUG : 0, IID_PPV_ARGS(&m_factory));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
@@ -132,8 +135,9 @@ CD3D12Device::InitResult CD3D12Device::Init(CIVSHMEM &ivshmem, UINT64 &alignSize
|
||||
m_indirectCopy ? CD3D12CommandQueue::NORMAL : CD3D12CommandQueue::FAST))
|
||||
return InitResult::FAILURE;
|
||||
|
||||
if (!m_computeQueue.Init(m_device.Get(), D3D12_COMMAND_LIST_TYPE_COMPUTE, L"Compute",
|
||||
CD3D12CommandQueue::FAST))
|
||||
if (m_computeEnabled &&
|
||||
!m_computeQueue.Init(m_device.Get(), D3D12_COMMAND_LIST_TYPE_COMPUTE,
|
||||
L"Compute", CD3D12CommandQueue::FAST))
|
||||
return InitResult::FAILURE;
|
||||
|
||||
DEBUG_INFO("Created CD3D12Device");
|
||||
@@ -160,7 +164,8 @@ void CD3D12Device::WaitForIdle()
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(m_copyQueue); ++i)
|
||||
drain(m_copyQueue[i]);
|
||||
drain(m_computeQueue);
|
||||
if (m_computeEnabled)
|
||||
drain(m_computeQueue);
|
||||
}
|
||||
|
||||
bool CD3D12Device::HeapTest()
|
||||
@@ -233,6 +238,12 @@ CD3D12CommandQueue * CD3D12Device::GetCopyQueue()
|
||||
|
||||
CD3D12CommandQueue * CD3D12Device::GetComputeQueue()
|
||||
{
|
||||
if (!m_computeEnabled)
|
||||
{
|
||||
DEBUG_ERROR("Compute queue requested while compute processing is disabled");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (int c = 0; c < 100; ++c)
|
||||
{
|
||||
if (m_computeQueue.IsReady())
|
||||
|
||||
@@ -52,6 +52,7 @@ struct CD3D12Device
|
||||
CD3D12CommandQueue m_copyQueue[4];
|
||||
unsigned m_copyQueueIndex = 0;
|
||||
CD3D12CommandQueue m_computeQueue;
|
||||
bool m_computeEnabled = false;
|
||||
|
||||
bool HeapTest();
|
||||
|
||||
@@ -66,7 +67,8 @@ struct CD3D12Device
|
||||
SUCCESS
|
||||
};
|
||||
|
||||
InitResult Init(CIVSHMEM &ivshmem, UINT64 &alignSize);
|
||||
InitResult Init(CIVSHMEM &ivshmem, UINT64 &alignSize,
|
||||
bool enableCompute);
|
||||
void DeInit();
|
||||
|
||||
// Wait for all command queues to finish in-flight GPU work and run their
|
||||
|
||||
@@ -45,6 +45,7 @@ static const BYTE EDID_MANUFACTURE_YEAR_2026 = 36; // 1990 + 36 = 2026
|
||||
static const BYTE EDID_VERSION = 1;
|
||||
static const BYTE EDID_REVISION = 4;
|
||||
|
||||
static const BYTE EDID_VIDEO_INPUT_DIGITAL_8BPC_HDMI_A = 0xa2;
|
||||
static const BYTE EDID_VIDEO_INPUT_DIGITAL_10BPC_HDMI_A = 0xb2;
|
||||
static const BYTE EDID_HORIZONTAL_SIZE_CM = 52;
|
||||
static const BYTE EDID_VERTICAL_SIZE_CM = 29;
|
||||
@@ -316,17 +317,16 @@ static WORD EdidChromaticity(double value)
|
||||
return (WORD)min(1023.0, max(0.0, value * 1024.0 + 0.5));
|
||||
}
|
||||
|
||||
static void SetChromaticityCoordinates(BYTE coordinates[10])
|
||||
static void SetChromaticityCoordinates(BYTE coordinates[10], bool hdr)
|
||||
{
|
||||
// The virtual display transports HDR in the BT.2020 container. Describe
|
||||
// that full container gamut and its D65 white point rather than leaving an
|
||||
// invalid all-zero base-block colour volume.
|
||||
const WORD rx = EdidChromaticity(0.7080);
|
||||
const WORD ry = EdidChromaticity(0.2920);
|
||||
const WORD gx = EdidChromaticity(0.1700);
|
||||
const WORD gy = EdidChromaticity(0.7970);
|
||||
const WORD bx = EdidChromaticity(0.1310);
|
||||
const WORD by = EdidChromaticity(0.0460);
|
||||
// Describe the wire gamut. Accelerated HDR uses the BT.2020 container;
|
||||
// software rendering is SDR-only and uses the standard sRGB/BT.709 gamut.
|
||||
const WORD rx = EdidChromaticity(hdr ? 0.7080 : 0.6400);
|
||||
const WORD ry = EdidChromaticity(hdr ? 0.2920 : 0.3300);
|
||||
const WORD gx = EdidChromaticity(hdr ? 0.1700 : 0.3000);
|
||||
const WORD gy = EdidChromaticity(hdr ? 0.7970 : 0.6000);
|
||||
const WORD bx = EdidChromaticity(hdr ? 0.1310 : 0.1500);
|
||||
const WORD by = EdidChromaticity(hdr ? 0.0460 : 0.0600);
|
||||
const WORD wx = EdidChromaticity(0.3127);
|
||||
const WORD wy = EdidChromaticity(0.3290);
|
||||
|
||||
@@ -344,7 +344,7 @@ static void SetChromaticityCoordinates(BYTE coordinates[10])
|
||||
coordinates[9] = (BYTE)(wy >> 2);
|
||||
}
|
||||
|
||||
static void InitEdidBaseBlock(EdidBaseBlock& base)
|
||||
static void InitEdidBaseBlock(EdidBaseBlock& base, bool hdr)
|
||||
{
|
||||
memcpy(base.header, EDID_HEADER, sizeof(base.header));
|
||||
|
||||
@@ -358,12 +358,14 @@ static void InitEdidBaseBlock(EdidBaseBlock& base)
|
||||
base.version = EDID_VERSION;
|
||||
base.revision = EDID_REVISION;
|
||||
|
||||
base.videoInputDefinition = EDID_VIDEO_INPUT_DIGITAL_10BPC_HDMI_A;
|
||||
base.videoInputDefinition = hdr ?
|
||||
EDID_VIDEO_INPUT_DIGITAL_10BPC_HDMI_A :
|
||||
EDID_VIDEO_INPUT_DIGITAL_8BPC_HDMI_A;
|
||||
base.horizontalSizeCm = EDID_HORIZONTAL_SIZE_CM;
|
||||
base.verticalSizeCm = EDID_VERTICAL_SIZE_CM;
|
||||
base.displayGamma = EDID_DISPLAY_GAMMA_2_2;
|
||||
base.supportedFeatures = EDID_FEATURES_PREFERRED_TIMING_RGB;
|
||||
SetChromaticityCoordinates(base.chromaticityCoordinates);
|
||||
SetChromaticityCoordinates(base.chromaticityCoordinates, hdr);
|
||||
|
||||
for (UINT i = 0; i < EDID_STANDARD_TIMING_COUNT; ++i)
|
||||
base.standardTimings[i] = MakeUnusedStandardTiming();
|
||||
@@ -572,12 +574,12 @@ bool CEdid::WriteDetailedTiming(BYTE* dtd, const CSettings::DisplayMode& mode)
|
||||
return true;
|
||||
}
|
||||
|
||||
void CEdid::Build(const CSettings::DisplayModes& modes)
|
||||
void CEdid::Build(const CSettings::DisplayModes& modes, bool hdr)
|
||||
{
|
||||
m_data.assign(static_cast<std::vector<BYTE, std::allocator<BYTE>>::size_type>(EDID_BLOCK_SIZE) * 2, 0);
|
||||
|
||||
EdidBaseBlock baseBlock = {};
|
||||
InitEdidBaseBlock(baseBlock);
|
||||
InitEdidBaseBlock(baseBlock, hdr);
|
||||
|
||||
CSettings::DisplayModes sorted = modes;
|
||||
std::stable_sort(sorted.begin(), sorted.end(),
|
||||
@@ -625,10 +627,13 @@ void CEdid::Build(const CSettings::DisplayModes& modes)
|
||||
ctaBlock.revision = CTA_REVISION;
|
||||
|
||||
UINT dataOffset = CTA_HEADER_SIZE;
|
||||
AppendCtaDataBlock(cta, dataOffset, MakeCtaHdrStaticMetadataDataBlock ());
|
||||
AppendCtaDataBlock(cta, dataOffset, MakeCtaColorimetryDataBlock ());
|
||||
AppendCtaDataBlock(cta, dataOffset, MakeCtaHdmiForumVendorSpecificDataBlock());
|
||||
AppendCtaDataBlock(cta, dataOffset, MakeCtaHdmiVendorSpecificDataBlock ());
|
||||
if (hdr)
|
||||
{
|
||||
AppendCtaDataBlock(cta, dataOffset, MakeCtaHdrStaticMetadataDataBlock ());
|
||||
AppendCtaDataBlock(cta, dataOffset, MakeCtaColorimetryDataBlock ());
|
||||
AppendCtaDataBlock(cta, dataOffset, MakeCtaHdmiForumVendorSpecificDataBlock());
|
||||
AppendCtaDataBlock(cta, dataOffset, MakeCtaHdmiVendorSpecificDataBlock ());
|
||||
}
|
||||
|
||||
ctaBlock.dtdOffset = (BYTE)dataOffset;
|
||||
ctaBlock.flags = 0x00;
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
class CEdid
|
||||
{
|
||||
public:
|
||||
void Build(const CSettings::DisplayModes& modes);
|
||||
void Build(const CSettings::DisplayModes& modes, bool hdr);
|
||||
|
||||
const BYTE* Data() const { return m_data.empty() ? nullptr : m_data.data(); }
|
||||
UINT Size() const { return (UINT)m_data.size(); }
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "CDebug.h"
|
||||
#include "VersionInfo.h"
|
||||
|
||||
#include <dxgi1_2.h>
|
||||
#include <sstream>
|
||||
|
||||
static const struct LGMPQueueConfig FRAME_QUEUE_CONFIG =
|
||||
@@ -67,6 +68,7 @@ void CIndirectDeviceContext::QueryIddCxCapabilities()
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
m_iddCxVersion = 0;
|
||||
m_hasIddCx110DDIs = false;
|
||||
m_canProcessFP16 = false;
|
||||
DEBUG_ERROR_HR(status, "IddCxGetVersion Failed");
|
||||
return;
|
||||
@@ -89,10 +91,15 @@ void CIndirectDeviceContext::QueryIddCxCapabilities()
|
||||
const bool hasIddCx110DDIs = false;
|
||||
#endif
|
||||
|
||||
m_canProcessFP16 = m_iddCxVersion >= IDDCX_VERSION_1_10 && hasIddCx110DDIs;
|
||||
m_hasIddCx110DDIs =
|
||||
m_iddCxVersion >= IDDCX_VERSION_1_10 && hasIddCx110DDIs;
|
||||
m_canProcessFP16 = !m_softwareMode && m_hasIddCx110DDIs;
|
||||
|
||||
DEBUG_INFO("IddCx version: 0x%04x", m_iddCxVersion);
|
||||
DEBUG_INFO("IddCx 1.10 HDR/WCG DDIs: %s", m_canProcessFP16 ? "available" : "unavailable");
|
||||
DEBUG_INFO("IddCx 1.10 HDR/WCG DDIs: %s",
|
||||
m_hasIddCx110DDIs ? "available" : "unavailable");
|
||||
if (m_softwareMode && m_hasIddCx110DDIs)
|
||||
DEBUG_INFO("HDR/WCG disabled for software rendering");
|
||||
}
|
||||
|
||||
void CIndirectDeviceContext::PopulateDefaultModes()
|
||||
@@ -117,7 +124,7 @@ void CIndirectDeviceContext::InitializeEdid()
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_modeLock);
|
||||
if (!m_edid.Size())
|
||||
m_edid.Build(m_displayModes);
|
||||
m_edid.Build(m_displayModes, CanProcessFP16());
|
||||
ReleaseSRWLockExclusive(&m_modeLock);
|
||||
}
|
||||
|
||||
@@ -194,6 +201,68 @@ void CIndirectDeviceContext::InitAdapter()
|
||||
m_ivshmemOpened = true;
|
||||
}
|
||||
|
||||
// Select the render adapter before advertising capabilities. If no hardware
|
||||
// adapter is available, this is a software-rendered display and must remain
|
||||
// SDR-only; the software path must never depend on compute processing.
|
||||
bool havePreferredRenderAdapter = false;
|
||||
LUID preferredRenderAdapter = {};
|
||||
IDXGIFactory1 * factory = NULL;
|
||||
HRESULT factoryStatus = CreateDXGIFactory(
|
||||
__uuidof(IDXGIFactory1), (void **)&factory);
|
||||
if (FAILED(factoryStatus))
|
||||
DEBUG_ERROR_HR(factoryStatus, "CreateDXGIFactory Failed");
|
||||
else
|
||||
{
|
||||
for (UINT i = 0;; ++i)
|
||||
{
|
||||
IDXGIAdapter1 * dxgiAdapter = nullptr;
|
||||
HRESULT enumStatus = factory->EnumAdapters1(i, &dxgiAdapter);
|
||||
if (enumStatus == DXGI_ERROR_NOT_FOUND)
|
||||
break;
|
||||
if (FAILED(enumStatus))
|
||||
{
|
||||
DEBUG_ERROR_HR(enumStatus, "Failed to enumerate DXGI adapter %u", i);
|
||||
break;
|
||||
}
|
||||
|
||||
DXGI_ADAPTER_DESC1 adapterDesc = {};
|
||||
HRESULT descStatus = dxgiAdapter->GetDesc1(&adapterDesc);
|
||||
dxgiAdapter->Release();
|
||||
if (FAILED(descStatus))
|
||||
{
|
||||
DEBUG_ERROR_HR(descStatus, "Failed to query DXGI adapter %u", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((adapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) ||
|
||||
(adapterDesc.VendorId == 0x1414 && adapterDesc.DeviceId == 0x008c))
|
||||
{
|
||||
DEBUG_INFO("Ignoring software render adapter %ls", adapterDesc.Description);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((adapterDesc.VendorId == 0x1b36 && adapterDesc.DeviceId == 0x000d) || // QXL
|
||||
(adapterDesc.VendorId == 0x1234 && adapterDesc.DeviceId == 0x1111)) // QEMU Standard VGA
|
||||
{
|
||||
DEBUG_INFO("Ignoring display-only adapter %ls (vendor 0x%04x, device 0x%04x)",
|
||||
adapterDesc.Description, adapterDesc.VendorId, adapterDesc.DeviceId);
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG_INFO("Selected render adapter %ls (vendor 0x%04x, device 0x%04x)",
|
||||
adapterDesc.Description, adapterDesc.VendorId, adapterDesc.DeviceId);
|
||||
preferredRenderAdapter = adapterDesc.AdapterLuid;
|
||||
havePreferredRenderAdapter = true;
|
||||
break;
|
||||
}
|
||||
|
||||
factory->Release();
|
||||
}
|
||||
|
||||
m_softwareMode = !havePreferredRenderAdapter;
|
||||
if (m_softwareMode)
|
||||
DEBUG_INFO("No hardware render adapter available; using SDR software mode");
|
||||
|
||||
QueryIddCxCapabilities();
|
||||
DEBUG_TRACE("Loading configured display modes");
|
||||
PopulateDefaultModes();
|
||||
@@ -218,7 +287,7 @@ void CIndirectDeviceContext::InitAdapter()
|
||||
*/
|
||||
caps.Flags = IDDCX_ADAPTER_FLAGS_USE_SMALLEST_MODE;
|
||||
#ifdef HAS_IDDCX_110
|
||||
if (CanUseIddCx110DDIs())
|
||||
if (CanProcessFP16())
|
||||
caps.Flags |= IDDCX_ADAPTER_FLAGS_CAN_PROCESS_FP16;
|
||||
#endif
|
||||
|
||||
@@ -250,12 +319,17 @@ void CIndirectDeviceContext::InitAdapter()
|
||||
DEBUG_INFO("Calling IddCxAdapterInitAsync with flags 0x%08x",
|
||||
caps.Flags);
|
||||
NTSTATUS status = IddCxAdapterInitAsync(&init, &initOut);
|
||||
if (!NT_SUCCESS(status) && CanUseIddCx110DDIs())
|
||||
if (!NT_SUCCESS(status) && CanProcessFP16())
|
||||
{
|
||||
DEBUG_WARN(
|
||||
"IddCxAdapterInitAsync rejected FP16 adapter capabilities (0x%08x), retrying without HDR/WCG",
|
||||
status);
|
||||
m_canProcessFP16 = false;
|
||||
// The monitor has not been created yet, so replace the provisional HDR
|
||||
// EDID before Windows can observe it.
|
||||
AcquireSRWLockExclusive(&m_modeLock);
|
||||
m_edid.Build(m_displayModes, false);
|
||||
ReleaseSRWLockExclusive(&m_modeLock);
|
||||
caps.Flags = (IDDCX_ADAPTER_FLAGS)(caps.Flags & ~IDDCX_ADAPTER_FLAGS_CAN_PROCESS_FP16);
|
||||
ZeroMemory(&initOut, sizeof(initOut));
|
||||
status = IddCxAdapterInitAsync(&init, &initOut);
|
||||
@@ -281,63 +355,12 @@ void CIndirectDeviceContext::InitAdapter()
|
||||
|
||||
// Try to co-exist with the virtual video device by telling IddCx which
|
||||
// hardware adapter we prefer to render on.
|
||||
IDXGIFactory * factory = NULL;
|
||||
HRESULT factoryStatus = CreateDXGIFactory(
|
||||
__uuidof(IDXGIFactory), (void **)&factory);
|
||||
if (FAILED(factoryStatus))
|
||||
DEBUG_ERROR_HR(factoryStatus, "CreateDXGIFactory Failed");
|
||||
else
|
||||
if (havePreferredRenderAdapter)
|
||||
{
|
||||
bool renderAdapterSelected = false;
|
||||
for (UINT i = 0;; ++i)
|
||||
{
|
||||
IDXGIAdapter * dxgiAdapter = nullptr;
|
||||
HRESULT enumStatus = factory->EnumAdapters(i, &dxgiAdapter);
|
||||
if (enumStatus == DXGI_ERROR_NOT_FOUND)
|
||||
break;
|
||||
if (FAILED(enumStatus))
|
||||
{
|
||||
DEBUG_ERROR_HR(enumStatus, "Failed to enumerate DXGI adapter %u", i);
|
||||
break;
|
||||
}
|
||||
|
||||
DXGI_ADAPTER_DESC adapterDesc = {};
|
||||
HRESULT descStatus = dxgiAdapter->GetDesc(&adapterDesc);
|
||||
dxgiAdapter->Release();
|
||||
if (FAILED(descStatus))
|
||||
{
|
||||
DEBUG_ERROR_HR(descStatus, "Failed to query DXGI adapter %u", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (adapterDesc.VendorId == 0x1414 && adapterDesc.DeviceId == 0x008c)
|
||||
{
|
||||
DEBUG_INFO("Ignoring software render adapter %ls", adapterDesc.Description);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((adapterDesc.VendorId == 0x1b36 && adapterDesc.DeviceId == 0x000d) || // QXL
|
||||
(adapterDesc.VendorId == 0x1234 && adapterDesc.DeviceId == 0x1111)) // QEMU Standard VGA
|
||||
{
|
||||
DEBUG_INFO("Ignoring display-only adapter %ls (vendor 0x%04x, device 0x%04x)",
|
||||
adapterDesc.Description, adapterDesc.VendorId, adapterDesc.DeviceId);
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG_INFO("Selecting render adapter %ls (vendor 0x%04x, device 0x%04x)",
|
||||
adapterDesc.Description, adapterDesc.VendorId, adapterDesc.DeviceId);
|
||||
IDARG_IN_ADAPTERSETRENDERADAPTER args = {};
|
||||
args.PreferredRenderAdapter = adapterDesc.AdapterLuid;
|
||||
IddCxAdapterSetRenderAdapter(m_adapter, &args);
|
||||
DEBUG_INFO("Preferred render adapter set");
|
||||
renderAdapterSelected = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!renderAdapterSelected)
|
||||
DEBUG_INFO("No preferred hardware render adapter was selected");
|
||||
|
||||
factory->Release();
|
||||
IDARG_IN_ADAPTERSETRENDERADAPTER args = {};
|
||||
args.PreferredRenderAdapter = preferredRenderAdapter;
|
||||
IddCxAdapterSetRenderAdapter(m_adapter, &args);
|
||||
DEBUG_INFO("Preferred render adapter set");
|
||||
}
|
||||
|
||||
auto * wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(m_adapter);
|
||||
@@ -684,7 +707,7 @@ NTSTATUS CIndirectDeviceContext::ParseMonitorDescription2(
|
||||
mode->Size = sizeof(IDDCX_MONITOR_MODE2);
|
||||
mode->Origin = IDDCX_MONITOR_MODE_ORIGIN_MONITORDESCRIPTOR;
|
||||
FillSignalInfo(mode->MonitorVideoSignalInfo, it->width, it->height, it->refresh, true);
|
||||
mode->BitsPerComponent = GetWireBitsPerComponent(CanUseIddCx110DDIs());
|
||||
mode->BitsPerComponent = GetWireBitsPerComponent(CanProcessFP16());
|
||||
|
||||
if (it->preferred)
|
||||
outArgs->PreferredMonitorModeIdx =
|
||||
@@ -716,7 +739,7 @@ NTSTATUS CIndirectDeviceContext::MonitorQueryTargetModes2(
|
||||
ZeroMemory(mode, sizeof(*mode));
|
||||
mode->Size = sizeof(IDDCX_TARGET_MODE2);
|
||||
FillSignalInfo(mode->TargetVideoSignalInfo.targetVideoSignalInfo, it->width, it->height, it->refresh, false);
|
||||
mode->BitsPerComponent = GetWireBitsPerComponent(CanUseIddCx110DDIs());
|
||||
mode->BitsPerComponent = GetWireBitsPerComponent(CanProcessFP16());
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
@@ -115,7 +115,9 @@ private:
|
||||
DXGI_FORMAT m_format = DXGI_FORMAT_UNKNOWN;
|
||||
FrameType m_frameType = FRAME_TYPE_INVALID;
|
||||
UINT m_iddCxVersion = 0;
|
||||
bool m_hasIddCx110DDIs = false;
|
||||
bool m_canProcessFP16 = false;
|
||||
bool m_softwareMode = true;
|
||||
|
||||
// HDR state from EvtIddCxMonitorSetDefaultHdrMetadata (IddCx 1.10+)
|
||||
// Protected by m_hdrLock - accessed from both the IDD callback thread
|
||||
@@ -147,7 +149,6 @@ private:
|
||||
std::shared_ptr<const D12ColorTransform> m_colorTransform;
|
||||
|
||||
void QueryIddCxCapabilities();
|
||||
bool CanUseIddCx110DDIs() const { return m_canProcessFP16; }
|
||||
|
||||
void ScheduleInitRetry();
|
||||
void StopInitRetry();
|
||||
@@ -211,7 +212,9 @@ public:
|
||||
|
||||
size_t GetAlignSize () const { return m_alignSize ; }
|
||||
size_t GetMaxFrameSize() const { return m_maxFrameSize ; }
|
||||
bool HasIddCx110DDIs() const { return m_hasIddCx110DDIs; }
|
||||
bool CanProcessFP16 () const { return m_canProcessFP16; }
|
||||
bool IsSoftwareMode () const { return m_softwareMode ; }
|
||||
|
||||
struct PreparedFrameBuffer
|
||||
{
|
||||
|
||||
@@ -64,7 +64,8 @@ void CIndirectMonitorContext::AssignSwapChain(IDDCX_SWAPCHAIN swapChain, LUID re
|
||||
|
||||
UINT64 alignSize = CPlatformInfo::GetPageSize();
|
||||
dx12Device = std::make_shared<CD3D12Device>(renderAdapter);
|
||||
CD3D12Device::InitResult r = dx12Device->Init(m_devContext->GetIVSHMEM(), alignSize);
|
||||
CD3D12Device::InitResult r = dx12Device->Init(
|
||||
m_devContext->GetIVSHMEM(), alignSize, !dx11Device->IsSoftware());
|
||||
if (r == CD3D12Device::RETRY)
|
||||
{
|
||||
dx12Device.reset();
|
||||
|
||||
@@ -30,6 +30,46 @@
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
|
||||
namespace
|
||||
{
|
||||
bool NearlyEqual(float a, float b, float tolerance)
|
||||
{
|
||||
const float delta = a - b;
|
||||
return delta >= -tolerance && delta <= tolerance;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsIdentityColorTransform(const D12ColorTransform& transform)
|
||||
{
|
||||
static const float matrixTolerance = 1.0f / 1048576.0f;
|
||||
static const float lutTolerance = 1.0f / 65535.0f;
|
||||
|
||||
if (transform.matrixEnabled)
|
||||
{
|
||||
for (unsigned row = 0; row < 3; ++row)
|
||||
for (unsigned column = 0; column < 4; ++column)
|
||||
{
|
||||
const float expected = row == column ? 1.0f : 0.0f;
|
||||
const float effective =
|
||||
transform.matrix[row][column] * transform.scalar;
|
||||
if (!NearlyEqual(effective, expected, matrixTolerance))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (transform.lutEnabled)
|
||||
for (unsigned i = 0; i < 4096; ++i)
|
||||
{
|
||||
const float expected = (float)i / 4095.0f;
|
||||
if (!NearlyEqual(transform.lut[i][0], expected, lutTolerance) ||
|
||||
!NearlyEqual(transform.lut[i][1], expected, lutTolerance) ||
|
||||
!NearlyEqual(transform.lut[i][2], expected, lutTolerance))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void CopyHDRMetadata(D12FrameFormat& dst, const D12FrameFormat& src)
|
||||
{
|
||||
dst.hdrMetadata = src.hdrMetadata;
|
||||
|
||||
@@ -52,6 +52,8 @@ struct D12ColorTransform
|
||||
float lut[4096][4] = {};
|
||||
};
|
||||
|
||||
bool IsIdentityColorTransform(const D12ColorTransform& transform);
|
||||
|
||||
struct D12FrameFormat
|
||||
{
|
||||
D3D12_RESOURCE_DESC desc = {};
|
||||
|
||||
@@ -40,7 +40,9 @@ CSwapChainProcessor::CSwapChainProcessor(CIndirectMonitorContext * monitorContex
|
||||
{
|
||||
m_resPool.Init(dx11Device, dx12Device);
|
||||
m_fbPool.Init(this);
|
||||
if (!m_postProcessor.Init(dx12Device))
|
||||
if (m_dx11Device->IsSoftware())
|
||||
DEBUG_INFO("Software render adapter: post-processing disabled");
|
||||
else if (!m_postProcessor.Init(dx12Device))
|
||||
DEBUG_ERROR("Failed to initialize post processor");
|
||||
|
||||
// Manual-reset: both worker threads wait on this, so it must stay signalled
|
||||
@@ -189,7 +191,7 @@ bool CSwapChainProcessor::SwapChainThreadCore()
|
||||
UINT sdrWhiteLevel = KVMFR_SDR_WHITE_LEVEL_DEFAULT;
|
||||
|
||||
#ifdef HAS_IDDCX_110
|
||||
if (m_devContext->CanProcessFP16())
|
||||
if (m_devContext->HasIddCx110DDIs())
|
||||
{
|
||||
IDARG_IN_RELEASEANDACQUIREBUFFER2 acquireIn = {};
|
||||
acquireIn.Size = sizeof(acquireIn);
|
||||
@@ -780,7 +782,7 @@ bool CSwapChainProcessor::QueryHWCursor()
|
||||
UINT cursorWhiteLevel = m_sdrWhiteLevel.load(std::memory_order_relaxed);
|
||||
NTSTATUS status;
|
||||
#ifdef HAS_IDDCX_110
|
||||
if (m_devContext->CanProcessFP16())
|
||||
if (m_devContext->HasIddCx110DDIs())
|
||||
{
|
||||
IDARG_OUT_QUERY_HWCURSOR3 out3 = {};
|
||||
status = IddCxMonitorQueryHardwareCursor3(m_monitor, &in, &out3);
|
||||
|
||||
@@ -160,13 +160,20 @@ NTSTATUS LGIddParseMonitorDescription2(const IDARG_IN_PARSEMONITORDESCRIPTION2*
|
||||
NTSTATUS LGIddAdapterQueryTargetInfo(IDDCX_ADAPTER adapter,
|
||||
IDARG_IN_QUERYTARGET_INFO* inArgs, IDARG_OUT_QUERYTARGET_INFO* outArgs)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(adapter);
|
||||
UNREFERENCED_PARAMETER(inArgs);
|
||||
|
||||
outArgs->TargetCaps =
|
||||
(IDDCX_TARGET_CAPS)(IDDCX_TARGET_CAPS_WIDE_COLOR_SPACE | IDDCX_TARGET_CAPS_HIGH_COLOR_SPACE);
|
||||
outArgs->DitheringSupport.Rgb =
|
||||
(IDDCX_BITS_PER_COMPONENT)(IDDCX_BITS_PER_COMPONENT_8 | IDDCX_BITS_PER_COMPONENT_10);
|
||||
auto* wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(adapter);
|
||||
const bool hdr = wrapper && wrapper->context &&
|
||||
wrapper->context->CanProcessFP16();
|
||||
|
||||
outArgs->TargetCaps = hdr ?
|
||||
(IDDCX_TARGET_CAPS)(IDDCX_TARGET_CAPS_WIDE_COLOR_SPACE |
|
||||
IDDCX_TARGET_CAPS_HIGH_COLOR_SPACE) :
|
||||
(IDDCX_TARGET_CAPS)0;
|
||||
outArgs->DitheringSupport.Rgb = hdr ?
|
||||
(IDDCX_BITS_PER_COMPONENT)(IDDCX_BITS_PER_COMPONENT_8 |
|
||||
IDDCX_BITS_PER_COMPONENT_10) :
|
||||
IDDCX_BITS_PER_COMPONENT_8;
|
||||
outArgs->DitheringSupport.YCbCr444 = IDDCX_BITS_PER_COMPONENT_NONE;
|
||||
outArgs->DitheringSupport.YCbCr422 = IDDCX_BITS_PER_COMPONENT_NONE;
|
||||
outArgs->DitheringSupport.YCbCr420 = IDDCX_BITS_PER_COMPONENT_NONE;
|
||||
@@ -187,6 +194,12 @@ NTSTATUS LGIddMonitorSetDefaultHdrMetadata(IDDCX_MONITOR monitor,
|
||||
auto* wrapper = WdfObjectGet_CIndirectMonitorContextWrapper(monitor);
|
||||
auto* ctx = wrapper->context->GetDeviceContext();
|
||||
|
||||
if (ctx->IsSoftwareMode())
|
||||
{
|
||||
ctx->SetHDRActive(nullptr);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ctx->SetHDRActive(inArgs->Data.pHdr10);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
@@ -197,6 +210,13 @@ NTSTATUS LGIddMonitorSetGammaRamp(IDDCX_MONITOR monitor, const IDARG_IN_SET_GAMM
|
||||
auto* wrapper = WdfObjectGet_CIndirectMonitorContextWrapper(monitor);
|
||||
auto* ctx = wrapper->context->GetDeviceContext();
|
||||
|
||||
if (ctx->IsSoftwareMode())
|
||||
{
|
||||
ctx->SetColorTransform(nullptr);
|
||||
DEBUG_INFO("Ignoring display color transform in software mode");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (inArgs->Type == IDDCX_GAMMARAMP_TYPE_DEFAULT)
|
||||
{
|
||||
ctx->SetColorTransform(nullptr);
|
||||
@@ -236,6 +256,13 @@ NTSTATUS LGIddMonitorSetGammaRamp(IDDCX_MONITOR monitor, const IDARG_IN_SET_GAMM
|
||||
transform->lut[i][3] = 1.0f;
|
||||
}
|
||||
|
||||
if (IsIdentityColorTransform(*transform))
|
||||
{
|
||||
ctx->SetColorTransform(nullptr);
|
||||
DEBUG_INFO("Ignoring identity display color transform");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ctx->SetColorTransform(std::move(transform));
|
||||
DEBUG_INFO("Display color transform updated (matrix:%d lut:%d)",
|
||||
input->MatrixEnabled, input->LutEnabled);
|
||||
|
||||
@@ -208,7 +208,7 @@ PostProcessStatus CColorTransformEffect::SetFormat(
|
||||
const ComPtr<ID3D12Device3>& device,
|
||||
const D12FrameFormat& src, D12FrameFormat& dst)
|
||||
{
|
||||
if (!src.colorTransform ||
|
||||
if (!src.colorTransform || IsIdentityColorTransform(*src.colorTransform) ||
|
||||
(!src.colorTransform->matrixEnabled && !src.colorTransform->lutEnabled))
|
||||
return PostProcessStatus::BYPASS_EFFECT;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user