SDL
SDL copied to clipboard
[Feature Request] Add 4k support for UWP on xbox
UWP on Xbox will always return a windows size of 1080p regardless of display res. However, you are still able to create a 4k swapchain will output at this resolution. You can instead get the display res from the HDMI device information on Xbox to get the actual display res. It would be nice to see SDL implement this for proper 4k support on UWP. I have tried a quick and dirty implementation of this by manually overriding the window size as 4k however this produces a zoomed in image even though the swapchain says that it is set to 4k. I think somewhere in the chain SDL is still only producing an output that is only 1080p
You can find more about 4k on UWP here: https://walbourn.github.io/directx-and-uwp-on-xbox-one/
Below I have added the functions that retroarch uses to get the output res on its UWP port as an example.
int uwp_get_height(void)
{
/* This function must be performed within UI thread,
* otherwise it will cause a crash in specific cases
* https://github.com/libretro/RetroArch/issues/13491 */
float surface_scale = 0;
int ret = -1;
volatile bool finished = false;
Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([&surface_scale, &ret, &finished]()
{
if (is_running_on_xbox())
{
const Windows::Graphics::Display::Core::HdmiDisplayInformation^ hdi = Windows::Graphics::Display::Core::HdmiDisplayInformation::GetForCurrentView();
if (hdi)
ret = Windows::Graphics::Display::Core::HdmiDisplayInformation::GetForCurrentView()->GetCurrentDisplayMode()->ResolutionHeightInRawPixels;
}
if (ret == -1)
{
const LONG32 resolution_scale = static_cast<LONG32>(Windows::Graphics::Display::DisplayInformation::GetForCurrentView()->ResolutionScale);
surface_scale = static_cast<float>(resolution_scale) / 100.0f;
ret = static_cast<LONG32>(
CoreWindow::GetForCurrentThread()->Bounds.Height
* surface_scale);
}
finished = true;
}));
Windows::UI::Core::CoreWindow^ corewindow = Windows::UI::Core::CoreWindow::GetForCurrentThread();
while (!finished)
{
if (corewindow)
corewindow->Dispatcher->ProcessEvents(Windows::UI::Core::CoreProcessEventsOption::ProcessAllIfPresent);
}
return ret;
}
int uwp_get_width(void)
{
/* This function must be performed within UI thread,
* otherwise it will cause a crash in specific cases
* https://github.com/libretro/RetroArch/issues/13491 */
float surface_scale = 0;
int returnValue = -1;
volatile bool finished = false;
Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([&surface_scale, &returnValue, &finished]()
{
if (is_running_on_xbox())
{
const Windows::Graphics::Display::Core::HdmiDisplayInformation^ hdi = Windows::Graphics::Display::Core::HdmiDisplayInformation::GetForCurrentView();
if (hdi)
returnValue = Windows::Graphics::Display::Core::HdmiDisplayInformation::GetForCurrentView()->GetCurrentDisplayMode()->ResolutionWidthInRawPixels;
}
if(returnValue == -1)
{
const LONG32 resolution_scale = static_cast<LONG32>(Windows::Graphics::Display::DisplayInformation::GetForCurrentView()->ResolutionScale);
surface_scale = static_cast<float>(resolution_scale) / 100.0f;
returnValue = static_cast<LONG32>(
CoreWindow::GetForCurrentThread()->Bounds.Width
* surface_scale);
}
finished = true;
}));
Windows::UI::Core::CoreWindow^ corewindow = Windows::UI::Core::CoreWindow::GetForCurrentThread();
while (!finished)
{
if (corewindow)
corewindow->Dispatcher->ProcessEvents(Windows::UI::Core::CoreProcessEventsOption::ProcessAllIfPresent);
}
return returnValue;
}
Feel free to submit a PR for this!
Feel free to submit a PR for this!
I can open a pr but unfortunately it will have to be in an uncomplete state as like I have mentioned I was unable to find a way to prevent the image from being zoomed into as somewhere along the chain the resolution must be set to 1080p
The most reliable way to do this is to use GetGamingDeviceModelInformation
per a more recent blog post.
The most reliable way to do this is to use
GetGamingDeviceModelInformation
per a more recent blog post.
Thanks!
The most reliable way to do this is to use
GetGamingDeviceModelInformation
per a more recent blog post.
Yes, however the benefit of using the resolution from the HDMI device information is that you can avoid rendering at a higher resolution than needed.
For Xbox games just create the swapchain at the 4K or 1440p size regardless of the current setting of the TV. The hardware scalar takes care of the rest. The only reason you need use GGDMI is to deal with:
(a) Xbox One original h/w scalar can't handle anything larger than 1080p (b) The pixel throughput for 4K requires an Xbox One X or Xbox Series X to get a good framerate.
@walbourn do you know if UWP titles can support higher refresh rates than 60hz?
Most advanced graphics features (HDR, 120Hz, etc.) require access to the Microsoft GDK with Xbox extensions.