mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-04-01 09:25:24 +02:00
[dxvk] Don't create swapchains with sRGB formats
Third-party software is broken and doesn't understand non-linear formats.
This commit is contained in:
parent
8b68c767b1
commit
329edcee55
@ -587,6 +587,16 @@ namespace dxvk {
|
|||||||
|
|
||||||
VkSurfaceFormatKHR surfaceFormat = pickSurfaceFormat(formats.size(), formats.data(), m_preferredFormat);
|
VkSurfaceFormatKHR surfaceFormat = pickSurfaceFormat(formats.size(), formats.data(), m_preferredFormat);
|
||||||
|
|
||||||
|
// Set up image format list for mutable swap chain if necessary
|
||||||
|
small_vector<VkFormat, 2> viewFormats = { };
|
||||||
|
|
||||||
|
auto formatPair = vk::getSrgbFormatPair(surfaceFormat.format);
|
||||||
|
|
||||||
|
if (formatPair.second) {
|
||||||
|
viewFormats.push_back(formatPair.first);
|
||||||
|
viewFormats.push_back(formatPair.second);
|
||||||
|
}
|
||||||
|
|
||||||
// Select a present mode for the current sync interval
|
// Select a present mode for the current sync interval
|
||||||
if ((status = getSupportedPresentModes(modes)))
|
if ((status = getSupportedPresentModes(modes)))
|
||||||
return status;
|
return status;
|
||||||
@ -684,6 +694,10 @@ namespace dxvk {
|
|||||||
VkSwapchainLatencyCreateInfoNV latencyInfo = { VK_STRUCTURE_TYPE_SWAPCHAIN_LATENCY_CREATE_INFO_NV };
|
VkSwapchainLatencyCreateInfoNV latencyInfo = { VK_STRUCTURE_TYPE_SWAPCHAIN_LATENCY_CREATE_INFO_NV };
|
||||||
latencyInfo.latencyModeEnable = m_latencySleepMode.has_value();
|
latencyInfo.latencyModeEnable = m_latencySleepMode.has_value();
|
||||||
|
|
||||||
|
VkImageFormatListCreateInfo formatList = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO };
|
||||||
|
formatList.viewFormatCount = viewFormats.size();
|
||||||
|
formatList.pViewFormats = viewFormats.data();
|
||||||
|
|
||||||
VkSwapchainCreateInfoKHR swapInfo = { VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR };
|
VkSwapchainCreateInfoKHR swapInfo = { VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR };
|
||||||
swapInfo.surface = m_surface;
|
swapInfo.surface = m_surface;
|
||||||
swapInfo.minImageCount = pickImageCount(minImageCount, maxImageCount);
|
swapInfo.minImageCount = pickImageCount(minImageCount, maxImageCount);
|
||||||
@ -699,6 +713,11 @@ namespace dxvk {
|
|||||||
swapInfo.presentMode = m_presentMode;
|
swapInfo.presentMode = m_presentMode;
|
||||||
swapInfo.clipped = VK_TRUE;
|
swapInfo.clipped = VK_TRUE;
|
||||||
|
|
||||||
|
if (m_device->features().khrSwapchainMutableFormat && formatList.viewFormatCount) {
|
||||||
|
swapInfo.flags |= VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR;
|
||||||
|
formatList.pNext = std::exchange(swapInfo.pNext, &formatList);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_device->features().extFullScreenExclusive)
|
if (m_device->features().extFullScreenExclusive)
|
||||||
fullScreenInfo.pNext = const_cast<void*>(std::exchange(swapInfo.pNext, &fullScreenInfo));
|
fullScreenInfo.pNext = const_cast<void*>(std::exchange(swapInfo.pNext, &fullScreenInfo));
|
||||||
|
|
||||||
@ -744,6 +763,17 @@ namespace dxvk {
|
|||||||
imageInfo.shared = VK_TRUE;
|
imageInfo.shared = VK_TRUE;
|
||||||
imageInfo.debugName = debugName.c_str();
|
imageInfo.debugName = debugName.c_str();
|
||||||
|
|
||||||
|
// If possible, expose the image with an sRGB format internally so
|
||||||
|
// that it will be used as the default format for composition.
|
||||||
|
if (swapInfo.flags & VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR) {
|
||||||
|
imageInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
|
||||||
|
imageInfo.viewFormatCount = formatList.viewFormatCount;
|
||||||
|
imageInfo.viewFormats = formatList.pViewFormats;
|
||||||
|
|
||||||
|
if (formatPair.second)
|
||||||
|
imageInfo.format = formatPair.second;
|
||||||
|
}
|
||||||
|
|
||||||
m_images.push_back(m_device->importImage(imageInfo, images[i],
|
m_images.push_back(m_device->importImage(imageInfo, images[i],
|
||||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
|
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
|
||||||
}
|
}
|
||||||
@ -952,21 +982,15 @@ namespace dxvk {
|
|||||||
const VkSurfaceFormatKHR* pSupported,
|
const VkSurfaceFormatKHR* pSupported,
|
||||||
VkColorSpaceKHR colorSpace,
|
VkColorSpaceKHR colorSpace,
|
||||||
VkFormat format) {
|
VkFormat format) {
|
||||||
static const std::array<std::pair<VkFormat, VkFormat>, 3> srgbFormatMap = {{
|
|
||||||
{ VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_SRGB },
|
|
||||||
{ VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_SRGB },
|
|
||||||
{ VK_FORMAT_A8B8G8R8_UNORM_PACK32, VK_FORMAT_A8B8G8R8_SRGB_PACK32 },
|
|
||||||
}};
|
|
||||||
|
|
||||||
static const std::array<VkFormat, 13> srgbFormatList = {
|
static const std::array<VkFormat, 13> srgbFormatList = {
|
||||||
VK_FORMAT_B5G5R5A1_UNORM_PACK16,
|
VK_FORMAT_B5G5R5A1_UNORM_PACK16,
|
||||||
VK_FORMAT_R5G5B5A1_UNORM_PACK16,
|
VK_FORMAT_R5G5B5A1_UNORM_PACK16,
|
||||||
VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR,
|
VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR,
|
||||||
VK_FORMAT_R5G6B5_UNORM_PACK16,
|
VK_FORMAT_R5G6B5_UNORM_PACK16,
|
||||||
VK_FORMAT_B5G6R5_UNORM_PACK16,
|
VK_FORMAT_B5G6R5_UNORM_PACK16,
|
||||||
VK_FORMAT_R8G8B8A8_SRGB,
|
VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
VK_FORMAT_B8G8R8A8_SRGB,
|
VK_FORMAT_B8G8R8A8_UNORM,
|
||||||
VK_FORMAT_A8B8G8R8_SRGB_PACK32,
|
VK_FORMAT_A8B8G8R8_UNORM_PACK32,
|
||||||
VK_FORMAT_A2R10G10B10_UNORM_PACK32,
|
VK_FORMAT_A2R10G10B10_UNORM_PACK32,
|
||||||
VK_FORMAT_A2B10G10R10_UNORM_PACK32,
|
VK_FORMAT_A2B10G10R10_UNORM_PACK32,
|
||||||
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
|
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
|
||||||
@ -995,14 +1019,12 @@ namespace dxvk {
|
|||||||
scRGBFormatList.size(), scRGBFormatList.data() },
|
scRGBFormatList.size(), scRGBFormatList.data() },
|
||||||
}};
|
}};
|
||||||
|
|
||||||
// For the sRGB color space, always prefer an actual sRGB
|
// Third-party overlays don't handle sRGB image formats correctly,
|
||||||
// format so that the blitter can use alpha blending.
|
// so use the corresponding linear format instead.
|
||||||
if (colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
|
auto formatPair = vk::getSrgbFormatPair(format);
|
||||||
for (const auto& e : srgbFormatMap) {
|
|
||||||
if (format == e.first)
|
if (formatPair.first)
|
||||||
format = e.second;
|
format = formatPair.first;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the desired format is supported natively, use it
|
// If the desired format is supported natively, use it
|
||||||
VkFormat fallback = VK_FORMAT_UNDEFINED;
|
VkFormat fallback = VK_FORMAT_UNDEFINED;
|
||||||
|
@ -233,6 +233,30 @@ namespace dxvk::vk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Queries sRGB and non-sSRGB format pair
|
||||||
|
*
|
||||||
|
* \param [in] format Format to look up
|
||||||
|
* \returns Pair of the corresponding non-SRGB and sRGB formats.
|
||||||
|
* If the format in quesion has no sRGB equivalent, this
|
||||||
|
* function returns \c VK_FORMAT_UNDEFINED.
|
||||||
|
*/
|
||||||
|
inline std::pair<VkFormat, VkFormat> getSrgbFormatPair(VkFormat format) {
|
||||||
|
static const std::array<std::pair<VkFormat, VkFormat>, 3> srgbFormatMap = {{
|
||||||
|
{ VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_SRGB },
|
||||||
|
{ VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_SRGB },
|
||||||
|
{ VK_FORMAT_A8B8G8R8_UNORM_PACK32, VK_FORMAT_A8B8G8R8_SRGB_PACK32 },
|
||||||
|
}};
|
||||||
|
|
||||||
|
for (const auto& f : srgbFormatMap) {
|
||||||
|
if (f.first == format || f.second == format)
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_pair(VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Makes debug label
|
* \brief Makes debug label
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user