Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

prefer DRM formats over VkFormat #1227

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
2 changes: 1 addition & 1 deletion src/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ namespace gamescope
virtual std::span<const char *const> GetInstanceExtensions() const = 0;
virtual std::span<const char *const> GetDeviceExtensions( VkPhysicalDevice pVkPhysicalDevice ) const = 0;
virtual VkImageLayout GetPresentLayout() const = 0;
virtual void GetPreferredOutputFormat( VkFormat *pPrimaryPlaneFormat, VkFormat *pOverlayPlaneFormat ) const = 0;
virtual void GetPreferredOutputFormat( uint32_t *pPrimaryPlaneFormat, uint32_t *pOverlayPlaneFormat ) const = 0;
virtual bool ValidPhysicalDevice( VkPhysicalDevice pVkPhysicalDevice ) const = 0;

virtual int Present( const FrameInfo_t *pFrameInfo, bool bAsync ) = 0;
Expand Down
10 changes: 5 additions & 5 deletions src/drm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3014,11 +3014,11 @@ namespace gamescope
// thus: newLayout is ignored.
return VK_IMAGE_LAYOUT_GENERAL;
}
virtual void GetPreferredOutputFormat( VkFormat *pPrimaryPlaneFormat, VkFormat *pOverlayPlaneFormat ) const override
{
*pPrimaryPlaneFormat = DRMFormatToVulkan( g_nDRMFormat, false );
*pOverlayPlaneFormat = DRMFormatToVulkan( g_nDRMFormatOverlay, false );
}
virtual void GetPreferredOutputFormat( uint32_t *pPrimaryPlaneFormat, uint32_t *pOverlayPlaneFormat ) const override
{
*pPrimaryPlaneFormat = g_nDRMFormat;
*pOverlayPlaneFormat = g_nDRMFormatOverlay;
}
virtual bool ValidPhysicalDevice( VkPhysicalDevice pVkPhysicalDevice ) const override
{
return true;
Expand Down
9 changes: 5 additions & 4 deletions src/headless.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "rendervulkan.hpp"
#include "wlserver.hpp"
#include "refresh_rate.h"
#include <drm_fourcc.h>

extern int g_nPreferredOutputWidth;
extern int g_nPreferredOutputHeight;
Expand Down Expand Up @@ -147,10 +148,10 @@ namespace gamescope
{
return VK_IMAGE_LAYOUT_GENERAL;
}
virtual void GetPreferredOutputFormat( VkFormat *pPrimaryPlaneFormat, VkFormat *pOverlayPlaneFormat ) const override
virtual void GetPreferredOutputFormat( uint32_t *pPrimaryPlaneFormat, uint32_t *pOverlayPlaneFormat ) const override
{
*pPrimaryPlaneFormat = VK_FORMAT_A2B10G10R10_UNORM_PACK32;
*pOverlayPlaneFormat = VK_FORMAT_B8G8R8A8_UNORM;
*pPrimaryPlaneFormat = DRM_FORMAT_ABGR2101010;
*pOverlayPlaneFormat = DRM_FORMAT_BGRA8888;
}
virtual bool ValidPhysicalDevice( VkPhysicalDevice pVkPhysicalDevice ) const override
{
Expand Down Expand Up @@ -272,4 +273,4 @@ namespace gamescope
return Set( new CHeadlessBackend{} );
}

}
}
45 changes: 23 additions & 22 deletions src/rendervulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,11 @@ struct {
{ DRM_FORMAT_INVALID, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, false, true },
};

