Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/rendervulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,15 +464,21 @@ bool CVulkanDevice::createDevice()
// We need to refactor some Vulkan stuff to do that though.
if ( hasDrmProps )
{
VkPhysicalDeviceDriverProperties driverProps = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES,
};
VkPhysicalDeviceDrmPropertiesEXT drmProps = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT,
.pNext = &driverProps,
};
VkPhysicalDeviceProperties2 props2 = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
.pNext = &drmProps,
};
vk.GetPhysicalDeviceProperties2( physDev(), &props2 );

m_bIsNvidiaProprietaryDriver = driverProps.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY;

if ( !GetBackend()->UsesVulkanSwapchain() && !drmProps.hasPrimary ) {
vk_log.errorf( "physical device has no primary node" );
return false;
Expand Down Expand Up @@ -3638,6 +3644,7 @@ gamescope::Rc<CVulkanTexture> vulkan_acquire_screenshot_texture(uint32_t width,
screenshotImageFlags.bMappable = true;
screenshotImageFlags.bTransferDst = true;
screenshotImageFlags.bStorage = true;
screenshotImageFlags.bSampled = true; // required for RGB-to-NV12 shader to sample this texture
if (exportable || drmFormat == DRM_FORMAT_NV12) {
screenshotImageFlags.bExportable = true;
screenshotImageFlags.bLinear = true; // TODO: support multi-planar DMA-BUF export via PipeWire
Expand Down
2 changes: 2 additions & 0 deletions src/rendervulkan.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,7 @@ class CVulkanDevice
inline bool hasDrmPrimaryDevId() {return m_bHasDrmPrimaryDevId;}
inline dev_t primaryDevId() {return m_drmPrimaryDevId;}
inline bool supportsFp16() {return m_bSupportsFp16;}
inline bool isNvidiaProprietaryDriver() {return m_bIsNvidiaProprietaryDriver;}

inline std::pair<void *, uint32_t> uploadBufferData(uint32_t size)
{
Expand Down Expand Up @@ -873,6 +874,7 @@ class CVulkanDevice
bool m_bSupportsFp16 = false;
bool m_bHasDrmPrimaryDevId = false;
bool m_bSupportsModifiers = false;
bool m_bIsNvidiaProprietaryDriver = false;
bool m_bInitialized = false;


Expand Down
9 changes: 8 additions & 1 deletion src/steamcompmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2388,8 +2388,15 @@ static void paint_pipewire()
if ( pFocus->overrideWindow && !pFocus->focusWindow->isSteamStreamingClient )
paint_window( pFocus->overrideWindow, pFocus->focusWindow, &frameInfo, nullptr, PaintWindowFlag::NoFilter, 1.0f, pFocus->overrideWindow );

// On the NVIDIA proprietary driver, sampling VK_FORMAT_A2R10G10B10_UNORM_PACK32
// (DRM_FORMAT_XRGB2101010) storage images returns R and B swapped, causing colour
// inversion in the RGB-to-NV12 conversion shader. Use DRM_FORMAT_XBGR2101010
// (VK_FORMAT_A2B10G10R10_UNORM_PACK32) instead so components arrive in the correct
// order. This does not affect non-proprietary NVIDIA drivers or other vendors.
const uint32_t uRGBCaptureFormat = g_device.isNvidiaProprietaryDriver()
? DRM_FORMAT_XBGR2101010 : DRM_FORMAT_XRGB2101010;
gamescope::Rc<CVulkanTexture> pRGBTexture = s_pPipewireBuffer->texture->isYcbcr()
? vulkan_acquire_screenshot_texture( uWidth, uHeight, false, DRM_FORMAT_XRGB2101010 )
? vulkan_acquire_screenshot_texture( uWidth, uHeight, false, uRGBCaptureFormat )
: gamescope::Rc<CVulkanTexture>{ s_pPipewireBuffer->texture };

gamescope::Rc<CVulkanTexture> pYUVTexture = s_pPipewireBuffer->texture->isYcbcr() ? s_pPipewireBuffer->texture : nullptr;
Expand Down