- add some support for using the HDR10 ST2084 color space on monitors that support it (unfortunately it doesn't work, and with virtually no documentation either from nvidia or khronos it is hard to say why)

This commit is contained in:
Magnus Norddahl 2019-03-14 00:21:53 +01:00
parent 625cc11ea2
commit 2d885d4e4c
3 changed files with 80 additions and 5 deletions

View file

@ -184,6 +184,18 @@ void VulkanDevice::SelectPhysicalDevice()
if (selected >= SupportedDevices.size())
selected = 0;
// Enable optional extensions we are interested in, if they are available on this device
for (const auto &ext : SupportedDevices[selected].device->Extensions)
{
for (const auto &opt : OptionalDeviceExtensions)
{
if (strcmp(ext.extensionName, opt) == 0)
{
EnabledDeviceExtensions.push_back(opt);
}
}
}
PhysicalDevice = *SupportedDevices[selected].device;
graphicsFamily = SupportedDevices[selected].graphicsFamily;
presentFamily = SupportedDevices[selected].presentFamily;
@ -313,6 +325,18 @@ void VulkanDevice::CreateInstance()
}
}
// Enable optional instance extensions we are interested in
for (const auto &ext : Extensions)
{
for (const auto &opt : OptionalExtensions)
{
if (strcmp(ext.extensionName, opt) == 0)
{
EnabledExtensions.push_back(opt);
}
}
}
VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "GZDoom";

View file

@ -62,11 +62,13 @@ public:
std::vector<VkLayerProperties> AvailableLayers;
std::vector<VkExtensionProperties> Extensions;
std::vector<const char *> EnabledExtensions;
std::vector<const char *> OptionalExtensions = { VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME };
std::vector<const char*> EnabledValidationLayers;
// Device setup
VkPhysicalDeviceFeatures UsedDeviceFeatures = {};
std::vector<const char *> EnabledDeviceExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
std::vector<const char *> OptionalDeviceExtensions = { VK_EXT_HDR_METADATA_EXTENSION_NAME };
VulkanPhysicalDevice PhysicalDevice;
bool DebugLayerActive = false;

View file

@ -1,5 +1,12 @@
#include "vk_swapchain.h"
#include "c_cvars.h"
#include "version.h"
CUSTOM_CVAR(Bool, vk_hdr, false, /*CVAR_ARCHIVE | CVAR_GLOBALCONFIG |*/ CVAR_NOINITCALL)
{
Printf("This won't take effect until " GAMENAME " is restarted.\n");
}
VulkanSwapChain::VulkanSwapChain(VulkanDevice *device, int width, int height, bool vsync) : vsync(vsync), device(device)
{
@ -40,12 +47,30 @@ VulkanSwapChain::VulkanSwapChain(VulkanDevice *device, int width, int height, bo
else
{
swapChainFormat = surfaceFormats.front();
for (const auto &format : surfaceFormats)
bool found = false;
if (vk_hdr)
{
if (format.format == VK_FORMAT_B8G8R8A8_UNORM && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
for (const auto &format : surfaceFormats)
{
swapChainFormat = format;
break;
if (format.format == VK_FORMAT_R16G16B16A16_SFLOAT && format.colorSpace == VK_COLOR_SPACE_HDR10_ST2084_EXT)
{
swapChainFormat = format;
found = true;
break;
}
}
}
if (!found)
{
for (const auto &format : surfaceFormats)
{
if (format.format == VK_FORMAT_B8G8R8A8_UNORM && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
{
swapChainFormat = format;
break;
}
}
}
}
@ -85,7 +110,7 @@ VulkanSwapChain::VulkanSwapChain(VulkanDevice *device, int width, int height, bo
swapChainCreateInfo.imageColorSpace = swapChainFormat.colorSpace;
swapChainCreateInfo.imageExtent = actualExtent;
swapChainCreateInfo.imageArrayLayers = 1;
swapChainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
swapChainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
uint32_t queueFamilyIndices[] = { (uint32_t)device->graphicsFamily, (uint32_t)device->presentFamily };
if (device->graphicsFamily != device->presentFamily)
@ -143,6 +168,30 @@ VulkanSwapChain::VulkanSwapChain(VulkanDevice *device, int width, int height, bo
device->SetDebugObjectName("SwapChainImageView", (uint64_t)swapChainImageViews[i], VK_OBJECT_TYPE_IMAGE_VIEW);
}
if (swapChainFormat.colorSpace == VK_COLOR_SPACE_HDR10_ST2084_EXT)
{
// Mastering display with DCI-P3 color primaries and D65 white point,
// maximum luminance of 1000 nits and minimum luminance of 0.001 nits;
// content has maximum luminance of 2000 nits and maximum frame average light level (MaxFALL) of 500 nits.
VkHdrMetadataEXT metadata = {};
metadata.sType = VK_STRUCTURE_TYPE_HDR_METADATA_EXT;
metadata.displayPrimaryRed.x = 0.680f;
metadata.displayPrimaryRed.y = 0.320f;
metadata.displayPrimaryGreen.x = 0.265f;
metadata.displayPrimaryGreen.y = 0.690f;
metadata.displayPrimaryBlue.x = 0.150f;
metadata.displayPrimaryBlue.y = 0.060f;
metadata.whitePoint.x = 0.3127f;
metadata.whitePoint.y = 0.3290f;
metadata.maxLuminance = 1000.0f;
metadata.minLuminance = 0.001f;
metadata.maxContentLightLevel = 2000.0f;
metadata.maxFrameAverageLightLevel = 500.0f;
vkSetHdrMetadataEXT(device->device, 1, &swapChain, &metadata);
}
}
catch (...)
{