Remove those two terrible structs

This commit is contained in:
Georg Lehmann 2022-05-04 22:58:20 +02:00 committed by Joshie
parent d760586543
commit d29d83f792
6 changed files with 295 additions and 281 deletions

View file

@ -818,7 +818,7 @@ void finish_drm(struct drm_t *drm)
// page-flip handler thread. // page-flip handler thread.
} }
int drm_commit(struct drm_t *drm, struct Composite_t *pComposite, struct VulkanPipeline_t *pPipeline ) int drm_commit(struct drm_t *drm, const struct FrameInfo_t *frameInfo )
{ {
int ret; int ret;
@ -1080,25 +1080,25 @@ void drm_unlock_fbid( struct drm_t *drm, uint32_t fbid )
/* Prepares an atomic commit without using libliftoff */ /* Prepares an atomic commit without using libliftoff */
static int static int
drm_prepare_basic( struct drm_t *drm, const struct Composite_t *pComposite, const struct VulkanPipeline_t *pPipeline ) drm_prepare_basic( struct drm_t *drm, const struct FrameInfo_t *frameInfo )
{ {
// Discard cases where our non-liftoff path is known to fail // Discard cases where our non-liftoff path is known to fail
// It only supports one layer // It only supports one layer
if ( pComposite->nLayerCount > 1 ) if ( frameInfo->layerCount > 1 )
{ {
drm_verbose_log.errorf("drm_prepare_basic: cannot handle %d layers", pComposite->nLayerCount); drm_verbose_log.errorf("drm_prepare_basic: cannot handle %d layers", frameInfo->layerCount);
return -EINVAL; return -EINVAL;
} }
if ( pPipeline->layerBindings[ 0 ].fbid == 0 ) if ( frameInfo->layers[ 0 ].fbid == 0 )
{ {
drm_verbose_log.errorf("drm_prepare_basic: layer has no FB"); drm_verbose_log.errorf("drm_prepare_basic: layer has no FB");
return -EINVAL; return -EINVAL;
} }
drmModeAtomicReq *req = drm->req; drmModeAtomicReq *req = drm->req;
uint32_t fb_id = pPipeline->layerBindings[ 0 ].fbid; uint32_t fb_id = frameInfo->layers[ 0 ].fbid;
drm->fbids_in_req.push_back( fb_id ); drm->fbids_in_req.push_back( fb_id );
@ -1109,8 +1109,8 @@ drm_prepare_basic( struct drm_t *drm, const struct Composite_t *pComposite, cons
add_plane_property(req, drm->primary, "SRC_X", 0); add_plane_property(req, drm->primary, "SRC_X", 0);
add_plane_property(req, drm->primary, "SRC_Y", 0); add_plane_property(req, drm->primary, "SRC_Y", 0);
const uint16_t srcWidth = pPipeline->layerBindings[ 0 ].surfaceWidth; const uint16_t srcWidth = frameInfo->layers[ 0 ].tex->m_width;
const uint16_t srcHeight = pPipeline->layerBindings[ 0 ].surfaceHeight; const uint16_t srcHeight = frameInfo->layers[ 0 ].tex->m_height;
add_plane_property(req, drm->primary, "SRC_W", srcWidth << 16); add_plane_property(req, drm->primary, "SRC_W", srcWidth << 16);
add_plane_property(req, drm->primary, "SRC_H", srcHeight << 16); add_plane_property(req, drm->primary, "SRC_H", srcHeight << 16);
@ -1118,14 +1118,14 @@ drm_prepare_basic( struct drm_t *drm, const struct Composite_t *pComposite, cons
gpuvis_trace_printf ( "legacy flip fb_id %u src %ix%i", fb_id, gpuvis_trace_printf ( "legacy flip fb_id %u src %ix%i", fb_id,
srcWidth, srcHeight ); srcWidth, srcHeight );
int64_t crtcX = pComposite->data.vOffset[ 0 ].x * -1; int64_t crtcX = frameInfo->layers[ 0 ].offset.x * -1;
int64_t crtcY = pComposite->data.vOffset[ 0 ].y * -1; int64_t crtcY = frameInfo->layers[ 0 ].offset.y * -1;
int64_t crtcW = pPipeline->layerBindings[ 0 ].surfaceWidth / pComposite->data.vScale[ 0 ].x; int64_t crtcW = srcWidth / frameInfo->layers[ 0 ].scale.x;
int64_t crtcH = pPipeline->layerBindings[ 0 ].surfaceHeight / pComposite->data.vScale[ 0 ].y; int64_t crtcH = srcHeight / frameInfo->layers[ 0 ].scale.y;
if ( g_bRotated ) if ( g_bRotated )
{ {
int64_t imageH = pPipeline->layerBindings[ 0 ].imageHeight / pComposite->data.vScale[ 0 ].y; int64_t imageH = frameInfo->layers[ 0 ].imageHeight / frameInfo->layers[ 0 ].scale.y;
int64_t tmp = crtcX; int64_t tmp = crtcX;
crtcX = g_nOutputHeight - imageH - crtcY; crtcX = g_nOutputHeight - imageH - crtcY;
@ -1156,39 +1156,39 @@ drm_prepare_basic( struct drm_t *drm, const struct Composite_t *pComposite, cons
} }
static int static int
drm_prepare_liftoff( struct drm_t *drm, const struct Composite_t *pComposite, const struct VulkanPipeline_t *pPipeline ) drm_prepare_liftoff( struct drm_t *drm, const struct FrameInfo_t *frameInfo )
{ {
for ( int i = 0; i < k_nMaxLayers; i++ ) for ( int i = 0; i < k_nMaxLayers; i++ )
{ {
if ( i < pComposite->nLayerCount ) if ( i < frameInfo->layerCount )
{ {
if ( pPipeline->layerBindings[ i ].fbid == 0 ) if ( frameInfo->layers[ i ].fbid == 0 )
{ {
drm_verbose_log.errorf("drm_prepare_liftoff: layer %d has no FB", i ); drm_verbose_log.errorf("drm_prepare_liftoff: layer %d has no FB", i );
return -EINVAL; return -EINVAL;
} }
liftoff_layer_set_property( drm->lo_layers[ i ], "FB_ID", pPipeline->layerBindings[ i ].fbid); liftoff_layer_set_property( drm->lo_layers[ i ], "FB_ID", frameInfo->layers[ i ].fbid);
drm->fbids_in_req.push_back( pPipeline->layerBindings[ i ].fbid ); drm->fbids_in_req.push_back( frameInfo->layers[ i ].fbid );
liftoff_layer_set_property( drm->lo_layers[ i ], "zpos", pPipeline->layerBindings[ i ].zpos ); liftoff_layer_set_property( drm->lo_layers[ i ], "zpos", frameInfo->layers[ i ].zpos );
liftoff_layer_set_property( drm->lo_layers[ i ], "alpha", pComposite->data.flOpacity[ i ] * 0xffff); liftoff_layer_set_property( drm->lo_layers[ i ], "alpha", frameInfo->layers[ i ].opacity * 0xffff);
const uint16_t srcWidth = pPipeline->layerBindings[ i ].surfaceWidth; const uint16_t srcWidth = frameInfo->layers[ i ].tex->m_width;
const uint16_t srcHeight = pPipeline->layerBindings[ i ].surfaceHeight; const uint16_t srcHeight = frameInfo->layers[ i ].tex->m_height;
liftoff_layer_set_property( drm->lo_layers[ i ], "SRC_X", 0); liftoff_layer_set_property( drm->lo_layers[ i ], "SRC_X", 0);
liftoff_layer_set_property( drm->lo_layers[ i ], "SRC_Y", 0); liftoff_layer_set_property( drm->lo_layers[ i ], "SRC_Y", 0);
liftoff_layer_set_property( drm->lo_layers[ i ], "SRC_W", srcWidth << 16); liftoff_layer_set_property( drm->lo_layers[ i ], "SRC_W", srcWidth << 16);
liftoff_layer_set_property( drm->lo_layers[ i ], "SRC_H", srcHeight << 16); liftoff_layer_set_property( drm->lo_layers[ i ], "SRC_H", srcHeight << 16);
int32_t crtcX = -pComposite->data.vOffset[ i ].x; int32_t crtcX = -frameInfo->layers[ i ].offset.x;
int32_t crtcY = -pComposite->data.vOffset[ i ].y; int32_t crtcY = -frameInfo->layers[ i ].offset.y;
uint64_t crtcW = srcWidth / pComposite->data.vScale[ i ].x; uint64_t crtcW = srcWidth / frameInfo->layers[ i ].scale.x;
uint64_t crtcH = srcHeight / pComposite->data.vScale[ i ].y; uint64_t crtcH = srcHeight / frameInfo->layers[ i ].scale.y;
if (g_bRotated) { if (g_bRotated) {
int64_t imageH = pPipeline->layerBindings[ i ].imageHeight / pComposite->data.vScale[ i ].y; int64_t imageH = frameInfo->layers[ i ].imageHeight / frameInfo->layers[ i ].scale.y;
const int32_t x = crtcX; const int32_t x = crtcX;
const uint64_t w = crtcW; const uint64_t w = crtcW;
@ -1222,16 +1222,16 @@ drm_prepare_liftoff( struct drm_t *drm, const struct Composite_t *pComposite, co
} }
if ( ret == 0 ) if ( ret == 0 )
drm_verbose_log.debugf( "can drm present %i layers", pComposite->nLayerCount ); drm_verbose_log.debugf( "can drm present %i layers", frameInfo->layerCount );
else else
drm_verbose_log.debugf( "can NOT drm present %i layers", pComposite->nLayerCount ); drm_verbose_log.debugf( "can NOT drm present %i layers", frameInfo->layerCount );
return ret; return ret;
} }
/* Prepares an atomic commit for the provided scene-graph. Returns false on /* Prepares an atomic commit for the provided scene-graph. Returns false on
* error or if the scene-graph can't be presented directly. */ * error or if the scene-graph can't be presented directly. */
int drm_prepare( struct drm_t *drm, const struct Composite_t *pComposite, const struct VulkanPipeline_t *pPipeline ) int drm_prepare( struct drm_t *drm, const struct FrameInfo_t *frameInfo )
{ {
drm_update_gamma_lut(drm); drm_update_gamma_lut(drm);
@ -1297,9 +1297,9 @@ int drm_prepare( struct drm_t *drm, const struct Composite_t *pComposite, const
int ret; int ret;
if ( g_bUseLayers == true ) { if ( g_bUseLayers == true ) {
ret = drm_prepare_liftoff( drm, pComposite, pPipeline ); ret = drm_prepare_liftoff( drm, frameInfo );
} else { } else {
ret = drm_prepare_basic( drm, pComposite, pPipeline ); ret = drm_prepare_basic( drm, frameInfo );
} }
if ( ret != 0 ) { if ( ret != 0 ) {

View file

@ -145,8 +145,8 @@ extern enum drm_mode_generation g_drmModeGeneration;
bool init_drm(struct drm_t *drm, int width, int height, int refresh); bool init_drm(struct drm_t *drm, int width, int height, int refresh);
void finish_drm(struct drm_t *drm); void finish_drm(struct drm_t *drm);
int drm_commit(struct drm_t *drm, struct Composite_t *pComposite, struct VulkanPipeline_t *pPipeline ); int drm_commit(struct drm_t *drm, const struct FrameInfo_t *frameInfo );
int drm_prepare( struct drm_t *drm, const struct Composite_t *pComposite, const struct VulkanPipeline_t *pPipeline ); int drm_prepare( struct drm_t *drm, const struct FrameInfo_t *frameInfo );
void drm_rollback( struct drm_t *drm ); void drm_rollback( struct drm_t *drm );
bool drm_poll_state(struct drm_t *drm); bool drm_poll_state(struct drm_t *drm);
uint32_t drm_fbid_from_dmabuf( struct drm_t *drm, struct wlr_buffer *buf, struct wlr_dmabuf_attributes *dma_buf ); uint32_t drm_fbid_from_dmabuf( struct drm_t *drm, struct wlr_buffer *buf, struct wlr_dmabuf_attributes *dma_buf );

View file

@ -1562,7 +1562,7 @@ retry:
VkPushConstantRange pushConstantRange = { VkPushConstantRange pushConstantRange = {
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
.offset = 0, .offset = 0,
.size = uint32_t(sizeof(Composite_t::CompositeData_t) + sizeof(uint32_t)), .size = 128,
}; };
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = { VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
@ -2305,7 +2305,7 @@ bool float_is_integer(float x)
static uint32_t s_frameId = 0; static uint32_t s_frameId = 0;
VkDescriptorSet vulkan_update_descriptor( struct VulkanPipeline_t *pPipeline, int nYCBCRMask, bool firstNrm, bool firstSrgb, VkImageView targetImageView, VkImageView extraImageView = VK_NULL_HANDLE) VkDescriptorSet vulkan_update_descriptor( const struct FrameInfo_t *frameInfo, bool firstNrm, bool firstSrgb, VkImageView targetImageView, VkImageView extraImageView = VK_NULL_HANDLE)
{ {
VkDescriptorSet descriptorSet = descriptorSets[nCurrentDescriptorSet]; VkDescriptorSet descriptorSet = descriptorSets[nCurrentDescriptorSet];
nCurrentDescriptorSet = (nCurrentDescriptorSet + 1) % descriptorSets.size(); nCurrentDescriptorSet = (nCurrentDescriptorSet + 1) % descriptorSets.size();
@ -2337,12 +2337,12 @@ VkDescriptorSet vulkan_update_descriptor( struct VulkanPipeline_t *pPipeline, in
{ {
bool compositeLayer = i > 0; bool compositeLayer = i > 0;
VkImageView imageView = pPipeline->layerBindings[ i ].tex VkImageView imageView = frameInfo->layers[i].tex
? pPipeline->layerBindings[ i ].tex->getView(compositeLayer || !firstSrgb) ? frameInfo->layers[i].tex->getView(compositeLayer || !firstSrgb)
: VK_NULL_HANDLE; : VK_NULL_HANDLE;
VulkanSamplerCacheKey_t samplerKey; VulkanSamplerCacheKey_t samplerKey;
samplerKey.bNearest = !pPipeline->layerBindings[i].bFilter; samplerKey.bNearest = !frameInfo->layers[i].linearFilter;
samplerKey.bUnnormalized = compositeLayer || !firstNrm; samplerKey.bUnnormalized = compositeLayer || !firstNrm;
VkSampler sampler = vulkan_make_sampler(samplerKey); VkSampler sampler = vulkan_make_sampler(samplerKey);
@ -2364,7 +2364,7 @@ VkDescriptorSet vulkan_update_descriptor( struct VulkanPipeline_t *pPipeline, in
for (uint32_t i = 0; i < k_nMaxLayers; i++) for (uint32_t i = 0; i < k_nMaxLayers; i++)
{ {
if ( nYCBCRMask & ( 1u << i ) ) if ( frameInfo->ycbcrMask() & ( 1u << i ) )
{ {
ycbcrImageDescriptors[i] = imageDescriptors[i]; ycbcrImageDescriptors[i] = imageDescriptors[i];
// We use immutable samplers. // We use immutable samplers.
@ -2457,7 +2457,30 @@ std::shared_ptr<CVulkanTexture> vulkan_acquire_screenshot_texture(bool exportabl
return nullptr; return nullptr;
} }
bool vulkan_composite( struct Composite_t *pComposite, struct VulkanPipeline_t *pPipeline, std::shared_ptr<CVulkanTexture> pScreenshotTexture ) struct CompositeData_t
{
vec2_t scale[k_nMaxLayers];
vec2_t offset[k_nMaxLayers];
float opacity[k_nMaxLayers];
uint32_t borderMask;
uint32_t frameId;
};
static CompositeData_t pack_composite_data( const struct FrameInfo_t *frameInfo )
{
CompositeData_t result = {};
for (int i = 0; i < frameInfo->layerCount; i++) {
const FrameInfo_t::Layer_t *layer = &frameInfo->layers[i];
result.scale[i] = layer->scale;
result.offset[i] = layer->offset;
result.opacity[i] = layer->opacity;
}
result.borderMask = frameInfo->borderMask();
result.frameId = s_frameId++;
return result;
}
bool vulkan_composite( struct FrameInfo_t *frameInfo, std::shared_ptr<CVulkanTexture> pScreenshotTexture )
{ {
VkImage compositeImage; VkImage compositeImage;
VkImageView targetImageView; VkImageView targetImageView;
@ -2473,17 +2496,6 @@ bool vulkan_composite( struct Composite_t *pComposite, struct VulkanPipeline_t *
targetImageView = g_output.outputImage[ g_output.nOutImage ]->m_srgbView; targetImageView = g_output.outputImage[ g_output.nOutImage ]->m_srgbView;
} }
pComposite->nYCBCRMask = 0;
for (uint32_t i = 0; i < k_nMaxLayers; i++)
{
if ( pPipeline->layerBindings[ i ].tex != 0 )
{
const auto& pTex = pPipeline->layerBindings[ i ].tex;
if (pTex->m_format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM)
pComposite->nYCBCRMask |= 1 << i;
}
}
VkCommandBuffer curCommandBuffer = g_output.commandBuffers[ g_output.nCurCmdBuffer ]; VkCommandBuffer curCommandBuffer = g_output.commandBuffers[ g_output.nCurCmdBuffer ];
VkCommandBufferBeginInfo commandBufferBeginInfo = { VkCommandBufferBeginInfo commandBufferBeginInfo = {
@ -2537,8 +2549,8 @@ bool vulkan_composite( struct Composite_t *pComposite, struct VulkanPipeline_t *
vkCmdPipelineBarrier( curCommandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vkCmdPipelineBarrier( curCommandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
0, 0, nullptr, 0, nullptr, 1, &memoryBarrier ); 0, 0, nullptr, 0, nullptr, 1, &memoryBarrier );
std::vector<VkImageMemoryBarrier> textureBarriers(pComposite->nLayerCount); std::vector<VkImageMemoryBarrier> textureBarriers(frameInfo->layerCount);
for (int32_t i = 0; i < pComposite->nLayerCount; i++) for (int32_t i = 0; i < frameInfo->layerCount; i++)
{ {
textureBarriers[i].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; textureBarriers[i].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
textureBarriers[i].pNext = nullptr; textureBarriers[i].pNext = nullptr;
@ -2550,28 +2562,30 @@ bool vulkan_composite( struct Composite_t *pComposite, struct VulkanPipeline_t *
? VK_QUEUE_FAMILY_FOREIGN_EXT ? VK_QUEUE_FAMILY_FOREIGN_EXT
: VK_QUEUE_FAMILY_EXTERNAL_KHR; : VK_QUEUE_FAMILY_EXTERNAL_KHR;
textureBarriers[i].dstQueueFamilyIndex = queueFamilyIndex; textureBarriers[i].dstQueueFamilyIndex = queueFamilyIndex;
textureBarriers[i].image = pPipeline->layerBindings[i].tex->m_vkImage; textureBarriers[i].image = frameInfo->layers[i].tex->m_vkImage;
textureBarriers[i].subresourceRange = subResRange; textureBarriers[i].subresourceRange = subResRange;
} }
vkCmdPipelineBarrier( curCommandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vkCmdPipelineBarrier( curCommandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
0, 0, nullptr, 0, nullptr, textureBarriers.size(), textureBarriers.data() ); 0, 0, nullptr, 0, nullptr, textureBarriers.size(), textureBarriers.data() );
for ( int i = pComposite->useFSRLayer0 ? 1 : 0; i < pComposite->nLayerCount; i++ ) for ( int i = frameInfo->useFSRLayer0 ? 1 : 0; i < frameInfo->layerCount; i++ )
{ {
bool bForceNearest = pComposite->data.vScale[i].x == 1.0f && FrameInfo_t::Layer_t *layer = &frameInfo->layers[i];
pComposite->data.vScale[i].y == 1.0f &&
float_is_integer(pComposite->data.vOffset[i].x) &&
float_is_integer(pComposite->data.vOffset[i].y);
pPipeline->layerBindings[i].bFilter &= !bForceNearest; bool bForceNearest = layer->scale.x == 1.0f &&
layer->scale.y == 1.0f &&
float_is_integer(layer->offset.x) &&
float_is_integer(layer->offset.y);
pComposite->data.vOffset[ i ].x += 0.5f / pComposite->data.vScale[ i ].x; layer->linearFilter &= !bForceNearest;
pComposite->data.vOffset[ i ].y += 0.5f / pComposite->data.vScale[ i ].y;
layer->offset.x += 0.5f / layer->scale.x;
layer->offset.y += 0.5f / layer->scale.y;
} }
if ( pComposite->useFSRLayer0 ) if ( frameInfo->useFSRLayer0 )
{ {
struct uvec4_t struct uvec4_t
{ {
@ -2605,15 +2619,14 @@ bool vulkan_composite( struct Composite_t *pComposite, struct VulkanPipeline_t *
uint32_t u_c1; uint32_t u_c1;
} rcasConstants; } rcasConstants;
struct Composite_t fsrpComposite = *pComposite; struct FrameInfo_t fsrFrameInfo = *frameInfo;
struct VulkanPipeline_t fsrLayers = *pPipeline; fsrFrameInfo.layers[0].linearFilter = true;
fsrLayers.layerBindings[0].bFilter = true;
uint32_t inputX = fsrLayers.layerBindings[0].tex->m_width; uint32_t inputX = fsrFrameInfo.layers[0].tex->m_width;
uint32_t inputY = fsrLayers.layerBindings[0].tex->m_height; uint32_t inputY = fsrFrameInfo.layers[0].tex->m_height;
uint32_t tempX = float(inputX) / fsrpComposite.data.vScale[0].x; uint32_t tempX = fsrFrameInfo.layers[0].integerWidth();
uint32_t tempY = float(inputY) / fsrpComposite.data.vScale[0].y; uint32_t tempY = fsrFrameInfo.layers[0].integerHeight();
update_tmp_images(tempX, tempY); update_tmp_images(tempX, tempY);
@ -2623,7 +2636,7 @@ bool vulkan_composite( struct Composite_t *pComposite, struct VulkanPipeline_t *
vkCmdBindPipeline(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, easuPipeline); vkCmdBindPipeline(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, easuPipeline);
VkDescriptorSet descriptorSet = vulkan_update_descriptor( &fsrLayers, 0, true, true, g_output.tmpOutput->m_srgbView ); VkDescriptorSet descriptorSet = vulkan_update_descriptor( &fsrFrameInfo, true, true, g_output.tmpOutput->m_srgbView );
vkCmdBindDescriptorSets(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0, 1, &descriptorSet, 0, 0); vkCmdBindDescriptorSets(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0, 1, &descriptorSet, 0, 0);
@ -2655,25 +2668,25 @@ bool vulkan_composite( struct Composite_t *pComposite, struct VulkanPipeline_t *
0, 0, nullptr, 0, nullptr, 1, &memoryBarrier ); 0, 0, nullptr, 0, nullptr, 1, &memoryBarrier );
vkCmdBindPipeline(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, get_vk_pipeline(pComposite->nLayerCount - 1, pComposite->nYCBCRMask, 0, SHADER_TYPE_RCAS)); vkCmdBindPipeline(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, get_vk_pipeline(frameInfo->layerCount - 1, frameInfo->ycbcrMask(), 0, SHADER_TYPE_RCAS));
fsrLayers.layerBindings[0].tex = g_output.tmpOutput; fsrFrameInfo.layers[0].tex = g_output.tmpOutput;
descriptorSet = vulkan_update_descriptor( &fsrLayers, 0, true, true, targetImageView ); descriptorSet = vulkan_update_descriptor( &fsrFrameInfo, true, true, targetImageView );
vkCmdBindDescriptorSets(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0, 1, &descriptorSet, 0, 0); vkCmdBindDescriptorSets(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0, 1, &descriptorSet, 0, 0);
uvec4_t tmp; uvec4_t tmp;
FsrRcasCon(&tmp.x, g_fsrSharpness / 10.0f); FsrRcasCon(&tmp.x, g_fsrSharpness / 10.0f);
rcasConstants.u_layer0Offset.x = uint32_t(int32_t(fsrpComposite.data.vOffset[0].x)); rcasConstants.u_layer0Offset.x = uint32_t(int32_t(fsrFrameInfo.layers[0].offset.x));
rcasConstants.u_layer0Offset.y = uint32_t(int32_t(fsrpComposite.data.vOffset[0].y)); rcasConstants.u_layer0Offset.y = uint32_t(int32_t(fsrFrameInfo.layers[0].offset.y));
rcasConstants.u_opacity[0] = fsrpComposite.data.flOpacity[0]; rcasConstants.u_opacity[0] = fsrFrameInfo.layers[0].opacity;
rcasConstants.u_borderMask = fsrpComposite.data.nBorderMask >> 1u; rcasConstants.u_borderMask = fsrFrameInfo.borderMask() >> 1u;
rcasConstants.u_frameId = s_frameId++; rcasConstants.u_frameId = s_frameId++;
rcasConstants.u_c1 = tmp.x; rcasConstants.u_c1 = tmp.x;
for (uint32_t i = 1; i < k_nMaxLayers; i++) for (uint32_t i = 1; i < k_nMaxLayers; i++)
{ {
rcasConstants.u_scale[i - 1] = fsrpComposite.data.vScale[i]; rcasConstants.u_scale[i - 1] = fsrFrameInfo.layers[i].scale;
rcasConstants.u_offset[i - 1] = fsrpComposite.data.vOffset[i]; rcasConstants.u_offset[i - 1] = fsrFrameInfo.layers[i].offset;
rcasConstants.u_opacity[i] = fsrpComposite.data.flOpacity[i]; rcasConstants.u_opacity[i] = fsrFrameInfo.layers[i].opacity;
} }
@ -2684,11 +2697,10 @@ bool vulkan_composite( struct Composite_t *pComposite, struct VulkanPipeline_t *
vkCmdDispatch( curCommandBuffer, dispatchX, dispatchY, 1 ); vkCmdDispatch( curCommandBuffer, dispatchX, dispatchY, 1 );
} }
else if ( pComposite->blurLayer0 ) else if ( frameInfo->blurLayer0 )
{ {
struct Composite_t blurComposite = *pComposite; struct FrameInfo_t blurFrameInfo = *frameInfo;
struct VulkanPipeline_t blurLayers = *pPipeline; blurFrameInfo.layers[0].linearFilter = true;
blurLayers.layerBindings[0].bFilter = true;
update_tmp_images(currentOutputWidth, currentOutputHeight); update_tmp_images(currentOutputWidth, currentOutputHeight);
@ -2700,17 +2712,19 @@ bool vulkan_composite( struct Composite_t *pComposite, struct VulkanPipeline_t *
uint32_t blur_layer_count = 0; uint32_t blur_layer_count = 0;
// Also blur the override on top if we have one. // Also blur the override on top if we have one.
if (blurComposite.nLayerCount >= 2 && blurLayers.layerBindings[1].zpos == g_zposOverride) if (blurFrameInfo.layerCount >= 2 && blurFrameInfo.layers[1].zpos == g_zposOverride)
blur_layer_count++; blur_layer_count++;
vkCmdBindPipeline(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, get_vk_pipeline(blur_layer_count, blurComposite.nYCBCRMask & 0x1u, blurComposite.blurRadius, type)); vkCmdBindPipeline(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, get_vk_pipeline(blur_layer_count, blurFrameInfo.ycbcrMask() & 0x1u, blurFrameInfo.blurRadius, type));
VkDescriptorSet descriptorSet = vulkan_update_descriptor( &blurLayers, pComposite->nYCBCRMask, false, false, g_output.tmpOutput->m_srgbView ); VkDescriptorSet descriptorSet = vulkan_update_descriptor( &blurFrameInfo, false, false, g_output.tmpOutput->m_srgbView );
vkCmdBindDescriptorSets(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, vkCmdBindDescriptorSets(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE,
pipelineLayout, 0, 1, &descriptorSet, 0, 0); pipelineLayout, 0, 1, &descriptorSet, 0, 0);
vkCmdPushConstants(curCommandBuffer, pipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(blurComposite.data), &blurComposite.data); CompositeData_t data = pack_composite_data(frameInfo);
vkCmdPushConstants(curCommandBuffer, pipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(data), &data);
uint32_t nGroupCountX = currentOutputWidth % 8 ? currentOutputWidth / 8 + 1: currentOutputWidth / 8; uint32_t nGroupCountX = currentOutputWidth % 8 ? currentOutputWidth / 8 + 1: currentOutputWidth / 8;
uint32_t nGroupCountY = currentOutputHeight % 8 ? currentOutputHeight / 8 + 1: currentOutputHeight / 8; uint32_t nGroupCountY = currentOutputHeight % 8 ? currentOutputHeight / 8 + 1: currentOutputHeight / 8;
@ -2733,19 +2747,15 @@ bool vulkan_composite( struct Composite_t *pComposite, struct VulkanPipeline_t *
vkCmdPipelineBarrier( curCommandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vkCmdPipelineBarrier( curCommandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
0, 0, nullptr, 0, nullptr, 1, &memoryBarrier ); 0, 0, nullptr, 0, nullptr, 1, &memoryBarrier );
descriptorSet = vulkan_update_descriptor( &blurLayers, blurComposite.nYCBCRMask, false, false, targetImageView, g_output.tmpOutput->m_linearView ); descriptorSet = vulkan_update_descriptor( &blurFrameInfo, false, false, targetImageView, g_output.tmpOutput->m_linearView );
vkCmdBindDescriptorSets(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0, 1, &descriptorSet, 0, 0); vkCmdBindDescriptorSets(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0, 1, &descriptorSet, 0, 0);
type = pComposite->blurLayer0 == BLUR_MODE_COND ? SHADER_TYPE_BLUR_COND : SHADER_TYPE_BLUR; type = blurFrameInfo.blurLayer0 == BLUR_MODE_COND ? SHADER_TYPE_BLUR_COND : SHADER_TYPE_BLUR;
vkCmdBindPipeline(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, get_vk_pipeline(blurComposite.nLayerCount - 1, blurComposite.nYCBCRMask, blurComposite.blurRadius, type, blur_layer_count)); vkCmdBindPipeline(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, get_vk_pipeline(blurFrameInfo.layerCount - 1, blurFrameInfo.ycbcrMask(), blurFrameInfo.blurRadius, type, blur_layer_count));
vkCmdPushConstants(curCommandBuffer, pipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(blurComposite.data), &blurComposite.data); vkCmdPushConstants(curCommandBuffer, pipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(data), &data);
if (g_bIsCompositeDebug) {
vkCmdPushConstants(curCommandBuffer, pipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, sizeof(blurComposite.data), sizeof(uint32_t), &s_frameId);
s_frameId++;
}
nGroupCountX = currentOutputWidth % 8 ? currentOutputWidth / 8 + 1: currentOutputWidth / 8; nGroupCountX = currentOutputWidth % 8 ? currentOutputWidth / 8 + 1: currentOutputWidth / 8;
nGroupCountY = currentOutputHeight % 8 ? currentOutputHeight / 8 + 1: currentOutputHeight / 8; nGroupCountY = currentOutputHeight % 8 ? currentOutputHeight / 8 + 1: currentOutputHeight / 8;
@ -2755,18 +2765,16 @@ bool vulkan_composite( struct Composite_t *pComposite, struct VulkanPipeline_t *
else else
{ {
vkCmdBindPipeline(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, get_vk_pipeline(pComposite->nLayerCount - 1, pComposite->nYCBCRMask, 0, SHADER_TYPE_BLIT)); vkCmdBindPipeline(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, get_vk_pipeline(frameInfo->layerCount - 1, frameInfo->ycbcrMask(), 0, SHADER_TYPE_BLIT));
VkDescriptorSet descriptorSet = vulkan_update_descriptor( pPipeline, pComposite->nYCBCRMask, false, false, targetImageView ); VkDescriptorSet descriptorSet = vulkan_update_descriptor( frameInfo, false, false, targetImageView );
vkCmdBindDescriptorSets(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, vkCmdBindDescriptorSets(curCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE,
pipelineLayout, 0, 1, &descriptorSet, 0, 0); pipelineLayout, 0, 1, &descriptorSet, 0, 0);
vkCmdPushConstants(curCommandBuffer, pipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(pComposite->data), &pComposite->data); CompositeData_t data = pack_composite_data(frameInfo);
if (g_bIsCompositeDebug) {
vkCmdPushConstants(curCommandBuffer, pipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, sizeof(pComposite->data), sizeof(uint32_t), &s_frameId); vkCmdPushConstants(curCommandBuffer, pipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(data), &data);
s_frameId++;
}
uint32_t nGroupCountX = currentOutputWidth % 8 ? currentOutputWidth / 8 + 1: currentOutputWidth / 8; uint32_t nGroupCountX = currentOutputWidth % 8 ? currentOutputWidth / 8 + 1: currentOutputWidth / 8;
uint32_t nGroupCountY = currentOutputHeight % 8 ? currentOutputHeight / 8 + 1: currentOutputHeight / 8; uint32_t nGroupCountY = currentOutputHeight % 8 ? currentOutputHeight / 8 + 1: currentOutputHeight / 8;
@ -2862,7 +2870,7 @@ bool vulkan_composite( struct Composite_t *pComposite, struct VulkanPipeline_t *
useForeignQueue ? 0 : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, useForeignQueue ? 0 : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
0, 0, nullptr, 0, nullptr, 1, &memoryBarrier ); 0, 0, nullptr, 0, nullptr, 1, &memoryBarrier );
for (int32_t i = 0; i < pComposite->nLayerCount; i++) for (int32_t i = 0; i < frameInfo->layerCount; i++)
{ {
textureBarriers[i].dstAccessMask = 0; textureBarriers[i].dstAccessMask = 0;
textureBarriers[i].oldLayout = VK_IMAGE_LAYOUT_GENERAL; textureBarriers[i].oldLayout = VK_IMAGE_LAYOUT_GENERAL;
@ -2913,9 +2921,9 @@ bool vulkan_composite( struct Composite_t *pComposite, struct VulkanPipeline_t *
return true; return true;
} }
uint32_t vulkan_get_last_composite_fbid( void ) std::shared_ptr<CVulkanTexture> vulkan_get_last_output_image( void )
{ {
return g_output.outputImage[ !g_output.nOutImage ]->m_FBID; return g_output.outputImage[ !g_output.nOutImage ];
} }
uint32_t vulkan_texture_get_fbid( const std::shared_ptr<CVulkanTexture>& vulkanTex ) uint32_t vulkan_texture_get_fbid( const std::shared_ptr<CVulkanTexture>& vulkanTex )

View file

@ -34,50 +34,6 @@ enum BlurMode {
BLUR_MODE_ALWAYS = 2, BLUR_MODE_ALWAYS = 2,
}; };
class CVulkanTexture;
// These two structs are horrible
struct VulkanPipeline_t
{
struct LayerBinding_t
{
int surfaceWidth;
int surfaceHeight;
int imageWidth;
int imageHeight;
std::shared_ptr<CVulkanTexture> tex;
uint32_t fbid;
int zpos;
bool bFilter;
} layerBindings[ k_nMaxLayers ];
};
struct vec2_t
{
float x, y;
};
struct Composite_t
{
int nLayerCount;
int nYCBCRMask;
bool useFSRLayer0;
BlurMode blurLayer0;
int blurRadius;
struct CompositeData_t
{
vec2_t vScale[k_nMaxLayers];
vec2_t vOffset[k_nMaxLayers];
float flOpacity[k_nMaxLayers];
uint32_t nBorderMask;
} data;
};
#include "drm.hpp" #include "drm.hpp"
@ -169,6 +125,66 @@ public:
bool m_bTransitioned = false; bool m_bTransitioned = false;
}; };
struct vec2_t
{
float x, y;
};
struct FrameInfo_t
{
bool useFSRLayer0;
BlurMode blurLayer0;
int blurRadius;
int layerCount;
struct Layer_t
{
std::shared_ptr<CVulkanTexture> tex;
uint32_t fbid; // TODO pretty sure we can just move this into tex
// Cursor has a bigger surface than the actual image
// TODO maybe move into tex?
int imageWidth;
int imageHeight;
int zpos;
vec2_t offset;
vec2_t scale;
float opacity;
bool blackBorder;
bool linearFilter;
uint32_t integerWidth() const { return tex->m_width / scale.x; }
uint32_t integerHeight() const { return tex->m_height / scale.y; }
} layers[ k_nMaxLayers ];
uint32_t borderMask() const {
uint32_t result = 0;
for (int i = 0; i < layerCount; i++)
{
if (layers[ i ].blackBorder)
result |= 1 << i;
}
return result;
}
uint32_t ycbcrMask() const {
uint32_t result = 0;
for (int i = 0; i < layerCount; i++)
{
if ( layers[ i ].tex )
{
if (layers[ i ].tex->m_format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM)
result |= 1 << i;
}
}
return result;
}
};
extern bool g_vulkanSupportsModifiers; extern bool g_vulkanSupportsModifiers;
extern bool g_vulkanHasDrmPrimaryDevId; extern bool g_vulkanHasDrmPrimaryDevId;
@ -187,8 +203,8 @@ std::shared_ptr<CVulkanTexture> vulkan_create_texture_from_wlr_buffer( struct wl
uint32_t vulkan_texture_get_fbid( const std::shared_ptr<CVulkanTexture>& vulkanTex ); uint32_t vulkan_texture_get_fbid( const std::shared_ptr<CVulkanTexture>& vulkanTex );
int vulkan_texture_get_fence( const std::shared_ptr<CVulkanTexture>& vulkanTex ); int vulkan_texture_get_fence( const std::shared_ptr<CVulkanTexture>& vulkanTex );
bool vulkan_composite( struct Composite_t *pComposite, struct VulkanPipeline_t *pPipeline, std::shared_ptr<CVulkanTexture> pScreenshotTexture ); bool vulkan_composite( struct FrameInfo_t *frameInfo, std::shared_ptr<CVulkanTexture> pScreenshotTexture );
uint32_t vulkan_get_last_composite_fbid( void ); std::shared_ptr<CVulkanTexture> vulkan_get_last_output_image( void );
std::shared_ptr<CVulkanTexture> vulkan_acquire_screenshot_texture(bool exportable); std::shared_ptr<CVulkanTexture> vulkan_acquire_screenshot_texture(bool exportable);
void vulkan_present_to_window( void ); void vulkan_present_to_window( void );

View file

@ -1188,8 +1188,7 @@ bool MouseCursor::getTexture()
return true; return true;
} }
void MouseCursor::paint(win *window, win *fit, struct Composite_t *pComposite, void MouseCursor::paint(win *window, win *fit, struct FrameInfo_t *frameInfo)
struct VulkanPipeline_t *pPipeline)
{ {
if (m_hideForMovement || m_imageEmpty) { if (m_hideForMovement || m_imageEmpty) {
return; return;
@ -1247,31 +1246,28 @@ void MouseCursor::paint(win *window, win *fit, struct Composite_t *pComposite,
scaledX = scaledX - m_hotspotX; scaledX = scaledX - m_hotspotX;
scaledY = scaledY - m_hotspotY; scaledY = scaledY - m_hotspotY;
int curLayer = pComposite->nLayerCount; int curLayer = frameInfo->layerCount++;
pComposite->data.flOpacity[ curLayer ] = 1.0; FrameInfo_t::Layer_t *layer = &frameInfo->layers[ curLayer ];
pComposite->data.vScale[ curLayer ].x = 1.0; layer->opacity = 1.0;
pComposite->data.vScale[ curLayer ].y = 1.0;
pComposite->data.vOffset[ curLayer ].x = -scaledX; layer->scale.x = 1.0;
pComposite->data.vOffset[ curLayer ].y = -scaledY; layer->scale.y = 1.0;
pPipeline->layerBindings[ curLayer ].surfaceWidth = m_surfaceWidth; layer->offset.x = -scaledX;
pPipeline->layerBindings[ curLayer ].surfaceHeight = m_surfaceHeight; layer->offset.y = -scaledY;
pPipeline->layerBindings[ curLayer ].imageWidth = m_imageWidth; layer->imageWidth = m_imageWidth;
pPipeline->layerBindings[ curLayer ].imageHeight = m_imageHeight; layer->imageHeight = m_imageHeight;
pPipeline->layerBindings[ curLayer ].zpos = g_zposCursor; // cursor, on top of both bottom layers layer->zpos = g_zposCursor; // cursor, on top of both bottom layers
pPipeline->layerBindings[ curLayer ].tex = m_texture; layer->tex = m_texture;
pPipeline->layerBindings[ curLayer ].fbid = BIsNested() ? 0 : layer->fbid = BIsNested() ? 0 : vulkan_texture_get_fbid(m_texture);
vulkan_texture_get_fbid(m_texture);
pPipeline->layerBindings[ curLayer ].bFilter = false; layer->linearFilter = false;
layer->blackBorder = false;
pComposite->nLayerCount += 1;
} }
struct BaseLayerInfo_t struct BaseLayerInfo_t
@ -1284,23 +1280,23 @@ struct BaseLayerInfo_t
std::array< BaseLayerInfo_t, HELD_COMMIT_COUNT > g_CachedPlanes = {}; std::array< BaseLayerInfo_t, HELD_COMMIT_COUNT > g_CachedPlanes = {};
static void static void
paint_cached_base_layer(const std::shared_ptr<commit_t>& commit, const BaseLayerInfo_t& base, struct Composite_t *pComposite, struct VulkanPipeline_t *pPipeline, float flOpacityScale) paint_cached_base_layer(const std::shared_ptr<commit_t>& commit, const BaseLayerInfo_t& base, struct FrameInfo_t *frameInfo, float flOpacityScale)
{ {
int curLayer = pComposite->nLayerCount; int curLayer = frameInfo->layerCount++;
pComposite->data.vScale[ curLayer ].x = base.scale[0]; FrameInfo_t::Layer_t *layer = &frameInfo->layers[ curLayer ];
pComposite->data.vScale[ curLayer ].y = base.scale[1];
pComposite->data.vOffset[ curLayer ].x = base.offset[0];
pComposite->data.vOffset[ curLayer ].y = base.offset[1];
pComposite->data.flOpacity[ curLayer ] = base.opacity * flOpacityScale;
pPipeline->layerBindings[ curLayer ].tex = commit->vulkanTex; layer->scale.x = base.scale[0];
pPipeline->layerBindings[ curLayer ].fbid = commit->fb_id; layer->scale.y = base.scale[1];
pPipeline->layerBindings[ curLayer ].bFilter = true; layer->offset.x = base.offset[0];
layer->offset.y = base.offset[1];
layer->opacity = base.opacity * flOpacityScale;
pComposite->data.nBorderMask |= (1u << curLayer); layer->tex = commit->vulkanTex;
layer->fbid = commit->fb_id;
pComposite->nLayerCount++; layer->linearFilter = true;
layer->blackBorder = true;
} }
namespace PaintWindowFlag namespace PaintWindowFlag
@ -1314,8 +1310,8 @@ namespace PaintWindowFlag
using PaintWindowFlags = uint32_t; using PaintWindowFlags = uint32_t;
static void static void
paint_window(win *w, win *scaleW, struct Composite_t *pComposite, paint_window(win *w, win *scaleW, struct FrameInfo_t *frameInfo,
struct VulkanPipeline_t *pPipeline, MouseCursor *cursor, PaintWindowFlags flags = 0, float flOpacityScale = 1.0f, win *fit = nullptr ) MouseCursor *cursor, PaintWindowFlags flags = 0, float flOpacityScale = 1.0f, win *fit = nullptr )
{ {
uint32_t sourceWidth, sourceHeight; uint32_t sourceWidth, sourceHeight;
int drawXOffset = 0, drawYOffset = 0; int drawXOffset = 0, drawYOffset = 0;
@ -1332,7 +1328,7 @@ paint_window(win *w, win *scaleW, struct Composite_t *pComposite,
// pick up that buffer we've been holding onto if we have one. // pick up that buffer we've been holding onto if we have one.
if ( g_HeldCommits[ HELD_COMMIT_BASE ] ) if ( g_HeldCommits[ HELD_COMMIT_BASE ] )
{ {
paint_cached_base_layer( g_HeldCommits[ HELD_COMMIT_BASE ], g_CachedPlanes[ HELD_COMMIT_BASE ], pComposite, pPipeline, flOpacityScale ); paint_cached_base_layer( g_HeldCommits[ HELD_COMMIT_BASE ], g_CachedPlanes[ HELD_COMMIT_BASE ], frameInfo, flOpacityScale );
return; return;
} }
} }
@ -1422,17 +1418,19 @@ paint_window(win *w, win *scaleW, struct Composite_t *pComposite,
} }
} }
int curLayer = pComposite->nLayerCount; int curLayer = frameInfo->layerCount++;
pComposite->data.flOpacity[ curLayer ] = ( (w->isOverlay || w->isExternalOverlay) ? w->opacity / (float)OPAQUE : 1.0f ) * flOpacityScale; FrameInfo_t::Layer_t *layer = &frameInfo->layers[ curLayer ];
pComposite->data.vScale[ curLayer ].x = 1.0 / currentScaleRatio; layer->opacity = ( (w->isOverlay || w->isExternalOverlay) ? w->opacity / (float)OPAQUE : 1.0f ) * flOpacityScale;
pComposite->data.vScale[ curLayer ].y = 1.0 / currentScaleRatio;
layer->scale.x = 1.0 / currentScaleRatio;
layer->scale.y = 1.0 / currentScaleRatio;
if ( w != scaleW ) if ( w != scaleW )
{ {
pComposite->data.vOffset[ curLayer ].x = -drawXOffset; layer->offset.x = -drawXOffset;
pComposite->data.vOffset[ curLayer ].y = -drawYOffset; layer->offset.y = -drawYOffset;
} }
else if (notificationMode) else if (notificationMode)
{ {
@ -1447,60 +1445,54 @@ paint_window(win *w, win *scaleW, struct Composite_t *pComposite,
yOffset = (currentOutputHeight - currentOutputHeight * globalScaleRatio) / 2.0; yOffset = (currentOutputHeight - currentOutputHeight * globalScaleRatio) / 2.0;
} }
pComposite->data.vOffset[ curLayer ].x = (currentOutputWidth - xOffset - width) * -1.0f; layer->offset.x = (currentOutputWidth - xOffset - width) * -1.0f;
pComposite->data.vOffset[ curLayer ].y = (currentOutputHeight - yOffset - height) * -1.0f; layer->offset.y = (currentOutputHeight - yOffset - height) * -1.0f;
} }
else else
{ {
pComposite->data.vOffset[ curLayer ].x = -drawXOffset; layer->offset.x = -drawXOffset;
pComposite->data.vOffset[ curLayer ].y = -drawYOffset; layer->offset.y = -drawYOffset;
} }
if ( flags & PaintWindowFlag::DrawBorders ) layer->blackBorder = flags & PaintWindowFlag::DrawBorders;
pComposite->data.nBorderMask |= (1u << curLayer);
pPipeline->layerBindings[ curLayer ].surfaceWidth = w->a.width; layer->imageWidth = w->a.width;
pPipeline->layerBindings[ curLayer ].surfaceHeight = w->a.height; layer->imageHeight = w->a.height;
pPipeline->layerBindings[ curLayer ].imageWidth = w->a.width; layer->zpos = g_zposBase;
pPipeline->layerBindings[ curLayer ].imageHeight = w->a.height;
pPipeline->layerBindings[ curLayer ].zpos = g_zposBase;
if ( w != scaleW ) if ( w != scaleW )
{ {
pPipeline->layerBindings[ curLayer ].zpos = g_zposOverride; layer->zpos = g_zposOverride;
} }
if ( w->isOverlay || w->isSteamStreamingClient ) if ( w->isOverlay || w->isSteamStreamingClient )
{ {
pPipeline->layerBindings[ curLayer ].zpos = g_zposOverlay; layer->zpos = g_zposOverlay;
} }
if ( w->isExternalOverlay ) if ( w->isExternalOverlay )
{ {
pPipeline->layerBindings[ curLayer ].zpos = g_zposExternalOverlay; layer->zpos = g_zposExternalOverlay;
} }
pPipeline->layerBindings[ curLayer ].tex = lastCommit->vulkanTex; layer->tex = lastCommit->vulkanTex;
pPipeline->layerBindings[ curLayer ].fbid = lastCommit->fb_id; layer->fbid = lastCommit->fb_id;
pPipeline->layerBindings[ curLayer ].bFilter = (w->isOverlay || w->isExternalOverlay) ? true : g_bFilterGameWindow; layer->linearFilter = (w->isOverlay || w->isExternalOverlay) ? true : g_bFilterGameWindow;
if ( flags & PaintWindowFlag::BasePlane ) if ( flags & PaintWindowFlag::BasePlane )
{ {
BaseLayerInfo_t basePlane = {}; BaseLayerInfo_t basePlane = {};
basePlane.scale[0] = pComposite->data.vScale[ curLayer ].x; basePlane.scale[0] = layer->scale.x;
basePlane.scale[1] = pComposite->data.vScale[ curLayer ].y; basePlane.scale[1] = layer->scale.y;
basePlane.offset[0] = pComposite->data.vOffset[ curLayer ].x; basePlane.offset[0] = layer->offset.x;
basePlane.offset[1] = pComposite->data.vOffset[ curLayer ].y; basePlane.offset[1] = layer->offset.y;
basePlane.opacity = pComposite->data.flOpacity[ curLayer ]; basePlane.opacity = layer->opacity;
g_CachedPlanes[ HELD_COMMIT_BASE ] = basePlane; g_CachedPlanes[ HELD_COMMIT_BASE ] = basePlane;
if ( !(flags & PaintWindowFlag::FadeTarget) ) if ( !(flags & PaintWindowFlag::FadeTarget) )
g_CachedPlanes[ HELD_COMMIT_FADE ] = basePlane; g_CachedPlanes[ HELD_COMMIT_FADE ] = basePlane;
} }
pComposite->nLayerCount += 1;
} }
bool g_bFirstFrame = true; bool g_bFirstFrame = true;
@ -1510,15 +1502,15 @@ static bool is_fading_out()
return fadeOutStartTime || g_bPendingFade; return fadeOutStartTime || g_bPendingFade;
} }
static void update_touch_scaling( struct Composite_t *pComposite ) static void update_touch_scaling( const struct FrameInfo_t *frameInfo )
{ {
if ( !pComposite->nLayerCount ) if ( !frameInfo->layerCount )
return; return;
focusedWindowScaleX = pComposite->data.vScale[ pComposite->nLayerCount - 1 ].x; focusedWindowScaleX = frameInfo->layers[ frameInfo->layerCount - 1 ].scale.x;
focusedWindowScaleY = pComposite->data.vScale[ pComposite->nLayerCount - 1 ].y; focusedWindowScaleY = frameInfo->layers[ frameInfo->layerCount - 1 ].scale.y;
focusedWindowOffsetX = pComposite->data.vOffset[ pComposite->nLayerCount - 1 ].x; focusedWindowOffsetX = frameInfo->layers[ frameInfo->layerCount - 1 ].offset.x;
focusedWindowOffsetY = pComposite->data.vOffset[ pComposite->nLayerCount - 1 ].y; focusedWindowOffsetY = frameInfo->layers[ frameInfo->layerCount - 1 ].offset.y;
} }
static void static void
@ -1566,8 +1558,7 @@ paint_all()
} }
} }
struct Composite_t composite = {}; struct FrameInfo_t frameInfo = {};
struct VulkanPipeline_t pipeline = {};
// If the window we'd paint as the base layer is the streaming client, // If the window we'd paint as the base layer is the streaming client,
// find the video underlay and put it up first in the scenegraph // find the video underlay and put it up first in the scenegraph
@ -1586,25 +1577,25 @@ paint_all()
if ( videow->isSteamStreamingClientVideo == true ) if ( videow->isSteamStreamingClientVideo == true )
{ {
// TODO: also check matching AppID so we can have several pairs // TODO: also check matching AppID so we can have several pairs
paint_window(videow, videow, &composite, &pipeline, global_focus.cursor, PaintWindowFlag::BasePlane | PaintWindowFlag::DrawBorders); paint_window(videow, videow, &frameInfo, global_focus.cursor, PaintWindowFlag::BasePlane | PaintWindowFlag::DrawBorders);
bHasVideoUnderlay = true; bHasVideoUnderlay = true;
break; break;
} }
} }
} }
int nOldLayerCount = composite.nLayerCount; int nOldLayerCount = frameInfo.layerCount;
uint32_t flags = 0; uint32_t flags = 0;
if ( !bHasVideoUnderlay ) if ( !bHasVideoUnderlay )
flags |= PaintWindowFlag::BasePlane; flags |= PaintWindowFlag::BasePlane;
paint_window(w, w, &composite, &pipeline, global_focus.cursor, flags); paint_window(w, w, &frameInfo, global_focus.cursor, flags);
update_touch_scaling( &composite ); update_touch_scaling( &frameInfo );
// paint UI unless it's fully hidden, which it communicates to us through opacity=0 // paint UI unless it's fully hidden, which it communicates to us through opacity=0
// we paint it to extract scaling coefficients above, then remove the layer if one was added // we paint it to extract scaling coefficients above, then remove the layer if one was added
if ( w->opacity == TRANSLUCENT && bHasVideoUnderlay && nOldLayerCount < composite.nLayerCount ) if ( w->opacity == TRANSLUCENT && bHasVideoUnderlay && nOldLayerCount < frameInfo.layerCount )
composite.nLayerCount--; frameInfo.layerCount--;
} }
else else
{ {
@ -1614,8 +1605,8 @@ paint_all()
? 0.0f ? 0.0f
: ((currentTime - fadeOutStartTime) / (float)g_FadeOutDuration); : ((currentTime - fadeOutStartTime) / (float)g_FadeOutDuration);
paint_cached_base_layer(g_HeldCommits[HELD_COMMIT_FADE], g_CachedPlanes[HELD_COMMIT_FADE], &composite, &pipeline, 1.0f - opacityScale); paint_cached_base_layer(g_HeldCommits[HELD_COMMIT_FADE], g_CachedPlanes[HELD_COMMIT_FADE], &frameInfo, 1.0f - opacityScale);
paint_window(w, w, &composite, &pipeline, global_focus.cursor, PaintWindowFlag::BasePlane | PaintWindowFlag::FadeTarget | PaintWindowFlag::DrawBorders, opacityScale, override); paint_window(w, w, &frameInfo, global_focus.cursor, PaintWindowFlag::BasePlane | PaintWindowFlag::FadeTarget | PaintWindowFlag::DrawBorders, opacityScale, override);
} }
else else
{ {
@ -1629,17 +1620,17 @@ paint_all()
} }
} }
// Just draw focused window as normal, be it Steam or the game // Just draw focused window as normal, be it Steam or the game
paint_window(w, w, &composite, &pipeline, global_focus.cursor, PaintWindowFlag::BasePlane | PaintWindowFlag::DrawBorders, 1.0f, override); paint_window(w, w, &frameInfo, global_focus.cursor, PaintWindowFlag::BasePlane | PaintWindowFlag::DrawBorders, 1.0f, override);
composite.useFSRLayer0 = g_fsrUpscale && composite.data.vScale[0].x < 1.0f && composite.data.vScale[0].y < 1.0f; frameInfo.useFSRLayer0 = g_fsrUpscale && frameInfo.layers[0].scale.x < 1.0f && frameInfo.layers[0].scale.y < 1.0f;
} }
update_touch_scaling( &composite ); update_touch_scaling( &frameInfo );
} }
} }
else else
{ {
if ( g_HeldCommits[HELD_COMMIT_BASE] ) if ( g_HeldCommits[HELD_COMMIT_BASE] )
paint_cached_base_layer(g_HeldCommits[HELD_COMMIT_BASE], g_CachedPlanes[HELD_COMMIT_BASE], &composite, &pipeline, 1.0f); paint_cached_base_layer(g_HeldCommits[HELD_COMMIT_BASE], g_CachedPlanes[HELD_COMMIT_BASE], &frameInfo, 1.0f);
} }
// TODO: We want to paint this at the same scale as the normal window and probably // TODO: We want to paint this at the same scale as the normal window and probably
@ -1648,23 +1639,23 @@ paint_all()
// as we will have too many layers. Better to be safe than sorry. // as we will have too many layers. Better to be safe than sorry.
if ( override && w && !w->isSteamStreamingClient ) if ( override && w && !w->isSteamStreamingClient )
{ {
paint_window(override, w, &composite, &pipeline, global_focus.cursor, 0, 1.0f, override); paint_window(override, w, &frameInfo, global_focus.cursor, 0, 1.0f, override);
// Don't update touch scaling for composite. We don't ever make it our // Don't update touch scaling for frameInfo. We don't ever make it our
// wlserver_mousefocus window. // wlserver_mousefocus window.
//update_touch_scaling( &composite ); //update_touch_scaling( &frameInfo );
} }
// If we have any layers that aren't a cursor or overlay, then we have valid contents for presentation. // If we have any layers that aren't a cursor or overlay, then we have valid contents for presentation.
const bool bValidContents = composite.nLayerCount > 0; const bool bValidContents = frameInfo.layerCount > 0;
if (externalOverlay) if (externalOverlay)
{ {
if (externalOverlay->opacity) if (externalOverlay->opacity)
{ {
paint_window(externalOverlay, externalOverlay, &composite, &pipeline, global_focus.cursor, PaintWindowFlag::NoScale); paint_window(externalOverlay, externalOverlay, &frameInfo, global_focus.cursor, PaintWindowFlag::NoScale);
if ( externalOverlay == global_focus.inputFocusWindow ) if ( externalOverlay == global_focus.inputFocusWindow )
update_touch_scaling( &composite ); update_touch_scaling( &frameInfo );
} }
} }
@ -1672,10 +1663,10 @@ paint_all()
{ {
if (overlay->opacity) if (overlay->opacity)
{ {
paint_window(overlay, overlay, &composite, &pipeline, global_focus.cursor, PaintWindowFlag::DrawBorders); paint_window(overlay, overlay, &frameInfo, global_focus.cursor, PaintWindowFlag::DrawBorders);
if ( overlay == global_focus.inputFocusWindow ) if ( overlay == global_focus.inputFocusWindow )
update_touch_scaling( &composite ); update_touch_scaling( &frameInfo );
} }
} }
@ -1683,7 +1674,7 @@ paint_all()
{ {
if (notification->opacity) if (notification->opacity)
{ {
paint_window(notification, notification, &composite, &pipeline, global_focus.cursor, PaintWindowFlag::NotificationMode); paint_window(notification, notification, &frameInfo, global_focus.cursor, PaintWindowFlag::NotificationMode);
} }
} }
@ -1691,11 +1682,11 @@ paint_all()
// Draw cursor if we need to // Draw cursor if we need to
if (input) { if (input) {
int nLayerCountBefore = composite.nLayerCount; int nLayerCountBefore = frameInfo.layerCount;
global_focus.cursor->paint( global_focus.cursor->paint(
input, w == input ? override : nullptr, input, w == input ? override : nullptr,
&composite, &pipeline); &frameInfo);
int nLayerCountAfter = composite.nLayerCount; int nLayerCountAfter = frameInfo.layerCount;
bDrewCursor = nLayerCountAfter > nLayerCountBefore; bDrewCursor = nLayerCountAfter > nLayerCountBefore;
} }
@ -1708,10 +1699,10 @@ paint_all()
bool blurFading = blurFadeTime < g_BlurFadeDuration; bool blurFading = blurFadeTime < g_BlurFadeDuration;
BlurMode currentBlurMode = blurFading ? std::max(g_BlurMode, g_BlurModeOld) : g_BlurMode; BlurMode currentBlurMode = blurFading ? std::max(g_BlurMode, g_BlurModeOld) : g_BlurMode;
if (currentBlurMode && !(composite.nLayerCount <= 1 && currentBlurMode == BLUR_MODE_COND)) if (currentBlurMode && !(frameInfo.layerCount <= 1 && currentBlurMode == BLUR_MODE_COND))
{ {
composite.blurLayer0 = currentBlurMode; frameInfo.blurLayer0 = currentBlurMode;
composite.blurRadius = g_BlurRadius; frameInfo.blurRadius = g_BlurRadius;
if (blurFading) if (blurFading)
{ {
@ -1721,13 +1712,13 @@ paint_all()
if (!fadingIn) if (!fadingIn)
ratio = 1.0 - ratio; ratio = 1.0 - ratio;
composite.blurRadius = ratio * g_BlurRadius; frameInfo.blurRadius = ratio * g_BlurRadius;
} }
composite.useFSRLayer0 = false; frameInfo.useFSRLayer0 = false;
} }
g_bFSRActive = composite.useFSRLayer0; g_bFSRActive = frameInfo.useFSRLayer0;
bool bWasFirstFrame = g_bFirstFrame; bool bWasFirstFrame = g_bFirstFrame;
g_bFirstFrame = false; g_bFirstFrame = false;
@ -1758,20 +1749,20 @@ paint_all()
if ( !BIsNested() && g_nOutputRefresh != nTargetRefresh && g_uDynamicRefreshEqualityTime + g_uDynamicRefreshDelay < now ) if ( !BIsNested() && g_nOutputRefresh != nTargetRefresh && g_uDynamicRefreshEqualityTime + g_uDynamicRefreshDelay < now )
drm_set_refresh( &g_DRM, nTargetRefresh ); drm_set_refresh( &g_DRM, nTargetRefresh );
bool bNeedsNearest = !g_bFilterGameWindow && composite.data.vScale[0].x != 1.0f && composite.data.vScale[0].y != 1.0f; bool bNeedsNearest = !g_bFilterGameWindow && frameInfo.layers[0].scale.x != 1.0f && frameInfo.layers[0].scale.y != 1.0f;
bool bNeedsComposite = BIsNested(); bool bNeedsComposite = BIsNested();
bNeedsComposite |= alwaysComposite; bNeedsComposite |= alwaysComposite;
bNeedsComposite |= bCapture; bNeedsComposite |= bCapture;
bNeedsComposite |= bWasFirstFrame; bNeedsComposite |= bWasFirstFrame;
bNeedsComposite |= composite.useFSRLayer0; bNeedsComposite |= frameInfo.useFSRLayer0;
bNeedsComposite |= composite.blurLayer0; bNeedsComposite |= frameInfo.blurLayer0;
bNeedsComposite |= bNeedsNearest; bNeedsComposite |= bNeedsNearest;
bNeedsComposite |= bDrewCursor; bNeedsComposite |= bDrewCursor;
if ( !bNeedsComposite ) if ( !bNeedsComposite )
{ {
int ret = drm_prepare( &g_DRM, &composite, &pipeline ); int ret = drm_prepare( &g_DRM, &frameInfo );
if ( ret == 0 ) if ( ret == 0 )
bDoComposite = false; bDoComposite = false;
else if ( ret == -EACCES ) else if ( ret == -EACCES )
@ -1792,7 +1783,7 @@ paint_all()
pCaptureTexture = vulkan_acquire_screenshot_texture(false); pCaptureTexture = vulkan_acquire_screenshot_texture(false);
} }
bool bResult = vulkan_composite( &composite, &pipeline, pCaptureTexture ); bool bResult = vulkan_composite( &frameInfo, pCaptureTexture );
if ( bResult != true ) if ( bResult != true )
{ {
@ -1809,23 +1800,23 @@ paint_all()
} }
else else
{ {
composite = {}; frameInfo = {};
composite.nLayerCount = 1;
composite.data.vScale[ 0 ].x = 1.0;
composite.data.vScale[ 0 ].y = 1.0;
composite.data.flOpacity[ 0 ] = 1.0;
pipeline = {}; frameInfo.layerCount = 1;
pipeline.layerBindings[ 0 ].surfaceWidth = g_nOutputWidth; FrameInfo_t::Layer_t *layer = &frameInfo.layers[ 0 ];
pipeline.layerBindings[ 0 ].surfaceHeight = g_nOutputHeight; layer->scale.x = 1.0;
layer->scale.y = 1.0;
layer->opacity = 1.0;
pipeline.layerBindings[ 0 ].imageWidth = g_nOutputWidth; layer->imageWidth = g_nOutputWidth;
pipeline.layerBindings[ 0 ].imageHeight = g_nOutputHeight; layer->imageHeight = g_nOutputHeight;
pipeline.layerBindings[ 0 ].fbid = vulkan_get_last_composite_fbid(); layer->tex = vulkan_get_last_output_image();
pipeline.layerBindings[ 0 ].bFilter = false; layer->fbid = layer->tex->m_FBID;
int ret = drm_prepare( &g_DRM, &composite, &pipeline ); layer->linearFilter = false;
int ret = drm_prepare( &g_DRM, &frameInfo );
// Happens when we're VT-switched away // Happens when we're VT-switched away
if ( ret == -EACCES ) if ( ret == -EACCES )
@ -1844,7 +1835,7 @@ paint_all()
drm_rollback( &g_DRM ); drm_rollback( &g_DRM );
// Try once again to in case we need to fall back to another mode. // Try once again to in case we need to fall back to another mode.
ret = drm_prepare( &g_DRM, &composite, &pipeline ); ret = drm_prepare( &g_DRM, &frameInfo );
// Happens when we're VT-switched away // Happens when we're VT-switched away
if ( ret == -EACCES ) if ( ret == -EACCES )
@ -1858,7 +1849,7 @@ paint_all()
} }
} }
drm_commit( &g_DRM, &composite, &pipeline ); drm_commit( &g_DRM, &frameInfo );
} }
if ( takeScreenshot ) if ( takeScreenshot )
@ -1926,11 +1917,11 @@ paint_all()
{ {
assert( BIsNested() == false ); assert( BIsNested() == false );
drm_commit( &g_DRM, &composite, &pipeline ); drm_commit( &g_DRM, &frameInfo );
} }
gpuvis_trace_end_ctx_printf( paintID, "paint_all" ); gpuvis_trace_end_ctx_printf( paintID, "paint_all" );
gpuvis_trace_printf( "paint_all %i layers, composite %i", (int)composite.nLayerCount, bDoComposite ); gpuvis_trace_printf( "paint_all %i layers, composite %i", (int)frameInfo.layerCount, bDoComposite );
} }
/* Get prop from window /* Get prop from window

View file

@ -48,8 +48,7 @@ public:
void constrainPosition(); void constrainPosition();
void resetPosition(); void resetPosition();
void paint(struct win *window, struct win *fit, struct Composite_t *pComposite, void paint(struct win *window, struct win *fit, struct FrameInfo_t *frameInfo);
struct VulkanPipeline_t *pPipeline);
void setDirty(); void setDirty();
// Will take ownership of data. // Will take ownership of data.