@@ -186,7 +186,7 @@ static VkFormat srgb_to_unorm_format(VkFormat vk_format) {
186
186
}
187
187
}
188
188
189
- static int fb_init (struct fb * fb , struct gbm_device * gbm_device , struct vk_renderer * renderer , int width , int height , enum pixfmt pixel_format , uint64_t drm_modifier ) {
189
+ static int fb_init (struct fb * fb , struct gbm_device * gbm_device , struct vk_renderer * renderer , int width , int height , enum pixfmt pixel_format ) {
190
190
PFN_vkGetMemoryFdPropertiesKHR get_memory_fd_props ;
191
191
VkSubresourceLayout layout ;
192
192
VkDeviceMemory img_device_memory ;
@@ -212,6 +212,17 @@ static int fb_init(struct fb *fb, struct gbm_device *gbm_device, struct vk_rende
212
212
vk_format = srgb_to_unorm_format (vk_format );
213
213
}
214
214
215
+ bo = gbm_bo_create (
216
+ gbm_device ,
217
+ width , height ,
218
+ get_pixfmt_info (pixel_format )-> gbm_format ,
219
+ GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT
220
+ );
221
+ if (bo == NULL ) {
222
+ LOG_ERROR ("Could not create GBM BO. gbm_bo_create: %s\n" , strerror (errno ));
223
+ goto fail_destroy_image ;
224
+ }
225
+
215
226
ok = vkCreateImage (
216
227
device ,
217
228
& (VkImageCreateInfo ){
@@ -241,14 +252,14 @@ static int fb_init(struct fb *fb, struct gbm_device *gbm_device, struct vk_rende
241
252
& (VkImageDrmFormatModifierExplicitCreateInfoEXT ){
242
253
.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT ,
243
254
.drmFormatModifierPlaneCount = 1 ,
244
- .drmFormatModifier = drm_modifier ,
255
+ .drmFormatModifier = gbm_bo_get_modifier ( bo ) ,
245
256
.pPlaneLayouts =
246
257
(VkSubresourceLayout [1 ]){
247
258
{
248
259
/// These are just dummy values, but they need to be there AFAIK
249
- .offset = 0 ,
250
- .size = 0 ,
251
- .rowPitch = 0 ,
260
+ .offset = gbm_bo_get_offset ( bo , 0 ) ,
261
+ .size = gbm_bo_get_stride_for_plane ( bo , 0 ) * gbm_bo_get_height ( bo ) + gbm_bo_get_offset ( bo , 0 ) ,
262
+ .rowPitch = gbm_bo_get_stride_for_plane ( bo , 0 ) ,
252
263
.arrayPitch = 0 ,
253
264
.depthPitch = 0 ,
254
265
},
@@ -277,20 +288,6 @@ static int fb_init(struct fb *fb, struct gbm_device *gbm_device, struct vk_rende
277
288
& layout
278
289
);
279
290
280
- // Create a GBM BO with the actual memory we're going to use
281
- bo = gbm_bo_create_with_modifiers (
282
- gbm_device ,
283
- width ,
284
- height ,
285
- get_pixfmt_info (pixel_format )-> gbm_format ,
286
- & drm_modifier ,
287
- 1
288
- );
289
- if (bo == NULL ) {
290
- LOG_ERROR ("Could not create GBM BO. gbm_bo_create_with_modifiers: %s\n" , strerror (errno ));
291
- goto fail_destroy_image ;
292
- }
293
-
294
291
// Just some paranoid checks that the layout matches (had some issues with that initially)
295
292
if (gbm_bo_get_offset (bo , 0 ) != layout .offset ) {
296
293
LOG_ERROR ("GBM BO layout doesn't match image layout. This is probably a driver / kernel bug.\n" );
@@ -428,11 +425,11 @@ static int fb_init(struct fb *fb, struct gbm_device *gbm_device, struct vk_rende
428
425
fail_close_fd :
429
426
close (fd );
430
427
431
- fail_destroy_bo :
432
- gbm_bo_destroy (bo );
433
-
434
428
fail_destroy_image :
435
429
vkDestroyImage (device , vkimg , NULL );
430
+
431
+ fail_destroy_bo :
432
+ gbm_bo_destroy (bo );
436
433
return EIO ;
437
434
}
438
435
@@ -460,7 +457,7 @@ int vk_gbm_render_surface_init(
460
457
}
461
458
462
459
for (int i = 0 ; i < ARRAY_SIZE (surface -> fbs ); i ++ ) {
463
- ok = fb_init (surface -> fbs + i , gbm_device , renderer , (int ) size .x , (int ) size .y , pixel_format , DRM_FORMAT_MOD_LINEAR );
460
+ ok = fb_init (surface -> fbs + i , gbm_device , renderer , (int ) size .x , (int ) size .y , pixel_format );
464
461
if (ok != 0 ) {
465
462
LOG_ERROR ("Could not initialize vulkan GBM framebuffer.\n" );
466
463
goto fail_deinit_previous_fbs ;
@@ -551,9 +548,6 @@ void vk_gbm_render_surface_deinit(struct surface *s) {
551
548
struct gbm_bo_meta {
552
549
struct drmdev * drmdev ;
553
550
uint32_t fb_id ;
554
- bool has_opaque_fb ;
555
- enum pixfmt opaque_pixel_format ;
556
- uint32_t opaque_fb_id ;
557
551
};
558
552
559
553
static void on_destroy_gbm_bo_meta (struct gbm_bo * bo , void * meta_void ) {
@@ -569,13 +563,6 @@ static void on_destroy_gbm_bo_meta(struct gbm_bo *bo, void *meta_void) {
569
563
LOG_ERROR ("Couldn't remove DRM framebuffer.\n" );
570
564
}
571
565
572
- if (meta -> has_opaque_fb && meta -> opaque_fb_id != meta -> fb_id ) {
573
- ok = drmdev_rm_fb (meta -> drmdev , meta -> opaque_fb_id );
574
- if (ok != 0 ) {
575
- LOG_ERROR ("Couldn't remove DRM framebuffer.\n" );
576
- }
577
- }
578
-
579
566
drmdev_unref (meta -> drmdev );
580
567
free (meta );
581
568
}
@@ -600,8 +587,8 @@ static int vk_gbm_render_surface_present_kms(struct surface *s, const struct fl_
600
587
struct gbm_bo_meta * meta ;
601
588
struct drmdev * drmdev ;
602
589
struct gbm_bo * bo ;
603
- enum pixfmt pixel_format , opaque_pixel_format ;
604
- uint32_t fb_id , opaque_fb_id ;
590
+ enum pixfmt pixel_format ;
591
+ uint32_t fb_id ;
605
592
int ok ;
606
593
607
594
vk_surface = CAST_THIS (s );
@@ -618,8 +605,6 @@ static int vk_gbm_render_surface_present_kms(struct surface *s, const struct fl_
618
605
bo = vk_surface -> front_fb -> fb -> bo ;
619
606
meta = gbm_bo_get_user_data (bo );
620
607
if (meta == NULL ) {
621
- bool has_opaque_fb ;
622
-
623
608
meta = malloc (sizeof * meta );
624
609
if (meta == NULL ) {
625
610
ok = ENOMEM ;
@@ -638,8 +623,7 @@ static int vk_gbm_render_surface_present_kms(struct surface *s, const struct fl_
638
623
gbm_bo_get_handle (bo ).u32 ,
639
624
gbm_bo_get_stride (bo ),
640
625
gbm_bo_get_offset (bo , 0 ),
641
- true, gbm_bo_get_modifier (bo ),
642
- 0
626
+ true, gbm_bo_get_modifier (bo )
643
627
);
644
628
TRACER_END (vk_surface -> surface .tracer , "drmdev_add_fb (non-opaque)" );
645
629
@@ -649,40 +633,8 @@ static int vk_gbm_render_surface_present_kms(struct surface *s, const struct fl_
649
633
goto fail_free_meta ;
650
634
}
651
635
652
- if (get_pixfmt_info (vk_surface -> pixel_format )-> is_opaque == false) {
653
- has_opaque_fb = false;
654
- opaque_pixel_format = pixfmt_opaque (vk_surface -> pixel_format );
655
- if (get_pixfmt_info (opaque_pixel_format )-> is_opaque ) {
656
-
657
- TRACER_BEGIN (vk_surface -> surface .tracer , "drmdev_add_fb (opaque)" );
658
- opaque_fb_id = drmdev_add_fb (
659
- drmdev ,
660
- gbm_bo_get_width (bo ),
661
- gbm_bo_get_height (bo ),
662
- opaque_pixel_format ,
663
- gbm_bo_get_handle (bo ).u32 ,
664
- gbm_bo_get_stride (bo ),
665
- gbm_bo_get_offset (bo , 0 ),
666
- true, gbm_bo_get_modifier (bo ),
667
- 0
668
- );
669
- TRACER_END (vk_surface -> surface .tracer , "drmdev_add_fb (opaque)" );
670
-
671
- if (opaque_fb_id != 0 ) {
672
- has_opaque_fb = true;
673
- }
674
- }
675
- } else {
676
- has_opaque_fb = true;
677
- opaque_fb_id = fb_id ;
678
- opaque_pixel_format = vk_surface -> pixel_format ;
679
- }
680
-
681
636
meta -> drmdev = drmdev_ref (drmdev );
682
637
meta -> fb_id = fb_id ;
683
- meta -> has_opaque_fb = has_opaque_fb ;
684
- meta -> opaque_pixel_format = opaque_pixel_format ;
685
- meta -> opaque_fb_id = opaque_fb_id ;
686
638
gbm_bo_set_user_data (bo , meta , on_destroy_gbm_bo_meta );
687
639
} else {
688
640
// We can only add this GBM BO to a single KMS device as an fb right now.
@@ -708,29 +660,19 @@ static int vk_gbm_render_surface_present_kms(struct surface *s, const struct fl_
708
660
// For example, on Pi 4, even though ARGB8888 is listed as supported for the primary plane,
709
661
// rendering is completely off.
710
662
// So we just cast our fb to an XRGB8888 framebuffer and scanout that instead.
711
- if (kms_req_builder_prefer_next_layer_opaque (builder )) {
712
- if (meta -> has_opaque_fb ) {
713
- fb_id = meta -> opaque_fb_id ;
714
- pixel_format = meta -> opaque_pixel_format ;
715
- } else {
716
- LOG_DEBUG ("Bottom-most framebuffer layer should be opaque, but an opaque framebuffer couldn't be created.\n" );
717
- LOG_DEBUG ("Using non-opaque framebuffer instead, which can result in visual glitches.\n" );
718
- fb_id = meta -> fb_id ;
719
- pixel_format = vk_surface -> pixel_format ;
720
- }
721
- } else {
722
- fb_id = meta -> fb_id ;
723
- pixel_format = vk_surface -> pixel_format ;
724
- }
663
+ fb_id = meta -> fb_id ;
664
+ pixel_format = vk_surface -> pixel_format ;
665
+
666
+ vkDeviceWaitIdle (vk_renderer_get_device (vk_surface -> renderer ));
725
667
726
668
TRACER_BEGIN (vk_surface -> surface .tracer , "kms_req_builder_push_fb_layer" );
727
669
ok = kms_req_builder_push_fb_layer (
728
670
builder ,
729
671
& (const struct kms_fb_layer ) {
730
672
.drm_fb_id = fb_id ,
731
673
.format = pixel_format ,
732
- .has_modifier = false ,
733
- .modifier = 0 ,
674
+ .has_modifier = true ,
675
+ .modifier = gbm_bo_get_modifier ( bo ) ,
734
676
735
677
.dst_x = (int32_t ) props -> aa_rect .offset .x ,
736
678
.dst_y = (int32_t ) props -> aa_rect .offset .y ,
0 commit comments