Skip to content

Commit 4527715

Browse files
committed
amd_ags_x64: Rewrite display code to use IDXGIOutput
Also allows us to expose HDR features and colorimetry of the display. Signed-off-by: Joshua Ashton <[email protected]>
1 parent dcd2b82 commit 4527715

File tree

1 file changed

+122
-91
lines changed

1 file changed

+122
-91
lines changed

dlls/amd_ags_x64/amd_ags_x64_main.c

Lines changed: 122 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -354,125 +354,156 @@ static enum amd_ags_version determine_ags_version(void)
354354
return ret;
355355
}
356356

357-
struct monitor_enum_context_600
357+
static void init_device_displays_600(IDXGIFactory1 *factory, const char *adapter_name, AGSDisplayInfo_600 **ret_displays, int *ret_display_count)
358358
{
359-
const char *adapter_name;
360-
AGSDisplayInfo_600 **ret_displays;
361-
int *ret_display_count;
362-
};
359+
IDXGIAdapter1 *adapter = NULL;
360+
WCHAR wide_adapter_name[128];
361+
UINT adapter_index = 0;
363362

364-
static BOOL WINAPI monitor_enum_proc_600(HMONITOR hmonitor, HDC hdc, RECT *rect, LPARAM context)
365-
{
366-
struct monitor_enum_context_600 *c = (struct monitor_enum_context_600 *)context;
367-
MONITORINFOEXA monitor_info;
368-
AGSDisplayInfo_600 *new_alloc;
369-
DISPLAY_DEVICEA device;
370-
AGSDisplayInfo_600 *info;
371-
unsigned int i, mode;
372-
DEVMODEA dev_mode;
373-
374-
375-
monitor_info.cbSize = sizeof(monitor_info);
376-
GetMonitorInfoA(hmonitor, (MONITORINFO *)&monitor_info);
377-
TRACE("monitor_info.szDevice %s.\n", debugstr_a(monitor_info.szDevice));
378-
379-
device.cb = sizeof(device);
380-
i = 0;
381-
while (EnumDisplayDevicesA(NULL, i, &device, 0))
363+
TRACE("adapter_name %s.\n", debugstr_a(adapter_name));
364+
365+
*ret_displays = NULL;
366+
*ret_display_count = 0;
367+
368+
MultiByteToWideChar(CP_ACP, 0, adapter_name, -1, wide_adapter_name, ARRAY_SIZE(wide_adapter_name));
369+
370+
while (SUCCEEDED(IDXGIFactory1_EnumAdapters1(factory, adapter_index++, &adapter)))
382371
{
383-
TRACE("device.DeviceName %s, device.DeviceString %s.\n", debugstr_a(device.DeviceName), debugstr_a(device.DeviceString));
384-
++i;
385-
if (strcmp(device.DeviceString, c->adapter_name) || strcmp(device.DeviceName, monitor_info.szDevice))
386-
continue;
372+
DXGI_ADAPTER_DESC1 adapter_desc;
373+
IDXGIOutput *output;
374+
UINT output_index;
387375

388-
if (*c->ret_display_count)
389-
{
390-
if (!(new_alloc = heap_realloc(*c->ret_displays, sizeof(*new_alloc) * (*c->ret_display_count + 1))))
391-
{
392-
ERR("No memory.");
393-
return FALSE;
394-
}
395-
*c->ret_displays = new_alloc;
396-
}
397-
else if (!(*c->ret_displays = heap_alloc(sizeof(**c->ret_displays))))
398-
{
399-
ERR("No memory.");
400-
return FALSE;
401-
}
402-
info = &(*c->ret_displays)[*c->ret_display_count];
403-
memset(info, 0, sizeof(*info));
404-
strcpy(info->displayDeviceName, device.DeviceName);
405-
if (EnumDisplayDevicesA(info->displayDeviceName, 0, &device, 0))
376+
IDXGIAdapter1_GetDesc1(adapter, &adapter_desc);
377+
378+
if (wcscmp(wide_adapter_name, adapter_desc.Description))
406379
{
407-
strcpy(info->name, device.DeviceString);
380+
IDXGIAdapter1_Release(adapter);
381+
continue;
408382
}
409-
else
383+
384+
output_index = 0;
385+
while (SUCCEEDED(IDXGIAdapter1_EnumOutputs(adapter, output_index, &output)))
410386
{
411-
ERR("Could not get monitor name for device %s.\n", debugstr_a(info->displayDeviceName));
412-
strcpy(info->name, "Unknown");
387+
IDXGIOutput_Release(output);
388+
output_index++;
413389
}
414-
if (monitor_info.dwFlags & MONITORINFOF_PRIMARY)
415-
info->isPrimaryDisplay = 1;
416390

417-
mode = 0;
418-
memset(&dev_mode, 0, sizeof(dev_mode));
419-
dev_mode.dmSize = sizeof(dev_mode);
420-
while (EnumDisplaySettingsExA(monitor_info.szDevice, mode, &dev_mode, EDS_RAWMODE))
391+
*ret_display_count = output_index;
392+
*ret_displays = heap_alloc(*ret_display_count * sizeof(AGSDisplayInfo_600));
393+
394+
output_index = 0;
395+
while (SUCCEEDED(IDXGIAdapter1_EnumOutputs(adapter, output_index++, &output)))
421396
{
422-
++mode;
423-
if (dev_mode.dmPelsWidth > info->maxResolutionX)
424-
info->maxResolutionX = dev_mode.dmPelsWidth;
425-
if (dev_mode.dmPelsHeight > info->maxResolutionY)
426-
info->maxResolutionY = dev_mode.dmPelsHeight;
427-
if (dev_mode.dmDisplayFrequency > info->maxRefreshRate)
428-
info->maxRefreshRate = dev_mode.dmDisplayFrequency;
397+
DXGI_OUTPUT_DESC1 output_desc;
398+
MONITORINFOEXA monitor_info;
399+
AGSDisplayInfo_600 *info;
400+
DISPLAY_DEVICEA device;
401+
IDXGIOutput6 *output6;
402+
DEVMODEA dev_mode;
403+
unsigned int mode;
404+
405+
info = &(*ret_displays)[output_index - 1];
406+
memset(info, 0, sizeof(*info));
407+
408+
if (FAILED(IDXGIOutput_QueryInterface(output, &IID_IDXGIOutput6, (void**)&output6)))
409+
{
410+
ERR("Failed to query IDXGIOutput6\n");
411+
IDXGIOutput_Release(output);
412+
break;
413+
}
414+
415+
IDXGIOutput6_GetDesc1(output6, &output_desc);
416+
417+
monitor_info.cbSize = sizeof(monitor_info);
418+
GetMonitorInfoA(output_desc.Monitor, (MONITORINFO *)&monitor_info);
419+
TRACE("monitor_info.szDevice %s.\n", debugstr_a(monitor_info.szDevice));
420+
421+
if (EnumDisplayDevicesA(monitor_info.szDevice, 0, &device, 0))
422+
{
423+
strcpy(info->name, device.DeviceString);
424+
}
425+
else
426+
{
427+
ERR("Could not get monitor name for device %s.\n", debugstr_a(info->displayDeviceName));
428+
strcpy(info->name, "Unknown");
429+
}
430+
strcpy(info->displayDeviceName, monitor_info.szDevice);
431+
if (monitor_info.dwFlags & MONITORINFOF_PRIMARY)
432+
info->isPrimaryDisplay = 1;
433+
if (output_desc.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020)
434+
{
435+
TRACE("Reporting monitor %s as HDR10 supported.\n", debugstr_a(monitor_info.szDevice));
436+
info->HDR10 = 1;
437+
}
438+
439+
mode = 0;
429440
memset(&dev_mode, 0, sizeof(dev_mode));
430441
dev_mode.dmSize = sizeof(dev_mode);
431-
}
442+
while (EnumDisplaySettingsExA(monitor_info.szDevice, mode, &dev_mode, EDS_RAWMODE))
443+
{
444+
++mode;
445+
if (dev_mode.dmPelsWidth > info->maxResolutionX)
446+
info->maxResolutionX = dev_mode.dmPelsWidth;
447+
if (dev_mode.dmPelsHeight > info->maxResolutionY)
448+
info->maxResolutionY = dev_mode.dmPelsHeight;
449+
if (dev_mode.dmDisplayFrequency > info->maxRefreshRate)
450+
info->maxRefreshRate = dev_mode.dmDisplayFrequency;
451+
memset(&dev_mode, 0, sizeof(dev_mode));
452+
dev_mode.dmSize = sizeof(dev_mode);
453+
}
432454

433-
info->currentResolution.offsetX = monitor_info.rcMonitor.left;
434-
info->currentResolution.offsetY = monitor_info.rcMonitor.top;
435-
info->currentResolution.width = monitor_info.rcMonitor.right - monitor_info.rcMonitor.left;
436-
info->currentResolution.height = monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top;
437-
info->visibleResolution = info->currentResolution;
455+
info->currentResolution.offsetX = monitor_info.rcMonitor.left;
456+
info->currentResolution.offsetY = monitor_info.rcMonitor.top;
457+
info->currentResolution.width = monitor_info.rcMonitor.right - monitor_info.rcMonitor.left;
458+
info->currentResolution.height = monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top;
459+
info->visibleResolution = info->currentResolution;
438460

439-
memset(&dev_mode, 0, sizeof(dev_mode));
440-
dev_mode.dmSize = sizeof(dev_mode);
461+
memset(&dev_mode, 0, sizeof(dev_mode));
462+
dev_mode.dmSize = sizeof(dev_mode);
441463

442-
if (EnumDisplaySettingsExA(monitor_info.szDevice, ENUM_CURRENT_SETTINGS, &dev_mode, EDS_RAWMODE))
443-
info->currentRefreshRate = dev_mode.dmDisplayFrequency;
444-
else
445-
ERR("Could not get current display settings.\n");
446-
++*c->ret_display_count;
464+
if (EnumDisplaySettingsExA(monitor_info.szDevice, ENUM_CURRENT_SETTINGS, &dev_mode, EDS_RAWMODE))
465+
info->currentRefreshRate = dev_mode.dmDisplayFrequency;
447466

448-
TRACE("Added display %s for %s.\n", debugstr_a(monitor_info.szDevice), debugstr_a(c->adapter_name));
449-
}
467+
info->eyefinityGridCoordX = -1;
468+
info->eyefinityGridCoordY = -1;
450469

451-
return TRUE;
452-
}
470+
info->chromaticityRedX = output_desc.RedPrimary[0];
471+
info->chromaticityRedY = output_desc.RedPrimary[1];
472+
info->chromaticityGreenX = output_desc.GreenPrimary[0];
473+
info->chromaticityGreenY = output_desc.GreenPrimary[1];
474+
info->chromaticityBlueX = output_desc.BluePrimary[0];
475+
info->chromaticityBlueY = output_desc.BluePrimary[1];
476+
info->chromaticityWhitePointX = output_desc.WhitePoint[0];
477+
info->chromaticityWhitePointY = output_desc.WhitePoint[1];
453478

