@@ -624,6 +624,32 @@ tu_image_update_layout(struct tu_device *device, struct tu_image *image,
624
624
}
625
625
TU_GENX (tu_image_update_layout);
626
626
627
+ /* Return true if all formats in the format list can support UBWC.
628
+ */
629
+ static bool
630
+ format_list_ubwc_possible (struct tu_device *dev,
631
+ const VkImageFormatListCreateInfo *fmt_list,
632
+ const VkImageCreateInfo *create_info)
633
+ {
634
+ /* If there is no format list, we may have to assume that a
635
+ * UBWC-incompatible format may be used.
636
+ * TODO: limit based on compatiblity class
637
+ */
638
+ if (!fmt_list || !fmt_list->viewFormatCount )
639
+ return false ;
640
+
641
+ for (uint32_t i = 0 ; i < fmt_list->viewFormatCount ; i++) {
642
+ if (!ubwc_possible (dev, fmt_list->pViewFormats [i],
643
+ create_info->imageType , create_info->usage ,
644
+ create_info->usage , dev->physical_device ->info ,
645
+ create_info->samples , create_info->mipLevels ,
646
+ dev->use_z24uint_s8uint ))
647
+ return false ;
648
+ }
649
+
650
+ return true ;
651
+ }
652
+
627
653
static VkResult
628
654
tu_image_init (struct tu_device *device, struct tu_image *image,
629
655
const VkImageCreateInfo *pCreateInfo)
@@ -677,7 +703,6 @@ tu_image_init(struct tu_device *device, struct tu_image *image,
677
703
pCreateInfo->mipLevels , device->use_z24uint_s8uint ))
678
704
image->ubwc_enabled = false ;
679
705
680
- bool fmt_list_has_swaps = false ;
681
706
/* Mutable images can be reinterpreted as any other compatible format.
682
707
* This is a problem with UBWC (compression for different formats is different),
683
708
* but also tiling ("swap" affects how tiled formats are stored in memory)
@@ -688,49 +713,66 @@ tu_image_init(struct tu_device *device, struct tu_image *image,
688
713
* - if the fmt_list contains only formats which are swapped, but compatible
689
714
* with each other (B8G8R8A8_UNORM and B8G8R8A8_UINT for example), then
690
715
* tiling is still possible
691
- * - figure out which UBWC compressions are compatible to keep it enabled
692
716
*/
693
717
if ((pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) &&
694
718
!vk_format_is_depth_or_stencil (image->vk .format )) {
695
719
const VkImageFormatListCreateInfo *fmt_list =
696
720
vk_find_struct_const (pCreateInfo->pNext , IMAGE_FORMAT_LIST_CREATE_INFO);
697
- fmt_list_has_swaps = format_list_has_swaps (fmt_list);
698
721
if (!tu6_mutable_format_list_ubwc_compatible (device->physical_device ->info ,
699
722
fmt_list)) {
700
723
bool mutable_ubwc_fc = device->physical_device ->info ->a7xx .ubwc_all_formats_compatible ;
701
- if (image->ubwc_enabled && !mutable_ubwc_fc) {
702
- if (fmt_list && fmt_list->viewFormatCount == 2 ) {
703
- perf_debug (
704
- device,
705
- " Disabling UBWC on %dx%d %s resource due to mutable formats "
706
- " (fmt list %s, %s)" ,
707
- image->vk .extent .width , image->vk .extent .height ,
708
- util_format_name (vk_format_to_pipe_format (image->vk .format )),
709
- util_format_name (vk_format_to_pipe_format (fmt_list->pViewFormats [0 ])),
710
- util_format_name (vk_format_to_pipe_format (fmt_list->pViewFormats [1 ])));
711
- } else {
724
+
725
+ /* NV12 uses a special compression scheme for the Y channel which
726
+ * doesn't support reinterpretation. We have to fall back to linear
727
+ * always.
728
+ */
729
+ if (pCreateInfo->format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM) {
730
+ if (image->ubwc_enabled ) {
712
731
perf_debug (
713
732
device,
714
- " Disabling UBWC on %dx%d %s resource due to mutable formats "
733
+ " Disabling UBWC and tiling on %dx%d %s resource due to mutable formats "
715
734
" (fmt list %s)" ,
716
735
image->vk .extent .width , image->vk .extent .height ,
717
736
util_format_name (vk_format_to_pipe_format (image->vk .format )),
718
737
fmt_list ? " present" : " missing" );
719
738
}
720
739
image->ubwc_enabled = false ;
721
- }
740
+ image->force_linear_tile = true ;
741
+ } else if (!mutable_ubwc_fc) {
742
+ if (image->ubwc_enabled ) {
743
+ if (fmt_list && fmt_list->viewFormatCount == 2 ) {
744
+ perf_debug (
745
+ device,
746
+ " Disabling UBWC on %dx%d %s resource due to mutable formats "
747
+ " (fmt list %s, %s)" ,
748
+ image->vk .extent .width , image->vk .extent .height ,
749
+ util_format_name (vk_format_to_pipe_format (image->vk .format )),
750
+ util_format_name (vk_format_to_pipe_format (fmt_list->pViewFormats [0 ])),
751
+ util_format_name (vk_format_to_pipe_format (fmt_list->pViewFormats [1 ])));
752
+ } else {
753
+ perf_debug (
754
+ device,
755
+ " Disabling UBWC on %dx%d %s resource due to mutable formats "
756
+ " (fmt list %s)" ,
757
+ image->vk .extent .width , image->vk .extent .height ,
758
+ util_format_name (vk_format_to_pipe_format (image->vk .format )),
759
+ fmt_list ? " present" : " missing" );
760
+ }
761
+ image->ubwc_enabled = false ;
762
+ }
722
763
723
- bool r8g8_r16 = format_list_reinterprets_r8g8_r16 (vk_format_to_pipe_format (image->vk .format ), fmt_list);
764
+ bool r8g8_r16 = format_list_reinterprets_r8g8_r16 (vk_format_to_pipe_format (image->vk .format ), fmt_list);
765
+ bool fmt_list_has_swaps = format_list_has_swaps (fmt_list);
724
766
725
- /* A750+ TODO: Correctly handle swaps when copying mutable images.
726
- * We should be able to support UBWC for mutable images with swaps.
727
- */
728
- if ((r8g8_r16 && !mutable_ubwc_fc) || fmt_list_has_swaps) {
729
- image->ubwc_enabled = false ;
730
- image->force_linear_tile = true ;
767
+ if (r8g8_r16 || fmt_list_has_swaps) {
768
+ image->ubwc_enabled = false ;
769
+ image->force_linear_tile = true ;
770
+ }
771
+ } else {
772
+ image->is_mutable = true ;
773
+ if (!format_list_ubwc_possible (device, fmt_list, pCreateInfo))
774
+ image->ubwc_enabled = false ;
731
775
}
732
-
733
- image->is_mutable = image->ubwc_enabled && mutable_ubwc_fc;
734
776
}
735
777
}
736
778
0 commit comments