uint32_t VulkanFormatToDRM( VkFormat vkFormat )
uint32_t VulkanFormatToDRM( VkFormat vkFormat, bool bHasAlpha )
{
for ( int i = 0; s_DRMVKFormatTable[i].vkFormat != VK_FORMAT_UNDEFINED; i++ )
{
if ( s_DRMVKFormatTable[i].vkFormat == vkFormat || s_DRMVKFormatTable[i].vkFormatSrgb == vkFormat )
if ( ( s_DRMVKFormatTable[i].vkFormat == vkFormat || s_DRMVKFormatTable[i].vkFormatSrgb == vkFormat ) && s_DRMVKFormatTable[i].bHasAlpha == bHasAlpha )
{
return s_DRMVKFormatTable[i].DRMFormat;
}
Expand Down Expand Up @@ -2373,15 +2373,15 @@ bool CVulkanTexture::BInit( uint32_t width, uint32_t height, uint32_t depth, uin
return true;
}

bool CVulkanTexture::BInitFromSwapchain( VkImage image, uint32_t width, uint32_t height, VkFormat format )
bool CVulkanTexture::BInitFromSwapchain( VkImage image, uint32_t width, uint32_t height, uint32_t drmFormat )
{
m_drmFormat = VulkanFormatToDRM( format );
m_drmFormat = drmFormat;
m_vkImage = image;
m_vkImageMemory = VK_NULL_HANDLE;
m_width = width;
m_height = height;
m_depth = 1;
m_format = format;
m_format = DRMFormatToVulkan( drmFormat, false );
m_contentWidth = width;
m_contentHeight = height;
m_bOutputImage = true;
Expand All @@ -2390,7 +2390,7 @@ bool CVulkanTexture::BInitFromSwapchain( VkImage image, uint32_t width, uint32_t
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.image = image,
.viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = ToLinearVulkanFormat( format ),
.format = ToLinearVulkanFormat( m_format ),
.components = {
.r = VK_COMPONENT_SWIZZLE_IDENTITY,
.g = VK_COMPONENT_SWIZZLE_IDENTITY,
Expand All @@ -2416,7 +2416,7 @@ bool CVulkanTexture::BInitFromSwapchain( VkImage image, uint32_t width, uint32_t
};

createInfo.pNext = &viewUsageInfo;
createInfo.format = ToSrgbVulkanFormat( format );
createInfo.format = ToSrgbVulkanFormat( m_format );

res = g_device.vk.CreateImageView(g_device.device(), &createInfo, nullptr, &m_linearView);
if ( res != VK_SUCCESS ) {
Expand Down Expand Up @@ -2806,7 +2806,7 @@ std::shared_ptr<CVulkanTexture> vulkan_create_1d_lut(uint32_t size)
flags.imageType = VK_IMAGE_TYPE_1D;

auto texture = std::make_shared<CVulkanTexture>();
auto drmFormat = VulkanFormatToDRM( VK_FORMAT_R16G16B16A16_UNORM );
auto drmFormat = VulkanFormatToDRM( VK_FORMAT_R16G16B16A16_UNORM, false );
bool bRes = texture->BInit( size, 1u, 1u, drmFormat, flags );
assert( bRes );

Expand All @@ -2821,7 +2821,7 @@ std::shared_ptr<CVulkanTexture> vulkan_create_3d_lut(uint32_t width, uint32_t he
flags.imageType = VK_IMAGE_TYPE_3D;

auto texture = std::make_shared<CVulkanTexture>();
auto drmFormat = VulkanFormatToDRM( VK_FORMAT_R16G16B16A16_UNORM );
auto drmFormat = VulkanFormatToDRM( VK_FORMAT_R16G16B16A16_UNORM, false );
bool bRes = texture->BInit( width, height, depth, drmFormat, flags );
assert( bRes );

Expand Down Expand Up @@ -2860,7 +2860,7 @@ std::shared_ptr<CVulkanTexture> vulkan_create_flat_texture( uint32_t width, uint
flags.bTransferDst = true;

auto texture = std::make_shared<CVulkanTexture>();
bool bRes = texture->BInit( width, height, 1u, VulkanFormatToDRM( VK_FORMAT_B8G8R8A8_UNORM ), flags );
bool bRes = texture->BInit( width, height, 1u, VulkanFormatToDRM( VK_FORMAT_B8G8R8A8_UNORM, true ), flags );
assert( bRes );

uint8_t* dst = (uint8_t *)g_device.uploadBufferData( width * height * 4 );
Expand Down Expand Up @@ -2942,12 +2942,13 @@ bool vulkan_make_swapchain( VulkanOutput_t *pOutput )
if ( surfaceFormat == formatCount )
return false;

pOutput->outputFormat = pOutput->surfaceFormats[ surfaceFormat ].format;
VkFormat format = pOutput->surfaceFormats[ surfaceFormat ].format;
pOutput->outputFormat = VulkanFormatToDRM( format, true );

VkFormat formats[2] =
{
ToSrgbVulkanFormat( pOutput->outputFormat ),
ToLinearVulkanFormat( pOutput->outputFormat ),
ToSrgbVulkanFormat( format ),
ToLinearVulkanFormat( format ),
};

VkImageFormatListCreateInfo usageListInfo = {
Expand All @@ -2964,7 +2965,7 @@ bool vulkan_make_swapchain( VulkanOutput_t *pOutput )
.flags = formats[0] != formats[1] ? VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR : (VkSwapchainCreateFlagBitsKHR )0,
.surface = pOutput->surface,
.minImageCount = imageCount,
.imageFormat = pOutput->outputFormat,
.imageFormat = format,
.imageColorSpace = pOutput->surfaceFormats[surfaceFormat].colorSpace,
.imageExtent = {
.width = g_nOutputWidth,
Expand Down Expand Up @@ -3050,26 +3051,26 @@ static bool vulkan_make_output_images( VulkanOutput_t *pOutput )
pOutput->outputImagesPartialOverlay[1] = nullptr;
pOutput->outputImagesPartialOverlay[2] = nullptr;

VkFormat format = pOutput->outputFormat;
uint32_t drmFormat = pOutput->outputFormat;

pOutput->outputImages[0] = std::make_shared<CVulkanTexture>();
bool bSuccess = pOutput->outputImages[0]->BInit( g_nOutputWidth, g_nOutputHeight, 1u, VulkanFormatToDRM(format), outputImageflags );
bool bSuccess = pOutput->outputImages[0]->BInit( g_nOutputWidth, g_nOutputHeight, 1u, drmFormat, outputImageflags );
if ( bSuccess != true )
{
vk_log.errorf( "failed to allocate buffer for KMS" );
return false;
}

pOutput->outputImages[1] = std::make_shared<CVulkanTexture>();
bSuccess = pOutput->outputImages[1]->BInit( g_nOutputWidth, g_nOutputHeight, 1u, VulkanFormatToDRM(format), outputImageflags );
bSuccess = pOutput->outputImages[1]->BInit( g_nOutputWidth, g_nOutputHeight, 1u, drmFormat, outputImageflags );
if ( bSuccess != true )
{
vk_log.errorf( "failed to allocate buffer for KMS" );
return false;
}

pOutput->outputImages[2] = std::make_shared<CVulkanTexture>();
bSuccess = pOutput->outputImages[2]->BInit( g_nOutputWidth, g_nOutputHeight, 1u, VulkanFormatToDRM(format), outputImageflags );
bSuccess = pOutput->outputImages[2]->BInit( g_nOutputWidth, g_nOutputHeight, 1u, drmFormat, outputImageflags );
if ( bSuccess != true )
{
vk_log.errorf( "failed to allocate buffer for KMS" );
Expand All @@ -3081,26 +3082,26 @@ static bool vulkan_make_output_images( VulkanOutput_t *pOutput )

if ( pOutput->outputFormatOverlay != VK_FORMAT_UNDEFINED && !kDisablePartialComposition )
{
VkFormat partialFormat = pOutput->outputFormatOverlay;
uint32_t partialDrmFormat = pOutput->outputFormatOverlay;

pOutput->outputImagesPartialOverlay[0] = std::make_shared<CVulkanTexture>();
bool bSuccess = pOutput->outputImagesPartialOverlay[0]->BInit( g_nOutputWidth, g_nOutputHeight, 1u, VulkanFormatToDRM(partialFormat), outputImageflags, nullptr, 0, 0, pOutput->outputImages[0].get() );
bool bSuccess = pOutput->outputImagesPartialOverlay[0]->BInit( g_nOutputWidth, g_nOutputHeight, 1u, partialDrmFormat, outputImageflags, nullptr, 0, 0, pOutput->outputImages[0].get() );
if ( bSuccess != true )
{
vk_log.errorf( "failed to allocate buffer for KMS" );
return false;
}

pOutput->outputImagesPartialOverlay[1] = std::make_shared<CVulkanTexture>();
bSuccess = pOutput->outputImagesPartialOverlay[1]->BInit( g_nOutputWidth, g_nOutputHeight, 1u, VulkanFormatToDRM(partialFormat), outputImageflags, nullptr, 0, 0, pOutput->outputImages[1].get() );
bSuccess = pOutput->outputImagesPartialOverlay[1]->BInit( g_nOutputWidth, g_nOutputHeight, 1u, partialDrmFormat, outputImageflags, nullptr, 0, 0, pOutput->outputImages[1].get() );
if ( bSuccess != true )
{
vk_log.errorf( "failed to allocate buffer for KMS" );
return false;
}

pOutput->outputImagesPartialOverlay[2] = std::make_shared<CVulkanTexture>();
bSuccess = pOutput->outputImagesPartialOverlay[2]->BInit( g_nOutputWidth, g_nOutputHeight, 1u, VulkanFormatToDRM(partialFormat), outputImageflags, nullptr, 0, 0, pOutput->outputImages[2].get() );
bSuccess = pOutput->outputImagesPartialOverlay[2]->BInit( g_nOutputWidth, g_nOutputHeight, 1u, partialDrmFormat, outputImageflags, nullptr, 0, 0, pOutput->outputImages[2].get() );
if ( bSuccess != true )
{
vk_log.errorf( "failed to allocate buffer for KMS" );
Expand Down
8 changes: 4 additions & 4 deletions src/rendervulkan.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ class CVulkanTexture
};

bool BInit( uint32_t width, uint32_t height, uint32_t depth, uint32_t drmFormat, createFlags flags, wlr_dmabuf_attributes *pDMA = nullptr, uint32_t contentWidth = 0, uint32_t contentHeight = 0, CVulkanTexture *pExistingImageToReuseMemory = nullptr );
bool BInitFromSwapchain( VkImage image, uint32_t width, uint32_t height, VkFormat format );
bool BInitFromSwapchain( VkImage image, uint32_t width, uint32_t height, uint32_t drmFormat );

inline VkImageView view( bool linear ) { return linear ? m_linearView : m_srgbView; }
inline VkImageView linearView() { return m_linearView; }
Expand Down Expand Up @@ -503,8 +503,8 @@ struct VulkanOutput_t
std::vector<std::shared_ptr<CVulkanTexture>> outputImagesPartialOverlay;
std::shared_ptr<CVulkanTexture> temporaryHackyBlankImage;

VkFormat outputFormat = VK_FORMAT_UNDEFINED;
VkFormat outputFormatOverlay = VK_FORMAT_UNDEFINED;
uint32_t outputFormat = DRM_FORMAT_INVALID;
uint32_t outputFormatOverlay = DRM_FORMAT_INVALID;

std::array<std::shared_ptr<CVulkanTexture>, 2> pScreenshotImages;

Expand Down Expand Up @@ -917,7 +917,7 @@ class CVulkanCmdBuffer
uint32_t m_renderBufferOffset = 0;
};

uint32_t VulkanFormatToDRM( VkFormat vkFormat );
uint32_t VulkanFormatToDRM( VkFormat vkFormat, bool bHasAlpha );
VkFormat DRMFormatToVulkan( uint32_t nDRMFormat, bool bSrgb );
bool DRMFormatHasAlpha( uint32_t nDRMFormat );
uint32_t DRMFormatGetBPP( uint32_t nDRMFormat );
Expand Down
4 changes: 2 additions & 2 deletions src/reshade_effect_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -940,7 +940,7 @@ bool ReshadeEffectPipeline::init(CVulkanDevice *device, const ReshadeEffectKey &
flags.bStorage = true;
flags.bColorAttachment = true;

bool ret = m_rt->BInit(m_key.bufferWidth, m_key.bufferHeight, 1, VulkanFormatToDRM(m_key.bufferFormat), flags, nullptr);
bool ret = m_rt->BInit(m_key.bufferWidth, m_key.bufferHeight, 1, VulkanFormatToDRM(m_key.bufferFormat, true), flags, nullptr);
assert(ret);
}

Expand All @@ -961,7 +961,7 @@ bool ReshadeEffectPipeline::init(CVulkanDevice *device, const ReshadeEffectKey &
assert(tex.levels == 1);
assert(tex.type == reshadefx::texture_type::texture_2d);

bool ret = texture->BInit(tex.width, tex.height, tex.depth, VulkanFormatToDRM(ConvertReshadeFormat(tex.format)), flags, nullptr);
bool ret = texture->BInit(tex.width, tex.height, tex.depth, VulkanFormatToDRM(ConvertReshadeFormat(tex.format), true), flags, nullptr);
assert(ret);
}

Expand Down
8 changes: 4 additions & 4 deletions src/sdlwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ namespace gamescope
virtual std::span<const char *const> GetInstanceExtensions() const override;
virtual std::span<const char *const> GetDeviceExtensions( VkPhysicalDevice pVkPhysicalDevice ) const override;
virtual VkImageLayout GetPresentLayout() const override;
virtual void GetPreferredOutputFormat( VkFormat *pPrimaryPlaneFormat, VkFormat *pOverlayPlaneFormat ) const override;
virtual void GetPreferredOutputFormat( uint32_t *pPrimaryPlaneFormat, uint32_t *pOverlayPlaneFormat ) const override;
virtual bool ValidPhysicalDevice( VkPhysicalDevice pVkPhysicalDevice ) const override;

virtual int Present( const FrameInfo_t *pFrameInfo, bool bAsync ) override;
Expand Down Expand Up @@ -350,10 +350,10 @@ namespace gamescope
return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
}

void CSDLBackend::GetPreferredOutputFormat( VkFormat *pPrimaryPlaneFormat, VkFormat *pOverlayPlaneFormat ) const
void CSDLBackend::GetPreferredOutputFormat( uint32_t *pPrimaryPlaneFormat, uint32_t *pOverlayPlaneFormat ) const
{
*pPrimaryPlaneFormat = VK_FORMAT_A2B10G10R10_UNORM_PACK32;
*pOverlayPlaneFormat = VK_FORMAT_B8G8R8A8_UNORM;
*pPrimaryPlaneFormat = DRM_FORMAT_ABGR2101010;
*pOverlayPlaneFormat = DRM_FORMAT_BGRA8888;
}

bool CSDLBackend::ValidPhysicalDevice( VkPhysicalDevice pVkPhysicalDevice ) const
Expand Down
6 changes: 3 additions & 3 deletions src/vr_session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,10 +409,10 @@ namespace gamescope
{
return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
}
virtual void GetPreferredOutputFormat( VkFormat *pPrimaryPlaneFormat, VkFormat *pOverlayPlaneFormat ) const override
virtual void GetPreferredOutputFormat( uint32_t *pPrimaryPlaneFormat, uint32_t *pOverlayPlaneFormat ) const override
{
*pPrimaryPlaneFormat = VK_FORMAT_A2B10G10R10_UNORM_PACK32;
*pOverlayPlaneFormat = VK_FORMAT_B8G8R8A8_UNORM;
*pPrimaryPlaneFormat = DRM_FORMAT_ABGR2101010;
*pOverlayPlaneFormat = DRM_FORMAT_BGRA8888;
}
virtual bool ValidPhysicalDevice( VkPhysicalDevice pVkPhysicalDevice ) const override
{
Expand Down
20 changes: 10 additions & 10 deletions src/wayland_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ namespace gamescope
virtual std::span<const char *const> GetInstanceExtensions() const override;
virtual std::span<const char *const> GetDeviceExtensions( VkPhysicalDevice pVkPhysicalDevice ) const override;
virtual VkImageLayout GetPresentLayout() const override;
virtual void GetPreferredOutputFormat( VkFormat *pPrimaryPlaneFormat, VkFormat *pOverlayPlaneFormat ) const override;
virtual void GetPreferredOutputFormat( uint32_t *pPrimaryPlaneFormat, uint32_t *pOverlayPlaneFormat ) const override;
virtual bool ValidPhysicalDevice( VkPhysicalDevice pVkPhysicalDevice ) const override;

virtual int Present( const FrameInfo_t *pFrameInfo, bool bAsync ) override;
Expand Down Expand Up @@ -1261,23 +1261,23 @@ namespace gamescope
return VK_IMAGE_LAYOUT_GENERAL;
}

void CWaylandBackend::GetPreferredOutputFormat( VkFormat *pPrimaryPlaneFormat, VkFormat *pOverlayPlaneFormat ) const
void CWaylandBackend::GetPreferredOutputFormat( uint32_t *pPrimaryPlaneFormat, uint32_t *pOverlayPlaneFormat ) const
{
VkFormat u8BitFormat = VK_FORMAT_UNDEFINED;
uint32_t u8BitFormat = DRM_FORMAT_INVALID;
if ( m_FormatModifiers.contains( DRM_FORMAT_ARGB8888 ) )
u8BitFormat = VK_FORMAT_B8G8R8A8_UNORM;
u8BitFormat = DRM_FORMAT_ARGB8888;
else if ( m_FormatModifiers.contains( DRM_FORMAT_ABGR8888 ) )
u8BitFormat = VK_FORMAT_R8G8B8A8_UNORM;
u8BitFormat = DRM_FORMAT_ABGR8888;

VkFormat u10BitFormat = VK_FORMAT_UNDEFINED;
uint32_t u10BitFormat = DRM_FORMAT_INVALID;
if ( m_FormatModifiers.contains( DRM_FORMAT_ABGR2101010 ) )
u10BitFormat = VK_FORMAT_A2B10G10R10_UNORM_PACK32;
u10BitFormat = DRM_FORMAT_ABGR2101010;
else if ( m_FormatModifiers.contains( DRM_FORMAT_ARGB2101010 ) )
u10BitFormat = VK_FORMAT_A2R10G10B10_UNORM_PACK32;
u10BitFormat = DRM_FORMAT_ARGB2101010;

assert( u8BitFormat != VK_FORMAT_UNDEFINED );
assert( u8BitFormat != DRM_FORMAT_INVALID );

*pPrimaryPlaneFormat = u10BitFormat != VK_FORMAT_UNDEFINED ? u10BitFormat : u8BitFormat;
*pPrimaryPlaneFormat = u10BitFormat != DRM_FORMAT_INVALID ? u10BitFormat : u8BitFormat;
*pOverlayPlaneFormat = u8BitFormat;
}

Expand Down