454-
static void init_device_displays_600(const char *adapter_name, AGSDisplayInfo_600 **ret_displays, int *ret_display_count)
455-
{
456-
struct monitor_enum_context_600 context;
479+
info->screenDiffuseReflectance = 0;
480+
info->screenSpecularReflectance = 0;
457481

458-
TRACE("adapter_name %s.\n", debugstr_a(adapter_name));
482+
info->minLuminance = output_desc.MinLuminance;
483+
info->maxLuminance = output_desc.MaxLuminance;
484+
info->avgLuminance = output_desc.MaxFullFrameLuminance;
459485

460-
context.adapter_name = adapter_name;
461-
context.ret_displays = ret_displays;
462-
context.ret_display_count = ret_display_count;
486+
info->logicalDisplayIndex = output_index - 1;
487+
info->adlAdapterIndex = adapter_index - 1;
463488

464-
EnumDisplayMonitors(NULL, NULL, monitor_enum_proc_600, (LPARAM)&context);
489+
IDXGIOutput6_Release(output6);
490+
IDXGIOutput_Release(output);
491+
}
492+
493+
IDXGIAdapter1_Release(adapter);
494+
break;
495+
}
465496
}
466497

467-
static void init_device_displays_511(const char *adapter_name, AGSDisplayInfo_511 **ret_displays, int *ret_display_count)
498+
static void init_device_displays_511(IDXGIFactory1 *factory, const char *adapter_name, AGSDisplayInfo_511 **ret_displays, int *ret_display_count)
468499
{
469500
AGSDisplayInfo_600 *displays = NULL;
470501
int display_count = 0;
471502
int i;
472503
*ret_displays = NULL;
473504
*ret_display_count = 0;
474505

475-
init_device_displays_600(adapter_name, &displays, &display_count);
506+
init_device_displays_600(factory, adapter_name, &displays, &display_count);
476507

477508
if ((*ret_displays = heap_alloc(sizeof(**ret_displays) * display_count)))
478509
{
@@ -575,13 +606,13 @@ static AGSReturnCode init_ags_context(AGSContext *context)
575606

576607
if (context->version >= AMD_AGS_VERSION_6_0_0)
577608
{
578-
init_device_displays_600(vk_properties->deviceName,
609+
init_device_displays_600(context->dxgi_factory, vk_properties->deviceName,
579610
GET_DEVICE_FIELD_ADDR(device, displays, AGSDisplayInfo_600 *, context->version),
580611
GET_DEVICE_FIELD_ADDR(device, numDisplays, int, context->version));
581612
}
582613
else
583614
{
584-
init_device_displays_511(vk_properties->deviceName,
615+
init_device_displays_511(context->dxgi_factory, vk_properties->deviceName,
585616
GET_DEVICE_FIELD_ADDR(device, displays, AGSDisplayInfo_511 *, context->version),
586617
GET_DEVICE_FIELD_ADDR(device, numDisplays, int, context->version));
587618
}

0 commit comments

Comments
 (0)