summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dist/qt_themes/colorful_midnight_blue/icons/16x16/lock.pngbin0 -> 401 bytes
-rw-r--r--dist/qt_themes/colorful_midnight_blue/icons/index.theme8
-rw-r--r--dist/qt_themes/colorful_midnight_blue/style.qrc57
-rw-r--r--dist/qt_themes/qdarkstyle/rc/checkbox_checked.pngbin492 -> 1935 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/checkbox_checked_disabled.pngbin491 -> 1960 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/checkbox_checked_focus.pngbin252 -> 1813 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate.pngbin493 -> 492 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_disabled.pngbin492 -> 491 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_focus.pngbin249 -> 252 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/style.qss8
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/LICENSE.rst405
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/icons/16x16/lock.pngbin0 -> 304 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/icons/256x256/plus_folder.pngbin0 -> 3438 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/bad_folder.pngbin0 -> 1098 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/chip.pngbin0 -> 15120 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/folder.pngbin0 -> 542 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/plus.pngbin0 -> 339 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/sd_card.pngbin0 -> 676 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/icons/index.theme14
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/Hmovetoolbar.pngbin0 -> 220 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/Hsepartoolbar.pngbin0 -> 172 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/Vmovetoolbar.pngbin0 -> 228 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/Vsepartoolbar.pngbin0 -> 187 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down.pngbin0 -> 525 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down@2x.pngbin0 -> 977 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_disabled.pngbin0 -> 547 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_disabled@2x.pngbin0 -> 1040 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_focus.pngbin0 -> 530 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_focus@2x.pngbin0 -> 1025 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_pressed.pngbin0 -> 518 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_pressed@2x.pngbin0 -> 1007 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left.pngbin0 -> 546 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left@2x.pngbin0 -> 1072 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_disabled.pngbin0 -> 569 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_disabled@2x.pngbin0 -> 1126 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_focus.pngbin0 -> 565 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_focus@2x.pngbin0 -> 1143 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_pressed.pngbin0 -> 541 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_pressed@2x.pngbin0 -> 1120 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right.pngbin0 -> 518 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right@2x.pngbin0 -> 1062 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_disabled.pngbin0 -> 553 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_disabled@2x.pngbin0 -> 1143 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_focus.pngbin0 -> 543 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_focus@2x.pngbin0 -> 1139 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_pressed.pngbin0 -> 544 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_pressed@2x.pngbin0 -> 1121 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up.pngbin0 -> 512 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up@2x.pngbin0 -> 969 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_disabled.pngbin0 -> 538 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_disabled@2x.pngbin0 -> 1046 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_focus.pngbin0 -> 530 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_focus@2x.pngbin0 -> 1017 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_pressed.pngbin0 -> 518 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_pressed@2x.pngbin0 -> 998 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon.pngbin0 -> 1256 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon@2x.pngbin0 -> 3286 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_disabled.pngbin0 -> 1256 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_disabled@2x.pngbin0 -> 3286 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_focus.pngbin0 -> 1256 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_focus@2x.pngbin0 -> 3286 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_pressed.pngbin0 -> 1256 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_pressed@2x.pngbin0 -> 3286 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed-on.pngbin0 -> 147 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed.pngbin0 -> 350 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed@2x.pngbin0 -> 704 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_disabled.pngbin0 -> 373 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_disabled@2x.pngbin0 -> 729 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_focus.pngbin0 -> 380 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_focus@2x.pngbin0 -> 717 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_pressed.pngbin0 -> 372 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_pressed@2x.pngbin0 -> 725 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end.pngbin0 -> 142 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end@2x.pngbin0 -> 220 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_disabled.pngbin0 -> 146 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_disabled@2x.pngbin0 -> 225 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_focus.pngbin0 -> 146 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_focus@2x.pngbin0 -> 226 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_pressed.pngbin0 -> 146 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_pressed@2x.pngbin0 -> 225 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line.pngbin0 -> 130 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line@2x.pngbin0 -> 242 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_disabled.pngbin0 -> 134 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_disabled@2x.pngbin0 -> 248 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_focus.pngbin0 -> 134 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_focus@2x.pngbin0 -> 249 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_pressed.pngbin0 -> 134 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_pressed@2x.pngbin0 -> 248 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more.pngbin0 -> 155 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more@2x.pngbin0 -> 257 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_disabled.pngbin0 -> 162 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_disabled@2x.pngbin0 -> 265 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_focus.pngbin0 -> 162 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_focus@2x.pngbin0 -> 266 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_pressed.pngbin0 -> 162 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_pressed@2x.pngbin0 -> 265 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open-on.pngbin0 -> 150 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open.pngbin0 -> 354 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open@2x.pngbin0 -> 657 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_disabled.pngbin0 -> 375 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_disabled@2x.pngbin0 -> 682 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_focus.pngbin0 -> 367 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_focus@2x.pngbin0 -> 665 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_pressed.pngbin0 -> 369 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_pressed@2x.pngbin0 -> 661 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked.pngbin0 -> 452 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked@2x.pngbin0 -> 825 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_disabled.pngbin0 -> 467 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_disabled@2x.pngbin0 -> 845 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_focus.pngbin0 -> 441 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_focus@2x.pngbin0 -> 823 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_pressed.pngbin0 -> 418 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_pressed@2x.pngbin0 -> 829 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate.pngbin0 -> 581 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate@2x.pngbin0 -> 1081 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_disabled.pngbin0 -> 614 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_disabled@2x.pngbin0 -> 1105 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_focus.pngbin0 -> 576 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_focus@2x.pngbin0 -> 1066 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_pressed.pngbin0 -> 563 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_pressed@2x.pngbin0 -> 1087 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked.pngbin0 -> 397 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked@2x.pngbin0 -> 828 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_disabled.pngbin0 -> 386 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_disabled@2x.pngbin0 -> 875 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_focus.pngbin0 -> 394 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_focus@2x.pngbin0 -> 866 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_pressed.pngbin0 -> 403 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_pressed@2x.pngbin0 -> 861 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/close-hover.pngbin0 -> 598 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/close-pressed.pngbin0 -> 598 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/close.pngbin0 -> 586 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/down_arrow.pngbin0 -> 165 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/down_arrow_disabled.pngbin0 -> 166 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/left_arrow.pngbin0 -> 166 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/left_arrow_disabled.pngbin0 -> 166 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal.pngbin0 -> 117 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal@2x.pngbin0 -> 135 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_disabled.pngbin0 -> 121 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_disabled@2x.pngbin0 -> 139 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_focus.pngbin0 -> 120 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_focus@2x.pngbin0 -> 138 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_pressed.pngbin0 -> 120 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_pressed@2x.pngbin0 -> 138 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical.pngbin0 -> 130 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical@2x.pngbin0 -> 242 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_disabled.pngbin0 -> 134 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_disabled@2x.pngbin0 -> 248 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_focus.pngbin0 -> 134 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_focus@2x.pngbin0 -> 249 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_pressed.pngbin0 -> 134 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_pressed@2x.pngbin0 -> 248 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked.pngbin0 -> 1224 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked@2x.pngbin0 -> 2714 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_disabled.pngbin0 -> 1325 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_disabled@2x.pngbin0 -> 2893 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_focus.pngbin0 -> 1293 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_focus@2x.pngbin0 -> 2736 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_pressed.pngbin0 -> 1276 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_pressed@2x.pngbin0 -> 2765 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked.pngbin0 -> 963 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked@2x.pngbin0 -> 2195 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_disabled.pngbin0 -> 1040 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_disabled@2x.pngbin0 -> 2294 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_focus.pngbin0 -> 1032 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_focus@2x.pngbin0 -> 2186 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_pressed.pngbin0 -> 1022 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_pressed@2x.pngbin0 -> 2197 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/right_arrow.pngbin0 -> 160 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/right_arrow_disabled.pngbin0 -> 160 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/sizegrip.pngbin0 -> 129 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-branch-end.pngbin0 -> 224 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-branch-more.pngbin0 -> 182 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-vline.pngbin0 -> 239 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal.pngbin0 -> 150 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal@2x.pngbin0 -> 304 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_disabled.pngbin0 -> 155 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_disabled@2x.pngbin0 -> 308 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_focus.pngbin0 -> 154 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_focus@2x.pngbin0 -> 311 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_pressed.pngbin0 -> 154 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_pressed@2x.pngbin0 -> 307 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical.pngbin0 -> 137 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical@2x.pngbin0 -> 201 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_disabled.pngbin0 -> 140 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_disabled@2x.pngbin0 -> 212 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_focus.pngbin0 -> 144 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_focus@2x.pngbin0 -> 211 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_pressed.pngbin0 -> 143 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_pressed@2x.pngbin0 -> 204 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal.pngbin0 -> 145 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal@2x.pngbin0 -> 286 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_disabled.pngbin0 -> 151 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_disabled@2x.pngbin0 -> 292 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_focus.pngbin0 -> 149 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_focus@2x.pngbin0 -> 294 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_pressed.pngbin0 -> 149 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_pressed@2x.pngbin0 -> 289 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical.pngbin0 -> 133 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical@2x.pngbin0 -> 191 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_disabled.pngbin0 -> 135 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_disabled@2x.pngbin0 -> 199 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_focus.pngbin0 -> 139 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_focus@2x.pngbin0 -> 196 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_pressed.pngbin0 -> 138 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_pressed@2x.pngbin0 -> 193 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent.pngbin0 -> 104 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent@2x.pngbin0 -> 117 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_disabled.pngbin0 -> 104 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_disabled@2x.pngbin0 -> 117 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_focus.pngbin0 -> 104 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_focus@2x.pngbin0 -> 117 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_pressed.pngbin0 -> 104 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_pressed@2x.pngbin0 -> 117 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/undock.pngbin0 -> 578 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/up_arrow.pngbin0 -> 158 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/up_arrow_disabled.pngbin0 -> 159 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close.pngbin0 -> 766 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close@2x.pngbin0 -> 1690 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_disabled.pngbin0 -> 838 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_disabled@2x.pngbin0 -> 1724 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_focus.pngbin0 -> 756 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_focus@2x.pngbin0 -> 1704 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_pressed.pngbin0 -> 745 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_pressed@2x.pngbin0 -> 1679 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip.pngbin0 -> 426 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip@2x.pngbin0 -> 735 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_disabled.pngbin0 -> 447 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_disabled@2x.pngbin0 -> 768 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_focus.pngbin0 -> 435 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_focus@2x.pngbin0 -> 738 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_pressed.pngbin0 -> 444 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_pressed@2x.pngbin0 -> 729 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize.pngbin0 -> 193 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize@2x.pngbin0 -> 316 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_disabled.pngbin0 -> 206 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_disabled@2x.pngbin0 -> 332 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_focus.pngbin0 -> 208 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_focus@2x.pngbin0 -> 339 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_pressed.pngbin0 -> 202 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_pressed@2x.pngbin0 -> 336 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock.pngbin0 -> 510 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock@2x.pngbin0 -> 875 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_disabled.pngbin0 -> 541 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_disabled@2x.pngbin0 -> 910 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_focus.pngbin0 -> 519 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_focus@2x.pngbin0 -> 877 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_pressed.pngbin0 -> 523 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_pressed@2x.pngbin0 -> 880 bytes
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/style.qrc225
-rw-r--r--dist/qt_themes/qdarkstyle_midnight_blue/style.qss2174
-rw-r--r--src/audio_core/stream.cpp7
-rw-r--r--src/common/string_util.h12
-rw-r--r--src/common/virtual_buffer.cpp2
-rw-r--r--src/core/CMakeLists.txt3
-rw-r--r--src/core/core.cpp6
-rw-r--r--src/core/core_timing.cpp16
-rw-r--r--src/core/core_timing.h7
-rw-r--r--src/core/device_memory.cpp5
-rw-r--r--src/core/device_memory.h8
-rw-r--r--src/core/file_sys/registered_cache.cpp101
-rw-r--r--src/core/file_sys/registered_cache.h6
-rw-r--r--src/core/file_sys/xts_archive.cpp14
-rw-r--r--src/core/hardware_interrupt_manager.cpp4
-rw-r--r--src/core/hle/kernel/kernel.cpp2
-rw-r--r--src/core/hle/kernel/server_session.cpp6
-rw-r--r--src/core/hle/kernel/time_manager.cpp10
-rw-r--r--src/core/hle/service/am/am.cpp1
-rw-r--r--src/core/hle/service/am/applets/software_keyboard.cpp61
-rw-r--r--src/core/hle/service/am/applets/software_keyboard.h1
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.cpp53
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.cpp17
-rw-r--r--src/core/hle/service/hid/hid.cpp8
-rw-r--r--src/core/hle/service/hid/hid.h2
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp4
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h30
-rw-r--r--src/core/hle/service/vi/vi.cpp4
-rw-r--r--src/core/memory/cheat_engine.cpp12
-rw-r--r--src/core/memory/cheat_engine.h2
-rw-r--r--src/core/network/network.cpp654
-rw-r--r--src/core/network/network.h87
-rw-r--r--src/core/network/sockets.h94
-rw-r--r--src/core/settings.cpp1
-rw-r--r--src/core/settings.h1
-rw-r--r--src/core/tools/freezer.cpp11
-rw-r--r--src/core/tools/freezer.h2
-rw-r--r--src/input_common/gcadapter/gc_adapter.cpp191
-rw-r--r--src/input_common/gcadapter/gc_adapter.h44
-rw-r--r--src/input_common/gcadapter/gc_poller.cpp6
-rw-r--r--src/input_common/udp/client.cpp1
-rw-r--r--src/tests/core/core_timing.cpp4
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h9
-rw-r--r--src/video_core/compatible_formats.cpp87
-rw-r--r--src/video_core/gpu.h86
-rw-r--r--src/video_core/gpu_thread.cpp4
-rw-r--r--src/video_core/macro/macro_jit_x64.cpp1
-rw-r--r--src/video_core/morton.cpp276
-rw-r--r--src/video_core/renderer_opengl/gl_arb_decompiler.cpp117
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_device.h5
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp103
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h4
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp5
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp26
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.cpp71
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h17
-rw-r--r--src/video_core/renderer_opengl/gl_stream_buffer.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp162
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp4
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.cpp1
-rw-r--r--src/video_core/renderer_vulkan/maxwell_to_vk.cpp173
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_device.cpp9
-rw-r--r--src/video_core/renderer_vulkan/vk_device.h5
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp17
-rw-r--r--src/video_core/renderer_vulkan/vk_swapchain.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp12
-rw-r--r--src/video_core/shader/decode/arithmetic_integer.cpp6
-rw-r--r--src/video_core/shader/decode/image.cpp54
-rw-r--r--src/video_core/shader/decode/other.cpp3
-rw-r--r--src/video_core/shader/decode/video.cpp19
-rw-r--r--src/video_core/shader/decode/xmad.cpp15
-rw-r--r--src/video_core/shader/shader_ir.cpp4
-rw-r--r--src/video_core/surface.cpp257
-rw-r--r--src/video_core/surface.h770
-rw-r--r--src/video_core/texture_cache/format_lookup_table.cpp149
-rw-r--r--src/video_core/texture_cache/surface_base.cpp2
-rw-r--r--src/video_core/texture_cache/surface_params.cpp111
-rw-r--r--src/video_core/texture_cache/texture_cache.h8
-rw-r--r--src/video_core/textures/convert.cpp6
-rw-r--r--src/video_core/textures/decoders.cpp89
-rw-r--r--src/video_core/textures/decoders.h4
-rw-r--r--src/video_core/textures/texture.h49
-rw-r--r--src/yuzu/configuration/config.cpp5
-rw-r--r--src/yuzu/configuration/configuration_shared.cpp74
-rw-r--r--src/yuzu/configuration/configuration_shared.h20
-rw-r--r--src/yuzu/configuration/configure_audio.cpp23
-rw-r--r--src/yuzu/configuration/configure_audio.h6
-rw-r--r--src/yuzu/configuration/configure_audio.ui151
-rw-r--r--src/yuzu/configuration/configure_debug.ui22
-rw-r--r--src/yuzu/configuration/configure_general.cpp37
-rw-r--r--src/yuzu/configuration/configure_general.h7
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp54
-rw-r--r--src/yuzu/configuration/configure_graphics.h7
-rw-r--r--src/yuzu/configuration/configure_graphics.ui282
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.cpp68
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.h9
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.ui161
-rw-r--r--src/yuzu/configuration/configure_system.cpp115
-rw-r--r--src/yuzu/configuration/configure_system.h7
-rw-r--r--src/yuzu/configuration/configure_system.ui972
-rw-r--r--src/yuzu/debugger/wait_tree.cpp5
-rw-r--r--src/yuzu/game_list.cpp34
-rw-r--r--src/yuzu/game_list.h15
-rw-r--r--src/yuzu/main.cpp182
-rw-r--r--src/yuzu/main.h9
-rw-r--r--src/yuzu/uisettings.cpp2
-rw-r--r--src/yuzu/uisettings.h2
360 files changed, 6770 insertions, 2646 deletions
diff --git a/dist/qt_themes/colorful_midnight_blue/icons/16x16/lock.png b/dist/qt_themes/colorful_midnight_blue/icons/16x16/lock.png
new file mode 100644
index 000000000..32c505848
--- /dev/null
+++ b/dist/qt_themes/colorful_midnight_blue/icons/16x16/lock.png
Binary files differ
diff --git a/dist/qt_themes/colorful_midnight_blue/icons/index.theme b/dist/qt_themes/colorful_midnight_blue/icons/index.theme
new file mode 100644
index 000000000..e23bfe6f9
--- /dev/null
+++ b/dist/qt_themes/colorful_midnight_blue/icons/index.theme
@@ -0,0 +1,8 @@
1[Icon Theme]
2Name=colorful_midnight_blue
3Comment=Colorful theme (Midnight Blue style)
4Inherits=default
5Directories=16x16
6
7[16x16]
8Size=16
diff --git a/dist/qt_themes/colorful_midnight_blue/style.qrc b/dist/qt_themes/colorful_midnight_blue/style.qrc
new file mode 100644
index 000000000..fd33bc850
--- /dev/null
+++ b/dist/qt_themes/colorful_midnight_blue/style.qrc
@@ -0,0 +1,57 @@
1<RCC>
2 <qresource prefix="icons/colorful_midnight_blue">
3 <file alias="index.theme">icons/index.theme</file>
4 <file alias="16x16/lock.png">icons/16x16/lock.png</file>
5 <file alias="48x48/bad_folder.png">../colorful/icons/48x48/bad_folder.png</file>
6 <file alias="48x48/chip.png">../colorful/icons/48x48/chip.png</file>
7 <file alias="48x48/folder.png">../colorful/icons/48x48/folder.png</file>
8 <file alias="48x48/plus.png">../colorful/icons/48x48/plus.png</file>
9 <file alias="48x48/sd_card.png">../colorful/icons/48x48/sd_card.png</file>
10 <file alias="256x256/plus_folder.png">../colorful/icons/256x256/plus_folder.png</file>
11 </qresource>
12
13 <qresource prefix="qss_icons">
14 <file alias="rc/up_arrow_disabled.png">../qdarkstyle_midnight_blue/rc/up_arrow_disabled.png</file>
15 <file alias="rc/Hmovetoolbar.png">../qdarkstyle_midnight_blue/rc/Hmovetoolbar.png</file>
16 <file alias="rc/stylesheet-branch-end.png">../qdarkstyle_midnight_blue/rc/stylesheet-branch-end.png</file>
17 <file alias="rc/branch_closed-on.png">../qdarkstyle_midnight_blue/rc/branch_closed-on.png</file>
18 <file alias="rc/stylesheet-vline.png">../qdarkstyle_midnight_blue/rc/stylesheet-vline.png</file>
19 <file alias="rc/branch_closed.png">../qdarkstyle_midnight_blue/rc/branch_closed.png</file>
20 <file alias="rc/branch_open-on.png">../qdarkstyle_midnight_blue/rc/branch_open-on.png</file>
21 <file alias="rc/transparent.png">../qdarkstyle_midnight_blue/rc/transparent.png</file>
22 <file alias="rc/right_arrow_disabled.png">../qdarkstyle_midnight_blue/rc/right_arrow_disabled.png</file>
23 <file alias="rc/sizegrip.png">../qdarkstyle_midnight_blue/rc/sizegrip.png</file>
24 <file alias="rc/close.png">../qdarkstyle_midnight_blue/rc/close.png</file>
25 <file alias="rc/close-hover.png">../qdarkstyle_midnight_blue/rc/close-hover.png</file>
26 <file alias="rc/close-pressed.png">../qdarkstyle_midnight_blue/rc/close-pressed.png</file>
27 <file alias="rc/down_arrow.png">../qdarkstyle_midnight_blue/rc/down_arrow.png</file>
28 <file alias="rc/Vmovetoolbar.png">../qdarkstyle_midnight_blue/rc/Vmovetoolbar.png</file>
29 <file alias="rc/left_arrow.png">../qdarkstyle_midnight_blue/rc/left_arrow.png</file>
30 <file alias="rc/stylesheet-branch-more.png">../qdarkstyle_midnight_blue/rc/stylesheet-branch-more.png</file>
31 <file alias="rc/up_arrow.png">../qdarkstyle_midnight_blue/rc/up_arrow.png</file>
32 <file alias="rc/right_arrow.png">../qdarkstyle_midnight_blue/rc/right_arrow.png</file>
33 <file alias="rc/left_arrow_disabled.png">../qdarkstyle_midnight_blue/rc/left_arrow_disabled.png</file>
34 <file alias="rc/Hsepartoolbar.png">../qdarkstyle_midnight_blue/rc/Hsepartoolbar.png</file>
35 <file alias="rc/branch_open.png">../qdarkstyle_midnight_blue/rc/branch_open.png</file>
36 <file alias="rc/Vsepartoolbar.png">../qdarkstyle_midnight_blue/rc/Vsepartoolbar.png</file>
37 <file alias="rc/down_arrow_disabled.png">../qdarkstyle_midnight_blue/rc/down_arrow_disabled.png</file>
38 <file alias="rc/undock.png">../qdarkstyle_midnight_blue/rc/undock.png</file>
39 <file alias="rc/checkbox_checked_disabled.png">../qdarkstyle_midnight_blue/rc/checkbox_checked_disabled.png</file>
40 <file alias="rc/checkbox_checked_focus.png">../qdarkstyle_midnight_blue/rc/checkbox_checked_focus.png</file>
41 <file alias="rc/checkbox_checked.png">../qdarkstyle_midnight_blue/rc/checkbox_checked.png</file>
42 <file alias="rc/checkbox_indeterminate.png">../qdarkstyle_midnight_blue/rc/checkbox_indeterminate.png</file>
43 <file alias="rc/checkbox_indeterminate_focus.png">../qdarkstyle_midnight_blue/rc/checkbox_indeterminate_focus.png</file>
44 <file alias="rc/checkbox_unchecked_disabled.png">../qdarkstyle_midnight_blue/rc/checkbox_unchecked_disabled.png</file>
45 <file alias="rc/checkbox_unchecked_focus.png">../qdarkstyle_midnight_blue/rc/checkbox_unchecked_focus.png</file>
46 <file alias="rc/checkbox_unchecked.png">../qdarkstyle_midnight_blue/rc/checkbox_unchecked.png</file>
47 <file alias="rc/radio_checked_disabled.png">../qdarkstyle_midnight_blue/rc/radio_checked_disabled.png</file>
48 <file alias="rc/radio_checked_focus.png">../qdarkstyle_midnight_blue/rc/radio_checked_focus.png</file>
49 <file alias="rc/radio_checked.png">../qdarkstyle_midnight_blue/rc/radio_checked.png</file>
50 <file alias="rc/radio_unchecked_disabled.png">../qdarkstyle_midnight_blue/rc/radio_unchecked_disabled.png</file>
51 <file alias="rc/radio_unchecked_focus.png">../qdarkstyle_midnight_blue/rc/radio_unchecked_focus.png</file>
52 <file alias="rc/radio_unchecked.png">../qdarkstyle_midnight_blue/rc/radio_unchecked.png</file>
53 </qresource>
54 <qresource prefix="colorful_midnight_blue">
55 <file alias="style.qss">../qdarkstyle_midnight_blue/style.qss</file>
56 </qresource>
57</RCC>
diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_checked.png b/dist/qt_themes/qdarkstyle/rc/checkbox_checked.png
index 830cfee65..dd891298f 100644
--- a/dist/qt_themes/qdarkstyle/rc/checkbox_checked.png
+++ b/dist/qt_themes/qdarkstyle/rc/checkbox_checked.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_checked_disabled.png b/dist/qt_themes/qdarkstyle/rc/checkbox_checked_disabled.png
index cb63cc2fa..44bf145f8 100644
--- a/dist/qt_themes/qdarkstyle/rc/checkbox_checked_disabled.png
+++ b/dist/qt_themes/qdarkstyle/rc/checkbox_checked_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_checked_focus.png b/dist/qt_themes/qdarkstyle/rc/checkbox_checked_focus.png
index 671be273b..60238b21d 100644
--- a/dist/qt_themes/qdarkstyle/rc/checkbox_checked_focus.png
+++ b/dist/qt_themes/qdarkstyle/rc/checkbox_checked_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate.png b/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate.png
index 41024f768..830cfee65 100644
--- a/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate.png
+++ b/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_disabled.png b/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_disabled.png
index abdc01d90..cb63cc2fa 100644
--- a/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_disabled.png
+++ b/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_focus.png b/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_focus.png
index 415f9b6e1..671be273b 100644
--- a/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_focus.png
+++ b/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/style.qss b/dist/qt_themes/qdarkstyle/style.qss
index 2d5c9761f..2926a05fa 100644
--- a/dist/qt_themes/qdarkstyle/style.qss
+++ b/dist/qt_themes/qdarkstyle/style.qss
@@ -654,7 +654,11 @@ QAbstractSpinBox::down-arrow:hover {
654 image: url(:/qss_icons/rc/down_arrow.png); 654 image: url(:/qss_icons/rc/down_arrow.png);
655} 655}
656 656
657QLabel, 657QLabel {
658 border: 0;
659 background: transparent;
660}
661
658QTabWidget { 662QTabWidget {
659 border: 0; 663 border: 0;
660} 664}
@@ -1269,4 +1273,4 @@ QPushButton#RendererStatusBarButton:checked {
1269 1273
1270QPushButton#RendererStatusBarButton:!checked{ 1274QPushButton#RendererStatusBarButton:!checked{
1271 color: #00ccdd; 1275 color: #00ccdd;
1272} \ No newline at end of file 1276}
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/LICENSE.rst b/dist/qt_themes/qdarkstyle_midnight_blue/LICENSE.rst
new file mode 100644
index 000000000..e22b68735
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/LICENSE.rst
@@ -0,0 +1,405 @@
1License
2=======
3
4The MIT License (MIT) - Code
5----------------------------
6
7Copyright (c) 2013-2019 Colin Duquesnoy
8
9Permission is hereby granted, free of charge, to any person obtaining a
10copy of this software and associated documentation files (the
11"Software"), to deal in the Software without restriction, including
12without limitation the rights to use, copy, modify, merge, publish,
13distribute, sublicense, and/or sell copies of the Software, and to
14permit persons to whom the Software is furnished to do so, subject to
15the following conditions:
16
17The above copyright notice and this permission notice shall be included
18in all copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28
29Creative Commons Attribution International 4.0 - Images
30-------------------------------------------------------
31
32QDarkStyle (c) 2013-2019 Colin Duquesnoy
33QDarkStyle (c) 2019-2019 Daniel Cosmo Pizetta
34
35Creative Commons Corporation (“Creative Commons”) is not a law firm and
36does not provide legal services or legal advice. Distribution of
37Creative Commons public licenses does not create a lawyer-client or
38other relationship. Creative Commons makes its licenses and related
39information available on an “as-is” basis. Creative Commons gives no
40warranties regarding its licenses, any material licensed under their
41terms and conditions, or any related information. Creative Commons
42disclaims all liability for damages resulting from their use to the
43fullest extent possible.
44
45Using Creative Commons Public Licenses
46~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47
48Creative Commons public licenses provide a standard set of terms and
49conditions that creators and other rights holders may use to share
50original works of authorship and other material subject to copyright and
51certain other rights specified in the public license below. The
52following considerations are for informational purposes only, are not
53exhaustive, and do not form part of our licenses.
54
55- **Considerations for licensors:** Our public licenses are intended
56 for use by those authorized to give the public permission to use
57 material in ways otherwise restricted by copyright and certain other
58 rights. Our licenses are irrevocable. Licensors should read and
59 understand the terms and conditions of the license they choose before
60 applying it. Licensors should also secure all rights necessary before
61 applying our licenses so that the public can reuse the material as
62 expected. Licensors should clearly mark any material not subject to
63 the license. This includes other CC-licensed material, or material
64 used under an exception or limitation to copyright. `More
65 considerations for
66 licensors <http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors>`__.
67
68- **Considerations for the public:** By using one of our public
69 licenses, a licensor grants the public permission to use the licensed
70 material under specified terms and conditions. If the licensor’s
71 permission is not necessary for any reason–for example, because of
72 any applicable exception or limitation to copyright–then that use is
73 not regulated by the license. Our licenses grant only permissions
74 under copyright and certain other rights that a licensor has
75 authority to grant. Use of the licensed material may still be
76 restricted for other reasons, including because others have copyright
77 or other rights in the material. A licensor may make special
78 requests, such as asking that all changes be marked or described.
79 Although not required by our licenses, you are encouraged to respect
80 those requests where reasonable. `More considerations for the
81 public <http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees>`__.
82
83
84Creative Commons Attribution 4.0 International Public License
85-------------------------------------------------------------
86
87By exercising the Licensed Rights (defined below), You accept and agree
88to be bound by the terms and conditions of this Creative Commons
89Attribution 4.0 International Public License ("Public License"). To the
90extent this Public License may be interpreted as a contract, You are
91granted the Licensed Rights in consideration of Your acceptance of these
92terms and conditions, and the Licensor grants You such rights in
93consideration of benefits the Licensor receives from making the Licensed
94Material available under these terms and conditions.
95
96Section 1 – Definitions
97~~~~~~~~~~~~~~~~~~~~~~~
98
99a. **Adapted Material** means material subject to Copyright and Similar
100 Rights that is derived from or based upon the Licensed Material and
101 in which the Licensed Material is translated, altered, arranged,
102 transformed, or otherwise modified in a manner requiring permission
103 under the Copyright and Similar Rights held by the Licensor. For
104 purposes of this Public License, where the Licensed Material is a
105 musical work, performance, or sound recording, Adapted Material is
106 always produced where the Licensed Material is synched in timed
107 relation with a moving image.
108
109b. **Adapter's License** means the license You apply to Your Copyright
110 and Similar Rights in Your contributions to Adapted Material in
111 accordance with the terms and conditions of this Public License.
112
113c. **Copyright and Similar Rights** means copyright and/or similar
114 rights closely related to copyright including, without limitation,
115 performance, broadcast, sound recording, and Sui Generis Database
116 Rights, without regard to how the rights are labeled or categorized.
117 For purposes of this Public License, the rights specified in Section
118 2(b)(1)-(2) are not Copyright and Similar Rights.
119
120d. **Effective Technological Measures** means those measures that, in
121 the absence of proper authority, may not be circumvented under laws
122 fulfilling obligations under Article 11 of the WIPO Copyright Treaty
123 adopted on December 20, 1996, and/or similar international
124 agreements.
125
126e. **Exceptions and Limitations** means fair use, fair dealing, and/or
127 any other exception or limitation to Copyright and Similar Rights
128 that applies to Your use of the Licensed Material.
129
130f. **Licensed Material** means the artistic or literary work, database,
131 or other material to which the Licensor applied this Public License.
132
133g. **Licensed Rights** means the rights granted to You subject to the
134 terms and conditions of this Public License, which are limited to all
135 Copyright and Similar Rights that apply to Your use of the Licensed
136 Material and that the Licensor has authority to license.
137
138h. **Licensor** means the individual(s) or entity(ies) granting rights
139 under this Public License.
140
141i. **Share** means to provide material to the public by any means or
142 process that requires permission under the Licensed Rights, such as
143 reproduction, public display, public performance, distribution,
144 dissemination, communication, or importation, and to make material
145 available to the public including in ways that members of the public
146 may access the material from a place and at a time individually
147 chosen by them.
148
149j. **Sui Generis Database Rights** means rights other than copyright
150 resulting from Directive 96/9/EC of the European Parliament and of
151 the Council of 11 March 1996 on the legal protection of databases, as
152 amended and/or succeeded, as well as other essentially equivalent
153 rights anywhere in the world.
154
155k. **You** means the individual or entity exercising the Licensed Rights
156 under this Public License. Your has a corresponding meaning.
157
158Section 2 – Scope
159~~~~~~~~~~~~~~~~~
160
161a. **License grant.**
162
1631. Subject to the terms and conditions of this Public License, the
164 Licensor hereby grants You a worldwide, royalty-free,
165 non-sublicensable, non-exclusive, irrevocable license to exercise the
166 Licensed Rights in the Licensed Material to:
167
168 A. reproduce and Share the Licensed Material, in whole or in part;
169 and
170
171 B. produce, reproduce, and Share Adapted Material.
172
1732. **Exceptions and Limitations.** For the avoidance of doubt, where
174 Exceptions and Limitations apply to Your use, this Public License
175 does not apply, and You do not need to comply with its terms and
176 conditions.
177
1783. **Term.** The term of this Public License is specified in Section
179 6(a).
180
1814. **Media and formats; technical modifications allowed.** The Licensor
182 authorizes You to exercise the Licensed Rights in all media and
183 formats whether now known or hereafter created, and to make technical
184 modifications necessary to do so. The Licensor waives and/or agrees
185 not to assert any right or authority to forbid You from making
186 technical modifications necessary to exercise the Licensed Rights,
187 including technical modifications necessary to circumvent Effective
188 Technological Measures. For purposes of this Public License, simply
189 making modifications authorized by this Section 2(a)(4) never
190 produces Adapted Material.
191
1925. **Downstream recipients.**
193
194 A. **Offer from the Licensor – Licensed Material.** Every recipient
195 of the Licensed Material automatically receives an offer from the
196 Licensor to exercise the Licensed Rights under the terms and
197 conditions of this Public License.
198
199 B. **No downstream restrictions.** You may not offer or impose any
200 additional or different terms or conditions on, or apply any
201 Effective Technological Measures to, the Licensed Material if doing
202 so restricts exercise of the Licensed Rights by any recipient of the
203 Licensed Material.
204
2056. **No endorsement.** Nothing in this Public License constitutes or may
206 be construed as permission to assert or imply that You are, or that
207 Your use of the Licensed Material is, connected with, or sponsored,
208 endorsed, or granted official status by, the Licensor or others
209 designated to receive attribution as provided in Section
210 3(a)(1)(A)(i).
211
212b. **Other rights.**
213
2141. Moral rights, such as the right of integrity, are not licensed under
215 this Public License, nor are publicity, privacy, and/or other similar
216 personality rights; however, to the extent possible, the Licensor
217 waives and/or agrees not to assert any such rights held by the
218 Licensor to the limited extent necessary to allow You to exercise the
219 Licensed Rights, but not otherwise.
220
2212. Patent and trademark rights are not licensed under this Public
222 License.
223
2243. To the extent possible, the Licensor waives any right to collect
225 royalties from You for the exercise of the Licensed Rights, whether
226 directly or through a collecting society under any voluntary or
227 waivable statutory or compulsory licensing scheme. In all other cases
228 the Licensor expressly reserves any right to collect such royalties.
229
230Section 3 – License Conditions
231~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
232
233Your exercise of the Licensed Rights is expressly made subject to the
234following conditions.
235
236a. **Attribution.**
237
2381. If You Share the Licensed Material (including in modified form), You
239 must:
240
241 A. retain the following if it is supplied by the Licensor with the
242 Licensed Material:
243
244 i. identification of the creator(s) of the Licensed Material and any
245 others designated to receive attribution, in any reasonable manner
246 requested by the Licensor (including by pseudonym if designated);
247
248 ii. a copyright notice;
249
250 iii. a notice that refers to this Public License;
251
252 iv. a notice that refers to the disclaimer of warranties;
253
254 v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
255
256 B. indicate if You modified the Licensed Material and retain an
257 indication of any previous modifications; and
258
259 C. indicate the Licensed Material is licensed under this Public
260 License, and include the text of, or the URI or hyperlink to, this
261 Public License.
262
2632. You may satisfy the conditions in Section 3(a)(1) in any reasonable
264 manner based on the medium, means, and context in which You Share the
265 Licensed Material. For example, it may be reasonable to satisfy the
266 conditions by providing a URI or hyperlink to a resource that
267 includes the required information.
268
2693. If requested by the Licensor, You must remove any of the information
270 required by Section 3(a)(1)(A) to the extent reasonably practicable.
271
2724. If You Share Adapted Material You produce, the Adapter's License You
273 apply must not prevent recipients of the Adapted Material from
274 complying with this Public License.
275
276Section 4 – Sui Generis Database Rights
277~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
278
279Where the Licensed Rights include Sui Generis Database Rights that apply
280to Your use of the Licensed Material:
281
282a. for the avoidance of doubt, Section 2(a)(1) grants You the right to
283 extract, reuse, reproduce, and Share all or a substantial portion of
284 the contents of the database;
285
286b. if You include all or a substantial portion of the database contents
287 in a database in which You have Sui Generis Database Rights, then the
288 database in which You have Sui Generis Database Rights (but not its
289 individual contents) is Adapted Material; and
290
291c. You must comply with the conditions in Section 3(a) if You Share all
292 or a substantial portion of the contents of the database.
293
294For the avoidance of doubt, this Section 4 supplements and does not
295replace Your obligations under this Public License where the Licensed
296Rights include other Copyright and Similar Rights.
297
298Section 5 – Disclaimer of Warranties and Limitation of Liability
299~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
300
301a. Unless otherwise separately undertaken by the Licensor, to the
302 extent possible, the Licensor offers the Licensed Material as-is and
303 as-available, and makes no representations or warranties of any kind
304 concerning the Licensed Material, whether express, implied,
305 statutory, or other. This includes, without limitation, warranties of
306 title, merchantability, fitness for a particular purpose,
307 non-infringement, absence of latent or other defects, accuracy, or
308 the presence or absence of errors, whether or not known or
309 discoverable. Where disclaimers of warranties are not allowed in full
310 or in part, this disclaimer may not apply to You.
311
312b. To the extent possible, in no event will the Licensor be liable to
313 You on any legal theory (including, without limitation, negligence)
314 or otherwise for any direct, special, indirect, incidental,
315 consequential, punitive, exemplary, or other losses, costs, expenses,
316 or damages arising out of this Public License or use of the Licensed
317 Material, even if the Licensor has been advised of the possibility of
318 such losses, costs, expenses, or damages. Where a limitation of
319 liability is not allowed in full or in part, this limitation may not
320 apply to You.
321
322c. The disclaimer of warranties and limitation of liability provided
323 above shall be interpreted in a manner that, to the extent possible,
324 most closely approximates an absolute disclaimer and waiver of all
325 liability.
326
327Section 6 – Term and Termination
328~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
329
330a. This Public License applies for the term of the Copyright and Similar
331 Rights licensed here. However, if You fail to comply with this Public
332 License, then Your rights under this Public License terminate
333 automatically.
334
335b. Where Your right to use the Licensed Material has terminated under
336 Section 6(a), it reinstates:
337
3381. automatically as of the date the violation is cured, provided it is
339 cured within 30 days of Your discovery of the violation; or
340
3412. upon express reinstatement by the Licensor.
342
343For the avoidance of doubt, this Section 6(b) does not affect any right
344the Licensor may have to seek remedies for Your violations of this
345Public License.
346
347c. For the avoidance of doubt, the Licensor may also offer the Licensed
348 Material under separate terms or conditions or stop distributing the
349 Licensed Material at any time; however, doing so will not terminate
350 this Public License.
351
352d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
353 License.
354
355Section 7 – Other Terms and Conditions
356~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
357
358a. The Licensor shall not be bound by any additional or different terms
359 or conditions communicated by You unless expressly agreed.
360
361b. Any arrangements, understandings, or agreements regarding the
362 Licensed Material not stated herein are separate from and independent
363 of the terms and conditions of this Public License.
364
365Section 8 – Interpretation
366~~~~~~~~~~~~~~~~~~~~~~~~~~
367
368a. For the avoidance of doubt, this Public License does not, and shall
369 not be interpreted to, reduce, limit, restrict, or impose conditions
370 on any use of the Licensed Material that could lawfully be made
371 without permission under this Public License.
372
373b. To the extent possible, if any provision of this Public License is
374 deemed unenforceable, it shall be automatically reformed to the
375 minimum extent necessary to make it enforceable. If the provision
376 cannot be reformed, it shall be severed from this Public License
377 without affecting the enforceability of the remaining terms and
378 conditions.
379
380c. No term or condition of this Public License will be waived and no
381 failure to comply consented to unless expressly agreed to by the
382 Licensor.
383
384d. Nothing in this Public License constitutes or may be interpreted as a
385 limitation upon, or waiver of, any privileges and immunities that
386 apply to the Licensor or You, including from the legal processes of
387 any jurisdiction or authority.
388
389 Creative Commons is not a party to its public licenses.
390 Notwithstanding, Creative Commons may elect to apply one of its
391 public licenses to material it publishes and in those instances will
392 be considered the “Licensor.” Except for the limited purpose of
393 indicating that material is shared under a Creative Commons public
394 license or as otherwise permitted by the Creative Commons policies
395 published at
396 `creativecommons.org/policies <http://creativecommons.org/policies>`__,
397 Creative Commons does not authorize the use of the trademark
398 “Creative Commons” or any other trademark or logo of Creative
399 Commons without its prior written consent including, without
400 limitation, in connection with any unauthorized modifications to any
401 of its public licenses or any other arrangements, understandings, or
402 agreements concerning use of licensed material. For the avoidance of
403 doubt, this paragraph does not form part of the public licenses.
404
405 Creative Commons may be contacted at creativecommons.org
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/16x16/lock.png b/dist/qt_themes/qdarkstyle_midnight_blue/icons/16x16/lock.png
new file mode 100644
index 000000000..c750a39e8
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/icons/16x16/lock.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/256x256/plus_folder.png b/dist/qt_themes/qdarkstyle_midnight_blue/icons/256x256/plus_folder.png
new file mode 100644
index 000000000..303f9a321
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/icons/256x256/plus_folder.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/bad_folder.png b/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/bad_folder.png
new file mode 100644
index 000000000..4a9709623
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/bad_folder.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/chip.png b/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/chip.png
new file mode 100644
index 000000000..973fabd05
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/chip.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/folder.png b/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/folder.png
new file mode 100644
index 000000000..0f1e987d6
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/folder.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/plus.png b/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/plus.png
new file mode 100644
index 000000000..16cc8b4f4
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/plus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/sd_card.png b/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/sd_card.png
new file mode 100644
index 000000000..0291c6542
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/sd_card.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/index.theme b/dist/qt_themes/qdarkstyle_midnight_blue/icons/index.theme
new file mode 100644
index 000000000..447a6c8be
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/icons/index.theme
@@ -0,0 +1,14 @@
1[Icon Theme]
2Name=qdarkstyle_midnight_blue
3Comment=dark theme
4Inherits=default
5Directories=16x16,48x48,256x256
6
7[16x16]
8Size=16
9
10[48x48]
11Size=48
12
13[256x256]
14Size=256
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/Hmovetoolbar.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/Hmovetoolbar.png
new file mode 100644
index 000000000..cead99ed1
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/Hmovetoolbar.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/Hsepartoolbar.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/Hsepartoolbar.png
new file mode 100644
index 000000000..7f183c8b3
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/Hsepartoolbar.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/Vmovetoolbar.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/Vmovetoolbar.png
new file mode 100644
index 000000000..512edcecd
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/Vmovetoolbar.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/Vsepartoolbar.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/Vsepartoolbar.png
new file mode 100644
index 000000000..d9dc1561b
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/Vsepartoolbar.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down.png
new file mode 100644
index 000000000..c4e6894ba
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down@2x.png
new file mode 100644
index 000000000..bb8cbed0d
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_disabled.png
new file mode 100644
index 000000000..aa1d06c08
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_disabled@2x.png
new file mode 100644
index 000000000..86bf434b8
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_focus.png
new file mode 100644
index 000000000..1c42ee8f6
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_focus@2x.png
new file mode 100644
index 000000000..7374637c5
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_pressed.png
new file mode 100644
index 000000000..8139ee3e8
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_pressed@2x.png
new file mode 100644
index 000000000..5e9d225ff
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_down_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left.png
new file mode 100644
index 000000000..ef929fdf0
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left@2x.png
new file mode 100644
index 000000000..c8923d6f4
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_disabled.png
new file mode 100644
index 000000000..9c69561a7
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_disabled@2x.png
new file mode 100644
index 000000000..e52114312
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_focus.png
new file mode 100644
index 000000000..a1f070455
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_focus@2x.png
new file mode 100644
index 000000000..c4267e856
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_pressed.png
new file mode 100644
index 000000000..bd706cbdd
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_pressed@2x.png
new file mode 100644
index 000000000..341b2e541
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_left_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right.png
new file mode 100644
index 000000000..4f3388505
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right@2x.png
new file mode 100644
index 000000000..94b260965
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_disabled.png
new file mode 100644
index 000000000..0fbc6b04c
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_disabled@2x.png
new file mode 100644
index 000000000..8e9272a5b
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_focus.png
new file mode 100644
index 000000000..764940945
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_focus@2x.png
new file mode 100644
index 000000000..6d52b5fa3
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_pressed.png
new file mode 100644
index 000000000..a5f04522a
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_pressed@2x.png
new file mode 100644
index 000000000..6f6a8130c
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_right_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up.png
new file mode 100644
index 000000000..61d7574a4
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up@2x.png
new file mode 100644
index 000000000..d711fae16
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_disabled.png
new file mode 100644
index 000000000..18e8ecd8d
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_disabled@2x.png
new file mode 100644
index 000000000..fb4defb52
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_focus.png
new file mode 100644
index 000000000..a7acd9b66
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_focus@2x.png
new file mode 100644
index 000000000..9cd982a1d
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_pressed.png
new file mode 100644
index 000000000..390a80e21
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_pressed@2x.png
new file mode 100644
index 000000000..dd352cff3
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/arrow_up_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon.png
new file mode 100644
index 000000000..37a6158cc
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon@2x.png
new file mode 100644
index 000000000..e6e5cb916
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_disabled.png
new file mode 100644
index 000000000..37a6158cc
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_disabled@2x.png
new file mode 100644
index 000000000..e6e5cb916
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_focus.png
new file mode 100644
index 000000000..37a6158cc
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_focus@2x.png
new file mode 100644
index 000000000..e6e5cb916
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_pressed.png
new file mode 100644
index 000000000..37a6158cc
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_pressed@2x.png
new file mode 100644
index 000000000..e6e5cb916
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/base_icon_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed-on.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed-on.png
new file mode 100644
index 000000000..d081e9b3b
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed-on.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed.png
new file mode 100644
index 000000000..53e2c51f5
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed@2x.png
new file mode 100644
index 000000000..06cdefa5f
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_disabled.png
new file mode 100644
index 000000000..5106a1438
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_disabled@2x.png
new file mode 100644
index 000000000..180bae9e6
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_focus.png
new file mode 100644
index 000000000..c227f9f71
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_focus@2x.png
new file mode 100644
index 000000000..ad23d0d33
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_pressed.png
new file mode 100644
index 000000000..90845a81f
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_pressed@2x.png
new file mode 100644
index 000000000..60aaeb7fb
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_closed_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end.png
new file mode 100644
index 000000000..08b5559b2
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end@2x.png
new file mode 100644
index 000000000..ae6dbe991
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_disabled.png
new file mode 100644
index 000000000..027a8894a
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_disabled@2x.png
new file mode 100644
index 000000000..43c1b0c76
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_focus.png
new file mode 100644
index 000000000..fdb3160bb
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_focus@2x.png
new file mode 100644
index 000000000..3ca890449
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_pressed.png
new file mode 100644
index 000000000..1c2432dd4
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_pressed@2x.png
new file mode 100644
index 000000000..af0f8fa5a
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_end_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line.png
new file mode 100644
index 000000000..a3a564e44
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line@2x.png
new file mode 100644
index 000000000..1dbf71fc7
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_disabled.png
new file mode 100644
index 000000000..ecc7e6d93
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_disabled@2x.png
new file mode 100644
index 000000000..adc6446c9
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_focus.png
new file mode 100644
index 000000000..0037f175a
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_focus@2x.png
new file mode 100644
index 000000000..cb257a914
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_pressed.png
new file mode 100644
index 000000000..2d0856527
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_pressed@2x.png
new file mode 100644
index 000000000..803708fb4
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_line_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more.png
new file mode 100644
index 000000000..31b6cee87
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more@2x.png
new file mode 100644
index 000000000..f1f7a67f1
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_disabled.png
new file mode 100644
index 000000000..d4b604905
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_disabled@2x.png
new file mode 100644
index 000000000..3ef752108
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_focus.png
new file mode 100644
index 000000000..943c13d0b
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_focus@2x.png
new file mode 100644
index 000000000..9f53ef1fa
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_pressed.png
new file mode 100644
index 000000000..9037ed3b3
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_pressed@2x.png
new file mode 100644
index 000000000..675d52c76
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_more_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open-on.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open-on.png
new file mode 100644
index 000000000..ec372b27d
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open-on.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open.png
new file mode 100644
index 000000000..0861d0bc7
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open@2x.png
new file mode 100644
index 000000000..8850f7367
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_disabled.png
new file mode 100644
index 000000000..b6c80243b
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_disabled@2x.png
new file mode 100644
index 000000000..15ce9f265
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_focus.png
new file mode 100644
index 000000000..eadb0962a
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_focus@2x.png
new file mode 100644
index 000000000..7dfcbbe8a
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_pressed.png
new file mode 100644
index 000000000..2b22e8d08
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_pressed@2x.png
new file mode 100644
index 000000000..269a0cbee
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/branch_open_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked.png
new file mode 100644
index 000000000..e7ed08081
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked@2x.png
new file mode 100644
index 000000000..35f2ade58
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_disabled.png
new file mode 100644
index 000000000..512b0a3e4
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_disabled@2x.png
new file mode 100644
index 000000000..557383ec8
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_focus.png
new file mode 100644
index 000000000..0b90412f2
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_focus@2x.png
new file mode 100644
index 000000000..7aee03cbb
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_pressed.png
new file mode 100644
index 000000000..3d4c869b7
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_pressed@2x.png
new file mode 100644
index 000000000..bfbc14b94
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_checked_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate.png
new file mode 100644
index 000000000..c21ab99bf
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate@2x.png
new file mode 100644
index 000000000..2fc29cee6
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_disabled.png
new file mode 100644
index 000000000..1d3c21492
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_disabled@2x.png
new file mode 100644
index 000000000..bb8e7a747
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_focus.png
new file mode 100644
index 000000000..13ca4a7a4
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_focus@2x.png
new file mode 100644
index 000000000..3907eb8d4
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_pressed.png
new file mode 100644
index 000000000..12f83ceba
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_pressed@2x.png
new file mode 100644
index 000000000..5ff4f6629
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_indeterminate_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked.png
new file mode 100644
index 000000000..e2da452fa
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked@2x.png
new file mode 100644
index 000000000..3732d5406
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_disabled.png
new file mode 100644
index 000000000..c2e30c690
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_disabled@2x.png
new file mode 100644
index 000000000..c4bddb6eb
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_focus.png
new file mode 100644
index 000000000..c57f04d9f
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_focus@2x.png
new file mode 100644
index 000000000..1776ad048
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_pressed.png
new file mode 100644
index 000000000..be41236e1
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_pressed@2x.png
new file mode 100644
index 000000000..b1ad7c72f
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/checkbox_unchecked_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/close-hover.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/close-hover.png
new file mode 100644
index 000000000..657943a66
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/close-hover.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/close-pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/close-pressed.png
new file mode 100644
index 000000000..937d00598
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/close-pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/close.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/close.png
new file mode 100644
index 000000000..bc0f57610
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/close.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/down_arrow.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/down_arrow.png
new file mode 100644
index 000000000..e271f7f90
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/down_arrow.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/down_arrow_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/down_arrow_disabled.png
new file mode 100644
index 000000000..5805d9842
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/down_arrow_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/left_arrow.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/left_arrow.png
new file mode 100644
index 000000000..f808d2d72
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/left_arrow.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/left_arrow_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/left_arrow_disabled.png
new file mode 100644
index 000000000..f5b9af8a3
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/left_arrow_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal.png
new file mode 100644
index 000000000..11bc5c003
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal@2x.png
new file mode 100644
index 000000000..c229ac963
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_disabled.png
new file mode 100644
index 000000000..204df8058
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_disabled@2x.png
new file mode 100644
index 000000000..a4713c565
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_focus.png
new file mode 100644
index 000000000..ecda0c10b
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_focus@2x.png
new file mode 100644
index 000000000..84397efdb
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_pressed.png
new file mode 100644
index 000000000..fd5d864ca
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_pressed@2x.png
new file mode 100644
index 000000000..140552e4f
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_horizontal_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical.png
new file mode 100644
index 000000000..a3a564e44
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical@2x.png
new file mode 100644
index 000000000..1dbf71fc7
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_disabled.png
new file mode 100644
index 000000000..ecc7e6d93
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_disabled@2x.png
new file mode 100644
index 000000000..adc6446c9
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_focus.png
new file mode 100644
index 000000000..0037f175a
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_focus@2x.png
new file mode 100644
index 000000000..cb257a914
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_pressed.png
new file mode 100644
index 000000000..2d0856527
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_pressed@2x.png
new file mode 100644
index 000000000..803708fb4
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/line_vertical_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked.png
new file mode 100644
index 000000000..6f1fd6ca6
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked@2x.png
new file mode 100644
index 000000000..228ffdbf2
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_disabled.png
new file mode 100644
index 000000000..27788530d
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_disabled@2x.png
new file mode 100644
index 000000000..930bfaf70
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_focus.png
new file mode 100644
index 000000000..ca8e8bc9a
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_focus@2x.png
new file mode 100644
index 000000000..aa0f1152b
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_pressed.png
new file mode 100644
index 000000000..6e391a0ff
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_pressed@2x.png
new file mode 100644
index 000000000..0512731ae
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_checked_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked.png
new file mode 100644
index 000000000..763306bdc
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked@2x.png
new file mode 100644
index 000000000..28b6a0784
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_disabled.png
new file mode 100644
index 000000000..fc0b12f78
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_disabled@2x.png
new file mode 100644
index 000000000..d31f2b4b9
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_focus.png
new file mode 100644
index 000000000..9c87b01e4
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_focus@2x.png
new file mode 100644
index 000000000..4b4c7321d
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_pressed.png
new file mode 100644
index 000000000..709e31633
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_pressed@2x.png
new file mode 100644
index 000000000..b014de5f0
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/radio_unchecked_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/right_arrow.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/right_arrow.png
new file mode 100644
index 000000000..9b0a4e6a7
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/right_arrow.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/right_arrow_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/right_arrow_disabled.png
new file mode 100644
index 000000000..5c0bee402
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/right_arrow_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/sizegrip.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/sizegrip.png
new file mode 100644
index 000000000..350583aaa
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/sizegrip.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-branch-end.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-branch-end.png
new file mode 100644
index 000000000..cb5d3b51f
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-branch-end.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-branch-more.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-branch-more.png
new file mode 100644
index 000000000..62711409d
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-branch-more.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-vline.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-vline.png
new file mode 100644
index 000000000..87536cce1
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/stylesheet-vline.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal.png
new file mode 100644
index 000000000..012ea2dfb
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal@2x.png
new file mode 100644
index 000000000..520c34f98
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_disabled.png
new file mode 100644
index 000000000..1f91df98f
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_disabled@2x.png
new file mode 100644
index 000000000..738008f92
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_focus.png
new file mode 100644
index 000000000..999b3c7d8
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_focus@2x.png
new file mode 100644
index 000000000..f8e40b7d1
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_pressed.png
new file mode 100644
index 000000000..c31b69deb
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_pressed@2x.png
new file mode 100644
index 000000000..2f4cb41c7
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_horizontal_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical.png
new file mode 100644
index 000000000..16473bfd8
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical@2x.png
new file mode 100644
index 000000000..90a5caee3
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_disabled.png
new file mode 100644
index 000000000..2d240edb5
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_disabled@2x.png
new file mode 100644
index 000000000..fd1df30f1
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_focus.png
new file mode 100644
index 000000000..58cda1f80
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_focus@2x.png
new file mode 100644
index 000000000..9222b4fd8
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_pressed.png
new file mode 100644
index 000000000..e7d641926
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_pressed@2x.png
new file mode 100644
index 000000000..9c438faf4
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_move_vertical_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal.png
new file mode 100644
index 000000000..3c0acbdcc
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal@2x.png
new file mode 100644
index 000000000..fb4e24c88
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_disabled.png
new file mode 100644
index 000000000..32f7e8ca6
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_disabled@2x.png
new file mode 100644
index 000000000..f7bec188b
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_focus.png
new file mode 100644
index 000000000..91c19d65c
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_focus@2x.png
new file mode 100644
index 000000000..c4829918d
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_pressed.png
new file mode 100644
index 000000000..7a7f91737
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_pressed@2x.png
new file mode 100644
index 000000000..d65773b48
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_horizontal_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical.png
new file mode 100644
index 000000000..4dde3f37f
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical@2x.png
new file mode 100644
index 000000000..fe97c0de3
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_disabled.png
new file mode 100644
index 000000000..7426ae2de
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_disabled@2x.png
new file mode 100644
index 000000000..7acc6d33e
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_focus.png
new file mode 100644
index 000000000..6e3c12143
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_focus@2x.png
new file mode 100644
index 000000000..cac3a56c2
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_pressed.png
new file mode 100644
index 000000000..b777784b8
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_pressed@2x.png
new file mode 100644
index 000000000..7ed878fd3
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/toolbar_separator_vertical_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent.png
new file mode 100644
index 000000000..8b241c4a4
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent@2x.png
new file mode 100644
index 000000000..2c3df7a5e
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_disabled.png
new file mode 100644
index 000000000..8b241c4a4
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_disabled@2x.png
new file mode 100644
index 000000000..2c3df7a5e
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_focus.png
new file mode 100644
index 000000000..8b241c4a4
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_focus@2x.png
new file mode 100644
index 000000000..2c3df7a5e
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_pressed.png
new file mode 100644
index 000000000..8b241c4a4
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_pressed@2x.png
new file mode 100644
index 000000000..2c3df7a5e
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/transparent_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/undock.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/undock.png
new file mode 100644
index 000000000..88691d779
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/undock.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/up_arrow.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/up_arrow.png
new file mode 100644
index 000000000..abcc72452
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/up_arrow.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/up_arrow_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/up_arrow_disabled.png
new file mode 100644
index 000000000..b9c8e3b53
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/up_arrow_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close.png
new file mode 100644
index 000000000..6f55c3ae7
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close@2x.png
new file mode 100644
index 000000000..ff644f2e8
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_disabled.png
new file mode 100644
index 000000000..22694e31d
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_disabled@2x.png
new file mode 100644
index 000000000..ebc97db70
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_focus.png
new file mode 100644
index 000000000..f017eda31
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_focus@2x.png
new file mode 100644
index 000000000..5a354d796
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_pressed.png
new file mode 100644
index 000000000..04b922dd0
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_pressed@2x.png
new file mode 100644
index 000000000..58c0bf592
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_close_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip.png
new file mode 100644
index 000000000..0528049bb
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip@2x.png
new file mode 100644
index 000000000..1ca1b073c
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_disabled.png
new file mode 100644
index 000000000..15f55c056
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_disabled@2x.png
new file mode 100644
index 000000000..33a4588e8
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_focus.png
new file mode 100644
index 000000000..06e76c31f
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_focus@2x.png
new file mode 100644
index 000000000..58c2d06e4
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_pressed.png
new file mode 100644
index 000000000..b3a566cdb
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_pressed@2x.png
new file mode 100644
index 000000000..e9da94049
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_grip_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize.png
new file mode 100644
index 000000000..f60981615
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize@2x.png
new file mode 100644
index 000000000..30f728f02
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_disabled.png
new file mode 100644
index 000000000..29db1c9b1
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_disabled@2x.png
new file mode 100644
index 000000000..1572ca2fe
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_focus.png
new file mode 100644
index 000000000..cb592f598
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_focus@2x.png
new file mode 100644
index 000000000..6f6465169
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_pressed.png
new file mode 100644
index 000000000..6962440ac
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_pressed@2x.png
new file mode 100644
index 000000000..cb028272b
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_minimize_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock.png
new file mode 100644
index 000000000..616da991a
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock@2x.png
new file mode 100644
index 000000000..511036bf2
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_disabled.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_disabled.png
new file mode 100644
index 000000000..a2b3d25b2
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_disabled@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_disabled@2x.png
new file mode 100644
index 000000000..638ec8104
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_disabled@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_focus.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_focus.png
new file mode 100644
index 000000000..ae6dc4a60
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_focus@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_focus@2x.png
new file mode 100644
index 000000000..d06dd1eac
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_focus@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_pressed.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_pressed.png
new file mode 100644
index 000000000..e9142ded2
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_pressed@2x.png b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_pressed@2x.png
new file mode 100644
index 000000000..a597420f3
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/rc/window_undock_pressed@2x.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/style.qrc b/dist/qt_themes/qdarkstyle_midnight_blue/style.qrc
new file mode 100644
index 000000000..1b7686f15
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/style.qrc
@@ -0,0 +1,225 @@
1<RCC>
2 <qresource prefix="icons/qdarkstyle_midnight_blue">
3 <file alias="index.theme">icons/index.theme</file>
4 <file alias="16x16/lock.png">icons/16x16/lock.png</file>
5 <file alias="48x48/bad_folder.png">icons/48x48/bad_folder.png</file>
6 <file alias="48x48/chip.png">icons/48x48/chip.png</file>
7 <file alias="48x48/folder.png">icons/48x48/folder.png</file>
8 <file alias="48x48/plus.png">icons/48x48/plus.png</file>
9 <file alias="48x48/sd_card.png">icons/48x48/sd_card.png</file>
10 <file alias="256x256/plus_folder.png">icons/256x256/plus_folder.png</file>
11 </qresource>
12 <qresource prefix="qss_icons">
13 <file>rc/arrow_down.png</file>
14 <file>rc/arrow_down@2x.png</file>
15 <file>rc/arrow_down_disabled.png</file>
16 <file>rc/arrow_down_disabled@2x.png</file>
17 <file>rc/arrow_down_focus.png</file>
18 <file>rc/arrow_down_focus@2x.png</file>
19 <file>rc/arrow_down_pressed.png</file>
20 <file>rc/arrow_down_pressed@2x.png</file>
21 <file>rc/arrow_left.png</file>
22 <file>rc/arrow_left@2x.png</file>
23 <file>rc/arrow_left_disabled.png</file>
24 <file>rc/arrow_left_disabled@2x.png</file>
25 <file>rc/arrow_left_focus.png</file>
26 <file>rc/arrow_left_focus@2x.png</file>
27 <file>rc/arrow_left_pressed.png</file>
28 <file>rc/arrow_left_pressed@2x.png</file>
29 <file>rc/arrow_right.png</file>
30 <file>rc/arrow_right@2x.png</file>
31 <file>rc/arrow_right_disabled.png</file>
32 <file>rc/arrow_right_disabled@2x.png</file>
33 <file>rc/arrow_right_focus.png</file>
34 <file>rc/arrow_right_focus@2x.png</file>
35 <file>rc/arrow_right_pressed.png</file>
36 <file>rc/arrow_right_pressed@2x.png</file>
37 <file>rc/arrow_up.png</file>
38 <file>rc/arrow_up@2x.png</file>
39 <file>rc/arrow_up_disabled.png</file>
40 <file>rc/arrow_up_disabled@2x.png</file>
41 <file>rc/arrow_up_focus.png</file>
42 <file>rc/arrow_up_focus@2x.png</file>
43 <file>rc/arrow_up_pressed.png</file>
44 <file>rc/arrow_up_pressed@2x.png</file>
45 <file>rc/base_icon.png</file>
46 <file>rc/base_icon@2x.png</file>
47 <file>rc/base_icon_disabled.png</file>
48 <file>rc/base_icon_disabled@2x.png</file>
49 <file>rc/base_icon_focus.png</file>
50 <file>rc/base_icon_focus@2x.png</file>
51 <file>rc/base_icon_pressed.png</file>
52 <file>rc/base_icon_pressed@2x.png</file>
53 <file>rc/branch_closed.png</file>
54 <file>rc/branch_closed@2x.png</file>
55 <file>rc/branch_closed_disabled.png</file>
56 <file>rc/branch_closed_disabled@2x.png</file>
57 <file>rc/branch_closed_focus.png</file>
58 <file>rc/branch_closed_focus@2x.png</file>
59 <file>rc/branch_closed_pressed.png</file>
60 <file>rc/branch_closed_pressed@2x.png</file>
61 <file>rc/branch_end.png</file>
62 <file>rc/branch_end@2x.png</file>
63 <file>rc/branch_end_disabled.png</file>
64 <file>rc/branch_end_disabled@2x.png</file>
65 <file>rc/branch_end_focus.png</file>
66 <file>rc/branch_end_focus@2x.png</file>
67 <file>rc/branch_end_pressed.png</file>
68 <file>rc/branch_end_pressed@2x.png</file>
69 <file>rc/branch_line.png</file>
70 <file>rc/branch_line@2x.png</file>
71 <file>rc/branch_line_disabled.png</file>
72 <file>rc/branch_line_disabled@2x.png</file>
73 <file>rc/branch_line_focus.png</file>
74 <file>rc/branch_line_focus@2x.png</file>
75 <file>rc/branch_line_pressed.png</file>
76 <file>rc/branch_line_pressed@2x.png</file>
77 <file>rc/branch_more.png</file>
78 <file>rc/branch_more@2x.png</file>
79 <file>rc/branch_more_disabled.png</file>
80 <file>rc/branch_more_disabled@2x.png</file>
81 <file>rc/branch_more_focus.png</file>
82 <file>rc/branch_more_focus@2x.png</file>
83 <file>rc/branch_more_pressed.png</file>
84 <file>rc/branch_more_pressed@2x.png</file>
85 <file>rc/branch_open.png</file>
86 <file>rc/branch_open@2x.png</file>
87 <file>rc/branch_open_disabled.png</file>
88 <file>rc/branch_open_disabled@2x.png</file>
89 <file>rc/branch_open_focus.png</file>
90 <file>rc/branch_open_focus@2x.png</file>
91 <file>rc/branch_open_pressed.png</file>
92 <file>rc/branch_open_pressed@2x.png</file>
93 <file>rc/checkbox_checked.png</file>
94 <file>rc/checkbox_checked@2x.png</file>
95 <file>rc/checkbox_checked_disabled.png</file>
96 <file>rc/checkbox_checked_disabled@2x.png</file>
97 <file>rc/checkbox_checked_focus.png</file>
98 <file>rc/checkbox_checked_focus@2x.png</file>
99 <file>rc/checkbox_checked_pressed.png</file>
100 <file>rc/checkbox_checked_pressed@2x.png</file>
101 <file>rc/checkbox_indeterminate.png</file>
102 <file>rc/checkbox_indeterminate@2x.png</file>
103 <file>rc/checkbox_indeterminate_disabled.png</file>
104 <file>rc/checkbox_indeterminate_disabled@2x.png</file>
105 <file>rc/checkbox_indeterminate_focus.png</file>
106 <file>rc/checkbox_indeterminate_focus@2x.png</file>
107 <file>rc/checkbox_indeterminate_pressed.png</file>
108 <file>rc/checkbox_indeterminate_pressed@2x.png</file>
109 <file>rc/checkbox_unchecked.png</file>
110 <file>rc/checkbox_unchecked@2x.png</file>
111 <file>rc/checkbox_unchecked_disabled.png</file>
112 <file>rc/checkbox_unchecked_disabled@2x.png</file>
113 <file>rc/checkbox_unchecked_focus.png</file>
114 <file>rc/checkbox_unchecked_focus@2x.png</file>
115 <file>rc/checkbox_unchecked_pressed.png</file>
116 <file>rc/checkbox_unchecked_pressed@2x.png</file>
117 <file>rc/line_horizontal.png</file>
118 <file>rc/line_horizontal@2x.png</file>
119 <file>rc/line_horizontal_disabled.png</file>
120 <file>rc/line_horizontal_disabled@2x.png</file>
121 <file>rc/line_horizontal_focus.png</file>
122 <file>rc/line_horizontal_focus@2x.png</file>
123 <file>rc/line_horizontal_pressed.png</file>
124 <file>rc/line_horizontal_pressed@2x.png</file>
125 <file>rc/line_vertical.png</file>
126 <file>rc/line_vertical@2x.png</file>
127 <file>rc/line_vertical_disabled.png</file>
128 <file>rc/line_vertical_disabled@2x.png</file>
129 <file>rc/line_vertical_focus.png</file>
130 <file>rc/line_vertical_focus@2x.png</file>
131 <file>rc/line_vertical_pressed.png</file>
132 <file>rc/line_vertical_pressed@2x.png</file>
133 <file>rc/radio_checked.png</file>
134 <file>rc/radio_checked@2x.png</file>
135 <file>rc/radio_checked_disabled.png</file>
136 <file>rc/radio_checked_disabled@2x.png</file>
137 <file>rc/radio_checked_focus.png</file>
138 <file>rc/radio_checked_focus@2x.png</file>
139 <file>rc/radio_checked_pressed.png</file>
140 <file>rc/radio_checked_pressed@2x.png</file>
141 <file>rc/radio_unchecked.png</file>
142 <file>rc/radio_unchecked@2x.png</file>
143 <file>rc/radio_unchecked_disabled.png</file>
144 <file>rc/radio_unchecked_disabled@2x.png</file>
145 <file>rc/radio_unchecked_focus.png</file>
146 <file>rc/radio_unchecked_focus@2x.png</file>
147 <file>rc/radio_unchecked_pressed.png</file>
148 <file>rc/radio_unchecked_pressed@2x.png</file>
149 <file>rc/toolbar_move_horizontal.png</file>
150 <file>rc/toolbar_move_horizontal@2x.png</file>
151 <file>rc/toolbar_move_horizontal_disabled.png</file>
152 <file>rc/toolbar_move_horizontal_disabled@2x.png</file>
153 <file>rc/toolbar_move_horizontal_focus.png</file>
154 <file>rc/toolbar_move_horizontal_focus@2x.png</file>
155 <file>rc/toolbar_move_horizontal_pressed.png</file>
156 <file>rc/toolbar_move_horizontal_pressed@2x.png</file>
157 <file>rc/toolbar_move_vertical.png</file>
158 <file>rc/toolbar_move_vertical@2x.png</file>
159 <file>rc/toolbar_move_vertical_disabled.png</file>
160 <file>rc/toolbar_move_vertical_disabled@2x.png</file>
161 <file>rc/toolbar_move_vertical_focus.png</file>
162 <file>rc/toolbar_move_vertical_focus@2x.png</file>
163 <file>rc/toolbar_move_vertical_pressed.png</file>
164 <file>rc/toolbar_move_vertical_pressed@2x.png</file>
165 <file>rc/toolbar_separator_horizontal.png</file>
166 <file>rc/toolbar_separator_horizontal@2x.png</file>
167 <file>rc/toolbar_separator_horizontal_disabled.png</file>
168 <file>rc/toolbar_separator_horizontal_disabled@2x.png</file>
169 <file>rc/toolbar_separator_horizontal_focus.png</file>
170 <file>rc/toolbar_separator_horizontal_focus@2x.png</file>
171 <file>rc/toolbar_separator_horizontal_pressed.png</file>
172 <file>rc/toolbar_separator_horizontal_pressed@2x.png</file>
173 <file>rc/toolbar_separator_vertical.png</file>
174 <file>rc/toolbar_separator_vertical@2x.png</file>
175 <file>rc/toolbar_separator_vertical_disabled.png</file>
176 <file>rc/toolbar_separator_vertical_disabled@2x.png</file>
177 <file>rc/toolbar_separator_vertical_focus.png</file>
178 <file>rc/toolbar_separator_vertical_focus@2x.png</file>
179 <file>rc/toolbar_separator_vertical_pressed.png</file>
180 <file>rc/toolbar_separator_vertical_pressed@2x.png</file>
181 <file>rc/transparent.png</file>
182 <file>rc/transparent@2x.png</file>
183 <file>rc/transparent_disabled.png</file>
184 <file>rc/transparent_disabled@2x.png</file>
185 <file>rc/transparent_focus.png</file>
186 <file>rc/transparent_focus@2x.png</file>
187 <file>rc/transparent_pressed.png</file>
188 <file>rc/transparent_pressed@2x.png</file>
189 <file>rc/window_close.png</file>
190 <file>rc/window_close@2x.png</file>
191 <file>rc/window_close_disabled.png</file>
192 <file>rc/window_close_disabled@2x.png</file>
193 <file>rc/window_close_focus.png</file>
194 <file>rc/window_close_focus@2x.png</file>
195 <file>rc/window_close_pressed.png</file>
196 <file>rc/window_close_pressed@2x.png</file>
197 <file>rc/window_grip.png</file>
198 <file>rc/window_grip@2x.png</file>
199 <file>rc/window_grip_disabled.png</file>
200 <file>rc/window_grip_disabled@2x.png</file>
201 <file>rc/window_grip_focus.png</file>
202 <file>rc/window_grip_focus@2x.png</file>
203 <file>rc/window_grip_pressed.png</file>
204 <file>rc/window_grip_pressed@2x.png</file>
205 <file>rc/window_minimize.png</file>
206 <file>rc/window_minimize@2x.png</file>
207 <file>rc/window_minimize_disabled.png</file>
208 <file>rc/window_minimize_disabled@2x.png</file>
209 <file>rc/window_minimize_focus.png</file>
210 <file>rc/window_minimize_focus@2x.png</file>
211 <file>rc/window_minimize_pressed.png</file>
212 <file>rc/window_minimize_pressed@2x.png</file>
213 <file>rc/window_undock.png</file>
214 <file>rc/window_undock@2x.png</file>
215 <file>rc/window_undock_disabled.png</file>
216 <file>rc/window_undock_disabled@2x.png</file>
217 <file>rc/window_undock_focus.png</file>
218 <file>rc/window_undock_focus@2x.png</file>
219 <file>rc/window_undock_pressed.png</file>
220 <file>rc/window_undock_pressed@2x.png</file>
221 </qresource>
222 <qresource prefix="qdarkstyle_midnight_blue">
223 <file>style.qss</file>
224 </qresource>
225</RCC>
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/style.qss b/dist/qt_themes/qdarkstyle_midnight_blue/style.qss
new file mode 100644
index 000000000..9c24b0d07
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/style.qss
@@ -0,0 +1,2174 @@
1/* ---------------------------------------------------------------------------
2
3 Created by the qtsass compiler v0.1.1
4
5 The definitions are in the "qdarkstyle.qss._styles.scss" module
6
7 WARNING! All changes made in this file will be lost!
8
9--------------------------------------------------------------------------- */
10/* QDarkStyleSheet -----------------------------------------------------------
11
12This is the main style sheet, the palette has nine colors.
13
14It is based on three selecting colors, three greyish (background) colors
15plus three whitish (foreground) colors. Each set of widgets of the same
16type have a header like this:
17
18 ------------------
19 GroupName --------
20 ------------------
21
22And each widget is separated with a header like this:
23
24 QWidgetName ------
25
26This makes more easy to find and change some css field. The basic
27configuration is described bellow.
28
29 BACKGROUND -----------
30
31 Light (unpressed)
32 Normal (border, disabled, pressed, checked, toolbars, menus)
33 Dark (background)
34
35 FOREGROUND -----------
36
37 Light (texts/labels)
38 Normal (not used yet)
39 Dark (disabled texts)
40
41 SELECTION ------------
42
43 Light (selection/hover/active)
44 Normal (selected)
45 Dark (selected disabled)
46
47If a stranger configuration is required because of a bugfix or anything
48else, keep the comment on the line above so nobody changes it, including the
49issue number.
50
51*/
52/*
53
54See Qt documentation:
55
56 - https://doc.qt.io/qt-5/stylesheet.html
57 - https://doc.qt.io/qt-5/stylesheet-reference.html
58 - https://doc.qt.io/qt-5/stylesheet-examples.html
59
60--------------------------------------------------------------------------- */
61/* QWidget ----------------------------------------------------------------
62
63--------------------------------------------------------------------------- */
64QWidget {
65 background-color: #19232D;
66 border: 0px solid #32414B;
67 padding: 0px;
68 color: #F0F0F0;
69 selection-background-color: #1464A0;
70 selection-color: #F0F0F0;
71}
72
73QWidget:disabled {
74 background-color: #19232D;
75 color: #787878;
76 selection-background-color: #14506E;
77 selection-color: #787878;
78}
79
80QWidget::item:selected {
81 background-color: #1464A0;
82}
83
84QWidget::item:hover {
85 background-color: #148CD2;
86 color: #32414B;
87}
88
89/* QMainWindow ------------------------------------------------------------
90
91This adjusts the splitter in the dock widget, not qsplitter
92https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmainwindow
93
94--------------------------------------------------------------------------- */
95QMainWindow::separator {
96 background-color: #32414B;
97 border: 0px solid #19232D;
98 spacing: 0px;
99 padding: 2px;
100}
101
102QMainWindow::separator:hover {
103 background-color: #505F69;
104 border: 0px solid #148CD2;
105}
106
107QMainWindow::separator:horizontal {
108 width: 5px;
109 margin-top: 2px;
110 margin-bottom: 2px;
111 image: url(":/qss_icons/rc/toolbar_separator_vertical.png");
112}
113
114QMainWindow::separator:vertical {
115 height: 5px;
116 margin-left: 2px;
117 margin-right: 2px;
118 image: url(":/qss_icons/rc/toolbar_separator_horizontal.png");
119}
120
121/* QToolTip ---------------------------------------------------------------
122
123https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtooltip
124
125--------------------------------------------------------------------------- */
126QToolTip {
127 background-color: #148CD2;
128 border: 1px solid #19232D;
129 color: #19232D;
130 /* Remove padding, for fix combo box tooltip */
131 padding: 0px;
132 /* Remove opacity, fix #174 - may need to use RGBA */
133}
134
135/* QStatusBar -------------------------------------------------------------
136
137https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qstatusbar
138
139--------------------------------------------------------------------------- */
140QStatusBar {
141 border: 1px solid #32414B;
142 /* Fixes Spyder #9120, #9121 */
143 background: #32414B;
144 /* Fixes #205, white vertical borders separating items */
145}
146
147QStatusBar::item {
148 border: none;
149}
150
151QStatusBar QToolTip {
152 background-color: #148CD2;
153 border: 1px solid #19232D;
154 color: #19232D;
155 /* Remove padding, for fix combo box tooltip */
156 padding: 0px;
157 /* Reducing transparency to read better */
158 opacity: 230;
159}
160
161QStatusBar QLabel {
162 /* Fixes Spyder #9120, #9121 */
163 background: transparent;
164}
165
166/* QCheckBox --------------------------------------------------------------
167
168https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qcheckbox
169
170--------------------------------------------------------------------------- */
171QCheckBox {
172 background-color: #19232D;
173 color: #F0F0F0;
174 spacing: 4px;
175 outline: none;
176 padding-top: 4px;
177 padding-bottom: 4px;
178}
179
180QCheckBox:focus {
181 border: none;
182}
183
184QCheckBox QWidget:disabled {
185 background-color: #19232D;
186 color: #787878;
187}
188
189QCheckBox::indicator {
190 margin-left: 4px;
191 height: 16px;
192 width: 16px;
193}
194
195QCheckBox::indicator:unchecked {
196 image: url(":/qss_icons/rc/checkbox_unchecked.png");
197}
198
199QCheckBox::indicator:unchecked:hover, QCheckBox::indicator:unchecked:focus, QCheckBox::indicator:unchecked:pressed {
200 border: none;
201 image: url(":/qss_icons/rc/checkbox_unchecked_focus.png");
202}
203
204QCheckBox::indicator:unchecked:disabled {
205 image: url(":/qss_icons/rc/checkbox_unchecked_disabled.png");
206}
207
208QCheckBox::indicator:checked {
209 image: url(":/qss_icons/rc/checkbox_checked.png");
210}
211
212QCheckBox::indicator:checked:hover, QCheckBox::indicator:checked:focus, QCheckBox::indicator:checked:pressed {
213 border: none;
214 image: url(":/qss_icons/rc/checkbox_checked_focus.png");
215}
216
217QCheckBox::indicator:checked:disabled {
218 image: url(":/qss_icons/rc/checkbox_checked_disabled.png");
219}
220
221QCheckBox::indicator:indeterminate {
222 image: url(":/qss_icons/rc/checkbox_indeterminate.png");
223}
224
225QCheckBox::indicator:indeterminate:disabled {
226 image: url(":/qss_icons/rc/checkbox_indeterminate_disabled.png");
227}
228
229QCheckBox::indicator:indeterminate:focus, QCheckBox::indicator:indeterminate:hover, QCheckBox::indicator:indeterminate:pressed {
230 image: url(":/qss_icons/rc/checkbox_indeterminate_focus.png");
231}
232
233/* QGroupBox --------------------------------------------------------------
234
235https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qgroupbox
236
237--------------------------------------------------------------------------- */
238QGroupBox {
239 font-weight: bold;
240 border: 1px solid #32414B;
241 border-radius: 4px;
242 padding: 4px;
243 margin-top: 16px;
244}
245
246QGroupBox::title {
247 subcontrol-origin: margin;
248 subcontrol-position: top left;
249 left: 3px;
250 padding-left: 3px;
251 padding-right: 5px;
252 padding-top: 8px;
253 padding-bottom: 16px;
254}
255
256QGroupBox::indicator {
257 margin-left: 2px;
258 height: 16px;
259 width: 16px;
260}
261
262QGroupBox::indicator:unchecked {
263 border: none;
264 image: url(":/qss_icons/rc/checkbox_unchecked.png");
265}
266
267QGroupBox::indicator:unchecked:hover, QGroupBox::indicator:unchecked:focus, QGroupBox::indicator:unchecked:pressed {
268 border: none;
269 image: url(":/qss_icons/rc/checkbox_unchecked_focus.png");
270}
271
272QGroupBox::indicator:unchecked:disabled {
273 image: url(":/qss_icons/rc/checkbox_unchecked_disabled.png");
274}
275
276QGroupBox::indicator:checked {
277 border: none;
278 image: url(":/qss_icons/rc/checkbox_checked.png");
279}
280
281QGroupBox::indicator:checked:hover, QGroupBox::indicator:checked:focus, QGroupBox::indicator:checked:pressed {
282 border: none;
283 image: url(":/qss_icons/rc/checkbox_checked_focus.png");
284}
285
286QGroupBox::indicator:checked:disabled {
287 image: url(":/qss_icons/rc/checkbox_checked_disabled.png");
288}
289
290/* QRadioButton -----------------------------------------------------------
291
292https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qradiobutton
293
294--------------------------------------------------------------------------- */
295QRadioButton {
296 background-color: #19232D;
297 color: #F0F0F0;
298 spacing: 4px;
299 padding: 0px;
300 border: none;
301 outline: none;
302}
303
304QRadioButton:focus {
305 border: none;
306}
307
308QRadioButton:disabled {
309 background-color: #19232D;
310 color: #787878;
311 border: none;
312 outline: none;
313}
314
315QRadioButton QWidget {
316 background-color: #19232D;
317 color: #F0F0F0;
318 spacing: 0px;
319 padding: 0px;
320 outline: none;
321 border: none;
322}
323
324QRadioButton::indicator {
325 border: none;
326 outline: none;
327 margin-left: 4px;
328 height: 16px;
329 width: 16px;
330}
331
332QRadioButton::indicator:unchecked {
333 image: url(":/qss_icons/rc/radio_unchecked.png");
334}
335
336QRadioButton::indicator:unchecked:hover, QRadioButton::indicator:unchecked:focus, QRadioButton::indicator:unchecked:pressed {
337 border: none;
338 outline: none;
339 image: url(":/qss_icons/rc/radio_unchecked_focus.png");
340}
341
342QRadioButton::indicator:unchecked:disabled {
343 image: url(":/qss_icons/rc/radio_unchecked_disabled.png");
344}
345
346QRadioButton::indicator:checked {
347 border: none;
348 outline: none;
349 image: url(":/qss_icons/rc/radio_checked.png");
350}
351
352QRadioButton::indicator:checked:hover, QRadioButton::indicator:checked:focus, QRadioButton::indicator:checked:pressed {
353 border: none;
354 outline: none;
355 image: url(":/qss_icons/rc/radio_checked_focus.png");
356}
357
358QRadioButton::indicator:checked:disabled {
359 outline: none;
360 image: url(":/qss_icons/rc/radio_checked_disabled.png");
361}
362
363/* QMenuBar ---------------------------------------------------------------
364
365https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmenubar
366
367--------------------------------------------------------------------------- */
368QMenuBar {
369 background-color: #32414B;
370 padding: 2px;
371 border: 1px solid #19232D;
372 color: #F0F0F0;
373}
374
375QMenuBar:focus {
376 border: 1px solid #148CD2;
377}
378
379QMenuBar::item {
380 background: transparent;
381 padding: 4px;
382}
383
384QMenuBar::item:selected {
385 padding: 4px;
386 background: transparent;
387 border: 0px solid #32414B;
388}
389
390QMenuBar::item:pressed {
391 padding: 4px;
392 border: 0px solid #32414B;
393 background-color: #148CD2;
394 color: #F0F0F0;
395 margin-bottom: 0px;
396 padding-bottom: 0px;
397}
398
399/* QMenu ------------------------------------------------------------------
400
401https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmenu
402
403--------------------------------------------------------------------------- */
404QMenu {
405 border: 0px solid #32414B;
406 color: #F0F0F0;
407 margin: 0px;
408}
409
410QMenu::separator {
411 height: 1px;
412 background-color: #505F69;
413 color: #F0F0F0;
414}
415
416QMenu::icon {
417 margin: 0px;
418 padding-left: 8px;
419}
420
421QMenu::item {
422 background-color: #32414B;
423 padding: 4px 24px 4px 24px;
424 /* Reserve space for selection border */
425 border: 1px transparent #32414B;
426}
427
428QMenu::item:selected {
429 color: #F0F0F0;
430}
431
432QMenu::indicator {
433 width: 12px;
434 height: 12px;
435 padding-left: 6px;
436 /* non-exclusive indicator = check box style indicator (see QActionGroup::setExclusive) */
437 /* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */
438}
439
440QMenu::indicator:non-exclusive:unchecked {
441 image: url(":/qss_icons/rc/checkbox_unchecked.png");
442}
443
444QMenu::indicator:non-exclusive:unchecked:selected {
445 image: url(":/qss_icons/rc/checkbox_unchecked_disabled.png");
446}
447
448QMenu::indicator:non-exclusive:checked {
449 image: url(":/qss_icons/rc/checkbox_checked.png");
450}
451
452QMenu::indicator:non-exclusive:checked:selected {
453 image: url(":/qss_icons/rc/checkbox_checked_disabled.png");
454}
455
456QMenu::indicator:exclusive:unchecked {
457 image: url(":/qss_icons/rc/radio_unchecked.png");
458}
459
460QMenu::indicator:exclusive:unchecked:selected {
461 image: url(":/qss_icons/rc/radio_unchecked_disabled.png");
462}
463
464QMenu::indicator:exclusive:checked {
465 image: url(":/qss_icons/rc/radio_checked.png");
466}
467
468QMenu::indicator:exclusive:checked:selected {
469 image: url(":/qss_icons/rc/radio_checked_disabled.png");
470}
471
472QMenu::right-arrow {
473 margin: 5px;
474 image: url(":/qss_icons/rc/arrow_right.png");
475 height: 12px;
476 width: 12px;
477}
478
479/* QAbstractItemView ------------------------------------------------------
480
481https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qcombobox
482
483--------------------------------------------------------------------------- */
484QAbstractItemView {
485 alternate-background-color: #19232D;
486 color: #F0F0F0;
487 border: 1px solid #32414B;
488 border-radius: 4px;
489}
490
491QAbstractItemView QLineEdit {
492 padding: 2px;
493}
494
495/* QAbstractScrollArea ----------------------------------------------------
496
497https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea
498
499--------------------------------------------------------------------------- */
500QAbstractScrollArea {
501 background-color: #19232D;
502 border: 1px solid #32414B;
503 border-radius: 4px;
504 padding: 2px;
505 /* fix #159 */
506 min-height: 1.25em;
507 /* fix #159 */
508 color: #F0F0F0;
509}
510
511QAbstractScrollArea:disabled {
512 color: #787878;
513}
514
515/* QScrollArea ------------------------------------------------------------
516
517--------------------------------------------------------------------------- */
518QScrollArea QWidget QWidget:disabled {
519 background-color: #19232D;
520}
521
522/* QScrollBar -------------------------------------------------------------
523
524https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qscrollbar
525
526--------------------------------------------------------------------------- */
527QScrollBar:horizontal {
528 height: 16px;
529 margin: 2px 16px 2px 16px;
530 border: 1px solid #32414B;
531 border-radius: 4px;
532 background-color: #19232D;
533}
534
535QScrollBar:vertical {
536 background-color: #19232D;
537 width: 16px;
538 margin: 16px 2px 16px 2px;
539 border: 1px solid #32414B;
540 border-radius: 4px;
541}
542
543QScrollBar::handle:horizontal {
544 background-color: #787878;
545 border: 1px solid #32414B;
546 border-radius: 4px;
547 min-width: 8px;
548}
549
550QScrollBar::handle:horizontal:hover {
551 background-color: #148CD2;
552 border: 1px solid #148CD2;
553 border-radius: 4px;
554 min-width: 8px;
555}
556
557QScrollBar::handle:horizontal:focus {
558 border: 1px solid #1464A0;
559}
560
561QScrollBar::handle:vertical {
562 background-color: #787878;
563 border: 1px solid #32414B;
564 min-height: 8px;
565 border-radius: 4px;
566}
567
568QScrollBar::handle:vertical:hover {
569 background-color: #148CD2;
570 border: 1px solid #148CD2;
571 border-radius: 4px;
572 min-height: 8px;
573}
574
575QScrollBar::handle:vertical:focus {
576 border: 1px solid #1464A0;
577}
578
579QScrollBar::add-line:horizontal {
580 margin: 0px 0px 0px 0px;
581 border-image: url(":/qss_icons/rc/arrow_right_disabled.png");
582 height: 12px;
583 width: 12px;
584 subcontrol-position: right;
585 subcontrol-origin: margin;
586}
587
588QScrollBar::add-line:horizontal:hover, QScrollBar::add-line:horizontal:on {
589 border-image: url(":/qss_icons/rc/arrow_right.png");
590 height: 12px;
591 width: 12px;
592 subcontrol-position: right;
593 subcontrol-origin: margin;
594}
595
596QScrollBar::add-line:vertical {
597 margin: 3px 0px 3px 0px;
598 border-image: url(":/qss_icons/rc/arrow_down_disabled.png");
599 height: 12px;
600 width: 12px;
601 subcontrol-position: bottom;
602 subcontrol-origin: margin;
603}
604
605QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on {
606 border-image: url(":/qss_icons/rc/arrow_down.png");
607 height: 12px;
608 width: 12px;
609 subcontrol-position: bottom;
610 subcontrol-origin: margin;
611}
612
613QScrollBar::sub-line:horizontal {
614 margin: 0px 3px 0px 3px;
615 border-image: url(":/qss_icons/rc/arrow_left_disabled.png");
616 height: 12px;
617 width: 12px;
618 subcontrol-position: left;
619 subcontrol-origin: margin;
620}
621
622QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on {
623 border-image: url(":/qss_icons/rc/arrow_left.png");
624 height: 12px;
625 width: 12px;
626 subcontrol-position: left;
627 subcontrol-origin: margin;
628}
629
630QScrollBar::sub-line:vertical {
631 margin: 3px 0px 3px 0px;
632 border-image: url(":/qss_icons/rc/arrow_up_disabled.png");
633 height: 12px;
634 width: 12px;
635 subcontrol-position: top;
636 subcontrol-origin: margin;
637}
638
639QScrollBar::sub-line:vertical:hover, QScrollBar::sub-line:vertical:on {
640 border-image: url(":/qss_icons/rc/arrow_up.png");
641 height: 12px;
642 width: 12px;
643 subcontrol-position: top;
644 subcontrol-origin: margin;
645}
646
647QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal {
648 background: none;
649}
650
651QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical {
652 background: none;
653}
654
655QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {
656 background: none;
657}
658
659QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
660 background: none;
661}
662
663/* QTextEdit --------------------------------------------------------------
664
665https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-specific-widgets
666
667--------------------------------------------------------------------------- */
668QTextEdit {
669 background-color: #19232D;
670 color: #F0F0F0;
671 border-radius: 4px;
672 border: 1px solid #32414B;
673}
674
675QTextEdit:hover {
676 border: 1px solid #148CD2;
677 color: #F0F0F0;
678}
679
680QTextEdit:focus {
681 border: 1px solid #1464A0;
682}
683
684QTextEdit:selected {
685 background: #1464A0;
686 color: #32414B;
687}
688
689/* QPlainTextEdit ---------------------------------------------------------
690
691--------------------------------------------------------------------------- */
692QPlainTextEdit {
693 background-color: #19232D;
694 color: #F0F0F0;
695 border-radius: 4px;
696 border: 1px solid #32414B;
697}
698
699QPlainTextEdit:hover {
700 border: 1px solid #148CD2;
701 color: #F0F0F0;
702}
703
704QPlainTextEdit:focus {
705 border: 1px solid #1464A0;
706}
707
708QPlainTextEdit:selected {
709 background: #1464A0;
710 color: #32414B;
711}
712
713/* QSizeGrip --------------------------------------------------------------
714
715https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qsizegrip
716
717--------------------------------------------------------------------------- */
718QSizeGrip {
719 background: transparent;
720 width: 12px;
721 height: 12px;
722 image: url(":/qss_icons/rc/window_grip.png");
723}
724
725/* QStackedWidget ---------------------------------------------------------
726
727--------------------------------------------------------------------------- */
728QStackedWidget {
729 padding: 2px;
730 border: 1px solid #32414B;
731 border: 1px solid #19232D;
732}
733
734/* QToolBar ---------------------------------------------------------------
735
736https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbar
737
738--------------------------------------------------------------------------- */
739QToolBar {
740 background-color: #32414B;
741 border-bottom: 1px solid #19232D;
742 padding: 2px;
743 font-weight: bold;
744 spacing: 2px;
745}
746
747QToolBar QToolButton {
748 background-color: #32414B;
749 border: 1px solid #32414B;
750}
751
752QToolBar QToolButton:hover {
753 border: 1px solid #148CD2;
754}
755
756QToolBar QToolButton:checked {
757 border: 1px solid #19232D;
758 background-color: #19232D;
759}
760
761QToolBar QToolButton:checked:hover {
762 border: 1px solid #148CD2;
763}
764
765QToolBar::handle:horizontal {
766 width: 16px;
767 image: url(":/qss_icons/rc/toolbar_move_horizontal.png");
768}
769
770QToolBar::handle:vertical {
771 height: 16px;
772 image: url(":/qss_icons/rc/toolbar_move_vertical.png");
773}
774
775QToolBar::separator:horizontal {
776 width: 16px;
777 image: url(":/qss_icons/rc/toolbar_separator_horizontal.png");
778}
779
780QToolBar::separator:vertical {
781 height: 16px;
782 image: url(":/qss_icons/rc/toolbar_separator_vertical.png");
783}
784
785QToolButton#qt_toolbar_ext_button {
786 background: #32414B;
787 border: 0px;
788 color: #F0F0F0;
789 image: url(":/qss_icons/rc/arrow_right.png");
790}
791
792/* QAbstractSpinBox -------------------------------------------------------
793
794--------------------------------------------------------------------------- */
795QAbstractSpinBox {
796 background-color: #19232D;
797 border: 1px solid #32414B;
798 color: #F0F0F0;
799 /* This fixes 103, 111 */
800 padding-top: 2px;
801 /* This fixes 103, 111 */
802 padding-bottom: 2px;
803 padding-left: 4px;
804 padding-right: 4px;
805 border-radius: 4px;
806 /* min-width: 5px; removed to fix 109 */
807}
808
809QAbstractSpinBox:up-button {
810 background-color: transparent #19232D;
811 subcontrol-origin: border;
812 subcontrol-position: top right;
813 border-left: 1px solid #32414B;
814 border-bottom: 1px solid #32414B;
815 border-top-left-radius: 0;
816 border-bottom-left-radius: 0;
817 margin: 1px;
818 width: 12px;
819 margin-bottom: -1px;
820}
821
822QAbstractSpinBox::up-arrow, QAbstractSpinBox::up-arrow:disabled, QAbstractSpinBox::up-arrow:off {
823 image: url(":/qss_icons/rc/arrow_up_disabled.png");
824 height: 8px;
825 width: 8px;
826}
827
828QAbstractSpinBox::up-arrow:hover {
829 image: url(":/qss_icons/rc/arrow_up.png");
830}
831
832QAbstractSpinBox:down-button {
833 background-color: transparent #19232D;
834 subcontrol-origin: border;
835 subcontrol-position: bottom right;
836 border-left: 1px solid #32414B;
837 border-top: 1px solid #32414B;
838 border-top-left-radius: 0;
839 border-bottom-left-radius: 0;
840 margin: 1px;
841 width: 12px;
842 margin-top: -1px;
843}
844
845QAbstractSpinBox::down-arrow, QAbstractSpinBox::down-arrow:disabled, QAbstractSpinBox::down-arrow:off {
846 image: url(":/qss_icons/rc/arrow_down_disabled.png");
847 height: 8px;
848 width: 8px;
849}
850
851QAbstractSpinBox::down-arrow:hover {
852 image: url(":/qss_icons/rc/arrow_down.png");
853}
854
855QAbstractSpinBox:hover {
856 border: 1px solid #148CD2;
857 color: #F0F0F0;
858}
859
860QAbstractSpinBox:focus {
861 border: 1px solid #1464A0;
862}
863
864QAbstractSpinBox:selected {
865 background: #1464A0;
866 color: #32414B;
867}
868
869/* ------------------------------------------------------------------------ */
870/* DISPLAYS --------------------------------------------------------------- */
871/* ------------------------------------------------------------------------ */
872/* QLabel -----------------------------------------------------------------
873
874https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qframe
875
876--------------------------------------------------------------------------- */
877QLabel {
878 background: transparent;
879 border: 0px solid #32414B;
880 padding: 2px;
881 margin: 0px;
882 color: #F0F0F0;
883}
884
885QLabel:disabled {
886 border: 0px solid #32414B;
887 color: #787878;
888}
889
890/* QTextBrowser -----------------------------------------------------------
891
892https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea
893
894--------------------------------------------------------------------------- */
895QTextBrowser {
896 background-color: #19232D;
897 border: 1px solid #32414B;
898 color: #F0F0F0;
899 border-radius: 4px;
900}
901
902QTextBrowser:disabled {
903 background-color: #19232D;
904 border: 1px solid #32414B;
905 color: #787878;
906 border-radius: 4px;
907}
908
909QTextBrowser:hover, QTextBrowser:!hover, QTextBrowser:selected, QTextBrowser:pressed {
910 border: 1px solid #32414B;
911}
912
913/* QGraphicsView ----------------------------------------------------------
914
915--------------------------------------------------------------------------- */
916QGraphicsView {
917 background-color: #19232D;
918 border: 1px solid #32414B;
919 color: #F0F0F0;
920 border-radius: 4px;
921}
922
923QGraphicsView:disabled {
924 background-color: #19232D;
925 border: 1px solid #32414B;
926 color: #787878;
927 border-radius: 4px;
928}
929
930QGraphicsView:hover, QGraphicsView:!hover, QGraphicsView:selected, QGraphicsView:pressed {
931 border: 1px solid #32414B;
932}
933
934/* QCalendarWidget --------------------------------------------------------
935
936--------------------------------------------------------------------------- */
937QCalendarWidget {
938 border: 1px solid #32414B;
939 border-radius: 4px;
940}
941
942QCalendarWidget:disabled {
943 background-color: #19232D;
944 color: #787878;
945}
946
947/* QLCDNumber -------------------------------------------------------------
948
949--------------------------------------------------------------------------- */
950QLCDNumber {
951 background-color: #19232D;
952 color: #F0F0F0;
953}
954
955QLCDNumber:disabled {
956 background-color: #19232D;
957 color: #787878;
958}
959
960/* QProgressBar -----------------------------------------------------------
961
962https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qprogressbar
963
964--------------------------------------------------------------------------- */
965QProgressBar {
966 background-color: #19232D;
967 border: 1px solid #32414B;
968 color: #F0F0F0;
969 border-radius: 4px;
970 text-align: center;
971}
972
973QProgressBar:disabled {
974 background-color: #19232D;
975 border: 1px solid #32414B;
976 color: #787878;
977 border-radius: 4px;
978 text-align: center;
979}
980
981QProgressBar::chunk {
982 background-color: #1464A0;
983 color: #19232D;
984 border-radius: 4px;
985}
986
987QProgressBar::chunk:disabled {
988 background-color: #14506E;
989 color: #787878;
990 border-radius: 4px;
991}
992
993/* ------------------------------------------------------------------------ */
994/* BUTTONS ---------------------------------------------------------------- */
995/* ------------------------------------------------------------------------ */
996/* QPushButton ------------------------------------------------------------
997
998https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qpushbutton
999
1000--------------------------------------------------------------------------- */
1001QPushButton {
1002 background-color: #505F69;
1003 border: 1px solid #32414B;
1004 color: #F0F0F0;
1005 border-radius: 4px;
1006 padding: 3px;
1007 outline: none;
1008 /* Issue #194 - Special case of QPushButton inside dialogs, for better UI */
1009 min-width: 80px;
1010}
1011
1012QPushButton:disabled {
1013 background-color: #32414B;
1014 border: 1px solid #32414B;
1015 color: #787878;
1016 border-radius: 4px;
1017 padding: 3px;
1018}
1019
1020QPushButton:checked {
1021 background-color: #32414B;
1022 border: 1px solid #32414B;
1023 border-radius: 4px;
1024 padding: 3px;
1025 outline: none;
1026}
1027
1028QPushButton:checked:disabled {
1029 background-color: #19232D;
1030 border: 1px solid #32414B;
1031 color: #787878;
1032 border-radius: 4px;
1033 padding: 3px;
1034 outline: none;
1035}
1036
1037QPushButton:checked:selected {
1038 background: #1464A0;
1039 color: #32414B;
1040}
1041
1042QPushButton::menu-indicator {
1043 subcontrol-origin: padding;
1044 subcontrol-position: bottom right;
1045 bottom: 4px;
1046}
1047
1048QPushButton:pressed {
1049 background-color: #19232D;
1050 border: 1px solid #19232D;
1051}
1052
1053QPushButton:pressed:hover {
1054 border: 1px solid #148CD2;
1055}
1056
1057QPushButton:hover {
1058 border: 1px solid #148CD2;
1059 color: #F0F0F0;
1060}
1061
1062QPushButton:selected {
1063 background: #1464A0;
1064 color: #32414B;
1065}
1066
1067QPushButton:hover {
1068 border: 1px solid #148CD2;
1069 color: #F0F0F0;
1070}
1071
1072QPushButton:focus {
1073 border: 1px solid #1464A0;
1074}
1075
1076/* QToolButton ------------------------------------------------------------
1077
1078https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbutton
1079
1080--------------------------------------------------------------------------- */
1081QToolButton {
1082 background-color: transparent;
1083 border: 1px solid transparent;
1084 border-radius: 4px;
1085 margin: 0px;
1086 padding: 2px;
1087 /* The subcontrols below are used only in the DelayedPopup mode */
1088 /* The subcontrols below are used only in the MenuButtonPopup mode */
1089 /* The subcontrol below is used only in the InstantPopup or DelayedPopup mode */
1090}
1091
1092QToolButton:checked {
1093 background-color: transparent;
1094 border: 1px solid #1464A0;
1095}
1096
1097QToolButton:checked:disabled {
1098 border: 1px solid #14506E;
1099}
1100
1101QToolButton:pressed {
1102 margin: 1px;
1103 background-color: transparent;
1104 border: 1px solid #1464A0;
1105}
1106
1107QToolButton:disabled {
1108 border: none;
1109}
1110
1111QToolButton:hover {
1112 border: 1px solid #148CD2;
1113}
1114
1115QToolButton[popupMode="0"] {
1116 /* Only for DelayedPopup */
1117 padding-right: 2px;
1118}
1119
1120QToolButton[popupMode="1"] {
1121 /* Only for MenuButtonPopup */
1122 padding-right: 20px;
1123}
1124
1125QToolButton[popupMode="1"]::menu-button {
1126 border: none;
1127}
1128
1129QToolButton[popupMode="1"]::menu-button:hover {
1130 border: none;
1131 border-left: 1px solid #148CD2;
1132 border-radius: 0;
1133}
1134
1135QToolButton[popupMode="2"] {
1136 /* Only for InstantPopup */
1137 padding-right: 2px;
1138}
1139
1140QToolButton::menu-button {
1141 padding: 2px;
1142 border-radius: 4px;
1143 border: 1px solid #32414B;
1144 width: 12px;
1145 outline: none;
1146}
1147
1148QToolButton::menu-button:hover {
1149 border: 1px solid #148CD2;
1150}
1151
1152QToolButton::menu-button:checked:hover {
1153 border: 1px solid #148CD2;
1154}
1155
1156QToolButton::menu-indicator {
1157 image: url(":/qss_icons/rc/arrow_down.png");
1158 height: 8px;
1159 width: 8px;
1160 top: 0;
1161 /* Exclude a shift for better image */
1162 left: -2px;
1163 /* Shift it a bit */
1164}
1165
1166QToolButton::menu-arrow {
1167 image: url(":/qss_icons/rc/arrow_down.png");
1168 height: 8px;
1169 width: 8px;
1170}
1171
1172QToolButton::menu-arrow:hover {
1173 image: url(":/qss_icons/rc/arrow_down_focus.png");
1174}
1175
1176/* QCommandLinkButton -----------------------------------------------------
1177
1178--------------------------------------------------------------------------- */
1179QCommandLinkButton {
1180 background-color: transparent;
1181 border: 1px solid #32414B;
1182 color: #F0F0F0;
1183 border-radius: 4px;
1184 padding: 0px;
1185 margin: 0px;
1186}
1187
1188QCommandLinkButton:disabled {
1189 background-color: transparent;
1190 color: #787878;
1191}
1192
1193/* ------------------------------------------------------------------------ */
1194/* INPUTS - NO FIELDS ----------------------------------------------------- */
1195/* ------------------------------------------------------------------------ */
1196/* QComboBox --------------------------------------------------------------
1197
1198https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qcombobox
1199
1200--------------------------------------------------------------------------- */
1201QComboBox {
1202 border: 1px solid #32414B;
1203 border-radius: 4px;
1204 selection-background-color: #1464A0;
1205 padding-left: 4px;
1206 padding-right: 36px;
1207 /* 4 + 16*2 See scrollbar size */
1208 /* Fixes #103, #111 */
1209 min-height: 1.5em;
1210 /* padding-top: 2px; removed to fix #132 */
1211 /* padding-bottom: 2px; removed to fix #132 */
1212 /* min-width: 75px; removed to fix #109 */
1213 /* Needed to remove indicator - fix #132 */
1214}
1215
1216QComboBox QAbstractItemView {
1217 border: 1px solid #32414B;
1218 border-radius: 0;
1219 background-color: #19232D;
1220 selection-background-color: #1464A0;
1221}
1222
1223QComboBox QAbstractItemView:hover {
1224 background-color: #19232D;
1225 color: #F0F0F0;
1226}
1227
1228QComboBox QAbstractItemView:selected {
1229 background: #1464A0;
1230 color: #32414B;
1231}
1232
1233QComboBox QAbstractItemView:alternate {
1234 background: #19232D;
1235}
1236
1237QComboBox:disabled {
1238 background-color: #19232D;
1239 color: #787878;
1240}
1241
1242QComboBox:hover {
1243 border: 1px solid #148CD2;
1244}
1245
1246QComboBox:focus {
1247 border: 1px solid #1464A0;
1248}
1249
1250QComboBox:on {
1251 selection-background-color: #1464A0;
1252}
1253
1254QComboBox::indicator {
1255 border: none;
1256 border-radius: 0;
1257 background-color: transparent;
1258 selection-background-color: transparent;
1259 color: transparent;
1260 selection-color: transparent;
1261 /* Needed to remove indicator - fix #132 */
1262}
1263
1264QComboBox::indicator:alternate {
1265 background: #19232D;
1266}
1267
1268QComboBox::item:alternate {
1269 background: #19232D;
1270}
1271
1272QComboBox::item:checked {
1273 font-weight: bold;
1274}
1275
1276QComboBox::item:selected {
1277 border: 0px solid transparent;
1278}
1279
1280QComboBox::drop-down {
1281 subcontrol-origin: padding;
1282 subcontrol-position: top right;
1283 width: 12px;
1284 border-left: 1px solid #32414B;
1285}
1286
1287QComboBox::down-arrow {
1288 image: url(":/qss_icons/rc/arrow_down_disabled.png");
1289 height: 8px;
1290 width: 8px;
1291}
1292
1293QComboBox::down-arrow:on, QComboBox::down-arrow:hover, QComboBox::down-arrow:focus {
1294 image: url(":/qss_icons/rc/arrow_down.png");
1295}
1296
1297/* QSlider ----------------------------------------------------------------
1298
1299https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qslider
1300
1301--------------------------------------------------------------------------- */
1302QSlider:disabled {
1303 background: #19232D;
1304}
1305
1306QSlider:focus {
1307 border: none;
1308}
1309
1310QSlider::groove:horizontal {
1311 background: #32414B;
1312 border: 1px solid #32414B;
1313 height: 4px;
1314 margin: 0px;
1315 border-radius: 4px;
1316}
1317
1318QSlider::groove:vertical {
1319 background: #32414B;
1320 border: 1px solid #32414B;
1321 width: 4px;
1322 margin: 0px;
1323 border-radius: 4px;
1324}
1325
1326QSlider::add-page:vertical {
1327 background: #1464A0;
1328 border: 1px solid #32414B;
1329 width: 4px;
1330 margin: 0px;
1331 border-radius: 4px;
1332}
1333
1334QSlider::add-page:vertical :disabled {
1335 background: #14506E;
1336}
1337
1338QSlider::sub-page:horizontal {
1339 background: #1464A0;
1340 border: 1px solid #32414B;
1341 height: 4px;
1342 margin: 0px;
1343 border-radius: 4px;
1344}
1345
1346QSlider::sub-page:horizontal:disabled {
1347 background: #14506E;
1348}
1349
1350QSlider::handle:horizontal {
1351 background: #787878;
1352 border: 1px solid #32414B;
1353 width: 8px;
1354 height: 8px;
1355 margin: -8px 0px;
1356 border-radius: 4px;
1357}
1358
1359QSlider::handle:horizontal:hover {
1360 background: #148CD2;
1361 border: 1px solid #148CD2;
1362}
1363
1364QSlider::handle:horizontal:focus {
1365 border: 1px solid #1464A0;
1366}
1367
1368QSlider::handle:vertical {
1369 background: #787878;
1370 border: 1px solid #32414B;
1371 width: 8px;
1372 height: 8px;
1373 margin: 0 -8px;
1374 border-radius: 4px;
1375}
1376
1377QSlider::handle:vertical:hover {
1378 background: #148CD2;
1379 border: 1px solid #148CD2;
1380}
1381
1382QSlider::handle:vertical:focus {
1383 border: 1px solid #1464A0;
1384}
1385
1386/* QLineEdit --------------------------------------------------------------
1387
1388https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qlineedit
1389
1390--------------------------------------------------------------------------- */
1391QLineEdit {
1392 background-color: #19232D;
1393 padding-top: 2px;
1394 /* This QLineEdit fix 103, 111 */
1395 padding-bottom: 2px;
1396 /* This QLineEdit fix 103, 111 */
1397 padding-left: 4px;
1398 padding-right: 4px;
1399 border-style: solid;
1400 border: 1px solid #32414B;
1401 border-radius: 4px;
1402 color: #F0F0F0;
1403}
1404
1405QLineEdit:disabled {
1406 background-color: #19232D;
1407 color: #787878;
1408}
1409
1410QLineEdit:hover {
1411 border: 1px solid #148CD2;
1412 color: #F0F0F0;
1413}
1414
1415QLineEdit:focus {
1416 border: 1px solid #1464A0;
1417}
1418
1419QLineEdit:selected {
1420 background-color: #1464A0;
1421 color: #32414B;
1422}
1423
1424/* QTabWiget --------------------------------------------------------------
1425
1426https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtabwidget-and-qtabbar
1427
1428--------------------------------------------------------------------------- */
1429QTabWidget {
1430 padding: 2px;
1431 selection-background-color: #32414B;
1432}
1433
1434QTabWidget QWidget {
1435 /* Fixes #189 */
1436 border-radius: 4px;
1437}
1438
1439QTabWidget::pane {
1440 border: 1px solid #32414B;
1441 border-radius: 4px;
1442 margin: 0px;
1443 /* Fixes double border inside pane with pyqt5 */
1444 padding: 0px;
1445}
1446
1447QTabWidget::pane:selected {
1448 background-color: #32414B;
1449 border: 1px solid #1464A0;
1450}
1451
1452/* QTabBar ----------------------------------------------------------------
1453
1454https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtabwidget-and-qtabbar
1455
1456--------------------------------------------------------------------------- */
1457QTabBar {
1458 qproperty-drawBase: 0;
1459 border-radius: 4px;
1460 margin: 0px;
1461 padding: 2px;
1462 border: 0;
1463 /* left: 5px; move to the right by 5px - removed for fix */
1464}
1465
1466QTabBar::close-button {
1467 border: 0;
1468 margin: 2px;
1469 padding: 2px;
1470 image: url(":/qss_icons/rc/window_close.png");
1471}
1472
1473QTabBar::close-button:hover {
1474 image: url(":/qss_icons/rc/window_close_focus.png");
1475}
1476
1477QTabBar::close-button:pressed {
1478 image: url(":/qss_icons/rc/window_close_pressed.png");
1479}
1480
1481/* QTabBar::tab - selected ------------------------------------------------
1482
1483https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtabwidget-and-qtabbar
1484
1485--------------------------------------------------------------------------- */
1486QTabBar::tab {
1487 /* !selected and disabled ----------------------------------------- */
1488 /* selected ------------------------------------------------------- */
1489}
1490
1491QTabBar::tab:top:selected:disabled {
1492 border-bottom: 3px solid #14506E;
1493 color: #787878;
1494 background-color: #32414B;
1495}
1496
1497QTabBar::tab:bottom:selected:disabled {
1498 border-top: 3px solid #14506E;
1499 color: #787878;
1500 background-color: #32414B;
1501}
1502
1503QTabBar::tab:left:selected:disabled {
1504 border-right: 3px solid #14506E;
1505 color: #787878;
1506 background-color: #32414B;
1507}
1508
1509QTabBar::tab:right:selected:disabled {
1510 border-left: 3px solid #14506E;
1511 color: #787878;
1512 background-color: #32414B;
1513}
1514
1515QTabBar::tab:top:!selected:disabled {
1516 border-bottom: 3px solid #19232D;
1517 color: #787878;
1518 background-color: #19232D;
1519}
1520
1521QTabBar::tab:bottom:!selected:disabled {
1522 border-top: 3px solid #19232D;
1523 color: #787878;
1524 background-color: #19232D;
1525}
1526
1527QTabBar::tab:left:!selected:disabled {
1528 border-right: 3px solid #19232D;
1529 color: #787878;
1530 background-color: #19232D;
1531}
1532
1533QTabBar::tab:right:!selected:disabled {
1534 border-left: 3px solid #19232D;
1535 color: #787878;
1536 background-color: #19232D;
1537}
1538
1539QTabBar::tab:top:!selected {
1540 border-bottom: 2px solid #19232D;
1541 margin-top: 2px;
1542}
1543
1544QTabBar::tab:bottom:!selected {
1545 border-top: 2px solid #19232D;
1546 margin-bottom: 3px;
1547}
1548
1549QTabBar::tab:left:!selected {
1550 border-left: 2px solid #19232D;
1551 margin-right: 2px;
1552}
1553
1554QTabBar::tab:right:!selected {
1555 border-right: 2px solid #19232D;
1556 margin-left: 2px;
1557}
1558
1559QTabBar::tab:top {
1560 background-color: #32414B;
1561 color: #F0F0F0;
1562 margin-left: 2px;
1563 padding-left: 4px;
1564 padding-right: 4px;
1565 padding-top: 2px;
1566 padding-bottom: 2px;
1567 min-width: 5px;
1568 border-bottom: 3px solid #32414B;
1569 border-top-left-radius: 3px;
1570 border-top-right-radius: 3px;
1571}
1572
1573QTabBar::tab:top:selected {
1574 background-color: #505F69;
1575 color: #F0F0F0;
1576 border-bottom: 3px solid #1464A0;
1577 border-top-left-radius: 3px;
1578 border-top-right-radius: 3px;
1579}
1580
1581QTabBar::tab:top:!selected:hover {
1582 border: 1px solid #148CD2;
1583 border-bottom: 3px solid #148CD2;
1584 /* Fixes spyder-ide/spyder#9766 */
1585 padding-left: 4px;
1586 padding-right: 4px;
1587}
1588
1589QTabBar::tab:bottom {
1590 color: #F0F0F0;
1591 border-top: 3px solid #32414B;
1592 background-color: #32414B;
1593 margin-left: 2px;
1594 padding-left: 4px;
1595 padding-right: 4px;
1596 padding-top: 2px;
1597 padding-bottom: 2px;
1598 border-bottom-left-radius: 3px;
1599 border-bottom-right-radius: 3px;
1600 min-width: 5px;
1601}
1602
1603QTabBar::tab:bottom:selected {
1604 color: #F0F0F0;
1605 background-color: #505F69;
1606 border-top: 3px solid #1464A0;
1607 border-bottom-left-radius: 3px;
1608 border-bottom-right-radius: 3px;
1609}
1610
1611QTabBar::tab:bottom:!selected:hover {
1612 border: 1px solid #148CD2;
1613 border-top: 3px solid #148CD2;
1614 /* Fixes spyder-ide/spyder#9766 */
1615 padding-left: 4px;
1616 padding-right: 4px;
1617}
1618
1619QTabBar::tab:left {
1620 color: #F0F0F0;
1621 background-color: #32414B;
1622 margin-top: 2px;
1623 padding-left: 2px;
1624 padding-right: 2px;
1625 padding-top: 4px;
1626 padding-bottom: 4px;
1627 border-top-left-radius: 3px;
1628 border-bottom-left-radius: 3px;
1629 min-height: 5px;
1630}
1631
1632QTabBar::tab:left:selected {
1633 color: #F0F0F0;
1634 background-color: #505F69;
1635 border-right: 3px solid #1464A0;
1636}
1637
1638QTabBar::tab:left:!selected:hover {
1639 border: 1px solid #148CD2;
1640 border-right: 3px solid #148CD2;
1641 padding: 0px;
1642}
1643
1644QTabBar::tab:right {
1645 color: #F0F0F0;
1646 background-color: #32414B;
1647 margin-top: 2px;
1648 padding-left: 2px;
1649 padding-right: 2px;
1650 padding-top: 4px;
1651 padding-bottom: 4px;
1652 border-top-right-radius: 3px;
1653 border-bottom-right-radius: 3px;
1654 min-height: 5px;
1655}
1656
1657QTabBar::tab:right:selected {
1658 color: #F0F0F0;
1659 background-color: #505F69;
1660 border-left: 3px solid #1464A0;
1661}
1662
1663QTabBar::tab:right:!selected:hover {
1664 border: 1px solid #148CD2;
1665 border-left: 3px solid #148CD2;
1666 padding: 0px;
1667}
1668
1669QTabBar QToolButton {
1670 /* Fixes #136 */
1671 background-color: #32414B;
1672 height: 12px;
1673 width: 12px;
1674}
1675
1676QTabBar QToolButton:pressed {
1677 background-color: #32414B;
1678}
1679
1680QTabBar QToolButton:pressed:hover {
1681 border: 1px solid #148CD2;
1682}
1683
1684QTabBar QToolButton::left-arrow:enabled {
1685 image: url(":/qss_icons/rc/arrow_left.png");
1686}
1687
1688QTabBar QToolButton::left-arrow:disabled {
1689 image: url(":/qss_icons/rc/arrow_left_disabled.png");
1690}
1691
1692QTabBar QToolButton::right-arrow:enabled {
1693 image: url(":/qss_icons/rc/arrow_right.png");
1694}
1695
1696QTabBar QToolButton::right-arrow:disabled {
1697 image: url(":/qss_icons/rc/arrow_right_disabled.png");
1698}
1699
1700/* QDockWiget -------------------------------------------------------------
1701
1702--------------------------------------------------------------------------- */
1703QDockWidget {
1704 outline: 1px solid #32414B;
1705 background-color: #19232D;
1706 border: 1px solid #32414B;
1707 border-radius: 4px;
1708 titlebar-close-icon: url(":/qss_icons/rc/window_close.png");
1709 titlebar-normal-icon: url(":/qss_icons/rc/window_undock.png");
1710}
1711
1712QDockWidget::title {
1713 /* Better size for title bar */
1714 padding: 6px;
1715 spacing: 4px;
1716 border: none;
1717 background-color: #32414B;
1718}
1719
1720QDockWidget::close-button {
1721 background-color: #32414B;
1722 border-radius: 4px;
1723 border: none;
1724}
1725
1726QDockWidget::close-button:hover {
1727 image: url(":/qss_icons/rc/window_close_focus.png");
1728}
1729
1730QDockWidget::close-button:pressed {
1731 image: url(":/qss_icons/rc/window_close_pressed.png");
1732}
1733
1734QDockWidget::float-button {
1735 background-color: #32414B;
1736 border-radius: 4px;
1737 border: none;
1738}
1739
1740QDockWidget::float-button:hover {
1741 image: url(":/qss_icons/rc/window_undock_focus.png");
1742}
1743
1744QDockWidget::float-button:pressed {
1745 image: url(":/qss_icons/rc/window_undock_pressed.png");
1746}
1747
1748/* QTreeView QListView QTableView -----------------------------------------
1749
1750https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtreeview
1751https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qlistview
1752https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtableview
1753
1754--------------------------------------------------------------------------- */
1755QTreeView:branch:selected, QTreeView:branch:hover {
1756 background: url(":/qss_icons/rc/transparent.png");
1757}
1758
1759QTreeView:branch:has-siblings:!adjoins-item {
1760 border-image: url(":/qss_icons/rc/branch_line.png") 0;
1761}
1762
1763QTreeView:branch:has-siblings:adjoins-item {
1764 border-image: url(":/qss_icons/rc/branch_more.png") 0;
1765}
1766
1767QTreeView:branch:!has-children:!has-siblings:adjoins-item {
1768 border-image: url(":/qss_icons/rc/branch_end.png") 0;
1769}
1770
1771QTreeView:branch:has-children:!has-siblings:closed, QTreeView:branch:closed:has-children:has-siblings {
1772 border-image: none;
1773 image: url(":/qss_icons/rc/branch_closed.png");
1774}
1775
1776QTreeView:branch:open:has-children:!has-siblings, QTreeView:branch:open:has-children:has-siblings {
1777 border-image: none;
1778 image: url(":/qss_icons/rc/branch_open.png");
1779}
1780
1781QTreeView:branch:has-children:!has-siblings:closed:hover, QTreeView:branch:closed:has-children:has-siblings:hover {
1782 image: url(":/qss_icons/rc/branch_closed_focus.png");
1783}
1784
1785QTreeView:branch:open:has-children:!has-siblings:hover, QTreeView:branch:open:has-children:has-siblings:hover {
1786 image: url(":/qss_icons/rc/branch_open_focus.png");
1787}
1788
1789QTreeView::indicator:checked,
1790QListView::indicator:checked {
1791 image: url(":/qss_icons/rc/checkbox_checked.png");
1792}
1793
1794QTreeView::indicator:checked:hover, QTreeView::indicator:checked:focus, QTreeView::indicator:checked:pressed,
1795QListView::indicator:checked:hover,
1796QListView::indicator:checked:focus,
1797QListView::indicator:checked:pressed {
1798 image: url(":/qss_icons/rc/checkbox_checked_focus.png");
1799}
1800
1801QTreeView::indicator:unchecked,
1802QListView::indicator:unchecked {
1803 image: url(":/qss_icons/rc/checkbox_unchecked.png");
1804}
1805
1806QTreeView::indicator:unchecked:hover, QTreeView::indicator:unchecked:focus, QTreeView::indicator:unchecked:pressed,
1807QListView::indicator:unchecked:hover,
1808QListView::indicator:unchecked:focus,
1809QListView::indicator:unchecked:pressed {
1810 image: url(":/qss_icons/rc/checkbox_unchecked_focus.png");
1811}
1812
1813QTreeView::indicator:indeterminate,
1814QListView::indicator:indeterminate {
1815 image: url(":/qss_icons/rc/checkbox_indeterminate.png");
1816}
1817
1818QTreeView::indicator:indeterminate:hover, QTreeView::indicator:indeterminate:focus, QTreeView::indicator:indeterminate:pressed,
1819QListView::indicator:indeterminate:hover,
1820QListView::indicator:indeterminate:focus,
1821QListView::indicator:indeterminate:pressed {
1822 image: url(":/qss_icons/rc/checkbox_indeterminate_focus.png");
1823}
1824
1825QTreeView,
1826QListView,
1827QTableView,
1828QColumnView {
1829 background-color: #19232D;
1830 border: 1px solid #32414B;
1831 color: #F0F0F0;
1832 gridline-color: #32414B;
1833 border-radius: 4px;
1834}
1835
1836QTreeView:disabled,
1837QListView:disabled,
1838QTableView:disabled,
1839QColumnView:disabled {
1840 background-color: #19232D;
1841 color: #787878;
1842}
1843
1844QTreeView:selected,
1845QListView:selected,
1846QTableView:selected,
1847QColumnView:selected {
1848 background-color: #1464A0;
1849 color: #32414B;
1850}
1851
1852QTreeView:hover,
1853QListView:hover,
1854QTableView:hover,
1855QColumnView:hover {
1856 background-color: #19232D;
1857 border: 1px solid #148CD2;
1858}
1859
1860QTreeView::item:pressed,
1861QListView::item:pressed,
1862QTableView::item:pressed,
1863QColumnView::item:pressed {
1864 background-color: #1464A0;
1865}
1866
1867QTreeView::item:selected:hover,
1868QListView::item:selected:hover,
1869QTableView::item:selected:hover,
1870QColumnView::item:selected:hover {
1871 background: #1464A0;
1872 color: #19232D;
1873}
1874
1875QTreeView::item:selected:active,
1876QListView::item:selected:active,
1877QTableView::item:selected:active,
1878QColumnView::item:selected:active {
1879 background-color: #1464A0;
1880}
1881
1882QTreeView::item:!selected:hover,
1883QListView::item:!selected:hover,
1884QTableView::item:!selected:hover,
1885QColumnView::item:!selected:hover {
1886 outline: 0;
1887 color: #148CD2;
1888 background-color: #32414B;
1889}
1890
1891QTableCornerButton::section {
1892 background-color: #19232D;
1893 border: 1px transparent #32414B;
1894 border-radius: 0px;
1895}
1896
1897/* QHeaderView ------------------------------------------------------------
1898
1899https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qheaderview
1900
1901--------------------------------------------------------------------------- */
1902QHeaderView {
1903 background-color: #32414B;
1904 border: 0px transparent #32414B;
1905 padding: 0px;
1906 margin: 0px;
1907 border-radius: 0px;
1908}
1909
1910QHeaderView:disabled {
1911 background-color: #32414B;
1912 border: 1px transparent #32414B;
1913 padding: 2px;
1914}
1915
1916QHeaderView::section {
1917 background-color: #32414B;
1918 color: #F0F0F0;
1919 padding: 2px;
1920 border-radius: 0px;
1921 text-align: left;
1922}
1923
1924QHeaderView::section:checked {
1925 color: #F0F0F0;
1926 background-color: #1464A0;
1927}
1928
1929QHeaderView::section:checked:disabled {
1930 color: #787878;
1931 background-color: #14506E;
1932}
1933
1934QHeaderView::section::horizontal {
1935 padding-left: 4px;
1936 padding-right: 4px;
1937 border-left: 1px solid #19232D;
1938}
1939
1940QHeaderView::section::horizontal::first, QHeaderView::section::horizontal::only-one {
1941 border-left: 1px solid #32414B;
1942}
1943
1944QHeaderView::section::horizontal:disabled {
1945 color: #787878;
1946}
1947
1948QHeaderView::section::vertical {
1949 padding-left: 4px;
1950 padding-right: 4px;
1951 border-top: 1px solid #19232D;
1952}
1953
1954QHeaderView::section::vertical::first, QHeaderView::section::vertical::only-one {
1955 border-top: 1px solid #32414B;
1956}
1957
1958QHeaderView::section::vertical:disabled {
1959 color: #787878;
1960}
1961
1962QHeaderView::down-arrow {
1963 /* Those settings (border/width/height/background-color) solve bug */
1964 /* transparent arrow background and size */
1965 background-color: #32414B;
1966 border: none;
1967 height: 12px;
1968 width: 12px;
1969 padding-left: 2px;
1970 padding-right: 2px;
1971 image: url(":/qss_icons/rc/arrow_down.png");
1972}
1973
1974QHeaderView::up-arrow {
1975 background-color: #32414B;
1976 border: none;
1977 height: 12px;
1978 width: 12px;
1979 padding-left: 2px;
1980 padding-right: 2px;
1981 image: url(":/qss_icons/rc/arrow_up.png");
1982}
1983
1984/* QToolBox --------------------------------------------------------------
1985
1986https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbox
1987
1988--------------------------------------------------------------------------- */
1989QToolBox {
1990 padding: 0px;
1991 border: 0px;
1992 border: 1px solid #32414B;
1993}
1994
1995QToolBox:selected {
1996 padding: 0px;
1997 border: 2px solid #1464A0;
1998}
1999
2000QToolBox::tab {
2001 background-color: #19232D;
2002 border: 1px solid #32414B;
2003 color: #F0F0F0;
2004 border-top-left-radius: 4px;
2005 border-top-right-radius: 4px;
2006}
2007
2008QToolBox::tab:disabled {
2009 color: #787878;
2010}
2011
2012QToolBox::tab:selected {
2013 background-color: #505F69;
2014 border-bottom: 2px solid #1464A0;
2015}
2016
2017QToolBox::tab:selected:disabled {
2018 background-color: #32414B;
2019 border-bottom: 2px solid #14506E;
2020}
2021
2022QToolBox::tab:!selected {
2023 background-color: #32414B;
2024 border-bottom: 2px solid #32414B;
2025}
2026
2027QToolBox::tab:!selected:disabled {
2028 background-color: #19232D;
2029}
2030
2031QToolBox::tab:hover {
2032 border-color: #148CD2;
2033 border-bottom: 2px solid #148CD2;
2034}
2035
2036QToolBox QScrollArea QWidget QWidget {
2037 padding: 0px;
2038 border: 0px;
2039 background-color: #19232D;
2040}
2041
2042/* QFrame -----------------------------------------------------------------
2043
2044https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qframe
2045https://doc.qt.io/qt-5/qframe.html#-prop
2046https://doc.qt.io/qt-5/qframe.html#details
2047https://stackoverflow.com/questions/14581498/qt-stylesheet-for-hline-vline-color
2048
2049--------------------------------------------------------------------------- */
2050/* (dot) .QFrame fix #141, #126, #123 */
2051.QFrame {
2052 border-radius: 4px;
2053 border: 1px solid #32414B;
2054 /* No frame */
2055 /* HLine */
2056 /* HLine */
2057}
2058
2059.QFrame[frameShape="0"] {
2060 border-radius: 4px;
2061 border: 1px transparent #32414B;
2062}
2063
2064.QFrame[frameShape="4"] {
2065 max-height: 2px;
2066 border: none;
2067 background-color: #32414B;
2068}
2069
2070.QFrame[frameShape="5"] {
2071 max-width: 2px;
2072 border: none;
2073 background-color: #32414B;
2074}
2075
2076/* QSplitter --------------------------------------------------------------
2077
2078https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qsplitter
2079
2080--------------------------------------------------------------------------- */
2081QSplitter {
2082 background-color: #32414B;
2083 spacing: 0px;
2084 padding: 0px;
2085 margin: 0px;
2086}
2087
2088QSplitter::handle {
2089 background-color: #32414B;
2090 border: 0px solid #19232D;
2091 spacing: 0px;
2092 padding: 1px;
2093 margin: 0px;
2094}
2095
2096QSplitter::handle:hover {
2097 background-color: #787878;
2098}
2099
2100QSplitter::handle:horizontal {
2101 width: 5px;
2102 image: url(":/qss_icons/rc/line_vertical.png");
2103}
2104
2105QSplitter::handle:vertical {
2106 height: 5px;
2107 image: url(":/qss_icons/rc/line_horizontal.png");
2108}
2109
2110/* QDateEdit, QDateTimeEdit -----------------------------------------------
2111
2112--------------------------------------------------------------------------- */
2113QDateEdit, QDateTimeEdit {
2114 selection-background-color: #1464A0;
2115 border-style: solid;
2116 border: 1px solid #32414B;
2117 border-radius: 4px;
2118 /* This fixes 103, 111 */
2119 padding-top: 2px;
2120 /* This fixes 103, 111 */
2121 padding-bottom: 2px;
2122 padding-left: 4px;
2123 padding-right: 4px;
2124 min-width: 10px;
2125}
2126
2127QDateEdit:on, QDateTimeEdit:on {
2128 selection-background-color: #1464A0;
2129}
2130
2131QDateEdit::drop-down, QDateTimeEdit::drop-down {
2132 subcontrol-origin: padding;
2133 subcontrol-position: top right;
2134 width: 12px;
2135 border-left: 1px solid #32414B;
2136}
2137
2138QDateEdit::down-arrow, QDateTimeEdit::down-arrow {
2139 image: url(":/qss_icons/rc/arrow_down_disabled.png");
2140 height: 8px;
2141 width: 8px;
2142}
2143
2144QDateEdit::down-arrow:on, QDateEdit::down-arrow:hover, QDateEdit::down-arrow:focus, QDateTimeEdit::down-arrow:on, QDateTimeEdit::down-arrow:hover, QDateTimeEdit::down-arrow:focus {
2145 image: url(":/qss_icons/rc/arrow_down.png");
2146}
2147
2148QDateEdit QAbstractItemView, QDateTimeEdit QAbstractItemView {
2149 background-color: #19232D;
2150 border-radius: 4px;
2151 border: 1px solid #32414B;
2152 selection-background-color: #1464A0;
2153}
2154
2155/* QAbstractView ----------------------------------------------------------
2156
2157--------------------------------------------------------------------------- */
2158QAbstractView:hover {
2159 border: 1px solid #148CD2;
2160 color: #F0F0F0;
2161}
2162
2163QAbstractView:selected {
2164 background: #1464A0;
2165 color: #32414B;
2166}
2167
2168/* PlotWidget -------------------------------------------------------------
2169
2170--------------------------------------------------------------------------- */
2171PlotWidget {
2172 /* Fix cut labels in plots #134 */
2173 padding: 0px;
2174}
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp
index f80ab92e4..7be5d5087 100644
--- a/src/audio_core/stream.cpp
+++ b/src/audio_core/stream.cpp
@@ -36,9 +36,10 @@ Stream::Stream(Core::Timing::CoreTiming& core_timing, u32 sample_rate, Format fo
36 ReleaseCallback&& release_callback, SinkStream& sink_stream, std::string&& name_) 36 ReleaseCallback&& release_callback, SinkStream& sink_stream, std::string&& name_)
37 : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)}, 37 : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)},
38 sink_stream{sink_stream}, core_timing{core_timing}, name{std::move(name_)} { 38 sink_stream{sink_stream}, core_timing{core_timing}, name{std::move(name_)} {
39 39 release_event =
40 release_event = Core::Timing::CreateEvent( 40 Core::Timing::CreateEvent(name, [this](std::uintptr_t, std::chrono::nanoseconds ns_late) {
41 name, [this](u64, std::chrono::nanoseconds ns_late) { ReleaseActiveBuffer(ns_late); }); 41 ReleaseActiveBuffer(ns_late);
42 });
42} 43}
43 44
44void Stream::Play() { 45void Stream::Play() {
diff --git a/src/common/string_util.h b/src/common/string_util.h
index 583fd05e6..023dff5dc 100644
--- a/src/common/string_util.h
+++ b/src/common/string_util.h
@@ -74,16 +74,4 @@ std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, std::size_t
74std::u16string UTF16StringFromFixedZeroTerminatedBuffer(std::u16string_view buffer, 74std::u16string UTF16StringFromFixedZeroTerminatedBuffer(std::u16string_view buffer,
75 std::size_t max_len); 75 std::size_t max_len);
76 76
77/**
78 * Attempts to trim an arbitrary prefix from `path`, leaving only the part starting at `root`. It's
79 * intended to be used to strip a system-specific build directory from the `__FILE__` macro,
80 * leaving only the path relative to the sources root.
81 *
82 * @param path The input file path as a null-terminated string
83 * @param root The name of the root source directory as a null-terminated string. Path up to and
84 * including the last occurrence of this name will be stripped
85 * @return A pointer to the same string passed as `path`, but starting at the trimmed portion
86 */
87const char* TrimSourcePath(const char* path, const char* root = "src");
88
89} // namespace Common 77} // namespace Common
diff --git a/src/common/virtual_buffer.cpp b/src/common/virtual_buffer.cpp
index b426f4747..be5b67752 100644
--- a/src/common/virtual_buffer.cpp
+++ b/src/common/virtual_buffer.cpp
@@ -38,7 +38,7 @@ void* AllocateMemoryPages(std::size_t size) {
38 return base; 38 return base;
39} 39}
40 40
41void FreeMemoryPages(void* base, std::size_t size) { 41void FreeMemoryPages(void* base, [[maybe_unused]] std::size_t size) {
42 if (!base) { 42 if (!base) {
43 return; 43 return;
44 } 44 }
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index c42f95705..c85c9485f 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -586,6 +586,9 @@ add_library(core STATIC
586 memory/dmnt_cheat_vm.h 586 memory/dmnt_cheat_vm.h
587 memory.cpp 587 memory.cpp
588 memory.h 588 memory.h
589 network/network.cpp
590 network/network.h
591 network/sockets.h
589 perf_stats.cpp 592 perf_stats.cpp
590 perf_stats.h 593 perf_stats.h
591 reporter.cpp 594 reporter.cpp
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 69a1aa0a5..42277e2cd 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -43,6 +43,7 @@
43#include "core/loader/loader.h" 43#include "core/loader/loader.h"
44#include "core/memory.h" 44#include "core/memory.h"
45#include "core/memory/cheat_engine.h" 45#include "core/memory/cheat_engine.h"
46#include "core/network/network.h"
46#include "core/perf_stats.h" 47#include "core/perf_stats.h"
47#include "core/reporter.h" 48#include "core/reporter.h"
48#include "core/settings.h" 49#include "core/settings.h"
@@ -145,7 +146,7 @@ struct System::Impl {
145 ResultStatus Init(System& system, Frontend::EmuWindow& emu_window) { 146 ResultStatus Init(System& system, Frontend::EmuWindow& emu_window) {
146 LOG_DEBUG(HW_Memory, "initialized OK"); 147 LOG_DEBUG(HW_Memory, "initialized OK");
147 148
148 device_memory = std::make_unique<Core::DeviceMemory>(system); 149 device_memory = std::make_unique<Core::DeviceMemory>();
149 150
150 is_multicore = Settings::values.use_multi_core.GetValue(); 151 is_multicore = Settings::values.use_multi_core.GetValue();
151 is_async_gpu = is_multicore || Settings::values.use_asynchronous_gpu_emulation.GetValue(); 152 is_async_gpu = is_multicore || Settings::values.use_asynchronous_gpu_emulation.GetValue();
@@ -394,6 +395,9 @@ struct System::Impl {
394 /// Telemetry session for this emulation session 395 /// Telemetry session for this emulation session
395 std::unique_ptr<Core::TelemetrySession> telemetry_session; 396 std::unique_ptr<Core::TelemetrySession> telemetry_session;
396 397
398 /// Network instance
399 Network::NetworkInstance network_instance;
400
397 ResultStatus status = ResultStatus::Success; 401 ResultStatus status = ResultStatus::Success;
398 std::string status_details = ""; 402 std::string status_details = "";
399 403
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index b5feb3f24..71af26ec5 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -23,7 +23,7 @@ std::shared_ptr<EventType> CreateEvent(std::string name, TimedCallback&& callbac
23struct CoreTiming::Event { 23struct CoreTiming::Event {
24 u64 time; 24 u64 time;
25 u64 fifo_order; 25 u64 fifo_order;
26 u64 userdata; 26 std::uintptr_t user_data;
27 std::weak_ptr<EventType> type; 27 std::weak_ptr<EventType> type;
28 28
29 // Sort by time, unless the times are the same, in which case sort by 29 // Sort by time, unless the times are the same, in which case sort by
@@ -58,7 +58,7 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
58 event_fifo_id = 0; 58 event_fifo_id = 0;
59 shutting_down = false; 59 shutting_down = false;
60 ticks = 0; 60 ticks = 0;
61 const auto empty_timed_callback = [](u64, std::chrono::nanoseconds) {}; 61 const auto empty_timed_callback = [](std::uintptr_t, std::chrono::nanoseconds) {};
62 ev_lost = CreateEvent("_lost_event", empty_timed_callback); 62 ev_lost = CreateEvent("_lost_event", empty_timed_callback);
63 if (is_multicore) { 63 if (is_multicore) {
64 timer_thread = std::make_unique<std::thread>(ThreadEntry, std::ref(*this)); 64 timer_thread = std::make_unique<std::thread>(ThreadEntry, std::ref(*this));
@@ -107,22 +107,24 @@ bool CoreTiming::HasPendingEvents() const {
107} 107}
108 108
109void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future, 109void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future,
110 const std::shared_ptr<EventType>& event_type, u64 userdata) { 110 const std::shared_ptr<EventType>& event_type,
111 std::uintptr_t user_data) {
111 { 112 {
112 std::scoped_lock scope{basic_lock}; 113 std::scoped_lock scope{basic_lock};
113 const u64 timeout = static_cast<u64>((GetGlobalTimeNs() + ns_into_future).count()); 114 const u64 timeout = static_cast<u64>((GetGlobalTimeNs() + ns_into_future).count());
114 115
115 event_queue.emplace_back(Event{timeout, event_fifo_id++, userdata, event_type}); 116 event_queue.emplace_back(Event{timeout, event_fifo_id++, user_data, event_type});
116 117
117 std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>()); 118 std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>());
118 } 119 }
119 event.Set(); 120 event.Set();
120} 121}
121 122
122void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, u64 userdata) { 123void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type,
124 std::uintptr_t user_data) {
123 std::scoped_lock scope{basic_lock}; 125 std::scoped_lock scope{basic_lock};
124 const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) { 126 const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) {
125 return e.type.lock().get() == event_type.get() && e.userdata == userdata; 127 return e.type.lock().get() == event_type.get() && e.user_data == user_data;
126 }); 128 });
127 129
128 // Removing random items breaks the invariant so we have to re-establish it. 130 // Removing random items breaks the invariant so we have to re-establish it.
@@ -197,7 +199,7 @@ std::optional<s64> CoreTiming::Advance() {
197 199
198 if (const auto event_type{evt.type.lock()}) { 200 if (const auto event_type{evt.type.lock()}) {
199 event_type->callback( 201 event_type->callback(
200 evt.userdata, std::chrono::nanoseconds{static_cast<s64>(global_timer - evt.time)}); 202 evt.user_data, std::chrono::nanoseconds{static_cast<s64>(global_timer - evt.time)});
201 } 203 }
202 204
203 basic_lock.lock(); 205 basic_lock.lock();
diff --git a/src/core/core_timing.h b/src/core/core_timing.h
index 120c74e46..b0b6036e4 100644
--- a/src/core/core_timing.h
+++ b/src/core/core_timing.h
@@ -22,7 +22,8 @@
22namespace Core::Timing { 22namespace Core::Timing {
23 23
24/// A callback that may be scheduled for a particular core timing event. 24/// A callback that may be scheduled for a particular core timing event.
25using TimedCallback = std::function<void(u64 userdata, std::chrono::nanoseconds ns_late)>; 25using TimedCallback =
26 std::function<void(std::uintptr_t user_data, std::chrono::nanoseconds ns_late)>;
26 27
27/// Contains the characteristics of a particular event. 28/// Contains the characteristics of a particular event.
28struct EventType { 29struct EventType {
@@ -94,9 +95,9 @@ public:
94 95
95 /// Schedules an event in core timing 96 /// Schedules an event in core timing
96 void ScheduleEvent(std::chrono::nanoseconds ns_into_future, 97 void ScheduleEvent(std::chrono::nanoseconds ns_into_future,
97 const std::shared_ptr<EventType>& event_type, u64 userdata = 0); 98 const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data = 0);
98 99
99 void UnscheduleEvent(const std::shared_ptr<EventType>& event_type, u64 userdata); 100 void UnscheduleEvent(const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data);
100 101
101 /// We only permit one event of each type in the queue at a time. 102 /// We only permit one event of each type in the queue at a time.
102 void RemoveEvent(const std::shared_ptr<EventType>& event_type); 103 void RemoveEvent(const std::shared_ptr<EventType>& event_type);
diff --git a/src/core/device_memory.cpp b/src/core/device_memory.cpp
index 51097ced3..0c4b440ed 100644
--- a/src/core/device_memory.cpp
+++ b/src/core/device_memory.cpp
@@ -2,14 +2,11 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/core.h"
6#include "core/device_memory.h" 5#include "core/device_memory.h"
7#include "core/memory.h"
8 6
9namespace Core { 7namespace Core {
10 8
11DeviceMemory::DeviceMemory(System& system) : buffer{DramMemoryMap::Size}, system{system} {} 9DeviceMemory::DeviceMemory() : buffer{DramMemoryMap::Size} {}
12
13DeviceMemory::~DeviceMemory() = default; 10DeviceMemory::~DeviceMemory() = default;
14 11
15} // namespace Core 12} // namespace Core
diff --git a/src/core/device_memory.h b/src/core/device_memory.h
index 9efa088d0..5b1ae28f3 100644
--- a/src/core/device_memory.h
+++ b/src/core/device_memory.h
@@ -4,14 +4,11 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "common/assert.h" 7#include "common/common_types.h"
8#include "common/common_funcs.h"
9#include "common/virtual_buffer.h" 8#include "common/virtual_buffer.h"
10 9
11namespace Core { 10namespace Core {
12 11
13class System;
14
15namespace DramMemoryMap { 12namespace DramMemoryMap {
16enum : u64 { 13enum : u64 {
17 Base = 0x80000000ULL, 14 Base = 0x80000000ULL,
@@ -26,7 +23,7 @@ enum : u64 {
26 23
27class DeviceMemory : NonCopyable { 24class DeviceMemory : NonCopyable {
28public: 25public:
29 explicit DeviceMemory(Core::System& system); 26 explicit DeviceMemory();
30 ~DeviceMemory(); 27 ~DeviceMemory();
31 28
32 template <typename T> 29 template <typename T>
@@ -45,7 +42,6 @@ public:
45 42
46private: 43private:
47 Common::VirtualBuffer<u8> buffer; 44 Common::VirtualBuffer<u8> buffer;
48 Core::System& system;
49}; 45};
50 46
51} // namespace Core 47} // namespace Core
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp
index 37351c561..e94eed3b6 100644
--- a/src/core/file_sys/registered_cache.cpp
+++ b/src/core/file_sys/registered_cache.cpp
@@ -547,56 +547,6 @@ InstallResult RegisteredCache::InstallEntry(const XCI& xci, bool overwrite_if_ex
547 return InstallEntry(*xci.GetSecurePartitionNSP(), overwrite_if_exists, copy); 547 return InstallEntry(*xci.GetSecurePartitionNSP(), overwrite_if_exists, copy);
548} 548}
549 549
550bool RegisteredCache::RemoveExistingEntry(u64 title_id) {
551 const auto delete_nca = [this](const NcaID& id) {
552 const auto path = GetRelativePathFromNcaID(id, false, true, false);
553
554 if (dir->GetFileRelative(path) == nullptr) {
555 return false;
556 }
557
558 Core::Crypto::SHA256Hash hash{};
559 mbedtls_sha256_ret(id.data(), id.size(), hash.data(), 0);
560 const auto dirname = fmt::format("000000{:02X}", hash[0]);
561
562 const auto dir2 = GetOrCreateDirectoryRelative(dir, dirname);
563
564 const auto res = dir2->DeleteFile(fmt::format("{}.nca", Common::HexToString(id, false)));
565
566 return res;
567 };
568
569 // If an entry exists in the registered cache, remove it
570 if (HasEntry(title_id, ContentRecordType::Meta)) {
571 LOG_INFO(Loader,
572 "Previously installed entry (v{}) for title_id={:016X} detected! "
573 "Attempting to remove...",
574 GetEntryVersion(title_id).value_or(0), title_id);
575 // Get all the ncas associated with the current CNMT and delete them
576 const auto meta_old_id =
577 GetNcaIDFromMetadata(title_id, ContentRecordType::Meta).value_or(NcaID{});
578 const auto program_id =
579 GetNcaIDFromMetadata(title_id, ContentRecordType::Program).value_or(NcaID{});
580 const auto data_id =
581 GetNcaIDFromMetadata(title_id, ContentRecordType::Data).value_or(NcaID{});
582 const auto control_id =
583 GetNcaIDFromMetadata(title_id, ContentRecordType::Control).value_or(NcaID{});
584 const auto html_id =
585 GetNcaIDFromMetadata(title_id, ContentRecordType::HtmlDocument).value_or(NcaID{});
586 const auto legal_id =
587 GetNcaIDFromMetadata(title_id, ContentRecordType::LegalInformation).value_or(NcaID{});
588
589 delete_nca(meta_old_id);
590 delete_nca(program_id);
591 delete_nca(data_id);
592 delete_nca(control_id);
593 delete_nca(html_id);
594 delete_nca(legal_id);
595 return true;
596 }
597 return false;
598}
599
600InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_exists, 550InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_exists,
601 const VfsCopyFunction& copy) { 551 const VfsCopyFunction& copy) {
602 const auto ncas = nsp.GetNCAsCollapsed(); 552 const auto ncas = nsp.GetNCAsCollapsed();
@@ -692,6 +642,57 @@ InstallResult RegisteredCache::InstallEntry(const NCA& nca, TitleType type,
692 return RawInstallNCA(nca, copy, overwrite_if_exists, c_rec.nca_id); 642 return RawInstallNCA(nca, copy, overwrite_if_exists, c_rec.nca_id);
693} 643}
694 644
645bool RegisteredCache::RemoveExistingEntry(u64 title_id) const {
646 const auto delete_nca = [this](const NcaID& id) {
647 const auto path = GetRelativePathFromNcaID(id, false, true, false);
648
649 const bool isFile = dir->GetFileRelative(path) != nullptr;
650 const bool isDir = dir->GetDirectoryRelative(path) != nullptr;
651
652 if (isFile) {
653 return dir->DeleteFile(path);
654 } else if (isDir) {
655 return dir->DeleteSubdirectoryRecursive(path);
656 }
657
658 return false;
659 };
660
661 // If an entry exists in the registered cache, remove it
662 if (HasEntry(title_id, ContentRecordType::Meta)) {
663 LOG_INFO(Loader,
664 "Previously installed entry (v{}) for title_id={:016X} detected! "
665 "Attempting to remove...",
666 GetEntryVersion(title_id).value_or(0), title_id);
667
668 // Get all the ncas associated with the current CNMT and delete them
669 const auto meta_old_id =
670 GetNcaIDFromMetadata(title_id, ContentRecordType::Meta).value_or(NcaID{});
671 const auto program_id =
672 GetNcaIDFromMetadata(title_id, ContentRecordType::Program).value_or(NcaID{});
673 const auto data_id =
674 GetNcaIDFromMetadata(title_id, ContentRecordType::Data).value_or(NcaID{});
675 const auto control_id =
676 GetNcaIDFromMetadata(title_id, ContentRecordType::Control).value_or(NcaID{});
677 const auto html_id =
678 GetNcaIDFromMetadata(title_id, ContentRecordType::HtmlDocument).value_or(NcaID{});
679 const auto legal_id =
680 GetNcaIDFromMetadata(title_id, ContentRecordType::LegalInformation).value_or(NcaID{});
681
682 const auto deleted_meta = delete_nca(meta_old_id);
683 const auto deleted_program = delete_nca(program_id);
684 const auto deleted_data = delete_nca(data_id);
685 const auto deleted_control = delete_nca(control_id);
686 const auto deleted_html = delete_nca(html_id);
687 const auto deleted_legal = delete_nca(legal_id);
688
689 return deleted_meta && (deleted_meta || deleted_program || deleted_data ||
690 deleted_control || deleted_html || deleted_legal);
691 }
692
693 return false;
694}
695
695InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFunction& copy, 696InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFunction& copy,
696 bool overwrite_if_exists, 697 bool overwrite_if_exists,
697 std::optional<NcaID> override_id) { 698 std::optional<NcaID> override_id) {
diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h
index 29cf0d40c..ec1d54f27 100644
--- a/src/core/file_sys/registered_cache.h
+++ b/src/core/file_sys/registered_cache.h
@@ -155,9 +155,6 @@ public:
155 std::optional<TitleType> title_type = {}, std::optional<ContentRecordType> record_type = {}, 155 std::optional<TitleType> title_type = {}, std::optional<ContentRecordType> record_type = {},
156 std::optional<u64> title_id = {}) const override; 156 std::optional<u64> title_id = {}) const override;
157 157
158 // Removes an existing entry based on title id
159 bool RemoveExistingEntry(u64 title_id);
160
161 // Raw copies all the ncas from the xci/nsp to the csache. Does some quick checks to make sure 158 // Raw copies all the ncas from the xci/nsp to the csache. Does some quick checks to make sure
162 // there is a meta NCA and all of them are accessible. 159 // there is a meta NCA and all of them are accessible.
163 InstallResult InstallEntry(const XCI& xci, bool overwrite_if_exists = false, 160 InstallResult InstallEntry(const XCI& xci, bool overwrite_if_exists = false,
@@ -172,6 +169,9 @@ public:
172 InstallResult InstallEntry(const NCA& nca, TitleType type, bool overwrite_if_exists = false, 169 InstallResult InstallEntry(const NCA& nca, TitleType type, bool overwrite_if_exists = false,
173 const VfsCopyFunction& copy = &VfsRawCopy); 170 const VfsCopyFunction& copy = &VfsRawCopy);
174 171
172 // Removes an existing entry based on title id
173 bool RemoveExistingEntry(u64 title_id) const;
174
175private: 175private:
176 template <typename T> 176 template <typename T>
177 void IterateAllMetadata(std::vector<T>& out, 177 void IterateAllMetadata(std::vector<T>& out,
diff --git a/src/core/file_sys/xts_archive.cpp b/src/core/file_sys/xts_archive.cpp
index 86e06ccb9..81413c684 100644
--- a/src/core/file_sys/xts_archive.cpp
+++ b/src/core/file_sys/xts_archive.cpp
@@ -70,14 +70,18 @@ NAX::NAX(VirtualFile file_, std::array<u8, 0x10> nca_id)
70NAX::~NAX() = default; 70NAX::~NAX() = default;
71 71
72Loader::ResultStatus NAX::Parse(std::string_view path) { 72Loader::ResultStatus NAX::Parse(std::string_view path) {
73 if (file->ReadObject(header.get()) != sizeof(NAXHeader)) 73 if (file == nullptr) {
74 return Loader::ResultStatus::ErrorNullFile;
75 }
76 if (file->ReadObject(header.get()) != sizeof(NAXHeader)) {
74 return Loader::ResultStatus::ErrorBadNAXHeader; 77 return Loader::ResultStatus::ErrorBadNAXHeader;
75 78 }
76 if (header->magic != Common::MakeMagic('N', 'A', 'X', '0')) 79 if (header->magic != Common::MakeMagic('N', 'A', 'X', '0')) {
77 return Loader::ResultStatus::ErrorBadNAXHeader; 80 return Loader::ResultStatus::ErrorBadNAXHeader;
78 81 }
79 if (file->GetSize() < NAX_HEADER_PADDING_SIZE + header->file_size) 82 if (file->GetSize() < NAX_HEADER_PADDING_SIZE + header->file_size) {
80 return Loader::ResultStatus::ErrorIncorrectNAXFileSize; 83 return Loader::ResultStatus::ErrorIncorrectNAXFileSize;
84 }
81 85
82 keys.DeriveSDSeedLazy(); 86 keys.DeriveSDSeedLazy();
83 std::array<Core::Crypto::Key256, 2> sd_keys{}; 87 std::array<Core::Crypto::Key256, 2> sd_keys{};
diff --git a/src/core/hardware_interrupt_manager.cpp b/src/core/hardware_interrupt_manager.cpp
index efc1030c1..645f26e91 100644
--- a/src/core/hardware_interrupt_manager.cpp
+++ b/src/core/hardware_interrupt_manager.cpp
@@ -11,8 +11,8 @@
11namespace Core::Hardware { 11namespace Core::Hardware {
12 12
13InterruptManager::InterruptManager(Core::System& system_in) : system(system_in) { 13InterruptManager::InterruptManager(Core::System& system_in) : system(system_in) {
14 gpu_interrupt_event = 14 gpu_interrupt_event = Core::Timing::CreateEvent(
15 Core::Timing::CreateEvent("GPUInterrupt", [this](u64 message, std::chrono::nanoseconds) { 15 "GPUInterrupt", [this](std::uintptr_t message, std::chrono::nanoseconds) {
16 auto nvdrv = system.ServiceManager().GetService<Service::Nvidia::NVDRV>("nvdrv"); 16 auto nvdrv = system.ServiceManager().GetService<Service::Nvidia::NVDRV>("nvdrv");
17 const u32 syncpt = static_cast<u32>(message >> 32); 17 const u32 syncpt = static_cast<u32>(message >> 32);
18 const u32 value = static_cast<u32>(message); 18 const u32 value = static_cast<u32>(message);
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 8dd4a2637..cabe8d418 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -145,7 +145,7 @@ struct KernelCore::Impl {
145 145
146 void InitializePreemption(KernelCore& kernel) { 146 void InitializePreemption(KernelCore& kernel) {
147 preemption_event = Core::Timing::CreateEvent( 147 preemption_event = Core::Timing::CreateEvent(
148 "PreemptionCallback", [this, &kernel](u64, std::chrono::nanoseconds) { 148 "PreemptionCallback", [this, &kernel](std::uintptr_t, std::chrono::nanoseconds) {
149 { 149 {
150 SchedulerLock lock(kernel); 150 SchedulerLock lock(kernel);
151 global_scheduler.PreemptThreads(); 151 global_scheduler.PreemptThreads();
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp
index af22f4c33..7e6391c6c 100644
--- a/src/core/hle/kernel/server_session.cpp
+++ b/src/core/hle/kernel/server_session.cpp
@@ -33,8 +33,10 @@ ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kern
33 std::string name) { 33 std::string name) {
34 std::shared_ptr<ServerSession> session{std::make_shared<ServerSession>(kernel)}; 34 std::shared_ptr<ServerSession> session{std::make_shared<ServerSession>(kernel)};
35 35
36 session->request_event = Core::Timing::CreateEvent( 36 session->request_event =
37 name, [session](u64, std::chrono::nanoseconds) { session->CompleteSyncRequest(); }); 37 Core::Timing::CreateEvent(name, [session](std::uintptr_t, std::chrono::nanoseconds) {
38 session->CompleteSyncRequest();
39 });
38 session->name = std::move(name); 40 session->name = std::move(name);
39 session->parent = std::move(parent); 41 session->parent = std::move(parent);
40 42
diff --git a/src/core/hle/kernel/time_manager.cpp b/src/core/hle/kernel/time_manager.cpp
index 88b01b751..95f2446c9 100644
--- a/src/core/hle/kernel/time_manager.cpp
+++ b/src/core/hle/kernel/time_manager.cpp
@@ -16,14 +16,14 @@ namespace Kernel {
16 16
17TimeManager::TimeManager(Core::System& system_) : system{system_} { 17TimeManager::TimeManager(Core::System& system_) : system{system_} {
18 time_manager_event_type = Core::Timing::CreateEvent( 18 time_manager_event_type = Core::Timing::CreateEvent(
19 "Kernel::TimeManagerCallback", [this](u64 thread_handle, std::chrono::nanoseconds) { 19 "Kernel::TimeManagerCallback",
20 SchedulerLock lock(system.Kernel()); 20 [this](std::uintptr_t thread_handle, std::chrono::nanoseconds) {
21 Handle proper_handle = static_cast<Handle>(thread_handle); 21 const SchedulerLock lock(system.Kernel());
22 const auto proper_handle = static_cast<Handle>(thread_handle);
22 if (cancelled_events[proper_handle]) { 23 if (cancelled_events[proper_handle]) {
23 return; 24 return;
24 } 25 }
25 std::shared_ptr<Thread> thread = 26 auto thread = this->system.Kernel().RetrieveThreadFromGlobalHandleTable(proper_handle);
26 this->system.Kernel().RetrieveThreadFromGlobalHandleTable(proper_handle);
27 thread->OnWakeUp(); 27 thread->OnWakeUp();
28 }); 28 });
29} 29}
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 4e7a0bec9..ceed20609 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -1405,7 +1405,6 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
1405 // Get supported languages from NACP, if possible 1405 // Get supported languages from NACP, if possible
1406 // Default to 0 (all languages supported) 1406 // Default to 0 (all languages supported)
1407 u32 supported_languages = 0; 1407 u32 supported_languages = 0;
1408 FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()};
1409 1408
1410 const auto res = [this] { 1409 const auto res = [this] {
1411 const auto title_id = system.CurrentProcess()->GetTitleID(); 1410 const auto title_id = system.CurrentProcess()->GetTitleID();
diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp
index fbe3686ae..289da2619 100644
--- a/src/core/hle/service/am/applets/software_keyboard.cpp
+++ b/src/core/hle/service/am/applets/software_keyboard.cpp
@@ -13,11 +13,23 @@
13 13
14namespace Service::AM::Applets { 14namespace Service::AM::Applets {
15 15
16namespace {
17enum class Request : u32 {
18 Finalize = 0x4,
19 SetUserWordInfo = 0x6,
20 SetCustomizeDic = 0x7,
21 Calc = 0xa,
22 SetCustomizedDictionaries = 0xb,
23 UnsetCustomizedDictionaries = 0xc,
24 UnknownD = 0xd,
25 UnknownE = 0xe,
26};
27constexpr std::size_t SWKBD_INLINE_INIT_SIZE = 0x8;
16constexpr std::size_t SWKBD_OUTPUT_BUFFER_SIZE = 0x7D8; 28constexpr std::size_t SWKBD_OUTPUT_BUFFER_SIZE = 0x7D8;
17constexpr std::size_t SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE = 0x7D4; 29constexpr std::size_t SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE = 0x7D4;
18constexpr std::size_t DEFAULT_MAX_LENGTH = 500; 30constexpr std::size_t DEFAULT_MAX_LENGTH = 500;
19constexpr bool INTERACTIVE_STATUS_OK = false; 31constexpr bool INTERACTIVE_STATUS_OK = false;
20 32} // Anonymous namespace
21static Core::Frontend::SoftwareKeyboardParameters ConvertToFrontendParameters( 33static Core::Frontend::SoftwareKeyboardParameters ConvertToFrontendParameters(
22 KeyboardConfig config, std::u16string initial_text) { 34 KeyboardConfig config, std::u16string initial_text) {
23 Core::Frontend::SoftwareKeyboardParameters params{}; 35 Core::Frontend::SoftwareKeyboardParameters params{};
@@ -47,6 +59,7 @@ SoftwareKeyboard::~SoftwareKeyboard() = default;
47 59
48void SoftwareKeyboard::Initialize() { 60void SoftwareKeyboard::Initialize() {
49 complete = false; 61 complete = false;
62 is_inline = false;
50 initial_text.clear(); 63 initial_text.clear();
51 final_data.clear(); 64 final_data.clear();
52 65
@@ -56,6 +69,11 @@ void SoftwareKeyboard::Initialize() {
56 ASSERT(keyboard_config_storage != nullptr); 69 ASSERT(keyboard_config_storage != nullptr);
57 const auto& keyboard_config = keyboard_config_storage->GetData(); 70 const auto& keyboard_config = keyboard_config_storage->GetData();
58 71
72 if (keyboard_config.size() == SWKBD_INLINE_INIT_SIZE) {
73 is_inline = true;
74 return;
75 }
76
59 ASSERT(keyboard_config.size() >= sizeof(KeyboardConfig)); 77 ASSERT(keyboard_config.size() >= sizeof(KeyboardConfig));
60 std::memcpy(&config, keyboard_config.data(), sizeof(KeyboardConfig)); 78 std::memcpy(&config, keyboard_config.data(), sizeof(KeyboardConfig));
61 79
@@ -87,16 +105,32 @@ void SoftwareKeyboard::ExecuteInteractive() {
87 const auto storage = broker.PopInteractiveDataToApplet(); 105 const auto storage = broker.PopInteractiveDataToApplet();
88 ASSERT(storage != nullptr); 106 ASSERT(storage != nullptr);
89 const auto data = storage->GetData(); 107 const auto data = storage->GetData();
90 const auto status = static_cast<bool>(data[0]); 108 if (!is_inline) {
91 109 const auto status = static_cast<bool>(data[0]);
92 if (status == INTERACTIVE_STATUS_OK) { 110 if (status == INTERACTIVE_STATUS_OK) {
93 complete = true; 111 complete = true;
112 } else {
113 std::array<char16_t, SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE / 2 - 2> string;
114 std::memcpy(string.data(), data.data() + 4, string.size() * 2);
115 frontend.SendTextCheckDialog(
116 Common::UTF16StringFromFixedZeroTerminatedBuffer(string.data(), string.size()),
117 [this] { broker.SignalStateChanged(); });
118 }
94 } else { 119 } else {
95 std::array<char16_t, SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE / 2 - 2> string; 120 Request request{};
96 std::memcpy(string.data(), data.data() + 4, string.size() * 2); 121 std::memcpy(&request, data.data(), sizeof(Request));
97 frontend.SendTextCheckDialog( 122
98 Common::UTF16StringFromFixedZeroTerminatedBuffer(string.data(), string.size()), 123 switch (request) {
99 [this] { broker.SignalStateChanged(); }); 124 case Request::Calc: {
125 broker.PushNormalDataFromApplet(
126 std::make_shared<IStorage>(std::move(std::vector<u8>{1})));
127 broker.SignalStateChanged();
128 break;
129 }
130 default:
131 UNIMPLEMENTED_MSG("Request {:X} is not implemented", request);
132 break;
133 }
100 } 134 }
101} 135}
102 136
@@ -108,9 +142,10 @@ void SoftwareKeyboard::Execute() {
108 } 142 }
109 143
110 const auto parameters = ConvertToFrontendParameters(config, initial_text); 144 const auto parameters = ConvertToFrontendParameters(config, initial_text);
111 145 if (!is_inline) {
112 frontend.RequestText([this](std::optional<std::u16string> text) { WriteText(std::move(text)); }, 146 frontend.RequestText(
113 parameters); 147 [this](std::optional<std::u16string> text) { WriteText(std::move(text)); }, parameters);
148 }
114} 149}
115 150
116void SoftwareKeyboard::WriteText(std::optional<std::u16string> text) { 151void SoftwareKeyboard::WriteText(std::optional<std::u16string> text) {
diff --git a/src/core/hle/service/am/applets/software_keyboard.h b/src/core/hle/service/am/applets/software_keyboard.h
index ef4801fc6..5a3824b5a 100644
--- a/src/core/hle/service/am/applets/software_keyboard.h
+++ b/src/core/hle/service/am/applets/software_keyboard.h
@@ -78,6 +78,7 @@ private:
78 KeyboardConfig config; 78 KeyboardConfig config;
79 std::u16string initial_text; 79 std::u16string initial_text;
80 bool complete = false; 80 bool complete = false;
81 bool is_inline = false;
81 std::vector<u8> final_data; 82 std::vector<u8> final_data;
82}; 83};
83 84
diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp
index cb35919e9..ad251ed4a 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.cpp
+++ b/src/core/hle/service/hid/controllers/debug_pad.cpp
@@ -39,33 +39,36 @@ void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing,
39 39
40 cur_entry.sampling_number = last_entry.sampling_number + 1; 40 cur_entry.sampling_number = last_entry.sampling_number + 1;
41 cur_entry.sampling_number2 = cur_entry.sampling_number; 41 cur_entry.sampling_number2 = cur_entry.sampling_number;
42 cur_entry.attribute.connected.Assign(1);
43 auto& pad = cur_entry.pad_state;
44 42
45 using namespace Settings::NativeButton; 43 if (Settings::values.debug_pad_enabled) {
46 pad.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus()); 44 cur_entry.attribute.connected.Assign(1);
47 pad.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus()); 45 auto& pad = cur_entry.pad_state;
48 pad.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus());
49 pad.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus());
50 pad.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus());
51 pad.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus());
52 pad.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus());
53 pad.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus());
54 pad.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus());
55 pad.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus());
56 pad.d_left.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus());
57 pad.d_up.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus());
58 pad.d_right.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus());
59 pad.d_down.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus());
60 46
61 const auto [stick_l_x_f, stick_l_y_f] = 47 using namespace Settings::NativeButton;
62 analogs[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetStatus(); 48 pad.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus());
63 const auto [stick_r_x_f, stick_r_y_f] = 49 pad.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus());
64 analogs[static_cast<std::size_t>(JoystickId::Joystick_Right)]->GetStatus(); 50 pad.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus());
65 cur_entry.l_stick.x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX); 51 pad.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus());
66 cur_entry.l_stick.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX); 52 pad.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus());
67 cur_entry.r_stick.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX); 53 pad.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus());
68 cur_entry.r_stick.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX); 54 pad.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus());
55 pad.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus());
56 pad.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus());
57 pad.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus());
58 pad.d_left.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus());
59 pad.d_up.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus());
60 pad.d_right.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus());
61 pad.d_down.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus());
62
63 const auto [stick_l_x_f, stick_l_y_f] =
64 analogs[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetStatus();
65 const auto [stick_r_x_f, stick_r_y_f] =
66 analogs[static_cast<std::size_t>(JoystickId::Joystick_Right)]->GetStatus();
67 cur_entry.l_stick.x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX);
68 cur_entry.l_stick.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX);
69 cur_entry.r_stick.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX);
70 cur_entry.r_stick.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX);
71 }
69 72
70 std::memcpy(data, &shared_memory, sizeof(SharedMemory)); 73 std::memcpy(data, &shared_memory, sizeof(SharedMemory));
71} 74}
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp
index feae89525..0b896d5ad 100644
--- a/src/core/hle/service/hid/controllers/keyboard.cpp
+++ b/src/core/hle/service/hid/controllers/keyboard.cpp
@@ -40,15 +40,16 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing,
40 40
41 cur_entry.key.fill(0); 41 cur_entry.key.fill(0);
42 cur_entry.modifier = 0; 42 cur_entry.modifier = 0;
43 43 if (Settings::values.keyboard_enabled) {
44 for (std::size_t i = 0; i < keyboard_keys.size(); ++i) { 44 for (std::size_t i = 0; i < keyboard_keys.size(); ++i) {
45 cur_entry.key[i / KEYS_PER_BYTE] |= (keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE)); 45 cur_entry.key[i / KEYS_PER_BYTE] |=
46 } 46 (keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE));
47 47 }
48 for (std::size_t i = 0; i < keyboard_mods.size(); ++i) { 48
49 cur_entry.modifier |= (keyboard_mods[i]->GetStatus() << i); 49 for (std::size_t i = 0; i < keyboard_mods.size(); ++i) {
50 cur_entry.modifier |= (keyboard_mods[i]->GetStatus() << i);
51 }
50 } 52 }
51
52 std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); 53 std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory));
53} 54}
54 55
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 680290cbd..1e95b7580 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -77,8 +77,9 @@ IAppletResource::IAppletResource(Core::System& system)
77 77
78 // Register update callbacks 78 // Register update callbacks
79 pad_update_event = Core::Timing::CreateEvent( 79 pad_update_event = Core::Timing::CreateEvent(
80 "HID::UpdatePadCallback", [this](u64 userdata, std::chrono::nanoseconds ns_late) { 80 "HID::UpdatePadCallback",
81 UpdateControllers(userdata, ns_late); 81 [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
82 UpdateControllers(user_data, ns_late);
82 }); 83 });
83 84
84 // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?) 85 // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?)
@@ -108,7 +109,8 @@ void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
108 rb.PushCopyObjects(shared_mem); 109 rb.PushCopyObjects(shared_mem);
109} 110}
110 111
111void IAppletResource::UpdateControllers(u64 userdata, std::chrono::nanoseconds ns_late) { 112void IAppletResource::UpdateControllers(std::uintptr_t user_data,
113 std::chrono::nanoseconds ns_late) {
112 auto& core_timing = system.CoreTiming(); 114 auto& core_timing = system.CoreTiming();
113 115
114 const bool should_reload = Settings::values.is_device_reload_pending.exchange(false); 116 const bool should_reload = Settings::values.is_device_reload_pending.exchange(false);
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index c6f0a2584..efb07547f 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -64,7 +64,7 @@ private:
64 } 64 }
65 65
66 void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); 66 void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
67 void UpdateControllers(u64 userdata, std::chrono::nanoseconds ns_late); 67 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
68 68
69 std::shared_ptr<Kernel::SharedMemory> shared_mem; 69 std::shared_ptr<Kernel::SharedMemory> shared_mem;
70 70
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 789856118..f644a460d 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -67,8 +67,8 @@ NVFlinger::NVFlinger(Core::System& system) : system(system) {
67 67
68 // Schedule the screen composition events 68 // Schedule the screen composition events
69 composition_event = Core::Timing::CreateEvent( 69 composition_event = Core::Timing::CreateEvent(
70 "ScreenComposition", [this](u64, std::chrono::nanoseconds ns_late) { 70 "ScreenComposition", [this](std::uintptr_t, std::chrono::nanoseconds ns_late) {
71 Lock(); 71 const auto guard = Lock();
72 Compose(); 72 Compose();
73 73
74 const auto ticks = std::chrono::nanoseconds{GetNextTicks()}; 74 const auto ticks = std::chrono::nanoseconds{GetNextTicks()};
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index e4959a9af..ff85cbba6 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -54,12 +54,12 @@ public:
54 /// Opens the specified display and returns the ID. 54 /// Opens the specified display and returns the ID.
55 /// 55 ///
56 /// If an invalid display name is provided, then an empty optional is returned. 56 /// If an invalid display name is provided, then an empty optional is returned.
57 std::optional<u64> OpenDisplay(std::string_view name); 57 [[nodiscard]] std::optional<u64> OpenDisplay(std::string_view name);
58 58
59 /// Creates a layer on the specified display and returns the layer ID. 59 /// Creates a layer on the specified display and returns the layer ID.
60 /// 60 ///
61 /// If an invalid display ID is specified, then an empty optional is returned. 61 /// If an invalid display ID is specified, then an empty optional is returned.
62 std::optional<u64> CreateLayer(u64 display_id); 62 [[nodiscard]] std::optional<u64> CreateLayer(u64 display_id);
63 63
64 /// Closes a layer on all displays for the given layer ID. 64 /// Closes a layer on all displays for the given layer ID.
65 void CloseLayer(u64 layer_id); 65 void CloseLayer(u64 layer_id);
@@ -67,41 +67,39 @@ public:
67 /// Finds the buffer queue ID of the specified layer in the specified display. 67 /// Finds the buffer queue ID of the specified layer in the specified display.
68 /// 68 ///
69 /// If an invalid display ID or layer ID is provided, then an empty optional is returned. 69 /// If an invalid display ID or layer ID is provided, then an empty optional is returned.
70 std::optional<u32> FindBufferQueueId(u64 display_id, u64 layer_id) const; 70 [[nodiscard]] std::optional<u32> FindBufferQueueId(u64 display_id, u64 layer_id) const;
71 71
72 /// Gets the vsync event for the specified display. 72 /// Gets the vsync event for the specified display.
73 /// 73 ///
74 /// If an invalid display ID is provided, then nullptr is returned. 74 /// If an invalid display ID is provided, then nullptr is returned.
75 std::shared_ptr<Kernel::ReadableEvent> FindVsyncEvent(u64 display_id) const; 75 [[nodiscard]] std::shared_ptr<Kernel::ReadableEvent> FindVsyncEvent(u64 display_id) const;
76 76
77 /// Obtains a buffer queue identified by the ID. 77 /// Obtains a buffer queue identified by the ID.
78 BufferQueue& FindBufferQueue(u32 id); 78 [[nodiscard]] BufferQueue& FindBufferQueue(u32 id);
79 79
80 /// Obtains a buffer queue identified by the ID. 80 /// Obtains a buffer queue identified by the ID.
81 const BufferQueue& FindBufferQueue(u32 id) const; 81 [[nodiscard]] const BufferQueue& FindBufferQueue(u32 id) const;
82 82
83 /// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when 83 /// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when
84 /// finished. 84 /// finished.
85 void Compose(); 85 void Compose();
86 86
87 s64 GetNextTicks() const; 87 [[nodiscard]] s64 GetNextTicks() const;
88 88
89 std::unique_lock<std::mutex> Lock() { 89 [[nodiscard]] std::unique_lock<std::mutex> Lock() const { return std::unique_lock{*guard}; }
90 return std::unique_lock{*guard};
91 }
92 90
93private: 91 private :
94 /// Finds the display identified by the specified ID. 92 /// Finds the display identified by the specified ID.
95 VI::Display* FindDisplay(u64 display_id); 93 [[nodiscard]] VI::Display* FindDisplay(u64 display_id);
96 94
97 /// Finds the display identified by the specified ID. 95 /// Finds the display identified by the specified ID.
98 const VI::Display* FindDisplay(u64 display_id) const; 96 [[nodiscard]] const VI::Display* FindDisplay(u64 display_id) const;
99 97
100 /// Finds the layer identified by the specified ID in the desired display. 98 /// Finds the layer identified by the specified ID in the desired display.
101 VI::Layer* FindLayer(u64 display_id, u64 layer_id); 99 [[nodiscard]] VI::Layer* FindLayer(u64 display_id, u64 layer_id);
102 100
103 /// Finds the layer identified by the specified ID in the desired display. 101 /// Finds the layer identified by the specified ID in the desired display.
104 const VI::Layer* FindLayer(u64 display_id, u64 layer_id) const; 102 [[nodiscard]] const VI::Layer* FindLayer(u64 display_id, u64 layer_id) const;
105 103
106 static void VSyncThread(NVFlinger& nv_flinger); 104 static void VSyncThread(NVFlinger& nv_flinger);
107 105
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index ea7b4ae13..825d11a3f 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -511,7 +511,7 @@ private:
511 LOG_DEBUG(Service_VI, "called. id=0x{:08X} transaction={:X}, flags=0x{:08X}", id, 511 LOG_DEBUG(Service_VI, "called. id=0x{:08X} transaction={:X}, flags=0x{:08X}", id,
512 static_cast<u32>(transaction), flags); 512 static_cast<u32>(transaction), flags);
513 513
514 nv_flinger->Lock(); 514 const auto guard = nv_flinger->Lock();
515 auto& buffer_queue = nv_flinger->FindBufferQueue(id); 515 auto& buffer_queue = nv_flinger->FindBufferQueue(id);
516 516
517 switch (transaction) { 517 switch (transaction) {
@@ -551,7 +551,7 @@ private:
551 [=](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, 551 [=](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx,
552 Kernel::ThreadWakeupReason reason) { 552 Kernel::ThreadWakeupReason reason) {
553 // Repeat TransactParcel DequeueBuffer when a buffer is available 553 // Repeat TransactParcel DequeueBuffer when a buffer is available
554 nv_flinger->Lock(); 554 const auto guard = nv_flinger->Lock();
555 auto& buffer_queue = nv_flinger->FindBufferQueue(id); 555 auto& buffer_queue = nv_flinger->FindBufferQueue(id);
556 auto result = buffer_queue.DequeueBuffer(width, height); 556 auto result = buffer_queue.DequeueBuffer(width, height);
557 ASSERT_MSG(result != std::nullopt, "Could not dequeue buffer."); 557 ASSERT_MSG(result != std::nullopt, "Could not dequeue buffer.");
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp
index ced41b1fe..eeebdf02e 100644
--- a/src/core/memory/cheat_engine.cpp
+++ b/src/core/memory/cheat_engine.cpp
@@ -188,11 +188,11 @@ CheatEngine::~CheatEngine() {
188} 188}
189 189
190void CheatEngine::Initialize() { 190void CheatEngine::Initialize() {
191 event = Core::Timing::CreateEvent("CheatEngine::FrameCallback::" + 191 event = Core::Timing::CreateEvent(
192 Common::HexToString(metadata.main_nso_build_id), 192 "CheatEngine::FrameCallback::" + Common::HexToString(metadata.main_nso_build_id),
193 [this](u64 userdata, std::chrono::nanoseconds ns_late) { 193 [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
194 FrameCallback(userdata, ns_late); 194 FrameCallback(user_data, ns_late);
195 }); 195 });
196 core_timing.ScheduleEvent(CHEAT_ENGINE_NS, event); 196 core_timing.ScheduleEvent(CHEAT_ENGINE_NS, event);
197 197
198 metadata.process_id = system.CurrentProcess()->GetProcessID(); 198 metadata.process_id = system.CurrentProcess()->GetProcessID();
@@ -219,7 +219,7 @@ void CheatEngine::Reload(std::vector<CheatEntry> cheats) {
219 219
220MICROPROFILE_DEFINE(Cheat_Engine, "Add-Ons", "Cheat Engine", MP_RGB(70, 200, 70)); 220MICROPROFILE_DEFINE(Cheat_Engine, "Add-Ons", "Cheat Engine", MP_RGB(70, 200, 70));
221 221
222void CheatEngine::FrameCallback(u64, std::chrono::nanoseconds ns_late) { 222void CheatEngine::FrameCallback(std::uintptr_t, std::chrono::nanoseconds ns_late) {
223 if (is_pending_reload.exchange(false)) { 223 if (is_pending_reload.exchange(false)) {
224 vm.LoadProgram(cheats); 224 vm.LoadProgram(cheats);
225 } 225 }
diff --git a/src/core/memory/cheat_engine.h b/src/core/memory/cheat_engine.h
index d4068cf84..fa039a831 100644
--- a/src/core/memory/cheat_engine.h
+++ b/src/core/memory/cheat_engine.h
@@ -72,7 +72,7 @@ public:
72 void Reload(std::vector<CheatEntry> cheats); 72 void Reload(std::vector<CheatEntry> cheats);
73 73
74private: 74private:
75 void FrameCallback(u64 userdata, std::chrono::nanoseconds ns_late); 75 void FrameCallback(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
76 76
77 DmntCheatVm vm; 77 DmntCheatVm vm;
78 CheatProcessMetadata metadata; 78 CheatProcessMetadata metadata;
diff --git a/src/core/network/network.cpp b/src/core/network/network.cpp
new file mode 100644
index 000000000..56d173b5e
--- /dev/null
+++ b/src/core/network/network.cpp
@@ -0,0 +1,654 @@
1// Copyright 2020 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <cstring>
7#include <limits>
8#include <utility>
9#include <vector>
10
11#ifdef _WIN32
12#define _WINSOCK_DEPRECATED_NO_WARNINGS // gethostname
13#include <winsock2.h>
14#elif __unix__
15#include <errno.h>
16#include <fcntl.h>
17#include <netdb.h>
18#include <netinet/in.h>
19#include <poll.h>
20#include <sys/socket.h>
21#include <unistd.h>
22#else
23#error "Unimplemented platform"
24#endif
25
26#include "common/assert.h"
27#include "common/common_types.h"
28#include "common/logging/log.h"
29#include "core/network/network.h"
30#include "core/network/sockets.h"
31
32namespace Network {
33
34namespace {
35
36#ifdef _WIN32
37
38using socklen_t = int;
39
40void Initialize() {
41 WSADATA wsa_data;
42 (void)WSAStartup(MAKEWORD(2, 2), &wsa_data);
43}
44
45void Finalize() {
46 WSACleanup();
47}
48
49constexpr IPv4Address TranslateIPv4(in_addr addr) {
50 auto& bytes = addr.S_un.S_un_b;
51 return IPv4Address{bytes.s_b1, bytes.s_b2, bytes.s_b3, bytes.s_b4};
52}
53
54sockaddr TranslateFromSockAddrIn(SockAddrIn input) {
55 sockaddr_in result;
56
57#ifdef __unix__
58 result.sin_len = sizeof(result);
59#endif
60
61 switch (static_cast<Domain>(input.family)) {
62 case Domain::INET:
63 result.sin_family = AF_INET;
64 break;
65 default:
66 UNIMPLEMENTED_MSG("Unhandled sockaddr family={}", static_cast<int>(input.family));
67 result.sin_family = AF_INET;
68 break;
69 }
70
71 result.sin_port = htons(input.portno);
72
73 auto& ip = result.sin_addr.S_un.S_un_b;
74 ip.s_b1 = input.ip[0];
75 ip.s_b2 = input.ip[1];
76 ip.s_b3 = input.ip[2];
77 ip.s_b4 = input.ip[3];
78
79 sockaddr addr;
80 std::memcpy(&addr, &result, sizeof(addr));
81 return addr;
82}
83
84LINGER MakeLinger(bool enable, u32 linger_value) {
85 ASSERT(linger_value <= std::numeric_limits<u_short>::max());
86
87 LINGER value;
88 value.l_onoff = enable ? 1 : 0;
89 value.l_linger = static_cast<u_short>(linger_value);
90 return value;
91}
92
93int LastError() {
94 return WSAGetLastError();
95}
96
97bool EnableNonBlock(SOCKET fd, bool enable) {
98 u_long value = enable ? 1 : 0;
99 return ioctlsocket(fd, FIONBIO, &value) != SOCKET_ERROR;
100}
101
102#elif __unix__ // ^ _WIN32 v __unix__
103
104using SOCKET = int;
105using WSAPOLLFD = pollfd;
106using ULONG = u64;
107
108constexpr SOCKET INVALID_SOCKET = -1;
109constexpr SOCKET SOCKET_ERROR = -1;
110
111constexpr int WSAEWOULDBLOCK = EAGAIN;
112constexpr int WSAENOTCONN = ENOTCONN;
113
114constexpr int SD_RECEIVE = SHUT_RD;
115constexpr int SD_SEND = SHUT_WR;
116constexpr int SD_BOTH = SHUT_RDWR;
117
118void Initialize() {}
119
120void Finalize() {}
121
122constexpr IPv4Address TranslateIPv4(in_addr addr) {
123 const u32 bytes = addr.s_addr;
124 return IPv4Address{static_cast<u8>(bytes), static_cast<u8>(bytes >> 8),
125 static_cast<u8>(bytes >> 16), static_cast<u8>(bytes >> 24)};
126}
127
128sockaddr TranslateFromSockAddrIn(SockAddrIn input) {
129 sockaddr_in result;
130
131 switch (static_cast<Domain>(input.family)) {
132 case Domain::INET:
133 result.sin_family = AF_INET;
134 break;
135 default:
136 UNIMPLEMENTED_MSG("Unhandled sockaddr family={}", static_cast<int>(input.family));
137 result.sin_family = AF_INET;
138 break;
139 }
140
141 result.sin_port = htons(input.portno);
142
143 result.sin_addr.s_addr = input.ip[0] | input.ip[1] << 8 | input.ip[2] << 16 | input.ip[3] << 24;
144
145 sockaddr addr;
146 std::memcpy(&addr, &result, sizeof(addr));
147 return addr;
148}
149
150int WSAPoll(WSAPOLLFD* fds, ULONG nfds, int timeout) {
151 return poll(fds, nfds, timeout);
152}
153
154int closesocket(SOCKET fd) {
155 return close(fd);
156}
157
158linger MakeLinger(bool enable, u32 linger_value) {
159 linger value;
160 value.l_onoff = enable ? 1 : 0;
161 value.l_linger = linger_value;
162 return value;
163}
164
165int LastError() {
166 return errno;
167}
168
169bool EnableNonBlock(int fd, bool enable) {
170 int flags = fcntl(fd, F_GETFD);
171 if (flags == -1) {
172 return false;
173 }
174 if (enable) {
175 flags |= O_NONBLOCK;
176 } else {
177 flags &= ~O_NONBLOCK;
178 }
179 return fcntl(fd, F_SETFD, flags) == 0;
180}
181
182#endif
183
184int TranslateDomain(Domain domain) {
185 switch (domain) {
186 case Domain::INET:
187 return AF_INET;
188 default:
189 UNIMPLEMENTED_MSG("Unimplemented domain={}", static_cast<int>(domain));
190 return 0;
191 }
192}
193
194int TranslateType(Type type) {
195 switch (type) {
196 case Type::STREAM:
197 return SOCK_STREAM;
198 case Type::DGRAM:
199 return SOCK_DGRAM;
200 default:
201 UNIMPLEMENTED_MSG("Unimplemented type={}", static_cast<int>(type));
202 return 0;
203 }
204}
205
206int TranslateProtocol(Protocol protocol) {
207 switch (protocol) {
208 case Protocol::TCP:
209 return IPPROTO_TCP;
210 case Protocol::UDP:
211 return IPPROTO_UDP;
212 default:
213 UNIMPLEMENTED_MSG("Unimplemented protocol={}", static_cast<int>(protocol));
214 return 0;
215 }
216}
217
218SockAddrIn TranslateToSockAddrIn(sockaddr input_) {
219 sockaddr_in input;
220 std::memcpy(&input, &input_, sizeof(input));
221
222 SockAddrIn result;
223
224 switch (input.sin_family) {
225 case AF_INET:
226 result.family = Domain::INET;
227 break;
228 default:
229 UNIMPLEMENTED_MSG("Unhandled sockaddr family={}", input.sin_family);
230 result.family = Domain::INET;
231 break;
232 }
233
234 result.portno = ntohs(input.sin_port);
235
236 result.ip = TranslateIPv4(input.sin_addr);
237
238 return result;
239}
240
241u16 TranslatePollEvents(u16 events) {
242 u16 result = 0;
243
244 if (events & POLL_IN) {
245 events &= ~POLL_IN;
246 result |= POLLIN;
247 }
248 if (events & POLL_PRI) {
249 events &= ~POLL_PRI;
250#ifdef _WIN32
251 LOG_WARNING(Service, "Winsock doesn't support POLLPRI");
252#else
253 result |= POLL_PRI;
254#endif
255 }
256 if (events & POLL_OUT) {
257 events &= ~POLL_OUT;
258 result |= POLLOUT;
259 }
260
261 UNIMPLEMENTED_IF_MSG(events != 0, "Unhandled guest events=0x{:x}", events);
262
263 return result;
264}
265
266u16 TranslatePollRevents(u16 revents) {
267 u16 result = 0;
268 const auto translate = [&result, &revents](int host, unsigned guest) {
269 if (revents & host) {
270 revents &= ~host;
271 result |= guest;
272 }
273 };
274
275 translate(POLLIN, POLL_IN);
276 translate(POLLPRI, POLL_PRI);
277 translate(POLLOUT, POLL_OUT);
278 translate(POLLERR, POLL_ERR);
279 translate(POLLHUP, POLL_HUP);
280
281 UNIMPLEMENTED_IF_MSG(revents != 0, "Unhandled host revents=0x{:x}", revents);
282
283 return result;
284}
285
286template <typename T>
287Errno SetSockOpt(SOCKET fd, int option, T value) {
288 const int result =
289 setsockopt(fd, SOL_SOCKET, option, reinterpret_cast<const char*>(&value), sizeof(value));
290 if (result != SOCKET_ERROR) {
291 return Errno::SUCCESS;
292 }
293 const int ec = LastError();
294 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
295 return Errno::SUCCESS;
296}
297
298} // Anonymous namespace
299
300NetworkInstance::NetworkInstance() {
301 Initialize();
302}
303
304NetworkInstance::~NetworkInstance() {
305 Finalize();
306}
307
308std::pair<IPv4Address, Errno> GetHostIPv4Address() {
309 std::array<char, 256> name{};
310 if (gethostname(name.data(), static_cast<int>(name.size()) - 1) == SOCKET_ERROR) {
311 UNIMPLEMENTED_MSG("Unhandled gethostname error");
312 return {IPv4Address{}, Errno::SUCCESS};
313 }
314
315 hostent* const ent = gethostbyname(name.data());
316 if (!ent) {
317 UNIMPLEMENTED_MSG("Unhandled gethostbyname error");
318 return {IPv4Address{}, Errno::SUCCESS};
319 }
320 if (ent->h_addr_list == nullptr) {
321 UNIMPLEMENTED_MSG("No addr provided in hostent->h_addr_list");
322 return {IPv4Address{}, Errno::SUCCESS};
323 }
324 if (ent->h_length != sizeof(in_addr)) {
325 UNIMPLEMENTED_MSG("Unexpected size={} in hostent->h_length", ent->h_length);
326 }
327
328 in_addr addr;
329 std::memcpy(&addr, ent->h_addr_list[0], sizeof(addr));
330 return {TranslateIPv4(addr), Errno::SUCCESS};
331}
332
333std::pair<s32, Errno> Poll(std::vector<PollFD>& pollfds, s32 timeout) {
334 const size_t num = pollfds.size();
335
336 std::vector<WSAPOLLFD> host_pollfds(pollfds.size());
337 std::transform(pollfds.begin(), pollfds.end(), host_pollfds.begin(), [](PollFD fd) {
338 WSAPOLLFD result;
339 result.fd = fd.socket->fd;
340 result.events = TranslatePollEvents(fd.events);
341 result.revents = 0;
342 return result;
343 });
344
345 const int result = WSAPoll(host_pollfds.data(), static_cast<ULONG>(num), timeout);
346 if (result == 0) {
347 ASSERT(std::all_of(host_pollfds.begin(), host_pollfds.end(),
348 [](WSAPOLLFD fd) { return fd.revents == 0; }));
349 return {0, Errno::SUCCESS};
350 }
351
352 for (size_t i = 0; i < num; ++i) {
353 pollfds[i].revents = TranslatePollRevents(host_pollfds[i].revents);
354 }
355
356 if (result > 0) {
357 return {result, Errno::SUCCESS};
358 }
359
360 ASSERT(result == SOCKET_ERROR);
361
362 const int ec = LastError();
363 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
364 return {-1, Errno::SUCCESS};
365}
366
367Socket::~Socket() {
368 if (fd == INVALID_SOCKET) {
369 return;
370 }
371 (void)closesocket(fd);
372 fd = INVALID_SOCKET;
373}
374
375Socket::Socket(Socket&& rhs) noexcept : fd{std::exchange(rhs.fd, INVALID_SOCKET)} {}
376
377Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) {
378 fd = socket(TranslateDomain(domain), TranslateType(type), TranslateProtocol(protocol));
379 if (fd != INVALID_SOCKET) {
380 return Errno::SUCCESS;
381 }
382
383 const int ec = LastError();
384 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
385 return Errno::SUCCESS;
386}
387
388std::pair<Socket::AcceptResult, Errno> Socket::Accept() {
389 sockaddr addr;
390 socklen_t addrlen = sizeof(addr);
391 const SOCKET new_socket = accept(fd, &addr, &addrlen);
392
393 if (new_socket == INVALID_SOCKET) {
394 const int ec = LastError();
395 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
396 return {AcceptResult{}, Errno::SUCCESS};
397 }
398
399 AcceptResult result;
400 result.socket = std::make_unique<Socket>();
401 result.socket->fd = new_socket;
402
403 ASSERT(addrlen == sizeof(sockaddr_in));
404 result.sockaddr_in = TranslateToSockAddrIn(addr);
405
406 return {std::move(result), Errno::SUCCESS};
407}
408
409Errno Socket::Connect(SockAddrIn addr_in) {
410 const sockaddr host_addr_in = TranslateFromSockAddrIn(addr_in);
411 if (connect(fd, &host_addr_in, sizeof(host_addr_in)) != INVALID_SOCKET) {
412 return Errno::SUCCESS;
413 }
414
415 switch (const int ec = LastError()) {
416 case WSAEWOULDBLOCK:
417 LOG_DEBUG(Service, "EAGAIN generated");
418 return Errno::AGAIN;
419 default:
420 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
421 return Errno::SUCCESS;
422 }
423}
424
425std::pair<SockAddrIn, Errno> Socket::GetPeerName() {
426 sockaddr addr;
427 socklen_t addrlen = sizeof(addr);
428 if (getpeername(fd, &addr, &addrlen) == SOCKET_ERROR) {
429 const int ec = LastError();
430 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
431 return {SockAddrIn{}, Errno::SUCCESS};
432 }
433
434 ASSERT(addrlen == sizeof(sockaddr_in));
435 return {TranslateToSockAddrIn(addr), Errno::SUCCESS};
436}
437
438std::pair<SockAddrIn, Errno> Socket::GetSockName() {
439 sockaddr addr;
440 socklen_t addrlen = sizeof(addr);
441 if (getsockname(fd, &addr, &addrlen) == SOCKET_ERROR) {
442 const int ec = LastError();
443 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
444 return {SockAddrIn{}, Errno::SUCCESS};
445 }
446
447 ASSERT(addrlen == sizeof(sockaddr_in));
448 return {TranslateToSockAddrIn(addr), Errno::SUCCESS};
449}
450
451Errno Socket::Bind(SockAddrIn addr) {
452 const sockaddr addr_in = TranslateFromSockAddrIn(addr);
453 if (bind(fd, &addr_in, sizeof(addr_in)) != SOCKET_ERROR) {
454 return Errno::SUCCESS;
455 }
456
457 const int ec = LastError();
458 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
459 return Errno::SUCCESS;
460}
461
462Errno Socket::Listen(s32 backlog) {
463 if (listen(fd, backlog) != SOCKET_ERROR) {
464 return Errno::SUCCESS;
465 }
466
467 const int ec = LastError();
468 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
469 return Errno::SUCCESS;
470}
471
472Errno Socket::Shutdown(ShutdownHow how) {
473 int host_how = 0;
474 switch (how) {
475 case ShutdownHow::RD:
476 host_how = SD_RECEIVE;
477 break;
478 case ShutdownHow::WR:
479 host_how = SD_SEND;
480 break;
481 case ShutdownHow::RDWR:
482 host_how = SD_BOTH;
483 break;
484 default:
485 UNIMPLEMENTED_MSG("Unimplemented flag how={}", static_cast<int>(how));
486 return Errno::SUCCESS;
487 }
488 if (shutdown(fd, host_how) != SOCKET_ERROR) {
489 return Errno::SUCCESS;
490 }
491
492 switch (const int ec = LastError()) {
493 case WSAENOTCONN:
494 LOG_ERROR(Service, "ENOTCONN generated");
495 return Errno::NOTCONN;
496 default:
497 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
498 return Errno::SUCCESS;
499 }
500}
501
502std::pair<s32, Errno> Socket::Recv(int flags, std::vector<u8>& message) {
503 ASSERT(flags == 0);
504 ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
505
506 const int result =
507 recv(fd, reinterpret_cast<char*>(message.data()), static_cast<int>(message.size()), 0);
508 if (result != SOCKET_ERROR) {
509 return {result, Errno::SUCCESS};
510 }
511
512 switch (const int ec = LastError()) {
513 case WSAEWOULDBLOCK:
514 LOG_DEBUG(Service, "EAGAIN generated");
515 return {-1, Errno::AGAIN};
516 case WSAENOTCONN:
517 LOG_ERROR(Service, "ENOTCONN generated");
518 return {-1, Errno::NOTCONN};
519 default:
520 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
521 return {0, Errno::SUCCESS};
522 }
523}
524
525std::pair<s32, Errno> Socket::RecvFrom(int flags, std::vector<u8>& message, SockAddrIn* addr) {
526 ASSERT(flags == 0);
527 ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
528
529 sockaddr addr_in{};
530 socklen_t addrlen = sizeof(addr_in);
531 socklen_t* const p_addrlen = addr ? &addrlen : nullptr;
532 sockaddr* const p_addr_in = addr ? &addr_in : nullptr;
533
534 const int result = recvfrom(fd, reinterpret_cast<char*>(message.data()),
535 static_cast<int>(message.size()), 0, p_addr_in, p_addrlen);
536 if (result != SOCKET_ERROR) {
537 if (addr) {
538 ASSERT(addrlen == sizeof(addr_in));
539 *addr = TranslateToSockAddrIn(addr_in);
540 }
541 return {result, Errno::SUCCESS};
542 }
543
544 switch (const int ec = LastError()) {
545 case WSAEWOULDBLOCK:
546 LOG_DEBUG(Service, "EAGAIN generated");
547 return {-1, Errno::AGAIN};
548 case WSAENOTCONN:
549 LOG_ERROR(Service, "ENOTCONN generated");
550 return {-1, Errno::NOTCONN};
551 default:
552 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
553 return {-1, Errno::SUCCESS};
554 }
555}
556
557std::pair<s32, Errno> Socket::Send(const std::vector<u8>& message, int flags) {
558 ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
559 ASSERT(flags == 0);
560
561 const int result = send(fd, reinterpret_cast<const char*>(message.data()),
562 static_cast<int>(message.size()), 0);
563 if (result != SOCKET_ERROR) {
564 return {result, Errno::SUCCESS};
565 }
566
567 const int ec = LastError();
568 switch (ec) {
569 case WSAEWOULDBLOCK:
570 LOG_DEBUG(Service, "EAGAIN generated");
571 return {-1, Errno::AGAIN};
572 case WSAENOTCONN:
573 LOG_ERROR(Service, "ENOTCONN generated");
574 return {-1, Errno::NOTCONN};
575 default:
576 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
577 return {-1, Errno::SUCCESS};
578 }
579}
580
581std::pair<s32, Errno> Socket::SendTo(u32 flags, const std::vector<u8>& message,
582 const SockAddrIn* addr) {
583 ASSERT(flags == 0);
584
585 const sockaddr* to = nullptr;
586 const int tolen = addr ? 0 : sizeof(sockaddr);
587 sockaddr host_addr_in;
588
589 if (addr) {
590 host_addr_in = TranslateFromSockAddrIn(*addr);
591 to = &host_addr_in;
592 }
593
594 const int result = sendto(fd, reinterpret_cast<const char*>(message.data()),
595 static_cast<int>(message.size()), 0, to, tolen);
596 if (result != SOCKET_ERROR) {
597 return {result, Errno::SUCCESS};
598 }
599
600 const int ec = LastError();
601 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
602 return {-1, Errno::SUCCESS};
603}
604
605Errno Socket::Close() {
606 [[maybe_unused]] const int result = closesocket(fd);
607 ASSERT(result == 0);
608 fd = INVALID_SOCKET;
609
610 return Errno::SUCCESS;
611}
612
613Errno Socket::SetLinger(bool enable, u32 linger) {
614 return SetSockOpt(fd, SO_LINGER, MakeLinger(enable, linger));
615}
616
617Errno Socket::SetReuseAddr(bool enable) {
618 return SetSockOpt<u32>(fd, SO_REUSEADDR, enable ? 1 : 0);
619}
620
621Errno Socket::SetBroadcast(bool enable) {
622 return SetSockOpt<u32>(fd, SO_BROADCAST, enable ? 1 : 0);
623}
624
625Errno Socket::SetSndBuf(u32 value) {
626 return SetSockOpt(fd, SO_SNDBUF, value);
627}
628
629Errno Socket::SetRcvBuf(u32 value) {
630 return SetSockOpt(fd, SO_RCVBUF, value);
631}
632
633Errno Socket::SetSndTimeo(u32 value) {
634 return SetSockOpt(fd, SO_SNDTIMEO, value);
635}
636
637Errno Socket::SetRcvTimeo(u32 value) {
638 return SetSockOpt(fd, SO_RCVTIMEO, value);
639}
640
641Errno Socket::SetNonBlock(bool enable) {
642 if (EnableNonBlock(fd, enable)) {
643 return Errno::SUCCESS;
644 }
645 const int ec = LastError();
646 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
647 return Errno::SUCCESS;
648}
649
650bool Socket::IsOpened() const {
651 return fd != INVALID_SOCKET;
652}
653
654} // namespace Network
diff --git a/src/core/network/network.h b/src/core/network/network.h
new file mode 100644
index 000000000..0622e4593
--- /dev/null
+++ b/src/core/network/network.h
@@ -0,0 +1,87 @@
1// Copyright 2020 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include <utility>
9
10#include "common/common_types.h"
11
12namespace Network {
13
14class Socket;
15
16/// Error code for network functions
17enum class Errno {
18 SUCCESS,
19 BADF,
20 INVAL,
21 MFILE,
22 NOTCONN,
23 AGAIN,
24};
25
26/// Address families
27enum class Domain {
28 INET, ///< Address family for IPv4
29};
30
31/// Socket types
32enum class Type {
33 STREAM,
34 DGRAM,
35 RAW,
36 SEQPACKET,
37};
38
39/// Protocol values for sockets
40enum class Protocol {
41 ICMP,
42 TCP,
43 UDP,
44};
45
46/// Shutdown mode
47enum class ShutdownHow {
48 RD,
49 WR,
50 RDWR,
51};
52
53/// Array of IPv4 address
54using IPv4Address = std::array<u8, 4>;
55
56/// Cross-platform sockaddr structure
57struct SockAddrIn {
58 Domain family;
59 IPv4Address ip;
60 u16 portno;
61};
62
63/// Cross-platform poll fd structure
64struct PollFD {
65 Socket* socket;
66 u16 events;
67 u16 revents;
68};
69
70constexpr u16 POLL_IN = 1 << 0;
71constexpr u16 POLL_PRI = 1 << 1;
72constexpr u16 POLL_OUT = 1 << 2;
73constexpr u16 POLL_ERR = 1 << 3;
74constexpr u16 POLL_HUP = 1 << 4;
75constexpr u16 POLL_NVAL = 1 << 5;
76
77class NetworkInstance {
78public:
79 explicit NetworkInstance();
80 ~NetworkInstance();
81};
82
83/// @brief Returns host's IPv4 address
84/// @return Pair of an array of human ordered IPv4 address (e.g. 192.168.0.1) and an error code
85std::pair<IPv4Address, Errno> GetHostIPv4Address();
86
87} // namespace Network
diff --git a/src/core/network/sockets.h b/src/core/network/sockets.h
new file mode 100644
index 000000000..7bdff0fe4
--- /dev/null
+++ b/src/core/network/sockets.h
@@ -0,0 +1,94 @@
1// Copyright 2020 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include <utility>
9
10#if defined(_WIN32)
11#include <winsock.h>
12#elif !defined(__unix__)
13#error "Platform not implemented"
14#endif
15
16#include "common/common_types.h"
17#include "core/network/network.h"
18
19// TODO: C++20 Replace std::vector usages with std::span
20
21namespace Network {
22
23class Socket {
24public:
25 struct AcceptResult {
26 std::unique_ptr<Socket> socket;
27 SockAddrIn sockaddr_in;
28 };
29
30 explicit Socket() = default;
31 ~Socket();
32
33 Socket(const Socket&) = delete;
34 Socket& operator=(const Socket&) = delete;
35
36 Socket(Socket&& rhs) noexcept;
37
38 // Avoid closing sockets implicitly
39 Socket& operator=(Socket&&) noexcept = delete;
40
41 Errno Initialize(Domain domain, Type type, Protocol protocol);
42
43 Errno Close();
44
45 std::pair<AcceptResult, Errno> Accept();
46
47 Errno Connect(SockAddrIn addr_in);
48
49 std::pair<SockAddrIn, Errno> GetPeerName();
50
51 std::pair<SockAddrIn, Errno> GetSockName();
52
53 Errno Bind(SockAddrIn addr);
54
55 Errno Listen(s32 backlog);
56
57 Errno Shutdown(ShutdownHow how);
58
59 std::pair<s32, Errno> Recv(int flags, std::vector<u8>& message);
60
61 std::pair<s32, Errno> RecvFrom(int flags, std::vector<u8>& message, SockAddrIn* addr);
62
63 std::pair<s32, Errno> Send(const std::vector<u8>& message, int flags);
64
65 std::pair<s32, Errno> SendTo(u32 flags, const std::vector<u8>& message, const SockAddrIn* addr);
66
67 Errno SetLinger(bool enable, u32 linger);
68
69 Errno SetReuseAddr(bool enable);
70
71 Errno SetBroadcast(bool enable);
72
73 Errno SetSndBuf(u32 value);
74
75 Errno SetRcvBuf(u32 value);
76
77 Errno SetSndTimeo(u32 value);
78
79 Errno SetRcvTimeo(u32 value);
80
81 Errno SetNonBlock(bool enable);
82
83 bool IsOpened() const;
84
85#if defined(_WIN32)
86 SOCKET fd = INVALID_SOCKET;
87#elif defined(__unix__)
88 int fd = -1;
89#endif
90};
91
92std::pair<s32, Errno> Poll(std::vector<PollFD>& poll_fds, s32 timeout);
93
94} // namespace Network
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index 44252dd81..416b2d866 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -173,7 +173,6 @@ void RestoreGlobalState() {
173 values.use_assembly_shaders.SetGlobal(true); 173 values.use_assembly_shaders.SetGlobal(true);
174 values.use_asynchronous_shaders.SetGlobal(true); 174 values.use_asynchronous_shaders.SetGlobal(true);
175 values.use_fast_gpu_time.SetGlobal(true); 175 values.use_fast_gpu_time.SetGlobal(true);
176 values.force_30fps_mode.SetGlobal(true);
177 values.bg_red.SetGlobal(true); 176 values.bg_red.SetGlobal(true);
178 values.bg_green.SetGlobal(true); 177 values.bg_green.SetGlobal(true);
179 values.bg_blue.SetGlobal(true); 178 values.bg_blue.SetGlobal(true);
diff --git a/src/core/settings.h b/src/core/settings.h
index 386233fdf..bb145f193 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -435,7 +435,6 @@ struct Values {
435 Setting<bool> use_vsync; 435 Setting<bool> use_vsync;
436 Setting<bool> use_assembly_shaders; 436 Setting<bool> use_assembly_shaders;
437 Setting<bool> use_asynchronous_shaders; 437 Setting<bool> use_asynchronous_shaders;
438 Setting<bool> force_30fps_mode;
439 Setting<bool> use_fast_gpu_time; 438 Setting<bool> use_fast_gpu_time;
440 439
441 Setting<float> bg_red; 440 Setting<float> bg_red;
diff --git a/src/core/tools/freezer.cpp b/src/core/tools/freezer.cpp
index 27b894b51..2003e096f 100644
--- a/src/core/tools/freezer.cpp
+++ b/src/core/tools/freezer.cpp
@@ -55,10 +55,11 @@ void MemoryWriteWidth(Core::Memory::Memory& memory, u32 width, VAddr addr, u64 v
55 55
56Freezer::Freezer(Core::Timing::CoreTiming& core_timing_, Core::Memory::Memory& memory_) 56Freezer::Freezer(Core::Timing::CoreTiming& core_timing_, Core::Memory::Memory& memory_)
57 : core_timing{core_timing_}, memory{memory_} { 57 : core_timing{core_timing_}, memory{memory_} {
58 event = Core::Timing::CreateEvent("MemoryFreezer::FrameCallback", 58 event = Core::Timing::CreateEvent(
59 [this](u64 userdata, std::chrono::nanoseconds ns_late) { 59 "MemoryFreezer::FrameCallback",
60 FrameCallback(userdata, ns_late); 60 [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
61 }); 61 FrameCallback(user_data, ns_late);
62 });
62 core_timing.ScheduleEvent(memory_freezer_ns, event); 63 core_timing.ScheduleEvent(memory_freezer_ns, event);
63} 64}
64 65
@@ -159,7 +160,7 @@ std::vector<Freezer::Entry> Freezer::GetEntries() const {
159 return entries; 160 return entries;
160} 161}
161 162
162void Freezer::FrameCallback(u64, std::chrono::nanoseconds ns_late) { 163void Freezer::FrameCallback(std::uintptr_t, std::chrono::nanoseconds ns_late) {
163 if (!IsActive()) { 164 if (!IsActive()) {
164 LOG_DEBUG(Common_Memory, "Memory freezer has been deactivated, ending callback events."); 165 LOG_DEBUG(Common_Memory, "Memory freezer has been deactivated, ending callback events.");
165 return; 166 return;
diff --git a/src/core/tools/freezer.h b/src/core/tools/freezer.h
index 8438783d5..2b2326bc4 100644
--- a/src/core/tools/freezer.h
+++ b/src/core/tools/freezer.h
@@ -73,7 +73,7 @@ public:
73 std::vector<Entry> GetEntries() const; 73 std::vector<Entry> GetEntries() const;
74 74
75private: 75private:
76 void FrameCallback(u64 userdata, std::chrono::nanoseconds ns_late); 76 void FrameCallback(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
77 void FillEntryReads(); 77 void FillEntryReads();
78 78
79 std::atomic_bool active{false}; 79 std::atomic_bool active{false};
diff --git a/src/input_common/gcadapter/gc_adapter.cpp b/src/input_common/gcadapter/gc_adapter.cpp
index 898a278a9..74759ea7d 100644
--- a/src/input_common/gcadapter/gc_adapter.cpp
+++ b/src/input_common/gcadapter/gc_adapter.cpp
@@ -24,12 +24,9 @@ Adapter::Adapter() {
24 } 24 }
25 LOG_INFO(Input, "GC Adapter Initialization started"); 25 LOG_INFO(Input, "GC Adapter Initialization started");
26 26
27 current_status = NO_ADAPTER_DETECTED;
28 get_origin.fill(true);
29
30 const int init_res = libusb_init(&libusb_ctx); 27 const int init_res = libusb_init(&libusb_ctx);
31 if (init_res == LIBUSB_SUCCESS) { 28 if (init_res == LIBUSB_SUCCESS) {
32 StartScanThread(); 29 Setup();
33 } else { 30 } else {
34 LOG_ERROR(Input, "libusb could not be initialized. failed with error = {}", init_res); 31 LOG_ERROR(Input, "libusb could not be initialized. failed with error = {}", init_res);
35 } 32 }
@@ -37,9 +34,9 @@ Adapter::Adapter() {
37 34
38GCPadStatus Adapter::GetPadStatus(std::size_t port, const std::array<u8, 37>& adapter_payload) { 35GCPadStatus Adapter::GetPadStatus(std::size_t port, const std::array<u8, 37>& adapter_payload) {
39 GCPadStatus pad = {}; 36 GCPadStatus pad = {};
37 const std::size_t offset = 1 + (9 * port);
40 38
41 ControllerTypes type = ControllerTypes(adapter_payload[1 + (9 * port)] >> 4); 39 adapter_controllers_status[port] = static_cast<ControllerTypes>(adapter_payload[offset] >> 4);
42 adapter_controllers_status[port] = type;
43 40
44 static constexpr std::array<PadButton, 8> b1_buttons{ 41 static constexpr std::array<PadButton, 8> b1_buttons{
45 PadButton::PAD_BUTTON_A, PadButton::PAD_BUTTON_B, PadButton::PAD_BUTTON_X, 42 PadButton::PAD_BUTTON_A, PadButton::PAD_BUTTON_B, PadButton::PAD_BUTTON_X,
@@ -54,14 +51,19 @@ GCPadStatus Adapter::GetPadStatus(std::size_t port, const std::array<u8, 37>& ad
54 PadButton::PAD_TRIGGER_L, 51 PadButton::PAD_TRIGGER_L,
55 }; 52 };
56 53
54 static constexpr std::array<PadAxes, 6> axes{
55 PadAxes::StickX, PadAxes::StickY, PadAxes::SubstickX,
56 PadAxes::SubstickY, PadAxes::TriggerLeft, PadAxes::TriggerRight,
57 };
58
57 if (adapter_controllers_status[port] == ControllerTypes::None && !get_origin[port]) { 59 if (adapter_controllers_status[port] == ControllerTypes::None && !get_origin[port]) {
58 // Controller may have been disconnected, recalibrate if reconnected. 60 // Controller may have been disconnected, recalibrate if reconnected.
59 get_origin[port] = true; 61 get_origin[port] = true;
60 } 62 }
61 63
62 if (adapter_controllers_status[port] != ControllerTypes::None) { 64 if (adapter_controllers_status[port] != ControllerTypes::None) {
63 const u8 b1 = adapter_payload[1 + (9 * port) + 1]; 65 const u8 b1 = adapter_payload[offset + 1];
64 const u8 b2 = adapter_payload[1 + (9 * port) + 2]; 66 const u8 b2 = adapter_payload[offset + 2];
65 67
66 for (std::size_t i = 0; i < b1_buttons.size(); ++i) { 68 for (std::size_t i = 0; i < b1_buttons.size(); ++i) {
67 if ((b1 & (1U << i)) != 0) { 69 if ((b1 & (1U << i)) != 0) {
@@ -74,21 +76,13 @@ GCPadStatus Adapter::GetPadStatus(std::size_t port, const std::array<u8, 37>& ad
74 pad.button |= static_cast<u16>(b2_buttons[j]); 76 pad.button |= static_cast<u16>(b2_buttons[j]);
75 } 77 }
76 } 78 }
77 79 for (PadAxes axis : axes) {
78 pad.stick_x = adapter_payload[1 + (9 * port) + 3]; 80 const std::size_t index = static_cast<std::size_t>(axis);
79 pad.stick_y = adapter_payload[1 + (9 * port) + 4]; 81 pad.axis_values[index] = adapter_payload[offset + 3 + index];
80 pad.substick_x = adapter_payload[1 + (9 * port) + 5]; 82 }
81 pad.substick_y = adapter_payload[1 + (9 * port) + 6];
82 pad.trigger_left = adapter_payload[1 + (9 * port) + 7];
83 pad.trigger_right = adapter_payload[1 + (9 * port) + 8];
84 83
85 if (get_origin[port]) { 84 if (get_origin[port]) {
86 origin_status[port].stick_x = pad.stick_x; 85 origin_status[port].axis_values = pad.axis_values;
87 origin_status[port].stick_y = pad.stick_y;
88 origin_status[port].substick_x = pad.substick_x;
89 origin_status[port].substick_y = pad.substick_y;
90 origin_status[port].trigger_left = pad.trigger_left;
91 origin_status[port].trigger_right = pad.trigger_right;
92 get_origin[port] = false; 86 get_origin[port] = false;
93 } 87 }
94 } 88 }
@@ -101,82 +95,47 @@ void Adapter::PadToState(const GCPadStatus& pad, GCState& state) {
101 state.buttons.insert_or_assign(button_value, pad.button & button_value); 95 state.buttons.insert_or_assign(button_value, pad.button & button_value);
102 } 96 }
103 97
104 state.axes.insert_or_assign(static_cast<u8>(PadAxes::StickX), pad.stick_x); 98 for (size_t i = 0; i < pad.axis_values.size(); ++i) {
105 state.axes.insert_or_assign(static_cast<u8>(PadAxes::StickY), pad.stick_y); 99 state.axes.insert_or_assign(static_cast<u8>(i), pad.axis_values[i]);
106 state.axes.insert_or_assign(static_cast<u8>(PadAxes::SubstickX), pad.substick_x); 100 }
107 state.axes.insert_or_assign(static_cast<u8>(PadAxes::SubstickY), pad.substick_y);
108 state.axes.insert_or_assign(static_cast<u8>(PadAxes::TriggerLeft), pad.trigger_left);
109 state.axes.insert_or_assign(static_cast<u8>(PadAxes::TriggerRight), pad.trigger_right);
110} 101}
111 102
112void Adapter::Read() { 103void Adapter::Read() {
113 LOG_DEBUG(Input, "GC Adapter Read() thread started"); 104 LOG_DEBUG(Input, "GC Adapter Read() thread started");
114 105
115 int payload_size_in, payload_size_copy; 106 int payload_size;
116 std::array<u8, 37> adapter_payload; 107 std::array<u8, 37> adapter_payload;
117 std::array<u8, 37> adapter_payload_copy;
118 std::array<GCPadStatus, 4> pads; 108 std::array<GCPadStatus, 4> pads;
119 109
120 while (adapter_thread_running) { 110 while (adapter_thread_running) {
121 libusb_interrupt_transfer(usb_adapter_handle, input_endpoint, adapter_payload.data(), 111 libusb_interrupt_transfer(usb_adapter_handle, input_endpoint, adapter_payload.data(),
122 sizeof(adapter_payload), &payload_size_in, 16); 112 sizeof(adapter_payload), &payload_size, 16);
123 payload_size_copy = 0;
124 // this mutex might be redundant?
125 {
126 std::lock_guard<std::mutex> lk(s_mutex);
127 std::copy(std::begin(adapter_payload), std::end(adapter_payload),
128 std::begin(adapter_payload_copy));
129 payload_size_copy = payload_size_in;
130 }
131 113
132 if (payload_size_copy != sizeof(adapter_payload_copy) || 114 if (payload_size != sizeof(adapter_payload) || adapter_payload[0] != LIBUSB_DT_HID) {
133 adapter_payload_copy[0] != LIBUSB_DT_HID) { 115 LOG_ERROR(Input,
134 LOG_ERROR(Input, "error reading payload (size: {}, type: {:02x})", payload_size_copy, 116 "Error reading payload (size: {}, type: {:02x}) Is the adapter connected?",
135 adapter_payload_copy[0]); 117 payload_size, adapter_payload[0]);
136 adapter_thread_running = false; // error reading from adapter, stop reading. 118 adapter_thread_running = false; // error reading from adapter, stop reading.
137 break; 119 break;
138 } 120 }
139 for (std::size_t port = 0; port < pads.size(); ++port) { 121 for (std::size_t port = 0; port < pads.size(); ++port) {
140 pads[port] = GetPadStatus(port, adapter_payload_copy); 122 pads[port] = GetPadStatus(port, adapter_payload);
141 if (DeviceConnected(port) && configuring) { 123 if (DeviceConnected(port) && configuring) {
142 if (pads[port].button != 0) { 124 if (pads[port].button != 0) {
143 pad_queue[port].Push(pads[port]); 125 pad_queue[port].Push(pads[port]);
144 } 126 }
145 127
146 // Accounting for a threshold here because of some controller variance 128 // Accounting for a threshold here to ensure an intentional press
147 if (pads[port].stick_x > origin_status[port].stick_x + pads[port].THRESHOLD || 129 for (size_t i = 0; i < pads[port].axis_values.size(); ++i) {
148 pads[port].stick_x < origin_status[port].stick_x - pads[port].THRESHOLD) { 130 const u8 value = pads[port].axis_values[i];
149 pads[port].axis = GCAdapter::PadAxes::StickX; 131 const u8 origin = origin_status[port].axis_values[i];
150 pads[port].axis_value = pads[port].stick_x; 132
151 pad_queue[port].Push(pads[port]); 133 if (value > origin + pads[port].THRESHOLD ||
152 } 134 value < origin - pads[port].THRESHOLD) {
153 if (pads[port].stick_y > origin_status[port].stick_y + pads[port].THRESHOLD || 135 pads[port].axis = static_cast<PadAxes>(i);
154 pads[port].stick_y < origin_status[port].stick_y - pads[port].THRESHOLD) { 136 pads[port].axis_value = pads[port].axis_values[i];
155 pads[port].axis = GCAdapter::PadAxes::StickY; 137 pad_queue[port].Push(pads[port]);
156 pads[port].axis_value = pads[port].stick_y; 138 }
157 pad_queue[port].Push(pads[port]);
158 }
159 if (pads[port].substick_x > origin_status[port].substick_x + pads[port].THRESHOLD ||
160 pads[port].substick_x < origin_status[port].substick_x - pads[port].THRESHOLD) {
161 pads[port].axis = GCAdapter::PadAxes::SubstickX;
162 pads[port].axis_value = pads[port].substick_x;
163 pad_queue[port].Push(pads[port]);
164 }
165 if (pads[port].substick_y > origin_status[port].substick_y + pads[port].THRESHOLD ||
166 pads[port].substick_y < origin_status[port].substick_y - pads[port].THRESHOLD) {
167 pads[port].axis = GCAdapter::PadAxes::SubstickY;
168 pads[port].axis_value = pads[port].substick_y;
169 pad_queue[port].Push(pads[port]);
170 }
171 if (pads[port].trigger_left > pads[port].TRIGGER_THRESHOLD) {
172 pads[port].axis = GCAdapter::PadAxes::TriggerLeft;
173 pads[port].axis_value = pads[port].trigger_left;
174 pad_queue[port].Push(pads[port]);
175 }
176 if (pads[port].trigger_right > pads[port].TRIGGER_THRESHOLD) {
177 pads[port].axis = GCAdapter::PadAxes::TriggerRight;
178 pads[port].axis_value = pads[port].trigger_right;
179 pad_queue[port].Push(pads[port]);
180 } 139 }
181 } 140 }
182 PadToState(pads[port], state[port]); 141 PadToState(pads[port], state[port]);
@@ -185,42 +144,11 @@ void Adapter::Read() {
185 } 144 }
186} 145}
187 146
188void Adapter::ScanThreadFunc() {
189 LOG_INFO(Input, "GC Adapter scanning thread started");
190
191 while (detect_thread_running) {
192 if (usb_adapter_handle == nullptr) {
193 std::lock_guard<std::mutex> lk(initialization_mutex);
194 Setup();
195 }
196 std::this_thread::sleep_for(std::chrono::milliseconds(500));
197 }
198}
199
200void Adapter::StartScanThread() {
201 if (detect_thread_running) {
202 return;
203 }
204 if (!libusb_ctx) {
205 return;
206 }
207
208 detect_thread_running = true;
209 detect_thread = std::thread(&Adapter::ScanThreadFunc, this);
210}
211
212void Adapter::StopScanThread() {
213 detect_thread_running = false;
214 detect_thread.join();
215}
216
217void Adapter::Setup() { 147void Adapter::Setup() {
218 // Reset the error status in case the adapter gets unplugged 148 // Initialize all controllers as unplugged
219 if (current_status < 0) {
220 current_status = NO_ADAPTER_DETECTED;
221 }
222
223 adapter_controllers_status.fill(ControllerTypes::None); 149 adapter_controllers_status.fill(ControllerTypes::None);
150 // Initialize all ports to store axis origin values
151 get_origin.fill(true);
224 152
225 // pointer to list of connected usb devices 153 // pointer to list of connected usb devices
226 libusb_device** devices{}; 154 libusb_device** devices{};
@@ -229,8 +157,6 @@ void Adapter::Setup() {
229 const ssize_t device_count = libusb_get_device_list(libusb_ctx, &devices); 157 const ssize_t device_count = libusb_get_device_list(libusb_ctx, &devices);
230 if (device_count < 0) { 158 if (device_count < 0) {
231 LOG_ERROR(Input, "libusb_get_device_list failed with error: {}", device_count); 159 LOG_ERROR(Input, "libusb_get_device_list failed with error: {}", device_count);
232 detect_thread_running = false; // Stop the loop constantly checking for gc adapter
233 // TODO: For hotplug+gc adapter checkbox implementation, revert this.
234 return; 160 return;
235 } 161 }
236 162
@@ -244,9 +170,6 @@ void Adapter::Setup() {
244 } 170 }
245 libusb_free_device_list(devices, 1); 171 libusb_free_device_list(devices, 1);
246 } 172 }
247 // Break out of the ScanThreadFunc() loop that is constantly looking for the device
248 // Assumes user has GC adapter plugged in before launch to use the adapter
249 detect_thread_running = false;
250} 173}
251 174
252bool Adapter::CheckDeviceAccess(libusb_device* device) { 175bool Adapter::CheckDeviceAccess(libusb_device* device) {
@@ -331,32 +254,23 @@ void Adapter::GetGCEndpoint(libusb_device* device) {
331 sizeof(clear_payload), nullptr, 16); 254 sizeof(clear_payload), nullptr, 16);
332 255
333 adapter_thread_running = true; 256 adapter_thread_running = true;
334 current_status = ADAPTER_DETECTED; 257 adapter_input_thread = std::thread(&Adapter::Read, this);
335 adapter_input_thread = std::thread([=] { Read(); }); // Read input
336} 258}
337 259
338Adapter::~Adapter() { 260Adapter::~Adapter() {
339 StopScanThread();
340 Reset(); 261 Reset();
341} 262}
342 263
343void Adapter::Reset() { 264void Adapter::Reset() {
344 std::unique_lock<std::mutex> lock(initialization_mutex, std::defer_lock);
345 if (!lock.try_lock()) {
346 return;
347 }
348 if (current_status != ADAPTER_DETECTED) {
349 return;
350 }
351
352 if (adapter_thread_running) { 265 if (adapter_thread_running) {
353 adapter_thread_running = false; 266 adapter_thread_running = false;
354 } 267 }
355 adapter_input_thread.join(); 268 if (adapter_input_thread.joinable()) {
269 adapter_input_thread.join();
270 }
356 271
357 adapter_controllers_status.fill(ControllerTypes::None); 272 adapter_controllers_status.fill(ControllerTypes::None);
358 get_origin.fill(true); 273 get_origin.fill(true);
359 current_status = NO_ADAPTER_DETECTED;
360 274
361 if (usb_adapter_handle) { 275 if (usb_adapter_handle) {
362 libusb_release_interface(usb_adapter_handle, 1); 276 libusb_release_interface(usb_adapter_handle, 1);
@@ -409,24 +323,7 @@ const std::array<GCState, 4>& Adapter::GetPadState() const {
409} 323}
410 324
411int Adapter::GetOriginValue(int port, int axis) const { 325int Adapter::GetOriginValue(int port, int axis) const {
412 const auto& status = origin_status[port]; 326 return origin_status[port].axis_values[axis];
413
414 switch (static_cast<PadAxes>(axis)) {
415 case PadAxes::StickX:
416 return status.stick_x;
417 case PadAxes::StickY:
418 return status.stick_y;
419 case PadAxes::SubstickX:
420 return status.substick_x;
421 case PadAxes::SubstickY:
422 return status.substick_y;
423 case PadAxes::TriggerLeft:
424 return status.trigger_left;
425 case PadAxes::TriggerRight:
426 return status.trigger_right;
427 default:
428 return 0;
429 }
430} 327}
431 328
432} // namespace GCAdapter 329} // namespace GCAdapter
diff --git a/src/input_common/gcadapter/gc_adapter.h b/src/input_common/gcadapter/gc_adapter.h
index 3586c8bda..bed81915c 100644
--- a/src/input_common/gcadapter/gc_adapter.h
+++ b/src/input_common/gcadapter/gc_adapter.h
@@ -47,24 +47,10 @@ enum class PadAxes : u8 {
47}; 47};
48 48
49struct GCPadStatus { 49struct GCPadStatus {
50 u16 button{}; // Or-ed PAD_BUTTON_* and PAD_TRIGGER_* bits 50 u16 button{}; // Or-ed PAD_BUTTON_* and PAD_TRIGGER_* bits
51 u8 stick_x{}; // 0 <= stick_x <= 255 51
52 u8 stick_y{}; // 0 <= stick_y <= 255 52 std::array<u8, 6> axis_values{}; // Triggers and sticks, following indices defined in PadAxes
53 u8 substick_x{}; // 0 <= substick_x <= 255 53 static constexpr u8 THRESHOLD = 50; // Threshold for axis press for polling
54 u8 substick_y{}; // 0 <= substick_y <= 255
55 u8 trigger_left{}; // 0 <= trigger_left <= 255
56 u8 trigger_right{}; // 0 <= trigger_right <= 255
57
58 static constexpr u8 MAIN_STICK_CENTER_X = 0x80;
59 static constexpr u8 MAIN_STICK_CENTER_Y = 0x80;
60 static constexpr u8 MAIN_STICK_RADIUS = 0x7f;
61 static constexpr u8 C_STICK_CENTER_X = 0x80;
62 static constexpr u8 C_STICK_CENTER_Y = 0x80;
63 static constexpr u8 C_STICK_RADIUS = 0x7f;
64 static constexpr u8 THRESHOLD = 10;
65
66 // 256/4, at least a quarter press to count as a press. For polling mostly
67 static constexpr u8 TRIGGER_THRESHOLD = 64;
68 54
69 u8 port{}; 55 u8 port{};
70 PadAxes axis{PadAxes::Undefined}; 56 PadAxes axis{PadAxes::Undefined};
@@ -78,11 +64,6 @@ struct GCState {
78 64
79enum class ControllerTypes { None, Wired, Wireless }; 65enum class ControllerTypes { None, Wired, Wireless };
80 66
81enum {
82 NO_ADAPTER_DETECTED = 0,
83 ADAPTER_DETECTED = 1,
84};
85
86class Adapter { 67class Adapter {
87public: 68public:
88 /// Initialize the GC Adapter capture and read sequence 69 /// Initialize the GC Adapter capture and read sequence
@@ -111,12 +92,6 @@ private:
111 void PadToState(const GCPadStatus& pad, GCState& state); 92 void PadToState(const GCPadStatus& pad, GCState& state);
112 93
113 void Read(); 94 void Read();
114 void ScanThreadFunc();
115 /// Begin scanning for the GC Adapter.
116 void StartScanThread();
117
118 /// Stop scanning for the adapter
119 void StopScanThread();
120 95
121 /// Resets status of device connected to port 96 /// Resets status of device connected to port
122 void ResetDeviceType(std::size_t port); 97 void ResetDeviceType(std::size_t port);
@@ -133,19 +108,11 @@ private:
133 /// For use in initialization, querying devices to find the adapter 108 /// For use in initialization, querying devices to find the adapter
134 void Setup(); 109 void Setup();
135 110
136 int current_status = NO_ADAPTER_DETECTED;
137 libusb_device_handle* usb_adapter_handle = nullptr; 111 libusb_device_handle* usb_adapter_handle = nullptr;
138 std::array<ControllerTypes, 4> adapter_controllers_status{};
139
140 std::mutex s_mutex;
141 112
142 std::thread adapter_input_thread; 113 std::thread adapter_input_thread;
143 bool adapter_thread_running; 114 bool adapter_thread_running;
144 115
145 std::mutex initialization_mutex;
146 std::thread detect_thread;
147 bool detect_thread_running = false;
148
149 libusb_context* libusb_ctx; 116 libusb_context* libusb_ctx;
150 117
151 u8 input_endpoint = 0; 118 u8 input_endpoint = 0;
@@ -153,10 +120,11 @@ private:
153 120
154 bool configuring = false; 121 bool configuring = false;
155 122
156 std::array<Common::SPSCQueue<GCPadStatus>, 4> pad_queue;
157 std::array<GCState, 4> state; 123 std::array<GCState, 4> state;
158 std::array<bool, 4> get_origin; 124 std::array<bool, 4> get_origin;
159 std::array<GCPadStatus, 4> origin_status; 125 std::array<GCPadStatus, 4> origin_status;
126 std::array<Common::SPSCQueue<GCPadStatus>, 4> pad_queue;
127 std::array<ControllerTypes, 4> adapter_controllers_status{};
160}; 128};
161 129
162} // namespace GCAdapter 130} // namespace GCAdapter
diff --git a/src/input_common/gcadapter/gc_poller.cpp b/src/input_common/gcadapter/gc_poller.cpp
index 96e22d3ad..f45983f3f 100644
--- a/src/input_common/gcadapter/gc_poller.cpp
+++ b/src/input_common/gcadapter/gc_poller.cpp
@@ -76,8 +76,7 @@ std::unique_ptr<Input::ButtonDevice> GCButtonFactory::Create(const Common::Param
76 76
77 // button is not an axis/stick button 77 // button is not an axis/stick button
78 if (button_id != PAD_STICK_ID) { 78 if (button_id != PAD_STICK_ID) {
79 auto button = std::make_unique<GCButton>(port, button_id, adapter.get()); 79 return std::make_unique<GCButton>(port, button_id, adapter.get());
80 return std::move(button);
81 } 80 }
82 81
83 // For Axis buttons, used by the binary sticks. 82 // For Axis buttons, used by the binary sticks.
@@ -264,7 +263,8 @@ Common::ParamPackage GCAnalogFactory::GetNextInput() {
264 if (analog_x_axis == -1) { 263 if (analog_x_axis == -1) {
265 analog_x_axis = axis; 264 analog_x_axis = axis;
266 controller_number = static_cast<int>(port); 265 controller_number = static_cast<int>(port);
267 } else if (analog_y_axis == -1 && analog_x_axis != axis && controller_number == port) { 266 } else if (analog_y_axis == -1 && analog_x_axis != axis &&
267 controller_number == static_cast<int>(port)) {
268 analog_y_axis = axis; 268 analog_y_axis = axis;
269 } 269 }
270 } 270 }
diff --git a/src/input_common/udp/client.cpp b/src/input_common/udp/client.cpp
index e63c73c4f..6c95a8b42 100644
--- a/src/input_common/udp/client.cpp
+++ b/src/input_common/udp/client.cpp
@@ -9,7 +9,6 @@
9#include <functional> 9#include <functional>
10#include <thread> 10#include <thread>
11#include <boost/asio.hpp> 11#include <boost/asio.hpp>
12#include <boost/bind.hpp>
13#include "common/logging/log.h" 12#include "common/logging/log.h"
14#include "input_common/udp/client.h" 13#include "input_common/udp/client.h"
15#include "input_common/udp/protocol.h" 14#include "input_common/udp/protocol.h"
diff --git a/src/tests/core/core_timing.cpp b/src/tests/core/core_timing.cpp
index 244463a47..022b26e6d 100644
--- a/src/tests/core/core_timing.cpp
+++ b/src/tests/core/core_timing.cpp
@@ -25,10 +25,10 @@ std::bitset<CB_IDS.size()> callbacks_ran_flags;
25u64 expected_callback = 0; 25u64 expected_callback = 0;
26 26
27template <unsigned int IDX> 27template <unsigned int IDX>
28void HostCallbackTemplate(u64 userdata, std::chrono::nanoseconds ns_late) { 28void HostCallbackTemplate(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
29 static_assert(IDX < CB_IDS.size(), "IDX out of range"); 29 static_assert(IDX < CB_IDS.size(), "IDX out of range");
30 callbacks_ran_flags.set(IDX); 30 callbacks_ran_flags.set(IDX);
31 REQUIRE(CB_IDS[IDX] == userdata); 31 REQUIRE(CB_IDS[IDX] == user_data);
32 REQUIRE(CB_IDS[IDX] == CB_IDS[calls_order[expected_callback]]); 32 REQUIRE(CB_IDS[IDX] == CB_IDS[calls_order[expected_callback]]);
33 delays[IDX] = ns_late.count(); 33 delays[IDX] = ns_late.count();
34 ++expected_callback; 34 ++expected_callback;
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index dd7ce8c99..b5dc68902 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -524,11 +524,8 @@ private:
524 void MarkRegionAsWritten(VAddr start, VAddr end) { 524 void MarkRegionAsWritten(VAddr start, VAddr end) {
525 const u64 page_end = end >> WRITE_PAGE_BIT; 525 const u64 page_end = end >> WRITE_PAGE_BIT;
526 for (u64 page_start = start >> WRITE_PAGE_BIT; page_start <= page_end; ++page_start) { 526 for (u64 page_start = start >> WRITE_PAGE_BIT; page_start <= page_end; ++page_start) {
527 auto it = written_pages.find(page_start); 527 if (const auto [it, inserted] = written_pages.emplace(page_start, 1); !inserted) {
528 if (it != written_pages.end()) { 528 ++it->second;
529 it->second = it->second + 1;
530 } else {
531 written_pages.insert_or_assign(page_start, 1);
532 } 529 }
533 } 530 }
534 } 531 }
@@ -539,7 +536,7 @@ private:
539 auto it = written_pages.find(page_start); 536 auto it = written_pages.find(page_start);
540 if (it != written_pages.end()) { 537 if (it != written_pages.end()) {
541 if (it->second > 1) { 538 if (it->second > 1) {
542 it->second = it->second - 1; 539 --it->second;
543 } else { 540 } else {
544 written_pages.erase(it); 541 written_pages.erase(it);
545 } 542 }
diff --git a/src/video_core/compatible_formats.cpp b/src/video_core/compatible_formats.cpp
index 6c426b035..b06c32c84 100644
--- a/src/video_core/compatible_formats.cpp
+++ b/src/video_core/compatible_formats.cpp
@@ -17,101 +17,94 @@ namespace {
17// https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_texture_view.txt 17// https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_texture_view.txt
18 18
19constexpr std::array VIEW_CLASS_128_BITS = { 19constexpr std::array VIEW_CLASS_128_BITS = {
20 PixelFormat::RGBA32F, 20 PixelFormat::R32G32B32A32_FLOAT,
21 PixelFormat::RGBA32UI, 21 PixelFormat::R32G32B32A32_UINT,
22 PixelFormat::R32G32B32A32_SINT,
22}; 23};
23// Missing formats:
24// PixelFormat::RGBA32I
25 24
26constexpr std::array VIEW_CLASS_96_BITS = { 25constexpr std::array VIEW_CLASS_96_BITS = {
27 PixelFormat::RGB32F, 26 PixelFormat::R32G32B32_FLOAT,
28}; 27};
29// Missing formats: 28// Missing formats:
30// PixelFormat::RGB32UI, 29// PixelFormat::RGB32UI,
31// PixelFormat::RGB32I, 30// PixelFormat::RGB32I,
32 31
33constexpr std::array VIEW_CLASS_64_BITS = { 32constexpr std::array VIEW_CLASS_64_BITS = {
34 PixelFormat::RGBA16F, PixelFormat::RG32F, PixelFormat::RGBA16UI, PixelFormat::RG32UI, 33 PixelFormat::R32G32_FLOAT, PixelFormat::R32G32_UINT,
35 PixelFormat::RGBA16U, PixelFormat::RGBA16F, PixelFormat::RGBA16S, 34 PixelFormat::R32G32_SINT, PixelFormat::R16G16B16A16_FLOAT,
35 PixelFormat::R16G16B16A16_UNORM, PixelFormat::R16G16B16A16_SNORM,
36 PixelFormat::R16G16B16A16_UINT, PixelFormat::R16G16B16A16_SINT,
36}; 37};
37// Missing formats:
38// PixelFormat::RGBA16I
39// PixelFormat::RG32I
40 38
41// TODO: How should we handle 48 bits? 39// TODO: How should we handle 48 bits?
42 40
43constexpr std::array VIEW_CLASS_32_BITS = { 41constexpr std::array VIEW_CLASS_32_BITS = {
44 PixelFormat::RG16F, PixelFormat::R11FG11FB10F, PixelFormat::R32F, 42 PixelFormat::R16G16_FLOAT, PixelFormat::B10G11R11_FLOAT, PixelFormat::R32_FLOAT,
45 PixelFormat::A2B10G10R10U, PixelFormat::RG16UI, PixelFormat::R32UI, 43 PixelFormat::A2B10G10R10_UNORM, PixelFormat::R16G16_UINT, PixelFormat::R32_UINT,
46 PixelFormat::RG16I, PixelFormat::R32I, PixelFormat::ABGR8U, 44 PixelFormat::R16G16_SINT, PixelFormat::R32_SINT, PixelFormat::A8B8G8R8_UNORM,
47 PixelFormat::RG16, PixelFormat::ABGR8S, PixelFormat::RG16S, 45 PixelFormat::R16G16_UNORM, PixelFormat::A8B8G8R8_SNORM, PixelFormat::R16G16_SNORM,
48 PixelFormat::RGBA8_SRGB, PixelFormat::E5B9G9R9F, PixelFormat::BGRA8, 46 PixelFormat::A8B8G8R8_SRGB, PixelFormat::E5B9G9R9_FLOAT, PixelFormat::B8G8R8A8_UNORM,
49 PixelFormat::BGRA8_SRGB, 47 PixelFormat::B8G8R8A8_SRGB, PixelFormat::A8B8G8R8_UINT, PixelFormat::A8B8G8R8_SINT,
48 PixelFormat::A2B10G10R10_UINT,
50}; 49};
51// Missing formats:
52// PixelFormat::RGBA8UI
53// PixelFormat::RGBA8I
54// PixelFormat::RGB10_A2_UI
55 50
56// TODO: How should we handle 24 bits? 51// TODO: How should we handle 24 bits?
57 52
58constexpr std::array VIEW_CLASS_16_BITS = { 53constexpr std::array VIEW_CLASS_16_BITS = {
59 PixelFormat::R16F, PixelFormat::RG8UI, PixelFormat::R16UI, PixelFormat::R16I, 54 PixelFormat::R16_FLOAT, PixelFormat::R8G8_UINT, PixelFormat::R16_UINT,
60 PixelFormat::RG8U, PixelFormat::R16U, PixelFormat::RG8S, PixelFormat::R16S, 55 PixelFormat::R16_SINT, PixelFormat::R8G8_UNORM, PixelFormat::R16_UNORM,
56 PixelFormat::R8G8_SNORM, PixelFormat::R16_SNORM, PixelFormat::R8G8_SINT,
61}; 57};
62// Missing formats:
63// PixelFormat::RG8I
64 58
65constexpr std::array VIEW_CLASS_8_BITS = { 59constexpr std::array VIEW_CLASS_8_BITS = {
66 PixelFormat::R8UI, 60 PixelFormat::R8_UINT,
67 PixelFormat::R8U, 61 PixelFormat::R8_UNORM,
62 PixelFormat::R8_SINT,
63 PixelFormat::R8_SNORM,
68}; 64};
69// Missing formats:
70// PixelFormat::R8I
71// PixelFormat::R8S
72 65
73constexpr std::array VIEW_CLASS_RGTC1_RED = { 66constexpr std::array VIEW_CLASS_RGTC1_RED = {
74 PixelFormat::DXN1, 67 PixelFormat::BC4_UNORM,
68 PixelFormat::BC4_SNORM,
75}; 69};
76// Missing formats:
77// COMPRESSED_SIGNED_RED_RGTC1
78 70
79constexpr std::array VIEW_CLASS_RGTC2_RG = { 71constexpr std::array VIEW_CLASS_RGTC2_RG = {
80 PixelFormat::DXN2UNORM, 72 PixelFormat::BC5_UNORM,
81 PixelFormat::DXN2SNORM, 73 PixelFormat::BC5_SNORM,
82}; 74};
83 75
84constexpr std::array VIEW_CLASS_BPTC_UNORM = { 76constexpr std::array VIEW_CLASS_BPTC_UNORM = {
85 PixelFormat::BC7U, 77 PixelFormat::BC7_UNORM,
86 PixelFormat::BC7U_SRGB, 78 PixelFormat::BC7_SRGB,
87}; 79};
88 80
89constexpr std::array VIEW_CLASS_BPTC_FLOAT = { 81constexpr std::array VIEW_CLASS_BPTC_FLOAT = {
90 PixelFormat::BC6H_SF16, 82 PixelFormat::BC6H_SFLOAT,
91 PixelFormat::BC6H_UF16, 83 PixelFormat::BC6H_UFLOAT,
92}; 84};
93 85
94// Compatibility table taken from Table 4.X.1 in: 86// Compatibility table taken from Table 4.X.1 in:
95// https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_copy_image.txt 87// https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_copy_image.txt
96 88
97constexpr std::array COPY_CLASS_128_BITS = { 89constexpr std::array COPY_CLASS_128_BITS = {
98 PixelFormat::RGBA32UI, PixelFormat::RGBA32F, PixelFormat::DXT23, 90 PixelFormat::R32G32B32A32_UINT, PixelFormat::R32G32B32A32_FLOAT, PixelFormat::R32G32B32A32_SINT,
99 PixelFormat::DXT23_SRGB, PixelFormat::DXT45, PixelFormat::DXT45_SRGB, 91 PixelFormat::BC2_UNORM, PixelFormat::BC2_SRGB, PixelFormat::BC3_UNORM,
100 PixelFormat::DXN2SNORM, PixelFormat::BC7U, PixelFormat::BC7U_SRGB, 92 PixelFormat::BC3_SRGB, PixelFormat::BC5_UNORM, PixelFormat::BC5_SNORM,
101 PixelFormat::BC6H_SF16, PixelFormat::BC6H_UF16, 93 PixelFormat::BC7_UNORM, PixelFormat::BC7_SRGB, PixelFormat::BC6H_SFLOAT,
94 PixelFormat::BC6H_UFLOAT,
102}; 95};
103// Missing formats: 96// Missing formats:
104// PixelFormat::RGBA32I 97// PixelFormat::RGBA32I
105// COMPRESSED_RG_RGTC2 98// COMPRESSED_RG_RGTC2
106 99
107constexpr std::array COPY_CLASS_64_BITS = { 100constexpr std::array COPY_CLASS_64_BITS = {
108 PixelFormat::RGBA16F, PixelFormat::RG32F, PixelFormat::RGBA16UI, PixelFormat::RG32UI, 101 PixelFormat::R16G16B16A16_FLOAT, PixelFormat::R16G16B16A16_UINT,
109 PixelFormat::RGBA16U, PixelFormat::RGBA16S, PixelFormat::DXT1_SRGB, PixelFormat::DXT1, 102 PixelFormat::R16G16B16A16_UNORM, PixelFormat::R16G16B16A16_SNORM,
110 103 PixelFormat::R16G16B16A16_SINT, PixelFormat::R32G32_UINT,
104 PixelFormat::R32G32_FLOAT, PixelFormat::R32G32_SINT,
105 PixelFormat::BC1_RGBA_UNORM, PixelFormat::BC1_RGBA_SRGB,
111}; 106};
112// Missing formats: 107// Missing formats:
113// PixelFormat::RGBA16I
114// PixelFormat::RG32I,
115// COMPRESSED_RGB_S3TC_DXT1_EXT 108// COMPRESSED_RGB_S3TC_DXT1_EXT
116// COMPRESSED_SRGB_S3TC_DXT1_EXT 109// COMPRESSED_SRGB_S3TC_DXT1_EXT
117// COMPRESSED_RGBA_S3TC_DXT1_EXT 110// COMPRESSED_RGBA_S3TC_DXT1_EXT
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index 8d04d9fd9..ebfc7b0c7 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -40,53 +40,61 @@ namespace Tegra {
40 40
41enum class RenderTargetFormat : u32 { 41enum class RenderTargetFormat : u32 {
42 NONE = 0x0, 42 NONE = 0x0,
43 RGBA32_FLOAT = 0xC0, 43 R32B32G32A32_FLOAT = 0xC0,
44 RGBA32_UINT = 0xC2, 44 R32G32B32A32_SINT = 0xC1,
45 RGBA16_UNORM = 0xC6, 45 R32G32B32A32_UINT = 0xC2,
46 RGBA16_SNORM = 0xC7, 46 R16G16B16A16_UNORM = 0xC6,
47 RGBA16_UINT = 0xC9, 47 R16G16B16A16_SNORM = 0xC7,
48 RGBA16_FLOAT = 0xCA, 48 R16G16B16A16_SINT = 0xC8,
49 RG32_FLOAT = 0xCB, 49 R16G16B16A16_UINT = 0xC9,
50 RG32_UINT = 0xCD, 50 R16G16B16A16_FLOAT = 0xCA,
51 RGBX16_FLOAT = 0xCE, 51 R32G32_FLOAT = 0xCB,
52 BGRA8_UNORM = 0xCF, 52 R32G32_SINT = 0xCC,
53 BGRA8_SRGB = 0xD0, 53 R32G32_UINT = 0xCD,
54 RGB10_A2_UNORM = 0xD1, 54 R16G16B16X16_FLOAT = 0xCE,
55 RGBA8_UNORM = 0xD5, 55 B8G8R8A8_UNORM = 0xCF,
56 RGBA8_SRGB = 0xD6, 56 B8G8R8A8_SRGB = 0xD0,
57 RGBA8_SNORM = 0xD7, 57 A2B10G10R10_UNORM = 0xD1,
58 RGBA8_UINT = 0xD9, 58 A2B10G10R10_UINT = 0xD2,
59 RG16_UNORM = 0xDA, 59 A8B8G8R8_UNORM = 0xD5,
60 RG16_SNORM = 0xDB, 60 A8B8G8R8_SRGB = 0xD6,
61 RG16_SINT = 0xDC, 61 A8B8G8R8_SNORM = 0xD7,
62 RG16_UINT = 0xDD, 62 A8B8G8R8_SINT = 0xD8,
63 RG16_FLOAT = 0xDE, 63 A8B8G8R8_UINT = 0xD9,
64 R11G11B10_FLOAT = 0xE0, 64 R16G16_UNORM = 0xDA,
65 R16G16_SNORM = 0xDB,
66 R16G16_SINT = 0xDC,
67 R16G16_UINT = 0xDD,
68 R16G16_FLOAT = 0xDE,
69 B10G11R11_FLOAT = 0xE0,
65 R32_SINT = 0xE3, 70 R32_SINT = 0xE3,
66 R32_UINT = 0xE4, 71 R32_UINT = 0xE4,
67 R32_FLOAT = 0xE5, 72 R32_FLOAT = 0xE5,
68 B5G6R5_UNORM = 0xE8, 73 R5G6B5_UNORM = 0xE8,
69 BGR5A1_UNORM = 0xE9, 74 A1R5G5B5_UNORM = 0xE9,
70 RG8_UNORM = 0xEA, 75 R8G8_UNORM = 0xEA,
71 RG8_SNORM = 0xEB, 76 R8G8_SNORM = 0xEB,
72 RG8_UINT = 0xED, 77 R8G8_SINT = 0xEC,
78 R8G8_UINT = 0xED,
73 R16_UNORM = 0xEE, 79 R16_UNORM = 0xEE,
74 R16_SNORM = 0xEF, 80 R16_SNORM = 0xEF,
75 R16_SINT = 0xF0, 81 R16_SINT = 0xF0,
76 R16_UINT = 0xF1, 82 R16_UINT = 0xF1,
77 R16_FLOAT = 0xF2, 83 R16_FLOAT = 0xF2,
78 R8_UNORM = 0xF3, 84 R8_UNORM = 0xF3,
85 R8_SNORM = 0xF4,
86 R8_SINT = 0xF5,
79 R8_UINT = 0xF6, 87 R8_UINT = 0xF6,
80}; 88};
81 89
82enum class DepthFormat : u32 { 90enum class DepthFormat : u32 {
83 Z32_FLOAT = 0xA, 91 D32_FLOAT = 0xA,
84 Z16_UNORM = 0x13, 92 D16_UNORM = 0x13,
85 S8_Z24_UNORM = 0x14, 93 S8_UINT_Z24_UNORM = 0x14,
86 Z24_X8_UNORM = 0x15, 94 D24X8_UNORM = 0x15,
87 Z24_S8_UNORM = 0x16, 95 D24S8_UNORM = 0x16,
88 Z24_C8_UNORM = 0x18, 96 D24C8_UNORM = 0x18,
89 Z32_S8_X24_FLOAT = 0x19, 97 D32_FLOAT_S8X24_UINT = 0x19,
90}; 98};
91 99
92struct CommandListHeader; 100struct CommandListHeader;
@@ -97,9 +105,9 @@ class DebugContext;
97 */ 105 */
98struct FramebufferConfig { 106struct FramebufferConfig {
99 enum class PixelFormat : u32 { 107 enum class PixelFormat : u32 {
100 ABGR8 = 1, 108 A8B8G8R8_UNORM = 1,
101 RGB565 = 4, 109 RGB565_UNORM = 4,
102 BGRA8 = 5, 110 B8G8R8A8_UNORM = 5,
103 }; 111 };
104 112
105 VAddr address; 113 VAddr address;
@@ -244,7 +252,7 @@ public:
244 const Tegra::DmaPusher& DmaPusher() const; 252 const Tegra::DmaPusher& DmaPusher() const;
245 253
246 struct Regs { 254 struct Regs {
247 static constexpr size_t NUM_REGS = 0x100; 255 static constexpr size_t NUM_REGS = 0x40;
248 256
249 union { 257 union {
250 struct { 258 struct {
@@ -263,7 +271,7 @@ public:
263 u32 semaphore_trigger; 271 u32 semaphore_trigger;
264 INSERT_UNION_PADDING_WORDS(0xC); 272 INSERT_UNION_PADDING_WORDS(0xC);
265 273
266 // The puser and the puller share the reference counter, the pusher only has read 274 // The pusher and the puller share the reference counter, the pusher only has read
267 // access 275 // access
268 u32 reference_count; 276 u32 reference_count;
269 INSERT_UNION_PADDING_WORDS(0x5); 277 INSERT_UNION_PADDING_WORDS(0x5);
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp
index 738c6f0c1..bf761abf2 100644
--- a/src/video_core/gpu_thread.cpp
+++ b/src/video_core/gpu_thread.cpp
@@ -44,9 +44,9 @@ static void RunThread(Core::System& system, VideoCore::RendererBase& renderer,
44 dma_pusher.DispatchCalls(); 44 dma_pusher.DispatchCalls();
45 } else if (const auto data = std::get_if<SwapBuffersCommand>(&next.data)) { 45 } else if (const auto data = std::get_if<SwapBuffersCommand>(&next.data)) {
46 renderer.SwapBuffers(data->framebuffer ? &*data->framebuffer : nullptr); 46 renderer.SwapBuffers(data->framebuffer ? &*data->framebuffer : nullptr);
47 } else if (const auto data = std::get_if<OnCommandListEndCommand>(&next.data)) { 47 } else if (std::holds_alternative<OnCommandListEndCommand>(next.data)) {
48 renderer.Rasterizer().ReleaseFences(); 48 renderer.Rasterizer().ReleaseFences();
49 } else if (const auto data = std::get_if<GPUTickCommand>(&next.data)) { 49 } else if (std::holds_alternative<GPUTickCommand>(next.data)) {
50 system.GPU().TickWork(); 50 system.GPU().TickWork();
51 } else if (const auto data = std::get_if<FlushRegionCommand>(&next.data)) { 51 } else if (const auto data = std::get_if<FlushRegionCommand>(&next.data)) {
52 renderer.Rasterizer().FlushRegion(data->addr, data->size); 52 renderer.Rasterizer().FlushRegion(data->addr, data->size);
diff --git a/src/video_core/macro/macro_jit_x64.cpp b/src/video_core/macro/macro_jit_x64.cpp
index 07292702f..c1b9e4ad9 100644
--- a/src/video_core/macro/macro_jit_x64.cpp
+++ b/src/video_core/macro/macro_jit_x64.cpp
@@ -419,7 +419,6 @@ void Tegra::MacroJITx64Impl::Optimizer_ScanFlags() {
419 419
420void MacroJITx64Impl::Compile() { 420void MacroJITx64Impl::Compile() {
421 MICROPROFILE_SCOPE(MacroJitCompile); 421 MICROPROFILE_SCOPE(MacroJitCompile);
422 bool keep_executing = true;
423 labels.fill(Xbyak::Label()); 422 labels.fill(Xbyak::Label());
424 423
425 Common::X64::ABI_PushRegistersAndAdjustStack(*this, Common::X64::ABI_ALL_CALLEE_SAVED, 8); 424 Common::X64::ABI_PushRegistersAndAdjustStack(*this, Common::X64::ABI_ALL_CALLEE_SAVED, 8);
diff --git a/src/video_core/morton.cpp b/src/video_core/morton.cpp
index 836b25c1d..9da9fb4ff 100644
--- a/src/video_core/morton.cpp
+++ b/src/video_core/morton.cpp
@@ -41,146 +41,168 @@ static void MortonCopy(u32 stride, u32 block_height, u32 height, u32 block_depth
41} 41}
42 42
43static constexpr ConversionArray morton_to_linear_fns = { 43static constexpr ConversionArray morton_to_linear_fns = {
44 MortonCopy<true, PixelFormat::ABGR8U>, 44 MortonCopy<true, PixelFormat::A8B8G8R8_UNORM>,
45 MortonCopy<true, PixelFormat::ABGR8S>, 45 MortonCopy<true, PixelFormat::A8B8G8R8_SNORM>,
46 MortonCopy<true, PixelFormat::ABGR8UI>, 46 MortonCopy<true, PixelFormat::A8B8G8R8_SINT>,
47 MortonCopy<true, PixelFormat::B5G6R5U>, 47 MortonCopy<true, PixelFormat::A8B8G8R8_UINT>,
48 MortonCopy<true, PixelFormat::A2B10G10R10U>, 48 MortonCopy<true, PixelFormat::R5G6B5_UNORM>,
49 MortonCopy<true, PixelFormat::A1B5G5R5U>, 49 MortonCopy<true, PixelFormat::B5G6R5_UNORM>,
50 MortonCopy<true, PixelFormat::R8U>, 50 MortonCopy<true, PixelFormat::A1R5G5B5_UNORM>,
51 MortonCopy<true, PixelFormat::R8UI>, 51 MortonCopy<true, PixelFormat::A2B10G10R10_UNORM>,
52 MortonCopy<true, PixelFormat::RGBA16F>, 52 MortonCopy<true, PixelFormat::A2B10G10R10_UINT>,
53 MortonCopy<true, PixelFormat::RGBA16U>, 53 MortonCopy<true, PixelFormat::A1B5G5R5_UNORM>,
54 MortonCopy<true, PixelFormat::RGBA16S>, 54 MortonCopy<true, PixelFormat::R8_UNORM>,
55 MortonCopy<true, PixelFormat::RGBA16UI>, 55 MortonCopy<true, PixelFormat::R8_SNORM>,
56 MortonCopy<true, PixelFormat::R11FG11FB10F>, 56 MortonCopy<true, PixelFormat::R8_SINT>,
57 MortonCopy<true, PixelFormat::RGBA32UI>, 57 MortonCopy<true, PixelFormat::R8_UINT>,
58 MortonCopy<true, PixelFormat::DXT1>, 58 MortonCopy<true, PixelFormat::R16G16B16A16_FLOAT>,
59 MortonCopy<true, PixelFormat::DXT23>, 59 MortonCopy<true, PixelFormat::R16G16B16A16_UNORM>,
60 MortonCopy<true, PixelFormat::DXT45>, 60 MortonCopy<true, PixelFormat::R16G16B16A16_SNORM>,
61 MortonCopy<true, PixelFormat::DXN1>, 61 MortonCopy<true, PixelFormat::R16G16B16A16_SINT>,
62 MortonCopy<true, PixelFormat::DXN2UNORM>, 62 MortonCopy<true, PixelFormat::R16G16B16A16_UINT>,
63 MortonCopy<true, PixelFormat::DXN2SNORM>, 63 MortonCopy<true, PixelFormat::B10G11R11_FLOAT>,
64 MortonCopy<true, PixelFormat::BC7U>, 64 MortonCopy<true, PixelFormat::R32G32B32A32_UINT>,
65 MortonCopy<true, PixelFormat::BC6H_UF16>, 65 MortonCopy<true, PixelFormat::BC1_RGBA_UNORM>,
66 MortonCopy<true, PixelFormat::BC6H_SF16>, 66 MortonCopy<true, PixelFormat::BC2_UNORM>,
67 MortonCopy<true, PixelFormat::ASTC_2D_4X4>, 67 MortonCopy<true, PixelFormat::BC3_UNORM>,
68 MortonCopy<true, PixelFormat::BGRA8>, 68 MortonCopy<true, PixelFormat::BC4_UNORM>,
69 MortonCopy<true, PixelFormat::RGBA32F>, 69 MortonCopy<true, PixelFormat::BC4_SNORM>,
70 MortonCopy<true, PixelFormat::RG32F>, 70 MortonCopy<true, PixelFormat::BC5_UNORM>,
71 MortonCopy<true, PixelFormat::R32F>, 71 MortonCopy<true, PixelFormat::BC5_SNORM>,
72 MortonCopy<true, PixelFormat::R16F>, 72 MortonCopy<true, PixelFormat::BC7_UNORM>,
73 MortonCopy<true, PixelFormat::R16U>, 73 MortonCopy<true, PixelFormat::BC6H_UFLOAT>,
74 MortonCopy<true, PixelFormat::R16S>, 74 MortonCopy<true, PixelFormat::BC6H_SFLOAT>,
75 MortonCopy<true, PixelFormat::R16UI>, 75 MortonCopy<true, PixelFormat::ASTC_2D_4X4_UNORM>,
76 MortonCopy<true, PixelFormat::R16I>, 76 MortonCopy<true, PixelFormat::B8G8R8A8_UNORM>,
77 MortonCopy<true, PixelFormat::RG16>, 77 MortonCopy<true, PixelFormat::R32G32B32A32_FLOAT>,
78 MortonCopy<true, PixelFormat::RG16F>, 78 MortonCopy<true, PixelFormat::R32G32B32A32_SINT>,
79 MortonCopy<true, PixelFormat::RG16UI>, 79 MortonCopy<true, PixelFormat::R32G32_FLOAT>,
80 MortonCopy<true, PixelFormat::RG16I>, 80 MortonCopy<true, PixelFormat::R32G32_SINT>,
81 MortonCopy<true, PixelFormat::RG16S>, 81 MortonCopy<true, PixelFormat::R32_FLOAT>,
82 MortonCopy<true, PixelFormat::RGB32F>, 82 MortonCopy<true, PixelFormat::R16_FLOAT>,
83 MortonCopy<true, PixelFormat::RGBA8_SRGB>, 83 MortonCopy<true, PixelFormat::R16_UNORM>,
84 MortonCopy<true, PixelFormat::RG8U>, 84 MortonCopy<true, PixelFormat::R16_SNORM>,
85 MortonCopy<true, PixelFormat::RG8S>, 85 MortonCopy<true, PixelFormat::R16_UINT>,
86 MortonCopy<true, PixelFormat::RG8UI>, 86 MortonCopy<true, PixelFormat::R16_SINT>,
87 MortonCopy<true, PixelFormat::RG32UI>, 87 MortonCopy<true, PixelFormat::R16G16_UNORM>,
88 MortonCopy<true, PixelFormat::RGBX16F>, 88 MortonCopy<true, PixelFormat::R16G16_FLOAT>,
89 MortonCopy<true, PixelFormat::R32UI>, 89 MortonCopy<true, PixelFormat::R16G16_UINT>,
90 MortonCopy<true, PixelFormat::R32I>, 90 MortonCopy<true, PixelFormat::R16G16_SINT>,
91 MortonCopy<true, PixelFormat::ASTC_2D_8X8>, 91 MortonCopy<true, PixelFormat::R16G16_SNORM>,
92 MortonCopy<true, PixelFormat::ASTC_2D_8X5>, 92 MortonCopy<true, PixelFormat::R32G32B32_FLOAT>,
93 MortonCopy<true, PixelFormat::ASTC_2D_5X4>, 93 MortonCopy<true, PixelFormat::A8B8G8R8_SRGB>,
94 MortonCopy<true, PixelFormat::BGRA8_SRGB>, 94 MortonCopy<true, PixelFormat::R8G8_UNORM>,
95 MortonCopy<true, PixelFormat::DXT1_SRGB>, 95 MortonCopy<true, PixelFormat::R8G8_SNORM>,
96 MortonCopy<true, PixelFormat::DXT23_SRGB>, 96 MortonCopy<true, PixelFormat::R8G8_SINT>,
97 MortonCopy<true, PixelFormat::DXT45_SRGB>, 97 MortonCopy<true, PixelFormat::R8G8_UINT>,
98 MortonCopy<true, PixelFormat::BC7U_SRGB>, 98 MortonCopy<true, PixelFormat::R32G32_UINT>,
99 MortonCopy<true, PixelFormat::R4G4B4A4U>, 99 MortonCopy<true, PixelFormat::R16G16B16X16_FLOAT>,
100 MortonCopy<true, PixelFormat::R32_UINT>,
101 MortonCopy<true, PixelFormat::R32_SINT>,
102 MortonCopy<true, PixelFormat::ASTC_2D_8X8_UNORM>,
103 MortonCopy<true, PixelFormat::ASTC_2D_8X5_UNORM>,
104 MortonCopy<true, PixelFormat::ASTC_2D_5X4_UNORM>,
105 MortonCopy<true, PixelFormat::B8G8R8A8_SRGB>,
106 MortonCopy<true, PixelFormat::BC1_RGBA_SRGB>,
107 MortonCopy<true, PixelFormat::BC2_SRGB>,
108 MortonCopy<true, PixelFormat::BC3_SRGB>,
109 MortonCopy<true, PixelFormat::BC7_SRGB>,
110 MortonCopy<true, PixelFormat::A4B4G4R4_UNORM>,
100 MortonCopy<true, PixelFormat::ASTC_2D_4X4_SRGB>, 111 MortonCopy<true, PixelFormat::ASTC_2D_4X4_SRGB>,
101 MortonCopy<true, PixelFormat::ASTC_2D_8X8_SRGB>, 112 MortonCopy<true, PixelFormat::ASTC_2D_8X8_SRGB>,
102 MortonCopy<true, PixelFormat::ASTC_2D_8X5_SRGB>, 113 MortonCopy<true, PixelFormat::ASTC_2D_8X5_SRGB>,
103 MortonCopy<true, PixelFormat::ASTC_2D_5X4_SRGB>, 114 MortonCopy<true, PixelFormat::ASTC_2D_5X4_SRGB>,
104 MortonCopy<true, PixelFormat::ASTC_2D_5X5>, 115 MortonCopy<true, PixelFormat::ASTC_2D_5X5_UNORM>,
105 MortonCopy<true, PixelFormat::ASTC_2D_5X5_SRGB>, 116 MortonCopy<true, PixelFormat::ASTC_2D_5X5_SRGB>,
106 MortonCopy<true, PixelFormat::ASTC_2D_10X8>, 117 MortonCopy<true, PixelFormat::ASTC_2D_10X8_UNORM>,
107 MortonCopy<true, PixelFormat::ASTC_2D_10X8_SRGB>, 118 MortonCopy<true, PixelFormat::ASTC_2D_10X8_SRGB>,
108 MortonCopy<true, PixelFormat::ASTC_2D_6X6>, 119 MortonCopy<true, PixelFormat::ASTC_2D_6X6_UNORM>,
109 MortonCopy<true, PixelFormat::ASTC_2D_6X6_SRGB>, 120 MortonCopy<true, PixelFormat::ASTC_2D_6X6_SRGB>,
110 MortonCopy<true, PixelFormat::ASTC_2D_10X10>, 121 MortonCopy<true, PixelFormat::ASTC_2D_10X10_UNORM>,
111 MortonCopy<true, PixelFormat::ASTC_2D_10X10_SRGB>, 122 MortonCopy<true, PixelFormat::ASTC_2D_10X10_SRGB>,
112 MortonCopy<true, PixelFormat::ASTC_2D_12X12>, 123 MortonCopy<true, PixelFormat::ASTC_2D_12X12_UNORM>,
113 MortonCopy<true, PixelFormat::ASTC_2D_12X12_SRGB>, 124 MortonCopy<true, PixelFormat::ASTC_2D_12X12_SRGB>,
114 MortonCopy<true, PixelFormat::ASTC_2D_8X6>, 125 MortonCopy<true, PixelFormat::ASTC_2D_8X6_UNORM>,
115 MortonCopy<true, PixelFormat::ASTC_2D_8X6_SRGB>, 126 MortonCopy<true, PixelFormat::ASTC_2D_8X6_SRGB>,
116 MortonCopy<true, PixelFormat::ASTC_2D_6X5>, 127 MortonCopy<true, PixelFormat::ASTC_2D_6X5_UNORM>,
117 MortonCopy<true, PixelFormat::ASTC_2D_6X5_SRGB>, 128 MortonCopy<true, PixelFormat::ASTC_2D_6X5_SRGB>,
118 MortonCopy<true, PixelFormat::E5B9G9R9F>, 129 MortonCopy<true, PixelFormat::E5B9G9R9_FLOAT>,
119 MortonCopy<true, PixelFormat::Z32F>, 130 MortonCopy<true, PixelFormat::D32_FLOAT>,
120 MortonCopy<true, PixelFormat::Z16>, 131 MortonCopy<true, PixelFormat::D16_UNORM>,
121 MortonCopy<true, PixelFormat::Z24S8>, 132 MortonCopy<true, PixelFormat::D24_UNORM_S8_UINT>,
122 MortonCopy<true, PixelFormat::S8Z24>, 133 MortonCopy<true, PixelFormat::S8_UINT_D24_UNORM>,
123 MortonCopy<true, PixelFormat::Z32FS8>, 134 MortonCopy<true, PixelFormat::D32_FLOAT_S8_UINT>,
124}; 135};
125 136
126static constexpr ConversionArray linear_to_morton_fns = { 137static constexpr ConversionArray linear_to_morton_fns = {
127 MortonCopy<false, PixelFormat::ABGR8U>, 138 MortonCopy<false, PixelFormat::A8B8G8R8_UNORM>,
128 MortonCopy<false, PixelFormat::ABGR8S>, 139 MortonCopy<false, PixelFormat::A8B8G8R8_SNORM>,
129 MortonCopy<false, PixelFormat::ABGR8UI>, 140 MortonCopy<false, PixelFormat::A8B8G8R8_SINT>,
130 MortonCopy<false, PixelFormat::B5G6R5U>, 141 MortonCopy<false, PixelFormat::A8B8G8R8_UINT>,
131 MortonCopy<false, PixelFormat::A2B10G10R10U>, 142 MortonCopy<false, PixelFormat::R5G6B5_UNORM>,
132 MortonCopy<false, PixelFormat::A1B5G5R5U>, 143 MortonCopy<false, PixelFormat::B5G6R5_UNORM>,
133 MortonCopy<false, PixelFormat::R8U>, 144 MortonCopy<false, PixelFormat::A1R5G5B5_UNORM>,
134 MortonCopy<false, PixelFormat::R8UI>, 145 MortonCopy<false, PixelFormat::A2B10G10R10_UNORM>,
135 MortonCopy<false, PixelFormat::RGBA16F>, 146 MortonCopy<false, PixelFormat::A2B10G10R10_UINT>,
136 MortonCopy<false, PixelFormat::RGBA16S>, 147 MortonCopy<false, PixelFormat::A1B5G5R5_UNORM>,
137 MortonCopy<false, PixelFormat::RGBA16U>, 148 MortonCopy<false, PixelFormat::R8_UNORM>,
138 MortonCopy<false, PixelFormat::RGBA16UI>, 149 MortonCopy<false, PixelFormat::R8_SNORM>,
139 MortonCopy<false, PixelFormat::R11FG11FB10F>, 150 MortonCopy<false, PixelFormat::R8_SINT>,
140 MortonCopy<false, PixelFormat::RGBA32UI>, 151 MortonCopy<false, PixelFormat::R8_UINT>,
141 MortonCopy<false, PixelFormat::DXT1>, 152 MortonCopy<false, PixelFormat::R16G16B16A16_FLOAT>,
142 MortonCopy<false, PixelFormat::DXT23>, 153 MortonCopy<false, PixelFormat::R16G16B16A16_SNORM>,
143 MortonCopy<false, PixelFormat::DXT45>, 154 MortonCopy<false, PixelFormat::R16G16B16A16_SINT>,
144 MortonCopy<false, PixelFormat::DXN1>, 155 MortonCopy<false, PixelFormat::R16G16B16A16_UNORM>,
145 MortonCopy<false, PixelFormat::DXN2UNORM>, 156 MortonCopy<false, PixelFormat::R16G16B16A16_UINT>,
146 MortonCopy<false, PixelFormat::DXN2SNORM>, 157 MortonCopy<false, PixelFormat::B10G11R11_FLOAT>,
147 MortonCopy<false, PixelFormat::BC7U>, 158 MortonCopy<false, PixelFormat::R32G32B32A32_UINT>,
148 MortonCopy<false, PixelFormat::BC6H_UF16>, 159 MortonCopy<false, PixelFormat::BC1_RGBA_UNORM>,
149 MortonCopy<false, PixelFormat::BC6H_SF16>, 160 MortonCopy<false, PixelFormat::BC2_UNORM>,
161 MortonCopy<false, PixelFormat::BC3_UNORM>,
162 MortonCopy<false, PixelFormat::BC4_UNORM>,
163 MortonCopy<false, PixelFormat::BC4_SNORM>,
164 MortonCopy<false, PixelFormat::BC5_UNORM>,
165 MortonCopy<false, PixelFormat::BC5_SNORM>,
166 MortonCopy<false, PixelFormat::BC7_UNORM>,
167 MortonCopy<false, PixelFormat::BC6H_UFLOAT>,
168 MortonCopy<false, PixelFormat::BC6H_SFLOAT>,
150 // TODO(Subv): Swizzling ASTC formats are not supported 169 // TODO(Subv): Swizzling ASTC formats are not supported
151 nullptr, 170 nullptr,
152 MortonCopy<false, PixelFormat::BGRA8>, 171 MortonCopy<false, PixelFormat::B8G8R8A8_UNORM>,
153 MortonCopy<false, PixelFormat::RGBA32F>, 172 MortonCopy<false, PixelFormat::R32G32B32A32_FLOAT>,
154 MortonCopy<false, PixelFormat::RG32F>, 173 MortonCopy<false, PixelFormat::R32G32B32A32_SINT>,
155 MortonCopy<false, PixelFormat::R32F>, 174 MortonCopy<false, PixelFormat::R32G32_FLOAT>,
156 MortonCopy<false, PixelFormat::R16F>, 175 MortonCopy<false, PixelFormat::R32G32_SINT>,
157 MortonCopy<false, PixelFormat::R16U>, 176 MortonCopy<false, PixelFormat::R32_FLOAT>,
158 MortonCopy<false, PixelFormat::R16S>, 177 MortonCopy<false, PixelFormat::R16_FLOAT>,
159 MortonCopy<false, PixelFormat::R16UI>, 178 MortonCopy<false, PixelFormat::R16_UNORM>,
160 MortonCopy<false, PixelFormat::R16I>, 179 MortonCopy<false, PixelFormat::R16_SNORM>,
161 MortonCopy<false, PixelFormat::RG16>, 180 MortonCopy<false, PixelFormat::R16_UINT>,
162 MortonCopy<false, PixelFormat::RG16F>, 181 MortonCopy<false, PixelFormat::R16_SINT>,
163 MortonCopy<false, PixelFormat::RG16UI>, 182 MortonCopy<false, PixelFormat::R16G16_UNORM>,
164 MortonCopy<false, PixelFormat::RG16I>, 183 MortonCopy<false, PixelFormat::R16G16_FLOAT>,
165 MortonCopy<false, PixelFormat::RG16S>, 184 MortonCopy<false, PixelFormat::R16G16_UINT>,
166 MortonCopy<false, PixelFormat::RGB32F>, 185 MortonCopy<false, PixelFormat::R16G16_SINT>,
167 MortonCopy<false, PixelFormat::RGBA8_SRGB>, 186 MortonCopy<false, PixelFormat::R16G16_SNORM>,
168 MortonCopy<false, PixelFormat::RG8U>, 187 MortonCopy<false, PixelFormat::R32G32B32_FLOAT>,
169 MortonCopy<false, PixelFormat::RG8S>, 188 MortonCopy<false, PixelFormat::A8B8G8R8_SRGB>,
170 MortonCopy<false, PixelFormat::RG8UI>, 189 MortonCopy<false, PixelFormat::R8G8_UNORM>,
171 MortonCopy<false, PixelFormat::RG32UI>, 190 MortonCopy<false, PixelFormat::R8G8_SNORM>,
172 MortonCopy<false, PixelFormat::RGBX16F>, 191 MortonCopy<false, PixelFormat::R8G8_SINT>,
173 MortonCopy<false, PixelFormat::R32UI>, 192 MortonCopy<false, PixelFormat::R8G8_UINT>,
174 MortonCopy<false, PixelFormat::R32I>, 193 MortonCopy<false, PixelFormat::R32G32_UINT>,
194 MortonCopy<false, PixelFormat::R16G16B16X16_FLOAT>,
195 MortonCopy<false, PixelFormat::R32_UINT>,
196 MortonCopy<false, PixelFormat::R32_SINT>,
175 nullptr, 197 nullptr,
176 nullptr, 198 nullptr,
177 nullptr, 199 nullptr,
178 MortonCopy<false, PixelFormat::BGRA8_SRGB>, 200 MortonCopy<false, PixelFormat::B8G8R8A8_SRGB>,
179 MortonCopy<false, PixelFormat::DXT1_SRGB>, 201 MortonCopy<false, PixelFormat::BC1_RGBA_SRGB>,
180 MortonCopy<false, PixelFormat::DXT23_SRGB>, 202 MortonCopy<false, PixelFormat::BC2_SRGB>,
181 MortonCopy<false, PixelFormat::DXT45_SRGB>, 203 MortonCopy<false, PixelFormat::BC3_SRGB>,
182 MortonCopy<false, PixelFormat::BC7U_SRGB>, 204 MortonCopy<false, PixelFormat::BC7_SRGB>,
183 MortonCopy<false, PixelFormat::R4G4B4A4U>, 205 MortonCopy<false, PixelFormat::A4B4G4R4_UNORM>,
184 nullptr, 206 nullptr,
185 nullptr, 207 nullptr,
186 nullptr, 208 nullptr,
@@ -199,12 +221,12 @@ static constexpr ConversionArray linear_to_morton_fns = {
199 nullptr, 221 nullptr,
200 nullptr, 222 nullptr,
201 nullptr, 223 nullptr,
202 MortonCopy<false, PixelFormat::E5B9G9R9F>, 224 MortonCopy<false, PixelFormat::E5B9G9R9_FLOAT>,
203 MortonCopy<false, PixelFormat::Z32F>, 225 MortonCopy<false, PixelFormat::D32_FLOAT>,
204 MortonCopy<false, PixelFormat::Z16>, 226 MortonCopy<false, PixelFormat::D16_UNORM>,
205 MortonCopy<false, PixelFormat::Z24S8>, 227 MortonCopy<false, PixelFormat::D24_UNORM_S8_UINT>,
206 MortonCopy<false, PixelFormat::S8Z24>, 228 MortonCopy<false, PixelFormat::S8_UINT_D24_UNORM>,
207 MortonCopy<false, PixelFormat::Z32FS8>, 229 MortonCopy<false, PixelFormat::D32_FLOAT_S8_UINT>,
208}; 230};
209 231
210static MortonCopyFn GetSwizzleFunction(MortonSwizzleMode mode, Surface::PixelFormat format) { 232static MortonCopyFn GetSwizzleFunction(MortonSwizzleMode mode, Surface::PixelFormat format) {
diff --git a/src/video_core/renderer_opengl/gl_arb_decompiler.cpp b/src/video_core/renderer_opengl/gl_arb_decompiler.cpp
index eb5158407..b7e9ed2e9 100644
--- a/src/video_core/renderer_opengl/gl_arb_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_arb_decompiler.cpp
@@ -185,10 +185,6 @@ std::string TextureType(const MetaTexture& meta) {
185 return type; 185 return type;
186} 186}
187 187
188std::string GlobalMemoryName(const GlobalMemoryBase& base) {
189 return fmt::format("gmem{}_{}", base.cbuf_index, base.cbuf_offset);
190}
191
192class ARBDecompiler final { 188class ARBDecompiler final {
193public: 189public:
194 explicit ARBDecompiler(const Device& device, const ShaderIR& ir, const Registry& registry, 190 explicit ARBDecompiler(const Device& device, const ShaderIR& ir, const Registry& registry,
@@ -199,6 +195,8 @@ public:
199 } 195 }
200 196
201private: 197private:
198 void DefineGlobalMemory();
199
202 void DeclareHeader(); 200 void DeclareHeader();
203 void DeclareVertex(); 201 void DeclareVertex();
204 void DeclareGeometry(); 202 void DeclareGeometry();
@@ -228,6 +226,7 @@ private:
228 226
229 std::pair<std::string, std::size_t> BuildCoords(Operation); 227 std::pair<std::string, std::size_t> BuildCoords(Operation);
230 std::string BuildAoffi(Operation); 228 std::string BuildAoffi(Operation);
229 std::string GlobalMemoryPointer(const GmemNode& gmem);
231 void Exit(); 230 void Exit();
232 231
233 std::string Assign(Operation); 232 std::string Assign(Operation);
@@ -378,10 +377,8 @@ private:
378 std::string address; 377 std::string address;
379 std::string_view opname; 378 std::string_view opname;
380 if (const auto gmem = std::get_if<GmemNode>(&*operation[0])) { 379 if (const auto gmem = std::get_if<GmemNode>(&*operation[0])) {
381 AddLine("SUB.U {}, {}, {};", temporary, Visit(gmem->GetRealAddress()), 380 address = GlobalMemoryPointer(*gmem);
382 Visit(gmem->GetBaseAddress())); 381 opname = "ATOM";
383 address = fmt::format("{}[{}]", GlobalMemoryName(gmem->GetDescriptor()), temporary);
384 opname = "ATOMB";
385 } else if (const auto smem = std::get_if<SmemNode>(&*operation[0])) { 382 } else if (const auto smem = std::get_if<SmemNode>(&*operation[0])) {
386 address = fmt::format("shared_mem[{}]", Visit(smem->GetAddress())); 383 address = fmt::format("shared_mem[{}]", Visit(smem->GetAddress()));
387 opname = "ATOMS"; 384 opname = "ATOMS";
@@ -456,9 +453,13 @@ private:
456 shader_source += '\n'; 453 shader_source += '\n';
457 } 454 }
458 455
459 std::string AllocTemporary() { 456 std::string AllocLongVectorTemporary() {
460 max_temporaries = std::max(max_temporaries, num_temporaries + 1); 457 max_long_temporaries = std::max(max_long_temporaries, num_long_temporaries + 1);
461 return fmt::format("T{}.x", num_temporaries++); 458 return fmt::format("L{}", num_long_temporaries++);
459 }
460
461 std::string AllocLongTemporary() {
462 return fmt::format("{}.x", AllocLongVectorTemporary());
462 } 463 }
463 464
464 std::string AllocVectorTemporary() { 465 std::string AllocVectorTemporary() {
@@ -466,8 +467,13 @@ private:
466 return fmt::format("T{}", num_temporaries++); 467 return fmt::format("T{}", num_temporaries++);
467 } 468 }
468 469
470 std::string AllocTemporary() {
471 return fmt::format("{}.x", AllocVectorTemporary());
472 }
473
469 void ResetTemporaries() noexcept { 474 void ResetTemporaries() noexcept {
470 num_temporaries = 0; 475 num_temporaries = 0;
476 num_long_temporaries = 0;
471 } 477 }
472 478
473 const Device& device; 479 const Device& device;
@@ -478,6 +484,11 @@ private:
478 std::size_t num_temporaries = 0; 484 std::size_t num_temporaries = 0;
479 std::size_t max_temporaries = 0; 485 std::size_t max_temporaries = 0;
480 486
487 std::size_t num_long_temporaries = 0;
488 std::size_t max_long_temporaries = 0;
489
490 std::map<GlobalMemoryBase, u32> global_memory_names;
491
481 std::string shader_source; 492 std::string shader_source;
482 493
483 static constexpr std::string_view ADD_F32 = "ADD.F32"; 494 static constexpr std::string_view ADD_F32 = "ADD.F32";
@@ -784,6 +795,8 @@ private:
784ARBDecompiler::ARBDecompiler(const Device& device, const ShaderIR& ir, const Registry& registry, 795ARBDecompiler::ARBDecompiler(const Device& device, const ShaderIR& ir, const Registry& registry,
785 ShaderType stage, std::string_view identifier) 796 ShaderType stage, std::string_view identifier)
786 : device{device}, ir{ir}, registry{registry}, stage{stage} { 797 : device{device}, ir{ir}, registry{registry}, stage{stage} {
798 DefineGlobalMemory();
799
787 AddLine("TEMP RC;"); 800 AddLine("TEMP RC;");
788 AddLine("TEMP FSWZA[4];"); 801 AddLine("TEMP FSWZA[4];");
789 AddLine("TEMP FSWZB[4];"); 802 AddLine("TEMP FSWZB[4];");
@@ -829,12 +842,20 @@ std::string_view HeaderStageName(ShaderType stage) {
829 } 842 }
830} 843}
831 844
845void ARBDecompiler::DefineGlobalMemory() {
846 u32 binding = 0;
847 for (const auto& pair : ir.GetGlobalMemory()) {
848 const GlobalMemoryBase base = pair.first;
849 global_memory_names.emplace(base, binding);
850 ++binding;
851 }
852}
853
832void ARBDecompiler::DeclareHeader() { 854void ARBDecompiler::DeclareHeader() {
833 AddLine("!!NV{}5.0", HeaderStageName(stage)); 855 AddLine("!!NV{}5.0", HeaderStageName(stage));
834 // Enabling this allows us to cheat on some instructions like TXL with SHADOWARRAY2D 856 // Enabling this allows us to cheat on some instructions like TXL with SHADOWARRAY2D
835 AddLine("OPTION NV_internal;"); 857 AddLine("OPTION NV_internal;");
836 AddLine("OPTION NV_gpu_program_fp64;"); 858 AddLine("OPTION NV_gpu_program_fp64;");
837 AddLine("OPTION NV_shader_storage_buffer;");
838 AddLine("OPTION NV_shader_thread_group;"); 859 AddLine("OPTION NV_shader_thread_group;");
839 if (ir.UsesWarps() && device.HasWarpIntrinsics()) { 860 if (ir.UsesWarps() && device.HasWarpIntrinsics()) {
840 AddLine("OPTION NV_shader_thread_shuffle;"); 861 AddLine("OPTION NV_shader_thread_shuffle;");
@@ -892,11 +913,19 @@ void ARBDecompiler::DeclareCompute() {
892 const ComputeInfo& info = registry.GetComputeInfo(); 913 const ComputeInfo& info = registry.GetComputeInfo();
893 AddLine("GROUP_SIZE {} {} {};", info.workgroup_size[0], info.workgroup_size[1], 914 AddLine("GROUP_SIZE {} {} {};", info.workgroup_size[0], info.workgroup_size[1],
894 info.workgroup_size[2]); 915 info.workgroup_size[2]);
895 if (info.shared_memory_size_in_words > 0) { 916 if (info.shared_memory_size_in_words == 0) {
896 const u32 size_in_bytes = info.shared_memory_size_in_words * 4; 917 return;
897 AddLine("SHARED_MEMORY {};", size_in_bytes); 918 }
898 AddLine("SHARED shared_mem[] = {{program.sharedmem}};"); 919 const u32 limit = device.GetMaxComputeSharedMemorySize();
920 u32 size_in_bytes = info.shared_memory_size_in_words * 4;
921 if (size_in_bytes > limit) {
922 LOG_ERROR(Render_OpenGL, "Shared memory size {} is clamped to host's limit {}",
923 size_in_bytes, limit);
924 size_in_bytes = limit;
899 } 925 }
926
927 AddLine("SHARED_MEMORY {};", size_in_bytes);
928 AddLine("SHARED shared_mem[] = {{program.sharedmem}};");
900} 929}
901 930
902void ARBDecompiler::DeclareInputAttributes() { 931void ARBDecompiler::DeclareInputAttributes() {
@@ -951,11 +980,10 @@ void ARBDecompiler::DeclareLocalMemory() {
951} 980}
952 981
953void ARBDecompiler::DeclareGlobalMemory() { 982void ARBDecompiler::DeclareGlobalMemory() {
954 u32 binding = 0; // device.GetBaseBindings(stage).shader_storage_buffer; 983 const std::size_t num_entries = ir.GetGlobalMemory().size();
955 for (const auto& pair : ir.GetGlobalMemory()) { 984 if (num_entries > 0) {
956 const auto& base = pair.first; 985 const std::size_t num_vectors = Common::AlignUp(num_entries, 2) / 2;
957 AddLine("STORAGE {}[] = {{ program.storage[{}] }};", GlobalMemoryName(base), binding); 986 AddLine("PARAM c[{}] = {{ program.local[0..{}] }};", num_vectors, num_vectors - 1);
958 ++binding;
959 } 987 }
960} 988}
961 989
@@ -977,6 +1005,9 @@ void ARBDecompiler::DeclareTemporaries() {
977 for (std::size_t i = 0; i < max_temporaries; ++i) { 1005 for (std::size_t i = 0; i < max_temporaries; ++i) {
978 AddLine("TEMP T{};", i); 1006 AddLine("TEMP T{};", i);
979 } 1007 }
1008 for (std::size_t i = 0; i < max_long_temporaries; ++i) {
1009 AddLine("LONG TEMP L{};", i);
1010 }
980} 1011}
981 1012
982void ARBDecompiler::DeclarePredicates() { 1013void ARBDecompiler::DeclarePredicates() {
@@ -1260,13 +1291,6 @@ std::string ARBDecompiler::Visit(const Node& node) {
1260 return "{0, 0, 0, 0}.x"; 1291 return "{0, 0, 0, 0}.x";
1261 } 1292 }
1262 1293
1263 const auto buffer_index = [this, &abuf]() -> std::string {
1264 if (stage != ShaderType::Geometry) {
1265 return "";
1266 }
1267 return fmt::format("[{}]", Visit(abuf->GetBuffer()));
1268 };
1269
1270 const Attribute::Index index = abuf->GetIndex(); 1294 const Attribute::Index index = abuf->GetIndex();
1271 const u32 element = abuf->GetElement(); 1295 const u32 element = abuf->GetElement();
1272 const char swizzle = Swizzle(element); 1296 const char swizzle = Swizzle(element);
@@ -1339,10 +1363,7 @@ std::string ARBDecompiler::Visit(const Node& node) {
1339 1363
1340 if (const auto gmem = std::get_if<GmemNode>(&*node)) { 1364 if (const auto gmem = std::get_if<GmemNode>(&*node)) {
1341 std::string temporary = AllocTemporary(); 1365 std::string temporary = AllocTemporary();
1342 AddLine("SUB.U {}, {}, {};", temporary, Visit(gmem->GetRealAddress()), 1366 AddLine("LOAD.U32 {}, {};", temporary, GlobalMemoryPointer(*gmem));
1343 Visit(gmem->GetBaseAddress()));
1344 AddLine("LDB.U32 {}, {}[{}];", temporary, GlobalMemoryName(gmem->GetDescriptor()),
1345 temporary);
1346 return temporary; 1367 return temporary;
1347 } 1368 }
1348 1369
@@ -1375,7 +1396,7 @@ std::string ARBDecompiler::Visit(const Node& node) {
1375 return {}; 1396 return {};
1376 } 1397 }
1377 1398
1378 if (const auto cmt = std::get_if<CommentNode>(&*node)) { 1399 if ([[maybe_unused]] const auto cmt = std::get_if<CommentNode>(&*node)) {
1379 // Uncommenting this will generate invalid code. GLASM lacks comments. 1400 // Uncommenting this will generate invalid code. GLASM lacks comments.
1380 // AddLine("// {}", cmt->GetText()); 1401 // AddLine("// {}", cmt->GetText());
1381 return {}; 1402 return {};
@@ -1419,6 +1440,22 @@ std::string ARBDecompiler::BuildAoffi(Operation operation) {
1419 return fmt::format(", offset({})", temporary); 1440 return fmt::format(", offset({})", temporary);
1420} 1441}
1421 1442
1443std::string ARBDecompiler::GlobalMemoryPointer(const GmemNode& gmem) {
1444 const u32 binding = global_memory_names.at(gmem.GetDescriptor());
1445 const char result_swizzle = binding % 2 == 0 ? 'x' : 'y';
1446
1447 const std::string pointer = AllocLongVectorTemporary();
1448 std::string temporary = AllocTemporary();
1449
1450 const u32 local_index = binding / 2;
1451 AddLine("PK64.U {}, c[{}];", pointer, local_index);
1452 AddLine("SUB.U {}, {}, {};", temporary, Visit(gmem.GetRealAddress()),
1453 Visit(gmem.GetBaseAddress()));
1454 AddLine("CVT.U64.U32 {}.z, {};", pointer, temporary);
1455 AddLine("ADD.U64 {}.x, {}.{}, {}.z;", pointer, pointer, result_swizzle, pointer);
1456 return fmt::format("{}.x", pointer);
1457}
1458
1422void ARBDecompiler::Exit() { 1459void ARBDecompiler::Exit() {
1423 if (stage != ShaderType::Fragment) { 1460 if (stage != ShaderType::Fragment) {
1424 AddLine("RET;"); 1461 AddLine("RET;");
@@ -1515,11 +1552,7 @@ std::string ARBDecompiler::Assign(Operation operation) {
1515 ResetTemporaries(); 1552 ResetTemporaries();
1516 return {}; 1553 return {};
1517 } else if (const auto gmem = std::get_if<GmemNode>(&*dest)) { 1554 } else if (const auto gmem = std::get_if<GmemNode>(&*dest)) {
1518 const std::string temporary = AllocTemporary(); 1555 AddLine("STORE.U32 {}, {};", Visit(src), GlobalMemoryPointer(*gmem));
1519 AddLine("SUB.U {}, {}, {};", temporary, Visit(gmem->GetRealAddress()),
1520 Visit(gmem->GetBaseAddress()));
1521 AddLine("STB.U32 {}, {}[{}];", Visit(src), GlobalMemoryName(gmem->GetDescriptor()),
1522 temporary);
1523 ResetTemporaries(); 1556 ResetTemporaries();
1524 return {}; 1557 return {};
1525 } else { 1558 } else {
@@ -1671,7 +1704,7 @@ std::string ARBDecompiler::HCastFloat(Operation operation) {
1671} 1704}
1672 1705
1673std::string ARBDecompiler::HUnpack(Operation operation) { 1706std::string ARBDecompiler::HUnpack(Operation operation) {
1674 const std::string operand = Visit(operation[0]); 1707 std::string operand = Visit(operation[0]);
1675 switch (std::get<Tegra::Shader::HalfType>(operation.GetMeta())) { 1708 switch (std::get<Tegra::Shader::HalfType>(operation.GetMeta())) {
1676 case Tegra::Shader::HalfType::H0_H1: 1709 case Tegra::Shader::HalfType::H0_H1:
1677 return operand; 1710 return operand;
@@ -2021,7 +2054,7 @@ std::string ARBDecompiler::InvocationId(Operation) {
2021 2054
2022std::string ARBDecompiler::YNegate(Operation) { 2055std::string ARBDecompiler::YNegate(Operation) {
2023 LOG_WARNING(Render_OpenGL, "(STUBBED)"); 2056 LOG_WARNING(Render_OpenGL, "(STUBBED)");
2024 const std::string temporary = AllocTemporary(); 2057 std::string temporary = AllocTemporary();
2025 AddLine("MOV.F {}, 1;", temporary); 2058 AddLine("MOV.F {}, 1;", temporary);
2026 return temporary; 2059 return temporary;
2027} 2060}
@@ -2044,10 +2077,6 @@ std::string ARBDecompiler::ShuffleIndexed(Operation operation) {
2044} 2077}
2045 2078
2046std::string ARBDecompiler::Barrier(Operation) { 2079std::string ARBDecompiler::Barrier(Operation) {
2047 if (!ir.IsDecompiled()) {
2048 LOG_ERROR(Render_OpenGL, "BAR used but shader is not decompiled");
2049 return {};
2050 }
2051 AddLine("BAR;"); 2080 AddLine("BAR;");
2052 return {}; 2081 return {};
2053} 2082}
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index e461e4c70..e866d8f2f 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -26,7 +26,7 @@ Buffer::Buffer(const Device& device, VAddr cpu_addr, std::size_t size)
26 : VideoCommon::BufferBlock{cpu_addr, size} { 26 : VideoCommon::BufferBlock{cpu_addr, size} {
27 gl_buffer.Create(); 27 gl_buffer.Create();
28 glNamedBufferData(gl_buffer.handle, static_cast<GLsizeiptr>(size), nullptr, GL_DYNAMIC_DRAW); 28 glNamedBufferData(gl_buffer.handle, static_cast<GLsizeiptr>(size), nullptr, GL_DYNAMIC_DRAW);
29 if (device.HasVertexBufferUnifiedMemory()) { 29 if (device.UseAssemblyShaders() || device.HasVertexBufferUnifiedMemory()) {
30 glMakeNamedBufferResidentNV(gl_buffer.handle, GL_READ_WRITE); 30 glMakeNamedBufferResidentNV(gl_buffer.handle, GL_READ_WRITE);
31 glGetNamedBufferParameterui64vNV(gl_buffer.handle, GL_BUFFER_GPU_ADDRESS_NV, &gpu_address); 31 glGetNamedBufferParameterui64vNV(gl_buffer.handle, GL_BUFFER_GPU_ADDRESS_NV, &gpu_address);
32 } 32 }
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index 630acb73b..e7d95149f 100644
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -212,6 +212,7 @@ Device::Device()
212 shader_storage_alignment = GetInteger<std::size_t>(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT); 212 shader_storage_alignment = GetInteger<std::size_t>(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT);
213 max_vertex_attributes = GetInteger<u32>(GL_MAX_VERTEX_ATTRIBS); 213 max_vertex_attributes = GetInteger<u32>(GL_MAX_VERTEX_ATTRIBS);
214 max_varyings = GetInteger<u32>(GL_MAX_VARYING_VECTORS); 214 max_varyings = GetInteger<u32>(GL_MAX_VARYING_VECTORS);
215 max_compute_shared_memory_size = GetInteger<u32>(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE);
215 has_warp_intrinsics = GLAD_GL_NV_gpu_shader5 && GLAD_GL_NV_shader_thread_group && 216 has_warp_intrinsics = GLAD_GL_NV_gpu_shader5 && GLAD_GL_NV_shader_thread_group &&
216 GLAD_GL_NV_shader_thread_shuffle; 217 GLAD_GL_NV_shader_thread_shuffle;
217 has_shader_ballot = GLAD_GL_ARB_shader_ballot; 218 has_shader_ballot = GLAD_GL_ARB_shader_ballot;
@@ -250,6 +251,7 @@ Device::Device(std::nullptr_t) {
250 shader_storage_alignment = 4; 251 shader_storage_alignment = 4;
251 max_vertex_attributes = 16; 252 max_vertex_attributes = 16;
252 max_varyings = 15; 253 max_varyings = 15;
254 max_compute_shared_memory_size = 0x10000;
253 has_warp_intrinsics = true; 255 has_warp_intrinsics = true;
254 has_shader_ballot = true; 256 has_shader_ballot = true;
255 has_vertex_viewport_layer = true; 257 has_vertex_viewport_layer = true;
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h
index 94d38d7d1..8a4b6b9fc 100644
--- a/src/video_core/renderer_opengl/gl_device.h
+++ b/src/video_core/renderer_opengl/gl_device.h
@@ -52,6 +52,10 @@ public:
52 return max_varyings; 52 return max_varyings;
53 } 53 }
54 54
55 u32 GetMaxComputeSharedMemorySize() const {
56 return max_compute_shared_memory_size;
57 }
58
55 bool HasWarpIntrinsics() const { 59 bool HasWarpIntrinsics() const {
56 return has_warp_intrinsics; 60 return has_warp_intrinsics;
57 } 61 }
@@ -118,6 +122,7 @@ private:
118 std::size_t shader_storage_alignment{}; 122 std::size_t shader_storage_alignment{};
119 u32 max_vertex_attributes{}; 123 u32 max_vertex_attributes{};
120 u32 max_varyings{}; 124 u32 max_varyings{};
125 u32 max_compute_shared_memory_size{};
121 bool has_warp_intrinsics{}; 126 bool has_warp_intrinsics{};
122 bool has_shader_ballot{}; 127 bool has_shader_ballot{};
123 bool has_vertex_viewport_layer{}; 128 bool has_vertex_viewport_layer{};
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index c3fad563c..03e82c599 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -139,6 +139,18 @@ void oglEnable(GLenum cap, bool state) {
139 (state ? glEnable : glDisable)(cap); 139 (state ? glEnable : glDisable)(cap);
140} 140}
141 141
142void UpdateBindlessPointers(GLenum target, GLuint64EXT* pointers, std::size_t num_entries) {
143 if (num_entries == 0) {
144 return;
145 }
146 if (num_entries % 2 == 1) {
147 pointers[num_entries] = 0;
148 }
149 const GLsizei num_vectors = static_cast<GLsizei>((num_entries + 1) / 2);
150 glProgramLocalParametersI4uivNV(target, 0, num_vectors,
151 reinterpret_cast<const GLuint*>(pointers));
152}
153
142} // Anonymous namespace 154} // Anonymous namespace
143 155
144RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, 156RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
@@ -324,7 +336,6 @@ GLintptr RasterizerOpenGL::SetupIndexBuffer() {
324void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { 336void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
325 MICROPROFILE_SCOPE(OpenGL_Shader); 337 MICROPROFILE_SCOPE(OpenGL_Shader);
326 auto& gpu = system.GPU().Maxwell3D(); 338 auto& gpu = system.GPU().Maxwell3D();
327 std::size_t num_ssbos = 0;
328 u32 clip_distances = 0; 339 u32 clip_distances = 0;
329 340
330 for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { 341 for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
@@ -347,29 +358,13 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
347 } 358 }
348 359
349 // Currently this stages are not supported in the OpenGL backend. 360 // Currently this stages are not supported in the OpenGL backend.
350 // Todo(Blinkhawk): Port tesselation shaders from Vulkan to OpenGL 361 // TODO(Blinkhawk): Port tesselation shaders from Vulkan to OpenGL
351 if (program == Maxwell::ShaderProgram::TesselationControl) { 362 if (program == Maxwell::ShaderProgram::TesselationControl ||
363 program == Maxwell::ShaderProgram::TesselationEval) {
352 continue; 364 continue;
353 } else if (program == Maxwell::ShaderProgram::TesselationEval) {
354 continue;
355 }
356
357 Shader* shader = shader_cache.GetStageProgram(program, async_shaders);
358
359 if (device.UseAssemblyShaders()) {
360 // Check for ARB limitation. We only have 16 SSBOs per context state. To workaround this
361 // all stages share the same bindings.
362 const std::size_t num_stage_ssbos = shader->GetEntries().global_memory_entries.size();
363 ASSERT_MSG(num_stage_ssbos == 0 || num_ssbos == 0, "SSBOs on more than one stage");
364 num_ssbos += num_stage_ssbos;
365 } 365 }
366 366
367 // Stage indices are 0 - 5 367 Shader* const shader = shader_cache.GetStageProgram(program, async_shaders);
368 const std::size_t stage = index == 0 ? 0 : index - 1;
369 SetupDrawConstBuffers(stage, shader);
370 SetupDrawGlobalMemory(stage, shader);
371 SetupDrawTextures(stage, shader);
372 SetupDrawImages(stage, shader);
373 368
374 const GLuint program_handle = shader->IsBuilt() ? shader->GetHandle() : 0; 369 const GLuint program_handle = shader->IsBuilt() ? shader->GetHandle() : 0;
375 switch (program) { 370 switch (program) {
@@ -388,6 +383,13 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
388 shader_config.enable.Value(), shader_config.offset); 383 shader_config.enable.Value(), shader_config.offset);
389 } 384 }
390 385
386 // Stage indices are 0 - 5
387 const std::size_t stage = index == 0 ? 0 : index - 1;
388 SetupDrawConstBuffers(stage, shader);
389 SetupDrawGlobalMemory(stage, shader);
390 SetupDrawTextures(stage, shader);
391 SetupDrawImages(stage, shader);
392
391 // Workaround for Intel drivers. 393 // Workaround for Intel drivers.
392 // When a clip distance is enabled but not set in the shader it crops parts of the screen 394 // When a clip distance is enabled but not set in the shader it crops parts of the screen
393 // (sometimes it's half the screen, sometimes three quarters). To avoid this, enable the 395 // (sometimes it's half the screen, sometimes three quarters). To avoid this, enable the
@@ -749,6 +751,8 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
749 current_cbuf = 0; 751 current_cbuf = 0;
750 752
751 auto kernel = shader_cache.GetComputeKernel(code_addr); 753 auto kernel = shader_cache.GetComputeKernel(code_addr);
754 program_manager.BindCompute(kernel->GetHandle());
755
752 SetupComputeTextures(kernel); 756 SetupComputeTextures(kernel);
753 SetupComputeImages(kernel); 757 SetupComputeImages(kernel);
754 758
@@ -763,7 +767,6 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
763 buffer_cache.Unmap(); 767 buffer_cache.Unmap();
764 768
765 const auto& launch_desc = system.GPU().KeplerCompute().launch_description; 769 const auto& launch_desc = system.GPU().KeplerCompute().launch_description;
766 program_manager.BindCompute(kernel->GetHandle());
767 glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z); 770 glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z);
768 ++num_queued_commands; 771 ++num_queued_commands;
769} 772}
@@ -1023,40 +1026,66 @@ void RasterizerOpenGL::SetupConstBuffer(GLenum stage, u32 binding,
1023} 1026}
1024 1027
1025void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* shader) { 1028void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* shader) {
1029 static constexpr std::array TARGET_LUT = {
1030 GL_VERTEX_PROGRAM_NV, GL_TESS_CONTROL_PROGRAM_NV, GL_TESS_EVALUATION_PROGRAM_NV,
1031 GL_GEOMETRY_PROGRAM_NV, GL_FRAGMENT_PROGRAM_NV,
1032 };
1033
1026 auto& gpu{system.GPU()}; 1034 auto& gpu{system.GPU()};
1027 auto& memory_manager{gpu.MemoryManager()}; 1035 auto& memory_manager{gpu.MemoryManager()};
1028 const auto cbufs{gpu.Maxwell3D().state.shader_stages[stage_index]}; 1036 const auto& cbufs{gpu.Maxwell3D().state.shader_stages[stage_index]};
1037 const auto& entries{shader->GetEntries().global_memory_entries};
1038
1039 std::array<GLuint64EXT, 32> pointers;
1040 ASSERT(entries.size() < pointers.size());
1029 1041
1030 u32 binding = 1042 const bool assembly_shaders = device.UseAssemblyShaders();
1031 device.UseAssemblyShaders() ? 0 : device.GetBaseBindings(stage_index).shader_storage_buffer; 1043 u32 binding = assembly_shaders ? 0 : device.GetBaseBindings(stage_index).shader_storage_buffer;
1032 for (const auto& entry : shader->GetEntries().global_memory_entries) { 1044 for (const auto& entry : entries) {
1033 const GPUVAddr addr{cbufs.const_buffers[entry.cbuf_index].address + entry.cbuf_offset}; 1045 const GPUVAddr addr{cbufs.const_buffers[entry.cbuf_index].address + entry.cbuf_offset};
1034 const GPUVAddr gpu_addr{memory_manager.Read<u64>(addr)}; 1046 const GPUVAddr gpu_addr{memory_manager.Read<u64>(addr)};
1035 const u32 size{memory_manager.Read<u32>(addr + 8)}; 1047 const u32 size{memory_manager.Read<u32>(addr + 8)};
1036 SetupGlobalMemory(binding++, entry, gpu_addr, size); 1048 SetupGlobalMemory(binding, entry, gpu_addr, size, &pointers[binding]);
1049 ++binding;
1050 }
1051 if (assembly_shaders) {
1052 UpdateBindlessPointers(TARGET_LUT[stage_index], pointers.data(), entries.size());
1037 } 1053 }
1038} 1054}
1039 1055
1040void RasterizerOpenGL::SetupComputeGlobalMemory(Shader* kernel) { 1056void RasterizerOpenGL::SetupComputeGlobalMemory(Shader* kernel) {
1041 auto& gpu{system.GPU()}; 1057 auto& gpu{system.GPU()};
1042 auto& memory_manager{gpu.MemoryManager()}; 1058 auto& memory_manager{gpu.MemoryManager()};
1043 const auto cbufs{gpu.KeplerCompute().launch_description.const_buffer_config}; 1059 const auto& cbufs{gpu.KeplerCompute().launch_description.const_buffer_config};
1060 const auto& entries{kernel->GetEntries().global_memory_entries};
1061
1062 std::array<GLuint64EXT, 32> pointers;
1063 ASSERT(entries.size() < pointers.size());
1044 1064
1045 u32 binding = 0; 1065 u32 binding = 0;
1046 for (const auto& entry : kernel->GetEntries().global_memory_entries) { 1066 for (const auto& entry : entries) {
1047 const auto addr{cbufs[entry.cbuf_index].Address() + entry.cbuf_offset}; 1067 const GPUVAddr addr{cbufs[entry.cbuf_index].Address() + entry.cbuf_offset};
1048 const auto gpu_addr{memory_manager.Read<u64>(addr)}; 1068 const GPUVAddr gpu_addr{memory_manager.Read<u64>(addr)};
1049 const auto size{memory_manager.Read<u32>(addr + 8)}; 1069 const u32 size{memory_manager.Read<u32>(addr + 8)};
1050 SetupGlobalMemory(binding++, entry, gpu_addr, size); 1070 SetupGlobalMemory(binding, entry, gpu_addr, size, &pointers[binding]);
1071 ++binding;
1072 }
1073 if (device.UseAssemblyShaders()) {
1074 UpdateBindlessPointers(GL_COMPUTE_PROGRAM_NV, pointers.data(), entries.size());
1051 } 1075 }
1052} 1076}
1053 1077
1054void RasterizerOpenGL::SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& entry, 1078void RasterizerOpenGL::SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& entry,
1055 GPUVAddr gpu_addr, std::size_t size) { 1079 GPUVAddr gpu_addr, std::size_t size,
1056 const auto alignment{device.GetShaderStorageBufferAlignment()}; 1080 GLuint64EXT* pointer) {
1081 const std::size_t alignment{device.GetShaderStorageBufferAlignment()};
1057 const auto info = buffer_cache.UploadMemory(gpu_addr, size, alignment, entry.is_written); 1082 const auto info = buffer_cache.UploadMemory(gpu_addr, size, alignment, entry.is_written);
1058 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, binding, info.handle, info.offset, 1083 if (device.UseAssemblyShaders()) {
1059 static_cast<GLsizeiptr>(size)); 1084 *pointer = info.address + info.offset;
1085 } else {
1086 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, binding, info.handle, info.offset,
1087 static_cast<GLsizeiptr>(size));
1088 }
1060} 1089}
1061 1090
1062void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, Shader* shader) { 1091void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, Shader* shader) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index a95646936..ccc6f50f6 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -124,9 +124,9 @@ private:
124 /// Configures the current global memory entries to use for the kernel invocation. 124 /// Configures the current global memory entries to use for the kernel invocation.
125 void SetupComputeGlobalMemory(Shader* kernel); 125 void SetupComputeGlobalMemory(Shader* kernel);
126 126
127 /// Configures a constant buffer. 127 /// Configures a global memory buffer.
128 void SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& entry, GPUVAddr gpu_addr, 128 void SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& entry, GPUVAddr gpu_addr,
129 std::size_t size); 129 std::size_t size, GLuint64EXT* pointer);
130 130
131 /// Configures the current textures to use for the draw command. 131 /// Configures the current textures to use for the draw command.
132 void SetupDrawTextures(std::size_t stage_index, Shader* shader); 132 void SetupDrawTextures(std::size_t stage_index, Shader* shader);
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index f469ed656..be71e1733 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -126,7 +126,7 @@ std::shared_ptr<Registry> MakeRegistry(const ShaderDiskCacheEntry& entry) {
126 const VideoCore::GuestDriverProfile guest_profile{entry.texture_handler_size}; 126 const VideoCore::GuestDriverProfile guest_profile{entry.texture_handler_size};
127 const VideoCommon::Shader::SerializedRegistryInfo info{guest_profile, entry.bound_buffer, 127 const VideoCommon::Shader::SerializedRegistryInfo info{guest_profile, entry.bound_buffer,
128 entry.graphics_info, entry.compute_info}; 128 entry.graphics_info, entry.compute_info};
129 const auto registry = std::make_shared<Registry>(entry.type, info); 129 auto registry = std::make_shared<Registry>(entry.type, info);
130 for (const auto& [address, value] : entry.keys) { 130 for (const auto& [address, value] : entry.keys) {
131 const auto [buffer, offset] = address; 131 const auto [buffer, offset] = address;
132 registry->InsertKey(buffer, offset, value); 132 registry->InsertKey(buffer, offset, value);
@@ -237,7 +237,6 @@ std::unique_ptr<Shader> Shader::CreateStageFromMemory(
237 const ShaderParameters& params, Maxwell::ShaderProgram program_type, ProgramCode code, 237 const ShaderParameters& params, Maxwell::ShaderProgram program_type, ProgramCode code,
238 ProgramCode code_b, VideoCommon::Shader::AsyncShaders& async_shaders, VAddr cpu_addr) { 238 ProgramCode code_b, VideoCommon::Shader::AsyncShaders& async_shaders, VAddr cpu_addr) {
239 const auto shader_type = GetShaderType(program_type); 239 const auto shader_type = GetShaderType(program_type);
240 const std::size_t size_in_bytes = code.size() * sizeof(u64);
241 240
242 auto& gpu = params.system.GPU(); 241 auto& gpu = params.system.GPU();
243 gpu.ShaderNotify().MarkSharderBuilding(); 242 gpu.ShaderNotify().MarkSharderBuilding();
@@ -287,8 +286,6 @@ std::unique_ptr<Shader> Shader::CreateStageFromMemory(
287 286
288std::unique_ptr<Shader> Shader::CreateKernelFromMemory(const ShaderParameters& params, 287std::unique_ptr<Shader> Shader::CreateKernelFromMemory(const ShaderParameters& params,
289 ProgramCode code) { 288 ProgramCode code) {
290 const std::size_t size_in_bytes = code.size() * sizeof(u64);
291
292 auto& gpu = params.system.GPU(); 289 auto& gpu = params.system.GPU();
293 gpu.ShaderNotify().MarkSharderBuilding(); 290 gpu.ShaderNotify().MarkSharderBuilding();
294 291
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 2c49aeaac..3f75fcd2b 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -602,8 +602,15 @@ private:
602 return; 602 return;
603 } 603 }
604 const auto& info = registry.GetComputeInfo(); 604 const auto& info = registry.GetComputeInfo();
605 if (const u32 size = info.shared_memory_size_in_words; size > 0) { 605 if (u32 size = info.shared_memory_size_in_words * 4; size > 0) {
606 code.AddLine("shared uint smem[{}];", size); 606 const u32 limit = device.GetMaxComputeSharedMemorySize();
607 if (size > limit) {
608 LOG_ERROR(Render_OpenGL, "Shared memory size {} is clamped to host's limit {}",
609 size, limit);
610 size = limit;
611 }
612
613 code.AddLine("shared uint smem[{}];", size / 4);
607 code.AddNewLine(); 614 code.AddNewLine();
608 } 615 }
609 code.AddLine("layout (local_size_x = {}, local_size_y = {}, local_size_z = {}) in;", 616 code.AddLine("layout (local_size_x = {}, local_size_y = {}, local_size_z = {}) in;",
@@ -1912,7 +1919,7 @@ private:
1912 Expression Comparison(Operation operation) { 1919 Expression Comparison(Operation operation) {
1913 static_assert(!unordered || type == Type::Float); 1920 static_assert(!unordered || type == Type::Float);
1914 1921
1915 const Expression expr = GenerateBinaryInfix(operation, op, Type::Bool, type, type); 1922 Expression expr = GenerateBinaryInfix(operation, op, Type::Bool, type, type);
1916 1923
1917 if constexpr (op.compare("!=") == 0 && type == Type::Float && !unordered) { 1924 if constexpr (op.compare("!=") == 0 && type == Type::Float && !unordered) {
1918 // GLSL's operator!=(float, float) doesn't seem be ordered. This happens on both AMD's 1925 // GLSL's operator!=(float, float) doesn't seem be ordered. This happens on both AMD's
@@ -1952,10 +1959,6 @@ private:
1952 return {fmt::format("({} != 0)", carry), Type::Bool}; 1959 return {fmt::format("({} != 0)", carry), Type::Bool};
1953 } 1960 }
1954 1961
1955 Expression LogicalFIsNan(Operation operation) {
1956 return GenerateUnary(operation, "isnan", Type::Bool, Type::Float);
1957 }
1958
1959 Expression LogicalAssign(Operation operation) { 1962 Expression LogicalAssign(Operation operation) {
1960 const Node& dest = operation[0]; 1963 const Node& dest = operation[0];
1961 const Node& src = operation[1]; 1964 const Node& src = operation[1];
@@ -2771,15 +2774,6 @@ private:
2771 return std::min<u32>(device.GetMaxVaryings(), Maxwell::NumVaryings); 2774 return std::min<u32>(device.GetMaxVaryings(), Maxwell::NumVaryings);
2772 } 2775 }
2773 2776
2774 bool IsRenderTargetEnabled(u32 render_target) const {
2775 for (u32 component = 0; component < 4; ++component) {
2776 if (header.ps.IsColorComponentOutputEnabled(render_target, component)) {
2777 return true;
2778 }
2779 }
2780 return false;
2781 }
2782
2783 const Device& device; 2777 const Device& device;
2784 const ShaderIR& ir; 2778 const ShaderIR& ir;
2785 const Registry& registry; 2779 const Registry& registry;
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp
index 8e754fa90..691c6c79b 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp
@@ -11,8 +11,30 @@
11 11
12namespace OpenGL { 12namespace OpenGL {
13 13
14ProgramManager::ProgramManager(const Device& device) { 14namespace {
15 use_assembly_programs = device.UseAssemblyShaders(); 15
16void BindProgram(GLenum stage, GLuint current, GLuint old, bool& enabled) {
17 if (current == old) {
18 return;
19 }
20 if (current == 0) {
21 if (enabled) {
22 enabled = false;
23 glDisable(stage);
24 }
25 return;
26 }
27 if (!enabled) {
28 enabled = true;
29 glEnable(stage);
30 }
31 glBindProgramARB(stage, current);
32}
33
34} // Anonymous namespace
35
36ProgramManager::ProgramManager(const Device& device)
37 : use_assembly_programs{device.UseAssemblyShaders()} {
16 if (use_assembly_programs) { 38 if (use_assembly_programs) {
17 glEnable(GL_COMPUTE_PROGRAM_NV); 39 glEnable(GL_COMPUTE_PROGRAM_NV);
18 } else { 40 } else {
@@ -33,9 +55,7 @@ void ProgramManager::BindCompute(GLuint program) {
33} 55}
34 56
35void ProgramManager::BindGraphicsPipeline() { 57void ProgramManager::BindGraphicsPipeline() {
36 if (use_assembly_programs) { 58 if (!use_assembly_programs) {
37 UpdateAssemblyPrograms();
38 } else {
39 UpdateSourcePrograms(); 59 UpdateSourcePrograms();
40 } 60 }
41} 61}
@@ -63,32 +83,25 @@ void ProgramManager::RestoreGuestPipeline() {
63 } 83 }
64} 84}
65 85
66void ProgramManager::UpdateAssemblyPrograms() { 86void ProgramManager::UseVertexShader(GLuint program) {
67 const auto update_state = [](GLenum stage, bool& enabled, GLuint current, GLuint old) { 87 if (use_assembly_programs) {
68 if (current == old) { 88 BindProgram(GL_VERTEX_PROGRAM_NV, program, current_state.vertex, vertex_enabled);
69 return; 89 }
70 } 90 current_state.vertex = program;
71 if (current == 0) { 91}
72 if (enabled) {
73 enabled = false;
74 glDisable(stage);
75 }
76 return;
77 }
78 if (!enabled) {
79 enabled = true;
80 glEnable(stage);
81 }
82 glBindProgramARB(stage, current);
83 };
84 92
85 update_state(GL_VERTEX_PROGRAM_NV, vertex_enabled, current_state.vertex, old_state.vertex); 93void ProgramManager::UseGeometryShader(GLuint program) {
86 update_state(GL_GEOMETRY_PROGRAM_NV, geometry_enabled, current_state.geometry, 94 if (use_assembly_programs) {
87 old_state.geometry); 95 BindProgram(GL_GEOMETRY_PROGRAM_NV, program, current_state.vertex, geometry_enabled);
88 update_state(GL_FRAGMENT_PROGRAM_NV, fragment_enabled, current_state.fragment, 96 }
89 old_state.fragment); 97 current_state.geometry = program;
98}
90 99
91 old_state = current_state; 100void ProgramManager::UseFragmentShader(GLuint program) {
101 if (use_assembly_programs) {
102 BindProgram(GL_FRAGMENT_PROGRAM_NV, program, current_state.vertex, fragment_enabled);
103 }
104 current_state.fragment = program;
92} 105}
93 106
94void ProgramManager::UpdateSourcePrograms() { 107void ProgramManager::UpdateSourcePrograms() {
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h
index 0f03b4f12..950e0dfcb 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.h
+++ b/src/video_core/renderer_opengl/gl_shader_manager.h
@@ -45,17 +45,9 @@ public:
45 /// Rewinds BindHostPipeline state changes. 45 /// Rewinds BindHostPipeline state changes.
46 void RestoreGuestPipeline(); 46 void RestoreGuestPipeline();
47 47
48 void UseVertexShader(GLuint program) { 48 void UseVertexShader(GLuint program);
49 current_state.vertex = program; 49 void UseGeometryShader(GLuint program);
50 } 50 void UseFragmentShader(GLuint program);
51
52 void UseGeometryShader(GLuint program) {
53 current_state.geometry = program;
54 }
55
56 void UseFragmentShader(GLuint program) {
57 current_state.fragment = program;
58 }
59 51
60private: 52private:
61 struct PipelineState { 53 struct PipelineState {
@@ -64,9 +56,6 @@ private:
64 GLuint fragment = 0; 56 GLuint fragment = 0;
65 }; 57 };
66 58
67 /// Update NV_gpu_program5 programs.
68 void UpdateAssemblyPrograms();
69
70 /// Update GLSL programs. 59 /// Update GLSL programs.
71 void UpdateSourcePrograms(); 60 void UpdateSourcePrograms();
72 61
diff --git a/src/video_core/renderer_opengl/gl_stream_buffer.cpp b/src/video_core/renderer_opengl/gl_stream_buffer.cpp
index 3655ff629..887995cf4 100644
--- a/src/video_core/renderer_opengl/gl_stream_buffer.cpp
+++ b/src/video_core/renderer_opengl/gl_stream_buffer.cpp
@@ -35,7 +35,7 @@ OGLStreamBuffer::OGLStreamBuffer(const Device& device, GLsizeiptr size, bool ver
35 mapped_ptr = static_cast<u8*>( 35 mapped_ptr = static_cast<u8*>(
36 glMapNamedBufferRange(gl_buffer.handle, 0, buffer_size, flags | GL_MAP_FLUSH_EXPLICIT_BIT)); 36 glMapNamedBufferRange(gl_buffer.handle, 0, buffer_size, flags | GL_MAP_FLUSH_EXPLICIT_BIT));
37 37
38 if (device.HasVertexBufferUnifiedMemory()) { 38 if (device.UseAssemblyShaders() || device.HasVertexBufferUnifiedMemory()) {
39 glMakeNamedBufferResidentNV(gl_buffer.handle, GL_READ_ONLY); 39 glMakeNamedBufferResidentNV(gl_buffer.handle, GL_READ_ONLY);
40 glGetNamedBufferParameterui64vNV(gl_buffer.handle, GL_BUFFER_GPU_ADDRESS_NV, &gpu_address); 40 glGetNamedBufferParameterui64vNV(gl_buffer.handle, GL_BUFFER_GPU_ADDRESS_NV, &gpu_address);
41 } 41 }
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index 61505879b..0a7bc9e2b 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -41,91 +41,103 @@ struct FormatTuple {
41}; 41};
42 42
43constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> tex_format_tuples = {{ 43constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> tex_format_tuples = {{
44 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV}, // ABGR8U 44 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV}, // A8B8G8R8_UNORM
45 {GL_RGBA8_SNORM, GL_RGBA, GL_BYTE}, // ABGR8S 45 {GL_RGBA8_SNORM, GL_RGBA, GL_BYTE}, // A8B8G8R8_SNORM
46 {GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE}, // ABGR8UI 46 {GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE}, // A8B8G8R8_SINT
47 {GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV}, // B5G6R5U 47 {GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE}, // A8B8G8R8_UINT
48 {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV}, // A2B10G10R10U 48 {GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, // R5G6B5_UNORM
49 {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, // A1B5G5R5U 49 {GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV}, // B5G6R5_UNORM
50 {GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R8U 50 {GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, // A1R5G5B5_UNORM
51 {GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE}, // R8UI 51 {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV}, // A2B10G10R10_UNORM
52 {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}, // RGBA16F 52 {GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV}, // A2B10G10R10_UINT
53 {GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT}, // RGBA16U 53 {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, // A1B5G5R5_UNORM
54 {GL_RGBA16_SNORM, GL_RGBA, GL_SHORT}, // RGBA16S 54 {GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R8_UNORM
55 {GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT}, // RGBA16UI 55 {GL_R8_SNORM, GL_RED, GL_BYTE}, // R8_SNORM
56 {GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV}, // R11FG11FB10F 56 {GL_R8I, GL_RED_INTEGER, GL_BYTE}, // R8_SINT
57 {GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT}, // RGBA32UI 57 {GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE}, // R8_UINT
58 {GL_COMPRESSED_RGBA_S3TC_DXT1_EXT}, // DXT1 58 {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}, // R16G16B16A16_FLOAT
59 {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT}, // DXT23 59 {GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT}, // R16G16B16A16_UNORM
60 {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT}, // DXT45 60 {GL_RGBA16_SNORM, GL_RGBA, GL_SHORT}, // R16G16B16A16_SNORM
61 {GL_COMPRESSED_RED_RGTC1}, // DXN1 61 {GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT}, // R16G16B16A16_SINT
62 {GL_COMPRESSED_RG_RGTC2}, // DXN2UNORM 62 {GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT}, // R16G16B16A16_UINT
63 {GL_COMPRESSED_SIGNED_RG_RGTC2}, // DXN2SNORM 63 {GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV}, // B10G11R11_FLOAT
64 {GL_COMPRESSED_RGBA_BPTC_UNORM}, // BC7U 64 {GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT}, // R32G32B32A32_UINT
65 {GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT}, // BC6H_UF16 65 {GL_COMPRESSED_RGBA_S3TC_DXT1_EXT}, // BC1_RGBA_UNORM
66 {GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT}, // BC6H_SF16 66 {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT}, // BC2_UNORM
67 {GL_COMPRESSED_RGBA_ASTC_4x4_KHR}, // ASTC_2D_4X4 67 {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT}, // BC3_UNORM
68 {GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE}, // BGRA8 68 {GL_COMPRESSED_RED_RGTC1}, // BC4_UNORM
69 {GL_RGBA32F, GL_RGBA, GL_FLOAT}, // RGBA32F 69 {GL_COMPRESSED_SIGNED_RED_RGTC1}, // BC4_SNORM
70 {GL_RG32F, GL_RG, GL_FLOAT}, // RG32F 70 {GL_COMPRESSED_RG_RGTC2}, // BC5_UNORM
71 {GL_R32F, GL_RED, GL_FLOAT}, // R32F 71 {GL_COMPRESSED_SIGNED_RG_RGTC2}, // BC5_SNORM
72 {GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16F 72 {GL_COMPRESSED_RGBA_BPTC_UNORM}, // BC7_UNORM
73 {GL_R16, GL_RED, GL_UNSIGNED_SHORT}, // R16U 73 {GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT}, // BC6H_UFLOAT
74 {GL_R16_SNORM, GL_RED, GL_SHORT}, // R16S 74 {GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT}, // BC6H_SFLOAT
75 {GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT}, // R16UI 75 {GL_COMPRESSED_RGBA_ASTC_4x4_KHR}, // ASTC_2D_4X4_UNORM
76 {GL_R16I, GL_RED_INTEGER, GL_SHORT}, // R16I 76 {GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE}, // B8G8R8A8_UNORM
77 {GL_RG16, GL_RG, GL_UNSIGNED_SHORT}, // RG16 77 {GL_RGBA32F, GL_RGBA, GL_FLOAT}, // R32G32B32A32_FLOAT
78 {GL_RG16F, GL_RG, GL_HALF_FLOAT}, // RG16F 78 {GL_RGBA32I, GL_RGBA_INTEGER, GL_INT}, // R32G32B32A32_SINT
79 {GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT}, // RG16UI 79 {GL_RG32F, GL_RG, GL_FLOAT}, // R32G32_FLOAT
80 {GL_RG16I, GL_RG_INTEGER, GL_SHORT}, // RG16I 80 {GL_RG32I, GL_RG_INTEGER, GL_INT}, // R32G32_SINT
81 {GL_RG16_SNORM, GL_RG, GL_SHORT}, // RG16S 81 {GL_R32F, GL_RED, GL_FLOAT}, // R32_FLOAT
82 {GL_RGB32F, GL_RGB, GL_FLOAT}, // RGB32F 82 {GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16_FLOAT
83 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV}, // RGBA8_SRGB 83 {GL_R16, GL_RED, GL_UNSIGNED_SHORT}, // R16_UNORM
84 {GL_RG8, GL_RG, GL_UNSIGNED_BYTE}, // RG8U 84 {GL_R16_SNORM, GL_RED, GL_SHORT}, // R16_SNORM
85 {GL_RG8_SNORM, GL_RG, GL_BYTE}, // RG8S 85 {GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT}, // R16_UINT
86 {GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_INT}, // RG8UI 86 {GL_R16I, GL_RED_INTEGER, GL_SHORT}, // R16_SINT
87 {GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT}, // RG32UI 87 {GL_RG16, GL_RG, GL_UNSIGNED_SHORT}, // R16G16_UNORM
88 {GL_RGB16F, GL_RGBA, GL_HALF_FLOAT}, // RGBX16F 88 {GL_RG16F, GL_RG, GL_HALF_FLOAT}, // R16G16_FLOAT
89 {GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, // R32UI 89 {GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT}, // R16G16_UINT
90 {GL_R32I, GL_RED_INTEGER, GL_INT}, // R32I 90 {GL_RG16I, GL_RG_INTEGER, GL_SHORT}, // R16G16_SINT
91 {GL_COMPRESSED_RGBA_ASTC_8x8_KHR}, // ASTC_2D_8X8 91 {GL_RG16_SNORM, GL_RG, GL_SHORT}, // R16G16_SNORM
92 {GL_COMPRESSED_RGBA_ASTC_8x5_KHR}, // ASTC_2D_8X5 92 {GL_RGB32F, GL_RGB, GL_FLOAT}, // R32G32B32_FLOAT
93 {GL_COMPRESSED_RGBA_ASTC_5x4_KHR}, // ASTC_2D_5X4 93 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV}, // A8B8G8R8_SRGB
94 {GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_BYTE}, // BGRA8 94 {GL_RG8, GL_RG, GL_UNSIGNED_BYTE}, // R8G8_UNORM
95 {GL_RG8_SNORM, GL_RG, GL_BYTE}, // R8G8_SNORM
96 {GL_RG8I, GL_RG_INTEGER, GL_BYTE}, // R8G8_SINT
97 {GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE}, // R8G8_UINT
98 {GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT}, // R32G32_UINT
99 {GL_RGB16F, GL_RGBA, GL_HALF_FLOAT}, // R16G16B16X16_FLOAT
100 {GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, // R32_UINT
101 {GL_R32I, GL_RED_INTEGER, GL_INT}, // R32_SINT
102 {GL_COMPRESSED_RGBA_ASTC_8x8_KHR}, // ASTC_2D_8X8_UNORM
103 {GL_COMPRESSED_RGBA_ASTC_8x5_KHR}, // ASTC_2D_8X5_UNORM
104 {GL_COMPRESSED_RGBA_ASTC_5x4_KHR}, // ASTC_2D_5X4_UNORM
105 {GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_BYTE}, // B8G8R8A8_UNORM
95 // Compressed sRGB formats 106 // Compressed sRGB formats
96 {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT}, // DXT1_SRGB 107 {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT}, // BC1_RGBA_SRGB
97 {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT}, // DXT23_SRGB 108 {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT}, // BC2_SRGB
98 {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT}, // DXT45_SRGB 109 {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT}, // BC3_SRGB
99 {GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM}, // BC7U_SRGB 110 {GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM}, // BC7_SRGB
100 {GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV}, // R4G4B4A4U 111 {GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV}, // A4B4G4R4_UNORM
101 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR}, // ASTC_2D_4X4_SRGB 112 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR}, // ASTC_2D_4X4_SRGB
102 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR}, // ASTC_2D_8X8_SRGB 113 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR}, // ASTC_2D_8X8_SRGB
103 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR}, // ASTC_2D_8X5_SRGB 114 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR}, // ASTC_2D_8X5_SRGB
104 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR}, // ASTC_2D_5X4_SRGB 115 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR}, // ASTC_2D_5X4_SRGB
105 {GL_COMPRESSED_RGBA_ASTC_5x5_KHR}, // ASTC_2D_5X5 116 {GL_COMPRESSED_RGBA_ASTC_5x5_KHR}, // ASTC_2D_5X5_UNORM
106 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR}, // ASTC_2D_5X5_SRGB 117 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR}, // ASTC_2D_5X5_SRGB
107 {GL_COMPRESSED_RGBA_ASTC_10x8_KHR}, // ASTC_2D_10X8 118 {GL_COMPRESSED_RGBA_ASTC_10x8_KHR}, // ASTC_2D_10X8_UNORM
108 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR}, // ASTC_2D_10X8_SRGB 119 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR}, // ASTC_2D_10X8_SRGB
109 {GL_COMPRESSED_RGBA_ASTC_6x6_KHR}, // ASTC_2D_6X6 120 {GL_COMPRESSED_RGBA_ASTC_6x6_KHR}, // ASTC_2D_6X6_UNORM
110 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR}, // ASTC_2D_6X6_SRGB 121 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR}, // ASTC_2D_6X6_SRGB
111 {GL_COMPRESSED_RGBA_ASTC_10x10_KHR}, // ASTC_2D_10X10 122 {GL_COMPRESSED_RGBA_ASTC_10x10_KHR}, // ASTC_2D_10X10_UNORM
112 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR}, // ASTC_2D_10X10_SRGB 123 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR}, // ASTC_2D_10X10_SRGB
113 {GL_COMPRESSED_RGBA_ASTC_12x12_KHR}, // ASTC_2D_12X12 124 {GL_COMPRESSED_RGBA_ASTC_12x12_KHR}, // ASTC_2D_12X12_UNORM
114 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR}, // ASTC_2D_12X12_SRGB 125 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR}, // ASTC_2D_12X12_SRGB
115 {GL_COMPRESSED_RGBA_ASTC_8x6_KHR}, // ASTC_2D_8X6 126 {GL_COMPRESSED_RGBA_ASTC_8x6_KHR}, // ASTC_2D_8X6_UNORM
116 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR}, // ASTC_2D_8X6_SRGB 127 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR}, // ASTC_2D_8X6_SRGB
117 {GL_COMPRESSED_RGBA_ASTC_6x5_KHR}, // ASTC_2D_6X5 128 {GL_COMPRESSED_RGBA_ASTC_6x5_KHR}, // ASTC_2D_6X5_UNORM
118 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR}, // ASTC_2D_6X5_SRGB 129 {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR}, // ASTC_2D_6X5_SRGB
119 {GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV}, // E5B9G9R9F 130 {GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV}, // E5B9G9R9_FLOAT
120 131
121 // Depth formats 132 // Depth formats
122 {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, // Z32F 133 {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, // D32_FLOAT
123 {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // Z16 134 {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // D16_UNORM
124 135
125 // DepthStencil formats 136 // DepthStencil formats
126 {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // Z24S8 137 {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // D24_UNORM_S8_UINT
127 {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // S8Z24 138 {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // S8_UINT_D24_UNORM
128 {GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV}, // Z32FS8 139 {GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL,
140 GL_FLOAT_32_UNSIGNED_INT_24_8_REV}, // D32_FLOAT_S8_UINT
129}}; 141}};
130 142
131const FormatTuple& GetFormatTuple(PixelFormat pixel_format) { 143const FormatTuple& GetFormatTuple(PixelFormat pixel_format) {
@@ -178,10 +190,10 @@ GLint GetSwizzleSource(SwizzleSource source) {
178 190
179GLenum GetComponent(PixelFormat format, bool is_first) { 191GLenum GetComponent(PixelFormat format, bool is_first) {
180 switch (format) { 192 switch (format) {
181 case PixelFormat::Z24S8: 193 case PixelFormat::D24_UNORM_S8_UINT:
182 case PixelFormat::Z32FS8: 194 case PixelFormat::D32_FLOAT_S8_UINT:
183 return is_first ? GL_DEPTH_COMPONENT : GL_STENCIL_INDEX; 195 return is_first ? GL_DEPTH_COMPONENT : GL_STENCIL_INDEX;
184 case PixelFormat::S8Z24: 196 case PixelFormat::S8_UINT_D24_UNORM:
185 return is_first ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT; 197 return is_first ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT;
186 default: 198 default:
187 UNREACHABLE(); 199 UNREACHABLE();
@@ -482,9 +494,9 @@ GLuint CachedSurfaceView::GetTexture(SwizzleSource x_source, SwizzleSource y_sou
482 std::array swizzle{x_source, y_source, z_source, w_source}; 494 std::array swizzle{x_source, y_source, z_source, w_source};
483 495
484 switch (const PixelFormat format = GetSurfaceParams().pixel_format) { 496 switch (const PixelFormat format = GetSurfaceParams().pixel_format) {
485 case PixelFormat::Z24S8: 497 case PixelFormat::D24_UNORM_S8_UINT:
486 case PixelFormat::Z32FS8: 498 case PixelFormat::D32_FLOAT_S8_UINT:
487 case PixelFormat::S8Z24: 499 case PixelFormat::S8_UINT_D24_UNORM:
488 UNIMPLEMENTED_IF(x_source != SwizzleSource::R && x_source != SwizzleSource::G); 500 UNIMPLEMENTED_IF(x_source != SwizzleSource::R && x_source != SwizzleSource::G);
489 glTextureParameteri(view.handle, GL_DEPTH_STENCIL_TEXTURE_MODE, 501 glTextureParameteri(view.handle, GL_DEPTH_STENCIL_TEXTURE_MODE,
490 GetComponent(format, x_source == SwizzleSource::R)); 502 GetComponent(format, x_source == SwizzleSource::R));
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index e66cdc083..52e9e8250 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -535,12 +535,12 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
535 535
536 GLint internal_format; 536 GLint internal_format;
537 switch (framebuffer.pixel_format) { 537 switch (framebuffer.pixel_format) {
538 case Tegra::FramebufferConfig::PixelFormat::ABGR8: 538 case Tegra::FramebufferConfig::PixelFormat::A8B8G8R8_UNORM:
539 internal_format = GL_RGBA8; 539 internal_format = GL_RGBA8;
540 texture.gl_format = GL_RGBA; 540 texture.gl_format = GL_RGBA;
541 texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; 541 texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
542 break; 542 break;
543 case Tegra::FramebufferConfig::PixelFormat::RGB565: 543 case Tegra::FramebufferConfig::PixelFormat::RGB565_UNORM:
544 internal_format = GL_RGB565; 544 internal_format = GL_RGB565;
545 texture.gl_format = GL_RGB; 545 texture.gl_format = GL_RGB;
546 texture.gl_type = GL_UNSIGNED_SHORT_5_6_5; 546 texture.gl_type = GL_UNSIGNED_SHORT_5_6_5;
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
index d1f0ea932..81a39a3b8 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
@@ -40,7 +40,6 @@ constexpr std::array POLYGON_OFFSET_ENABLE_LUT = {
40} // Anonymous namespace 40} // Anonymous namespace
41 41
42void FixedPipelineState::Fill(const Maxwell& regs, bool has_extended_dynamic_state) { 42void FixedPipelineState::Fill(const Maxwell& regs, bool has_extended_dynamic_state) {
43 const auto& clip = regs.view_volume_clip_control;
44 const std::array enabled_lut = {regs.polygon_offset_point_enable, 43 const std::array enabled_lut = {regs.polygon_offset_point_enable,
45 regs.polygon_offset_line_enable, 44 regs.polygon_offset_line_enable,
46 regs.polygon_offset_fill_enable}; 45 regs.polygon_offset_fill_enable};
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
index d7f1ae89f..f8c77f4fa 100644
--- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
+++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
@@ -117,90 +117,101 @@ struct FormatTuple {
117 VkFormat format; ///< Vulkan format 117 VkFormat format; ///< Vulkan format
118 int usage = 0; ///< Describes image format usage 118 int usage = 0; ///< Describes image format usage
119} constexpr tex_format_tuples[] = { 119} constexpr tex_format_tuples[] = {
120 {VK_FORMAT_A8B8G8R8_UNORM_PACK32, Attachable | Storage}, // ABGR8U 120 {VK_FORMAT_A8B8G8R8_UNORM_PACK32, Attachable | Storage}, // A8B8G8R8_UNORM
121 {VK_FORMAT_A8B8G8R8_SNORM_PACK32, Attachable | Storage}, // ABGR8S 121 {VK_FORMAT_A8B8G8R8_SNORM_PACK32, Attachable | Storage}, // A8B8G8R8_SNORM
122 {VK_FORMAT_A8B8G8R8_UINT_PACK32, Attachable | Storage}, // ABGR8UI 122 {VK_FORMAT_A8B8G8R8_SINT_PACK32, Attachable | Storage}, // A8B8G8R8_SINT
123 {VK_FORMAT_B5G6R5_UNORM_PACK16}, // B5G6R5U 123 {VK_FORMAT_A8B8G8R8_UINT_PACK32, Attachable | Storage}, // A8B8G8R8_UINT
124 {VK_FORMAT_A2B10G10R10_UNORM_PACK32, Attachable | Storage}, // A2B10G10R10U 124 {VK_FORMAT_R5G6B5_UNORM_PACK16, Attachable}, // R5G6B5_UNORM
125 {VK_FORMAT_A1R5G5B5_UNORM_PACK16, Attachable}, // A1B5G5R5U (flipped with swizzle) 125 {VK_FORMAT_B5G6R5_UNORM_PACK16, Attachable}, // B5G6R5_UNORM
126 {VK_FORMAT_R8_UNORM, Attachable | Storage}, // R8U 126 {VK_FORMAT_A1R5G5B5_UNORM_PACK16, Attachable}, // A1R5G5B5_UNORM
127 {VK_FORMAT_R8_UINT, Attachable | Storage}, // R8UI 127 {VK_FORMAT_A2B10G10R10_UNORM_PACK32, Attachable | Storage}, // A2B10G10R10_UNORM
128 {VK_FORMAT_R16G16B16A16_SFLOAT, Attachable | Storage}, // RGBA16F 128 {VK_FORMAT_A2B10G10R10_UINT_PACK32, Attachable | Storage}, // A2B10G10R10_UINT
129 {VK_FORMAT_R16G16B16A16_UNORM, Attachable | Storage}, // RGBA16U 129 {VK_FORMAT_A1R5G5B5_UNORM_PACK16, Attachable}, // A1B5G5R5_UNORM (flipped with swizzle)
130 {VK_FORMAT_R16G16B16A16_SNORM, Attachable | Storage}, // RGBA16S 130 {VK_FORMAT_R8_UNORM, Attachable | Storage}, // R8_UNORM
131 {VK_FORMAT_R16G16B16A16_UINT, Attachable | Storage}, // RGBA16UI 131 {VK_FORMAT_R8_SNORM, Attachable | Storage}, // R8_SNORM
132 {VK_FORMAT_B10G11R11_UFLOAT_PACK32, Attachable | Storage}, // R11FG11FB10F 132 {VK_FORMAT_R8_SINT, Attachable | Storage}, // R8_SINT
133 {VK_FORMAT_R32G32B32A32_UINT, Attachable | Storage}, // RGBA32UI 133 {VK_FORMAT_R8_UINT, Attachable | Storage}, // R8_UINT
134 {VK_FORMAT_BC1_RGBA_UNORM_BLOCK}, // DXT1 134 {VK_FORMAT_R16G16B16A16_SFLOAT, Attachable | Storage}, // R16G16B16A16_FLOAT
135 {VK_FORMAT_BC2_UNORM_BLOCK}, // DXT23 135 {VK_FORMAT_R16G16B16A16_UNORM, Attachable | Storage}, // R16G16B16A16_UNORM
136 {VK_FORMAT_BC3_UNORM_BLOCK}, // DXT45 136 {VK_FORMAT_R16G16B16A16_SNORM, Attachable | Storage}, // R16G16B16A16_SNORM
137 {VK_FORMAT_BC4_UNORM_BLOCK}, // DXN1 137 {VK_FORMAT_R16G16B16A16_SINT, Attachable | Storage}, // R16G16B16A16_SINT
138 {VK_FORMAT_BC5_UNORM_BLOCK}, // DXN2UNORM 138 {VK_FORMAT_R16G16B16A16_UINT, Attachable | Storage}, // R16G16B16A16_UINT
139 {VK_FORMAT_BC5_SNORM_BLOCK}, // DXN2SNORM 139 {VK_FORMAT_B10G11R11_UFLOAT_PACK32, Attachable | Storage}, // B10G11R11_FLOAT
140 {VK_FORMAT_BC7_UNORM_BLOCK}, // BC7U 140 {VK_FORMAT_R32G32B32A32_UINT, Attachable | Storage}, // R32G32B32A32_UINT
141 {VK_FORMAT_BC6H_UFLOAT_BLOCK}, // BC6H_UF16 141 {VK_FORMAT_BC1_RGBA_UNORM_BLOCK}, // BC1_RGBA_UNORM
142 {VK_FORMAT_BC6H_SFLOAT_BLOCK}, // BC6H_SF16 142 {VK_FORMAT_BC2_UNORM_BLOCK}, // BC2_UNORM
143 {VK_FORMAT_ASTC_4x4_UNORM_BLOCK}, // ASTC_2D_4X4 143 {VK_FORMAT_BC3_UNORM_BLOCK}, // BC3_UNORM
144 {VK_FORMAT_B8G8R8A8_UNORM, Attachable}, // BGRA8 144 {VK_FORMAT_BC4_UNORM_BLOCK}, // BC4_UNORM
145 {VK_FORMAT_R32G32B32A32_SFLOAT, Attachable | Storage}, // RGBA32F 145 {VK_FORMAT_BC4_SNORM_BLOCK}, // BC4_SNORM
146 {VK_FORMAT_R32G32_SFLOAT, Attachable | Storage}, // RG32F 146 {VK_FORMAT_BC5_UNORM_BLOCK}, // BC5_UNORM
147 {VK_FORMAT_R32_SFLOAT, Attachable | Storage}, // R32F 147 {VK_FORMAT_BC5_SNORM_BLOCK}, // BC5_SNORM
148 {VK_FORMAT_R16_SFLOAT, Attachable | Storage}, // R16F 148 {VK_FORMAT_BC7_UNORM_BLOCK}, // BC7_UNORM
149 {VK_FORMAT_R16_UNORM, Attachable | Storage}, // R16U 149 {VK_FORMAT_BC6H_UFLOAT_BLOCK}, // BC6H_UFLOAT
150 {VK_FORMAT_UNDEFINED}, // R16S 150 {VK_FORMAT_BC6H_SFLOAT_BLOCK}, // BC6H_SFLOAT
151 {VK_FORMAT_R16_UINT, Attachable | Storage}, // R16UI 151 {VK_FORMAT_ASTC_4x4_UNORM_BLOCK}, // ASTC_2D_4X4_UNORM
152 {VK_FORMAT_UNDEFINED}, // R16I 152 {VK_FORMAT_B8G8R8A8_UNORM, Attachable}, // B8G8R8A8_UNORM
153 {VK_FORMAT_R16G16_UNORM, Attachable | Storage}, // RG16 153 {VK_FORMAT_R32G32B32A32_SFLOAT, Attachable | Storage}, // R32G32B32A32_FLOAT
154 {VK_FORMAT_R16G16_SFLOAT, Attachable | Storage}, // RG16F 154 {VK_FORMAT_R32G32B32A32_SINT, Attachable | Storage}, // R32G32B32A32_SINT
155 {VK_FORMAT_UNDEFINED}, // RG16UI 155 {VK_FORMAT_R32G32_SFLOAT, Attachable | Storage}, // R32G32_FLOAT
156 {VK_FORMAT_UNDEFINED}, // RG16I 156 {VK_FORMAT_R32G32_SINT, Attachable | Storage}, // R32G32_SINT
157 {VK_FORMAT_R16G16_SNORM, Attachable | Storage}, // RG16S 157 {VK_FORMAT_R32_SFLOAT, Attachable | Storage}, // R32_FLOAT
158 {VK_FORMAT_UNDEFINED}, // RGB32F 158 {VK_FORMAT_R16_SFLOAT, Attachable | Storage}, // R16_FLOAT
159 {VK_FORMAT_R8G8B8A8_SRGB, Attachable}, // RGBA8_SRGB 159 {VK_FORMAT_R16_UNORM, Attachable | Storage}, // R16_UNORM
160 {VK_FORMAT_R8G8_UNORM, Attachable | Storage}, // RG8U 160 {VK_FORMAT_UNDEFINED}, // R16_SNORM
161 {VK_FORMAT_R8G8_SNORM, Attachable | Storage}, // RG8S 161 {VK_FORMAT_R16_UINT, Attachable | Storage}, // R16_UINT
162 {VK_FORMAT_R8G8_UINT, Attachable | Storage}, // RG8UI 162 {VK_FORMAT_UNDEFINED}, // R16_SINT
163 {VK_FORMAT_R32G32_UINT, Attachable | Storage}, // RG32UI 163 {VK_FORMAT_R16G16_UNORM, Attachable | Storage}, // R16G16_UNORM
164 {VK_FORMAT_UNDEFINED}, // RGBX16F 164 {VK_FORMAT_R16G16_SFLOAT, Attachable | Storage}, // R16G16_FLOAT
165 {VK_FORMAT_R32_UINT, Attachable | Storage}, // R32UI 165 {VK_FORMAT_UNDEFINED}, // R16G16_UINT
166 {VK_FORMAT_R32_SINT, Attachable | Storage}, // R32I 166 {VK_FORMAT_UNDEFINED}, // R16G16_SINT
167 {VK_FORMAT_ASTC_8x8_UNORM_BLOCK}, // ASTC_2D_8X8 167 {VK_FORMAT_R16G16_SNORM, Attachable | Storage}, // R16G16_SNORM
168 {VK_FORMAT_UNDEFINED}, // ASTC_2D_8X5 168 {VK_FORMAT_UNDEFINED}, // R32G32B32_FLOAT
169 {VK_FORMAT_UNDEFINED}, // ASTC_2D_5X4 169 {VK_FORMAT_R8G8B8A8_SRGB, Attachable}, // A8B8G8R8_SRGB
170 {VK_FORMAT_B8G8R8A8_SRGB, Attachable}, // BGRA8_SRGB 170 {VK_FORMAT_R8G8_UNORM, Attachable | Storage}, // R8G8_UNORM
171 {VK_FORMAT_BC1_RGBA_SRGB_BLOCK}, // DXT1_SRGB 171 {VK_FORMAT_R8G8_SNORM, Attachable | Storage}, // R8G8_SNORM
172 {VK_FORMAT_BC2_SRGB_BLOCK}, // DXT23_SRGB 172 {VK_FORMAT_R8G8_SINT, Attachable | Storage}, // R8G8_SINT
173 {VK_FORMAT_BC3_SRGB_BLOCK}, // DXT45_SRGB 173 {VK_FORMAT_R8G8_UINT, Attachable | Storage}, // R8G8_UINT
174 {VK_FORMAT_BC7_SRGB_BLOCK}, // BC7U_SRGB 174 {VK_FORMAT_R32G32_UINT, Attachable | Storage}, // R32G32_UINT
175 {VK_FORMAT_R4G4B4A4_UNORM_PACK16, Attachable}, // R4G4B4A4U 175 {VK_FORMAT_UNDEFINED}, // R16G16B16X16_FLOAT
176 {VK_FORMAT_ASTC_4x4_SRGB_BLOCK}, // ASTC_2D_4X4_SRGB 176 {VK_FORMAT_R32_UINT, Attachable | Storage}, // R32_UINT
177 {VK_FORMAT_ASTC_8x8_SRGB_BLOCK}, // ASTC_2D_8X8_SRGB 177 {VK_FORMAT_R32_SINT, Attachable | Storage}, // R32_SINT
178 {VK_FORMAT_ASTC_8x5_SRGB_BLOCK}, // ASTC_2D_8X5_SRGB 178 {VK_FORMAT_ASTC_8x8_UNORM_BLOCK}, // ASTC_2D_8X8_UNORM
179 {VK_FORMAT_ASTC_5x4_SRGB_BLOCK}, // ASTC_2D_5X4_SRGB 179 {VK_FORMAT_UNDEFINED}, // ASTC_2D_8X5_UNORM
180 {VK_FORMAT_ASTC_5x5_UNORM_BLOCK}, // ASTC_2D_5X5 180 {VK_FORMAT_UNDEFINED}, // ASTC_2D_5X4_UNORM
181 {VK_FORMAT_ASTC_5x5_SRGB_BLOCK}, // ASTC_2D_5X5_SRGB 181 {VK_FORMAT_B8G8R8A8_SRGB, Attachable}, // B8G8R8A8_SRGB
182 {VK_FORMAT_ASTC_10x8_UNORM_BLOCK}, // ASTC_2D_10X8 182 {VK_FORMAT_BC1_RGBA_SRGB_BLOCK}, // BC1_RGBA_SRGB
183 {VK_FORMAT_ASTC_10x8_SRGB_BLOCK}, // ASTC_2D_10X8_SRGB 183 {VK_FORMAT_BC2_SRGB_BLOCK}, // BC2_SRGB
184 {VK_FORMAT_ASTC_6x6_UNORM_BLOCK}, // ASTC_2D_6X6 184 {VK_FORMAT_BC3_SRGB_BLOCK}, // BC3_SRGB
185 {VK_FORMAT_ASTC_6x6_SRGB_BLOCK}, // ASTC_2D_6X6_SRGB 185 {VK_FORMAT_BC7_SRGB_BLOCK}, // BC7_SRGB
186 {VK_FORMAT_ASTC_10x10_UNORM_BLOCK}, // ASTC_2D_10X10 186 {VK_FORMAT_R4G4B4A4_UNORM_PACK16, Attachable}, // A4B4G4R4_UNORM
187 {VK_FORMAT_ASTC_10x10_SRGB_BLOCK}, // ASTC_2D_10X10_SRGB 187 {VK_FORMAT_ASTC_4x4_SRGB_BLOCK}, // ASTC_2D_4X4_SRGB
188 {VK_FORMAT_ASTC_12x12_UNORM_BLOCK}, // ASTC_2D_12X12 188 {VK_FORMAT_ASTC_8x8_SRGB_BLOCK}, // ASTC_2D_8X8_SRGB
189 {VK_FORMAT_ASTC_12x12_SRGB_BLOCK}, // ASTC_2D_12X12_SRGB 189 {VK_FORMAT_ASTC_8x5_SRGB_BLOCK}, // ASTC_2D_8X5_SRGB
190 {VK_FORMAT_ASTC_8x6_UNORM_BLOCK}, // ASTC_2D_8X6 190 {VK_FORMAT_ASTC_5x4_SRGB_BLOCK}, // ASTC_2D_5X4_SRGB
191 {VK_FORMAT_ASTC_8x6_SRGB_BLOCK}, // ASTC_2D_8X6_SRGB 191 {VK_FORMAT_ASTC_5x5_UNORM_BLOCK}, // ASTC_2D_5X5_UNORM
192 {VK_FORMAT_ASTC_6x5_UNORM_BLOCK}, // ASTC_2D_6X5 192 {VK_FORMAT_ASTC_5x5_SRGB_BLOCK}, // ASTC_2D_5X5_SRGB
193 {VK_FORMAT_ASTC_6x5_SRGB_BLOCK}, // ASTC_2D_6X5_SRGB 193 {VK_FORMAT_ASTC_10x8_UNORM_BLOCK}, // ASTC_2D_10X8_UNORM
194 {VK_FORMAT_E5B9G9R9_UFLOAT_PACK32}, // E5B9G9R9F 194 {VK_FORMAT_ASTC_10x8_SRGB_BLOCK}, // ASTC_2D_10X8_SRGB
195 {VK_FORMAT_ASTC_6x6_UNORM_BLOCK}, // ASTC_2D_6X6_UNORM
196 {VK_FORMAT_ASTC_6x6_SRGB_BLOCK}, // ASTC_2D_6X6_SRGB
197 {VK_FORMAT_ASTC_10x10_UNORM_BLOCK}, // ASTC_2D_10X10_UNORM
198 {VK_FORMAT_ASTC_10x10_SRGB_BLOCK}, // ASTC_2D_10X10_SRGB
199 {VK_FORMAT_ASTC_12x12_UNORM_BLOCK}, // ASTC_2D_12X12_UNORM
200 {VK_FORMAT_ASTC_12x12_SRGB_BLOCK}, // ASTC_2D_12X12_SRGB
201 {VK_FORMAT_ASTC_8x6_UNORM_BLOCK}, // ASTC_2D_8X6_UNORM
202 {VK_FORMAT_ASTC_8x6_SRGB_BLOCK}, // ASTC_2D_8X6_SRGB
203 {VK_FORMAT_ASTC_6x5_UNORM_BLOCK}, // ASTC_2D_6X5_UNORM
204 {VK_FORMAT_ASTC_6x5_SRGB_BLOCK}, // ASTC_2D_6X5_SRGB
205 {VK_FORMAT_E5B9G9R9_UFLOAT_PACK32}, // E5B9G9R9_FLOAT
195 206
196 // Depth formats 207 // Depth formats
197 {VK_FORMAT_D32_SFLOAT, Attachable}, // Z32F 208 {VK_FORMAT_D32_SFLOAT, Attachable}, // D32_FLOAT
198 {VK_FORMAT_D16_UNORM, Attachable}, // Z16 209 {VK_FORMAT_D16_UNORM, Attachable}, // D16_UNORM
199 210
200 // DepthStencil formats 211 // DepthStencil formats
201 {VK_FORMAT_D24_UNORM_S8_UINT, Attachable}, // Z24S8 212 {VK_FORMAT_D24_UNORM_S8_UINT, Attachable}, // D24_UNORM_S8_UINT
202 {VK_FORMAT_D24_UNORM_S8_UINT, Attachable}, // S8Z24 (emulated) 213 {VK_FORMAT_D24_UNORM_S8_UINT, Attachable}, // S8_UINT_D24_UNORM (emulated)
203 {VK_FORMAT_D32_SFLOAT_S8_UINT, Attachable}, // Z32FS8 214 {VK_FORMAT_D32_SFLOAT_S8_UINT, Attachable}, // D32_FLOAT_S8_UINT
204}; 215};
205static_assert(std::size(tex_format_tuples) == VideoCore::Surface::MaxPixelFormat); 216static_assert(std::size(tex_format_tuples) == VideoCore::Surface::MaxPixelFormat);
206 217
@@ -221,7 +232,7 @@ FormatInfo SurfaceFormat(const VKDevice& device, FormatType format_type, PixelFo
221 return {VK_FORMAT_A8B8G8R8_UNORM_PACK32, true, true}; 232 return {VK_FORMAT_A8B8G8R8_UNORM_PACK32, true, true};
222 } 233 }
223 234
224 // Use ABGR8 on hardware that doesn't support ASTC natively 235 // Use A8B8G8R8_UNORM on hardware that doesn't support ASTC natively
225 if (!device.IsOptimalAstcSupported() && VideoCore::Surface::IsPixelFormatASTC(pixel_format)) { 236 if (!device.IsOptimalAstcSupported() && VideoCore::Surface::IsPixelFormatASTC(pixel_format)) {
226 tuple.format = VideoCore::Surface::IsPixelFormatSRGB(pixel_format) 237 tuple.format = VideoCore::Surface::IsPixelFormatSRGB(pixel_format)
227 ? VK_FORMAT_A8B8G8R8_SRGB_PACK32 238 ? VK_FORMAT_A8B8G8R8_SRGB_PACK32
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
index 866813465..ce53e5a6b 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
@@ -187,9 +187,9 @@ std::size_t GetSizeInBytes(const Tegra::FramebufferConfig& framebuffer) {
187 187
188VkFormat GetFormat(const Tegra::FramebufferConfig& framebuffer) { 188VkFormat GetFormat(const Tegra::FramebufferConfig& framebuffer) {
189 switch (framebuffer.pixel_format) { 189 switch (framebuffer.pixel_format) {
190 case Tegra::FramebufferConfig::PixelFormat::ABGR8: 190 case Tegra::FramebufferConfig::PixelFormat::A8B8G8R8_UNORM:
191 return VK_FORMAT_A8B8G8R8_UNORM_PACK32; 191 return VK_FORMAT_A8B8G8R8_UNORM_PACK32;
192 case Tegra::FramebufferConfig::PixelFormat::RGB565: 192 case Tegra::FramebufferConfig::PixelFormat::RGB565_UNORM:
193 return VK_FORMAT_R5G6B5_UNORM_PACK16; 193 return VK_FORMAT_R5G6B5_UNORM_PACK16;
194 default: 194 default:
195 UNIMPLEMENTED_MSG("Unknown framebuffer pixel format: {}", 195 UNIMPLEMENTED_MSG("Unknown framebuffer pixel format: {}",
diff --git a/src/video_core/renderer_vulkan/vk_device.cpp b/src/video_core/renderer_vulkan/vk_device.cpp
index 26379ee01..6245e0d78 100644
--- a/src/video_core/renderer_vulkan/vk_device.cpp
+++ b/src/video_core/renderer_vulkan/vk_device.cpp
@@ -84,14 +84,19 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties(
84 VK_FORMAT_A8B8G8R8_UNORM_PACK32, 84 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
85 VK_FORMAT_A8B8G8R8_UINT_PACK32, 85 VK_FORMAT_A8B8G8R8_UINT_PACK32,
86 VK_FORMAT_A8B8G8R8_SNORM_PACK32, 86 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
87 VK_FORMAT_A8B8G8R8_SINT_PACK32,
87 VK_FORMAT_A8B8G8R8_SRGB_PACK32, 88 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
88 VK_FORMAT_B5G6R5_UNORM_PACK16, 89 VK_FORMAT_B5G6R5_UNORM_PACK16,
89 VK_FORMAT_A2B10G10R10_UNORM_PACK32, 90 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
91 VK_FORMAT_A2B10G10R10_UINT_PACK32,
90 VK_FORMAT_A1R5G5B5_UNORM_PACK16, 92 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
91 VK_FORMAT_R32G32B32A32_SFLOAT, 93 VK_FORMAT_R32G32B32A32_SFLOAT,
94 VK_FORMAT_R32G32B32A32_SINT,
92 VK_FORMAT_R32G32B32A32_UINT, 95 VK_FORMAT_R32G32B32A32_UINT,
93 VK_FORMAT_R32G32_SFLOAT, 96 VK_FORMAT_R32G32_SFLOAT,
97 VK_FORMAT_R32G32_SINT,
94 VK_FORMAT_R32G32_UINT, 98 VK_FORMAT_R32G32_UINT,
99 VK_FORMAT_R16G16B16A16_SINT,
95 VK_FORMAT_R16G16B16A16_UINT, 100 VK_FORMAT_R16G16B16A16_UINT,
96 VK_FORMAT_R16G16B16A16_SNORM, 101 VK_FORMAT_R16G16B16A16_SNORM,
97 VK_FORMAT_R16G16B16A16_UNORM, 102 VK_FORMAT_R16G16B16A16_UNORM,
@@ -103,8 +108,11 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties(
103 VK_FORMAT_R8G8B8A8_SRGB, 108 VK_FORMAT_R8G8B8A8_SRGB,
104 VK_FORMAT_R8G8_UNORM, 109 VK_FORMAT_R8G8_UNORM,
105 VK_FORMAT_R8G8_SNORM, 110 VK_FORMAT_R8G8_SNORM,
111 VK_FORMAT_R8G8_SINT,
106 VK_FORMAT_R8G8_UINT, 112 VK_FORMAT_R8G8_UINT,
107 VK_FORMAT_R8_UNORM, 113 VK_FORMAT_R8_UNORM,
114 VK_FORMAT_R8_SNORM,
115 VK_FORMAT_R8_SINT,
108 VK_FORMAT_R8_UINT, 116 VK_FORMAT_R8_UINT,
109 VK_FORMAT_B10G11R11_UFLOAT_PACK32, 117 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
110 VK_FORMAT_R32_SFLOAT, 118 VK_FORMAT_R32_SFLOAT,
@@ -124,6 +132,7 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties(
124 VK_FORMAT_BC2_UNORM_BLOCK, 132 VK_FORMAT_BC2_UNORM_BLOCK,
125 VK_FORMAT_BC3_UNORM_BLOCK, 133 VK_FORMAT_BC3_UNORM_BLOCK,
126 VK_FORMAT_BC4_UNORM_BLOCK, 134 VK_FORMAT_BC4_UNORM_BLOCK,
135 VK_FORMAT_BC4_SNORM_BLOCK,
127 VK_FORMAT_BC5_UNORM_BLOCK, 136 VK_FORMAT_BC5_UNORM_BLOCK,
128 VK_FORMAT_BC5_SNORM_BLOCK, 137 VK_FORMAT_BC5_SNORM_BLOCK,
129 VK_FORMAT_BC7_UNORM_BLOCK, 138 VK_FORMAT_BC7_UNORM_BLOCK,
diff --git a/src/video_core/renderer_vulkan/vk_device.h b/src/video_core/renderer_vulkan/vk_device.h
index ae5c21baa..529744f2d 100644
--- a/src/video_core/renderer_vulkan/vk_device.h
+++ b/src/video_core/renderer_vulkan/vk_device.h
@@ -122,6 +122,11 @@ public:
122 return properties.limits.maxPushConstantsSize; 122 return properties.limits.maxPushConstantsSize;
123 } 123 }
124 124
125 /// Returns the maximum size for shared memory.
126 u32 GetMaxComputeSharedMemorySize() const {
127 return properties.limits.maxComputeSharedMemorySize;
128 }
129
125 /// Returns true if ASTC is natively supported. 130 /// Returns true if ASTC is natively supported.
126 bool IsOptimalAstcSupported() const { 131 bool IsOptimalAstcSupported() const {
127 return is_optimal_astc_supported; 132 return is_optimal_astc_supported;
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 31e44aa2b..2ed2004f0 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -532,10 +532,6 @@ void RasterizerVulkan::Clear() {
532 532
533 scheduler.Record([clear_depth = regs.clear_depth, clear_stencil = regs.clear_stencil, 533 scheduler.Record([clear_depth = regs.clear_depth, clear_stencil = regs.clear_stencil,
534 clear_rect, aspect_flags](vk::CommandBuffer cmdbuf) { 534 clear_rect, aspect_flags](vk::CommandBuffer cmdbuf) {
535 VkClearValue clear_value;
536 clear_value.depthStencil.depth = clear_depth;
537 clear_value.depthStencil.stencil = clear_stencil;
538
539 VkClearAttachment attachment; 535 VkClearAttachment attachment;
540 attachment.aspectMask = aspect_flags; 536 attachment.aspectMask = aspect_flags;
541 attachment.colorAttachment = 0; 537 attachment.colorAttachment = 0;
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
index 97429cc59..cd7d7a4e4 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
@@ -685,13 +685,19 @@ private:
685 } 685 }
686 t_smem_uint = TypePointer(spv::StorageClass::Workgroup, t_uint); 686 t_smem_uint = TypePointer(spv::StorageClass::Workgroup, t_uint);
687 687
688 const u32 smem_size = specialization.shared_memory_size; 688 u32 smem_size = specialization.shared_memory_size * 4;
689 if (smem_size == 0) { 689 if (smem_size == 0) {
690 // Avoid declaring an empty array. 690 // Avoid declaring an empty array.
691 return; 691 return;
692 } 692 }
693 const auto element_count = static_cast<u32>(Common::AlignUp(smem_size, 4) / 4); 693 const u32 limit = device.GetMaxComputeSharedMemorySize();
694 const Id type_array = TypeArray(t_uint, Constant(t_uint, element_count)); 694 if (smem_size > limit) {
695 LOG_ERROR(Render_Vulkan, "Shared memory size {} is clamped to host's limit {}",
696 smem_size, limit);
697 smem_size = limit;
698 }
699
700 const Id type_array = TypeArray(t_uint, Constant(t_uint, smem_size / 4));
695 const Id type_pointer = TypePointer(spv::StorageClass::Workgroup, type_array); 701 const Id type_pointer = TypePointer(spv::StorageClass::Workgroup, type_array);
696 Name(type_pointer, "SharedMemory"); 702 Name(type_pointer, "SharedMemory");
697 703
@@ -700,9 +706,9 @@ private:
700 } 706 }
701 707
702 void DeclareInternalFlags() { 708 void DeclareInternalFlags() {
703 constexpr std::array names = {"zero", "sign", "carry", "overflow"}; 709 static constexpr std::array names{"zero", "sign", "carry", "overflow"};
710
704 for (std::size_t flag = 0; flag < INTERNAL_FLAGS_COUNT; ++flag) { 711 for (std::size_t flag = 0; flag < INTERNAL_FLAGS_COUNT; ++flag) {
705 const auto flag_code = static_cast<InternalFlag>(flag);
706 const Id id = OpVariable(t_prv_bool, spv::StorageClass::Private, v_false); 712 const Id id = OpVariable(t_prv_bool, spv::StorageClass::Private, v_false);
707 internal_flags[flag] = AddGlobalVariable(Name(id, names[flag])); 713 internal_flags[flag] = AddGlobalVariable(Name(id, names[flag]));
708 } 714 }
@@ -2798,7 +2804,6 @@ private:
2798 std::map<GlobalMemoryBase, Id> global_buffers; 2804 std::map<GlobalMemoryBase, Id> global_buffers;
2799 std::map<u32, TexelBuffer> uniform_texels; 2805 std::map<u32, TexelBuffer> uniform_texels;
2800 std::map<u32, SampledImage> sampled_images; 2806 std::map<u32, SampledImage> sampled_images;
2801 std::map<u32, TexelBuffer> storage_texels;
2802 std::map<u32, StorageImage> images; 2807 std::map<u32, StorageImage> images;
2803 2808
2804 std::array<Id, Maxwell::NumRenderTargets> frag_colors{}; 2809 std::array<Id, Maxwell::NumRenderTargets> frag_colors{};
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp
index c25e312b6..6bfd2abae 100644
--- a/src/video_core/renderer_vulkan/vk_swapchain.cpp
+++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp
@@ -156,6 +156,7 @@ void VKSwapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities,
156 .minImageCount = requested_image_count, 156 .minImageCount = requested_image_count,
157 .imageFormat = surface_format.format, 157 .imageFormat = surface_format.format,
158 .imageColorSpace = surface_format.colorSpace, 158 .imageColorSpace = surface_format.colorSpace,
159 .imageExtent = {},
159 .imageArrayLayers = 1, 160 .imageArrayLayers = 1,
160 .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 161 .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
161 .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE, 162 .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
@@ -204,6 +205,7 @@ void VKSwapchain::CreateImageViews() {
204 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 205 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
205 .pNext = nullptr, 206 .pNext = nullptr,
206 .flags = 0, 207 .flags = 0,
208 .image = {},
207 .viewType = VK_IMAGE_VIEW_TYPE_2D, 209 .viewType = VK_IMAGE_VIEW_TYPE_2D,
208 .format = image_format, 210 .format = image_format,
209 .components = 211 .components =
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 9bc18c21a..efd4bb13b 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -138,6 +138,7 @@ VkImageCreateInfo GenerateImageCreateInfo(const VKDevice& device, const SurfaceP
138 .flags = 0, 138 .flags = 0,
139 .imageType = SurfaceTargetToImage(params.target), 139 .imageType = SurfaceTargetToImage(params.target),
140 .format = format, 140 .format = format,
141 .extent = {},
141 .mipLevels = params.num_levels, 142 .mipLevels = params.num_levels,
142 .arrayLayers = static_cast<u32>(params.GetNumLayers()), 143 .arrayLayers = static_cast<u32>(params.GetNumLayers()),
143 .samples = VK_SAMPLE_COUNT_1_BIT, 144 .samples = VK_SAMPLE_COUNT_1_BIT,
@@ -235,7 +236,7 @@ void CachedSurface::UploadTexture(const std::vector<u8>& staging_buffer) {
235void CachedSurface::DownloadTexture(std::vector<u8>& staging_buffer) { 236void CachedSurface::DownloadTexture(std::vector<u8>& staging_buffer) {
236 UNIMPLEMENTED_IF(params.IsBuffer()); 237 UNIMPLEMENTED_IF(params.IsBuffer());
237 238
238 if (params.pixel_format == VideoCore::Surface::PixelFormat::A1B5G5R5U) { 239 if (params.pixel_format == VideoCore::Surface::PixelFormat::A1B5G5R5_UNORM) {
239 LOG_WARNING(Render_Vulkan, "A1B5G5R5 flushing is stubbed"); 240 LOG_WARNING(Render_Vulkan, "A1B5G5R5 flushing is stubbed");
240 } 241 }
241 242
@@ -385,7 +386,7 @@ VkImageView CachedSurfaceView::GetImageView(SwizzleSource x_source, SwizzleSourc
385 386
386 std::array swizzle{MaxwellToVK::SwizzleSource(x_source), MaxwellToVK::SwizzleSource(y_source), 387 std::array swizzle{MaxwellToVK::SwizzleSource(x_source), MaxwellToVK::SwizzleSource(y_source),
387 MaxwellToVK::SwizzleSource(z_source), MaxwellToVK::SwizzleSource(w_source)}; 388 MaxwellToVK::SwizzleSource(z_source), MaxwellToVK::SwizzleSource(w_source)};
388 if (params.pixel_format == VideoCore::Surface::PixelFormat::A1B5G5R5U) { 389 if (params.pixel_format == VideoCore::Surface::PixelFormat::A1B5G5R5_UNORM) {
389 // A1B5G5R5 is implemented as A1R5G5B5, we have to change the swizzle here. 390 // A1B5G5R5 is implemented as A1R5G5B5, we have to change the swizzle here.
390 std::swap(swizzle[0], swizzle[2]); 391 std::swap(swizzle[0], swizzle[2]);
391 } 392 }
@@ -397,11 +398,11 @@ VkImageView CachedSurfaceView::GetImageView(SwizzleSource x_source, SwizzleSourc
397 UNIMPLEMENTED_IF(x_source != SwizzleSource::R && x_source != SwizzleSource::G); 398 UNIMPLEMENTED_IF(x_source != SwizzleSource::R && x_source != SwizzleSource::G);
398 const bool is_first = x_source == SwizzleSource::R; 399 const bool is_first = x_source == SwizzleSource::R;
399 switch (params.pixel_format) { 400 switch (params.pixel_format) {
400 case VideoCore::Surface::PixelFormat::Z24S8: 401 case VideoCore::Surface::PixelFormat::D24_UNORM_S8_UINT:
401 case VideoCore::Surface::PixelFormat::Z32FS8: 402 case VideoCore::Surface::PixelFormat::D32_FLOAT_S8_UINT:
402 aspect = is_first ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT; 403 aspect = is_first ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT;
403 break; 404 break;
404 case VideoCore::Surface::PixelFormat::S8Z24: 405 case VideoCore::Surface::PixelFormat::S8_UINT_D24_UNORM:
405 aspect = is_first ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT; 406 aspect = is_first ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT;
406 break; 407 break;
407 default: 408 default:
@@ -458,6 +459,7 @@ VkImageView CachedSurfaceView::GetAttachment() {
458 .pNext = nullptr, 459 .pNext = nullptr,
459 .flags = 0, 460 .flags = 0,
460 .image = surface.GetImageHandle(), 461 .image = surface.GetImageHandle(),
462 .viewType = VK_IMAGE_VIEW_TYPE_1D,
461 .format = surface.GetImage().GetFormat(), 463 .format = surface.GetImage().GetFormat(),
462 .components = 464 .components =
463 { 465 {
diff --git a/src/video_core/shader/decode/arithmetic_integer.cpp b/src/video_core/shader/decode/arithmetic_integer.cpp
index a041519b7..73155966f 100644
--- a/src/video_core/shader/decode/arithmetic_integer.cpp
+++ b/src/video_core/shader/decode/arithmetic_integer.cpp
@@ -98,12 +98,12 @@ u32 ShaderIR::DecodeArithmeticInteger(NodeBlock& bb, u32 pc) {
98 op_b = GetOperandAbsNegInteger(op_b, false, instr.iadd3.neg_b, true); 98 op_b = GetOperandAbsNegInteger(op_b, false, instr.iadd3.neg_b, true);
99 op_c = GetOperandAbsNegInteger(op_c, false, instr.iadd3.neg_c, true); 99 op_c = GetOperandAbsNegInteger(op_c, false, instr.iadd3.neg_c, true);
100 100
101 const Node value = [&]() { 101 const Node value = [&] {
102 const Node add_ab = Operation(OperationCode::IAdd, NO_PRECISE, op_a, op_b); 102 Node add_ab = Operation(OperationCode::IAdd, NO_PRECISE, op_a, op_b);
103 if (opcode->get().GetId() != OpCode::Id::IADD3_R) { 103 if (opcode->get().GetId() != OpCode::Id::IADD3_R) {
104 return Operation(OperationCode::IAdd, NO_PRECISE, add_ab, op_c); 104 return Operation(OperationCode::IAdd, NO_PRECISE, add_ab, op_c);
105 } 105 }
106 const Node shifted = [&]() { 106 const Node shifted = [&] {
107 switch (instr.iadd3.mode) { 107 switch (instr.iadd3.mode) {
108 case Tegra::Shader::IAdd3Mode::RightShift: 108 case Tegra::Shader::IAdd3Mode::RightShift:
109 // TODO(tech4me): According to 109 // TODO(tech4me): According to
diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp
index 07778dc3e..e75ca4fdb 100644
--- a/src/video_core/shader/decode/image.cpp
+++ b/src/video_core/shader/decode/image.cpp
@@ -31,11 +31,11 @@ ComponentType GetComponentType(Tegra::Engines::SamplerDescriptor descriptor,
31 std::size_t component) { 31 std::size_t component) {
32 const TextureFormat format{descriptor.format}; 32 const TextureFormat format{descriptor.format};
33 switch (format) { 33 switch (format) {
34 case TextureFormat::R16_G16_B16_A16: 34 case TextureFormat::R16G16B16A16:
35 case TextureFormat::R32_G32_B32_A32: 35 case TextureFormat::R32G32B32A32:
36 case TextureFormat::R32_G32_B32: 36 case TextureFormat::R32G32B32:
37 case TextureFormat::R32_G32: 37 case TextureFormat::R32G32:
38 case TextureFormat::R16_G16: 38 case TextureFormat::R16G16:
39 case TextureFormat::R32: 39 case TextureFormat::R32:
40 case TextureFormat::R16: 40 case TextureFormat::R16:
41 case TextureFormat::R8: 41 case TextureFormat::R8:
@@ -97,7 +97,7 @@ ComponentType GetComponentType(Tegra::Engines::SamplerDescriptor descriptor,
97 break; 97 break;
98 case TextureFormat::B5G6R5: 98 case TextureFormat::B5G6R5:
99 case TextureFormat::B6G5R5: 99 case TextureFormat::B6G5R5:
100 case TextureFormat::BF10GF11RF11: 100 case TextureFormat::B10G11R11:
101 if (component == 0) { 101 if (component == 0) {
102 return descriptor.b_type; 102 return descriptor.b_type;
103 } 103 }
@@ -108,9 +108,9 @@ ComponentType GetComponentType(Tegra::Engines::SamplerDescriptor descriptor,
108 return descriptor.r_type; 108 return descriptor.r_type;
109 } 109 }
110 break; 110 break;
111 case TextureFormat::G8R24: 111 case TextureFormat::R24G8:
112 case TextureFormat::G24R8: 112 case TextureFormat::R8G24:
113 case TextureFormat::G8R8: 113 case TextureFormat::R8G8:
114 case TextureFormat::G4R4: 114 case TextureFormat::G4R4:
115 if (component == 0) { 115 if (component == 0) {
116 return descriptor.g_type; 116 return descriptor.g_type;
@@ -137,15 +137,15 @@ bool IsComponentEnabled(std::size_t component_mask, std::size_t component) {
137 137
138u32 GetComponentSize(TextureFormat format, std::size_t component) { 138u32 GetComponentSize(TextureFormat format, std::size_t component) {
139 switch (format) { 139 switch (format) {
140 case TextureFormat::R32_G32_B32_A32: 140 case TextureFormat::R32G32B32A32:
141 return 32; 141 return 32;
142 case TextureFormat::R16_G16_B16_A16: 142 case TextureFormat::R16G16B16A16:
143 return 16; 143 return 16;
144 case TextureFormat::R32_G32_B32: 144 case TextureFormat::R32G32B32:
145 return component <= 2 ? 32 : 0; 145 return component <= 2 ? 32 : 0;
146 case TextureFormat::R32_G32: 146 case TextureFormat::R32G32:
147 return component <= 1 ? 32 : 0; 147 return component <= 1 ? 32 : 0;
148 case TextureFormat::R16_G16: 148 case TextureFormat::R16G16:
149 return component <= 1 ? 16 : 0; 149 return component <= 1 ? 16 : 0;
150 case TextureFormat::R32: 150 case TextureFormat::R32:
151 return component == 0 ? 32 : 0; 151 return component == 0 ? 32 : 0;
@@ -192,7 +192,7 @@ u32 GetComponentSize(TextureFormat format, std::size_t component) {
192 return 6; 192 return 6;
193 } 193 }
194 return 0; 194 return 0;
195 case TextureFormat::BF10GF11RF11: 195 case TextureFormat::B10G11R11:
196 if (component == 1 || component == 2) { 196 if (component == 1 || component == 2) {
197 return 11; 197 return 11;
198 } 198 }
@@ -200,7 +200,7 @@ u32 GetComponentSize(TextureFormat format, std::size_t component) {
200 return 10; 200 return 10;
201 } 201 }
202 return 0; 202 return 0;
203 case TextureFormat::G8R24: 203 case TextureFormat::R24G8:
204 if (component == 0) { 204 if (component == 0) {
205 return 8; 205 return 8;
206 } 206 }
@@ -208,7 +208,7 @@ u32 GetComponentSize(TextureFormat format, std::size_t component) {
208 return 24; 208 return 24;
209 } 209 }
210 return 0; 210 return 0;
211 case TextureFormat::G24R8: 211 case TextureFormat::R8G24:
212 if (component == 0) { 212 if (component == 0) {
213 return 8; 213 return 8;
214 } 214 }
@@ -216,7 +216,7 @@ u32 GetComponentSize(TextureFormat format, std::size_t component) {
216 return 24; 216 return 24;
217 } 217 }
218 return 0; 218 return 0;
219 case TextureFormat::G8R8: 219 case TextureFormat::R8G8:
220 return (component == 0 || component == 1) ? 8 : 0; 220 return (component == 0 || component == 1) ? 8 : 0;
221 case TextureFormat::G4R4: 221 case TextureFormat::G4R4:
222 return (component == 0 || component == 1) ? 4 : 0; 222 return (component == 0 || component == 1) ? 4 : 0;
@@ -231,25 +231,25 @@ std::size_t GetImageComponentMask(TextureFormat format) {
231 constexpr u8 B = 0b0100; 231 constexpr u8 B = 0b0100;
232 constexpr u8 A = 0b1000; 232 constexpr u8 A = 0b1000;
233 switch (format) { 233 switch (format) {
234 case TextureFormat::R32_G32_B32_A32: 234 case TextureFormat::R32G32B32A32:
235 case TextureFormat::R16_G16_B16_A16: 235 case TextureFormat::R16G16B16A16:
236 case TextureFormat::A8R8G8B8: 236 case TextureFormat::A8R8G8B8:
237 case TextureFormat::A2B10G10R10: 237 case TextureFormat::A2B10G10R10:
238 case TextureFormat::A4B4G4R4: 238 case TextureFormat::A4B4G4R4:
239 case TextureFormat::A5B5G5R1: 239 case TextureFormat::A5B5G5R1:
240 case TextureFormat::A1B5G5R5: 240 case TextureFormat::A1B5G5R5:
241 return std::size_t{R | G | B | A}; 241 return std::size_t{R | G | B | A};
242 case TextureFormat::R32_G32_B32: 242 case TextureFormat::R32G32B32:
243 case TextureFormat::R32_B24G8: 243 case TextureFormat::R32_B24G8:
244 case TextureFormat::B5G6R5: 244 case TextureFormat::B5G6R5:
245 case TextureFormat::B6G5R5: 245 case TextureFormat::B6G5R5:
246 case TextureFormat::BF10GF11RF11: 246 case TextureFormat::B10G11R11:
247 return std::size_t{R | G | B}; 247 return std::size_t{R | G | B};
248 case TextureFormat::R32_G32: 248 case TextureFormat::R32G32:
249 case TextureFormat::R16_G16: 249 case TextureFormat::R16G16:
250 case TextureFormat::G8R24: 250 case TextureFormat::R24G8:
251 case TextureFormat::G24R8: 251 case TextureFormat::R8G24:
252 case TextureFormat::G8R8: 252 case TextureFormat::R8G8:
253 case TextureFormat::G4R4: 253 case TextureFormat::G4R4:
254 return std::size_t{R | G}; 254 return std::size_t{R | G};
255 case TextureFormat::R32: 255 case TextureFormat::R32:
diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp
index c0a8f233f..29a7cfbfe 100644
--- a/src/video_core/shader/decode/other.cpp
+++ b/src/video_core/shader/decode/other.cpp
@@ -75,8 +75,7 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
75 const Node value = [this, instr] { 75 const Node value = [this, instr] {
76 switch (instr.sys20) { 76 switch (instr.sys20) {
77 case SystemVariable::LaneId: 77 case SystemVariable::LaneId:
78 LOG_WARNING(HW_GPU, "S2R instruction with LaneId is incomplete"); 78 return Operation(OperationCode::ThreadId);
79 return Immediate(0U);
80 case SystemVariable::InvocationId: 79 case SystemVariable::InvocationId:
81 return Operation(OperationCode::InvocationId); 80 return Operation(OperationCode::InvocationId);
82 case SystemVariable::Ydirection: 81 case SystemVariable::Ydirection:
diff --git a/src/video_core/shader/decode/video.cpp b/src/video_core/shader/decode/video.cpp
index 64ba60ea2..1c0957277 100644
--- a/src/video_core/shader/decode/video.cpp
+++ b/src/video_core/shader/decode/video.cpp
@@ -91,29 +91,28 @@ u32 ShaderIR::DecodeVideo(NodeBlock& bb, u32 pc) {
91 return pc; 91 return pc;
92} 92}
93 93
94Node ShaderIR::GetVideoOperand(Node op, bool is_chunk, bool is_signed, 94Node ShaderIR::GetVideoOperand(Node op, bool is_chunk, bool is_signed, VideoType type,
95 Tegra::Shader::VideoType type, u64 byte_height) { 95 u64 byte_height) {
96 if (!is_chunk) { 96 if (!is_chunk) {
97 return BitfieldExtract(op, static_cast<u32>(byte_height * 8), 8); 97 return BitfieldExtract(op, static_cast<u32>(byte_height * 8), 8);
98 } 98 }
99 const Node zero = Immediate(0);
100 99
101 switch (type) { 100 switch (type) {
102 case Tegra::Shader::VideoType::Size16_Low: 101 case VideoType::Size16_Low:
103 return BitfieldExtract(op, 0, 16); 102 return BitfieldExtract(op, 0, 16);
104 case Tegra::Shader::VideoType::Size16_High: 103 case VideoType::Size16_High:
105 return BitfieldExtract(op, 16, 16); 104 return BitfieldExtract(op, 16, 16);
106 case Tegra::Shader::VideoType::Size32: 105 case VideoType::Size32:
107 // TODO(Rodrigo): From my hardware tests it becomes a bit "mad" when this type is used 106 // TODO(Rodrigo): From my hardware tests it becomes a bit "mad" when this type is used
108 // (1 * 1 + 0 == 0x5b800000). Until a better explanation is found: abort. 107 // (1 * 1 + 0 == 0x5b800000). Until a better explanation is found: abort.
109 UNIMPLEMENTED(); 108 UNIMPLEMENTED();
110 return zero; 109 return Immediate(0);
111 case Tegra::Shader::VideoType::Invalid: 110 case VideoType::Invalid:
112 UNREACHABLE_MSG("Invalid instruction encoding"); 111 UNREACHABLE_MSG("Invalid instruction encoding");
113 return zero; 112 return Immediate(0);
114 default: 113 default:
115 UNREACHABLE(); 114 UNREACHABLE();
116 return zero; 115 return Immediate(0);
117 } 116 }
118} 117}
119 118
diff --git a/src/video_core/shader/decode/xmad.cpp b/src/video_core/shader/decode/xmad.cpp
index c83dc6615..233b8fa42 100644
--- a/src/video_core/shader/decode/xmad.cpp
+++ b/src/video_core/shader/decode/xmad.cpp
@@ -81,20 +81,21 @@ u32 ShaderIR::DecodeXmad(NodeBlock& bb, u32 pc) {
81 SetTemporary(bb, 0, product); 81 SetTemporary(bb, 0, product);
82 product = GetTemporary(0); 82 product = GetTemporary(0);
83 83
84 const Node original_c = op_c; 84 Node original_c = op_c;
85 const Tegra::Shader::XmadMode set_mode = mode; // Workaround to clang compile error 85 const Tegra::Shader::XmadMode set_mode = mode; // Workaround to clang compile error
86 op_c = [&]() { 86 op_c = [&] {
87 switch (set_mode) { 87 switch (set_mode) {
88 case Tegra::Shader::XmadMode::None: 88 case Tegra::Shader::XmadMode::None:
89 return original_c; 89 return original_c;
90 case Tegra::Shader::XmadMode::CLo: 90 case Tegra::Shader::XmadMode::CLo:
91 return BitfieldExtract(original_c, 0, 16); 91 return BitfieldExtract(std::move(original_c), 0, 16);
92 case Tegra::Shader::XmadMode::CHi: 92 case Tegra::Shader::XmadMode::CHi:
93 return BitfieldExtract(original_c, 16, 16); 93 return BitfieldExtract(std::move(original_c), 16, 16);
94 case Tegra::Shader::XmadMode::CBcc: { 94 case Tegra::Shader::XmadMode::CBcc: {
95 const Node shifted_b = SignedOperation(OperationCode::ILogicalShiftLeft, is_signed_b, 95 Node shifted_b = SignedOperation(OperationCode::ILogicalShiftLeft, is_signed_b,
96 original_b, Immediate(16)); 96 original_b, Immediate(16));
97 return SignedOperation(OperationCode::IAdd, is_signed_c, original_c, shifted_b); 97 return SignedOperation(OperationCode::IAdd, is_signed_c, std::move(original_c),
98 std::move(shifted_b));
98 } 99 }
99 case Tegra::Shader::XmadMode::CSfu: { 100 case Tegra::Shader::XmadMode::CSfu: {
100 const Node comp_a = 101 const Node comp_a =
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index e322c3402..29d794b34 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -112,9 +112,9 @@ Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buff
112} 112}
113 113
114Node ShaderIR::GetInternalFlag(InternalFlag flag, bool negated) const { 114Node ShaderIR::GetInternalFlag(InternalFlag flag, bool negated) const {
115 const Node node = MakeNode<InternalFlagNode>(flag); 115 Node node = MakeNode<InternalFlagNode>(flag);
116 if (negated) { 116 if (negated) {
117 return Operation(OperationCode::LogicalNegate, node); 117 return Operation(OperationCode::LogicalNegate, std::move(node));
118 } 118 }
119 return node; 119 return node;
120} 120}
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp
index bbe93903c..1688267bb 100644
--- a/src/video_core/surface.cpp
+++ b/src/video_core/surface.cpp
@@ -74,117 +74,131 @@ bool SurfaceTargetIsArray(SurfaceTarget target) {
74 74
75PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) { 75PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) {
76 switch (format) { 76 switch (format) {
77 case Tegra::DepthFormat::S8_Z24_UNORM: 77 case Tegra::DepthFormat::S8_UINT_Z24_UNORM:
78 return PixelFormat::S8Z24; 78 return PixelFormat::S8_UINT_D24_UNORM;
79 case Tegra::DepthFormat::Z24_S8_UNORM: 79 case Tegra::DepthFormat::D24S8_UNORM:
80 return PixelFormat::Z24S8; 80 return PixelFormat::D24_UNORM_S8_UINT;
81 case Tegra::DepthFormat::Z32_FLOAT: 81 case Tegra::DepthFormat::D32_FLOAT:
82 return PixelFormat::Z32F; 82 return PixelFormat::D32_FLOAT;
83 case Tegra::DepthFormat::Z16_UNORM: 83 case Tegra::DepthFormat::D16_UNORM:
84 return PixelFormat::Z16; 84 return PixelFormat::D16_UNORM;
85 case Tegra::DepthFormat::Z32_S8_X24_FLOAT: 85 case Tegra::DepthFormat::D32_FLOAT_S8X24_UINT:
86 return PixelFormat::Z32FS8; 86 return PixelFormat::D32_FLOAT_S8_UINT;
87 default: 87 default:
88 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); 88 UNIMPLEMENTED_MSG("Unimplemented format={}", static_cast<u32>(format));
89 UNREACHABLE(); 89 return PixelFormat::S8_UINT_D24_UNORM;
90 return PixelFormat::S8Z24;
91 } 90 }
92} 91}
93 92
94PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) { 93PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) {
95 switch (format) { 94 switch (format) {
96 case Tegra::RenderTargetFormat::RGBA8_SRGB: 95 case Tegra::RenderTargetFormat::R32B32G32A32_FLOAT:
97 return PixelFormat::RGBA8_SRGB; 96 return PixelFormat::R32G32B32A32_FLOAT;
98 case Tegra::RenderTargetFormat::RGBA8_UNORM: 97 case Tegra::RenderTargetFormat::R32G32B32A32_SINT:
99 return PixelFormat::ABGR8U; 98 return PixelFormat::R32G32B32A32_SINT;
100 case Tegra::RenderTargetFormat::RGBA8_SNORM: 99 case Tegra::RenderTargetFormat::R32G32B32A32_UINT:
101 return PixelFormat::ABGR8S; 100 return PixelFormat::R32G32B32A32_UINT;
102 case Tegra::RenderTargetFormat::RGBA8_UINT: 101 case Tegra::RenderTargetFormat::R16G16B16A16_UNORM:
103 return PixelFormat::ABGR8UI; 102 return PixelFormat::R16G16B16A16_UNORM;
104 case Tegra::RenderTargetFormat::BGRA8_SRGB: 103 case Tegra::RenderTargetFormat::R16G16B16A16_SNORM:
105 return PixelFormat::BGRA8_SRGB; 104 return PixelFormat::R16G16B16A16_SNORM;
106 case Tegra::RenderTargetFormat::BGRA8_UNORM: 105 case Tegra::RenderTargetFormat::R16G16B16A16_SINT:
107 return PixelFormat::BGRA8; 106 return PixelFormat::R16G16B16A16_SINT;
108 case Tegra::RenderTargetFormat::RGB10_A2_UNORM: 107 case Tegra::RenderTargetFormat::R16G16B16A16_UINT:
109 return PixelFormat::A2B10G10R10U; 108 return PixelFormat::R16G16B16A16_UINT;
110 case Tegra::RenderTargetFormat::RGBA16_FLOAT: 109 case Tegra::RenderTargetFormat::R16G16B16A16_FLOAT:
111 return PixelFormat::RGBA16F; 110 return PixelFormat::R16G16B16A16_FLOAT;
112 case Tegra::RenderTargetFormat::RGBA16_UNORM: 111 case Tegra::RenderTargetFormat::R32G32_FLOAT:
113 return PixelFormat::RGBA16U; 112 return PixelFormat::R32G32_FLOAT;
114 case Tegra::RenderTargetFormat::RGBA16_SNORM: 113 case Tegra::RenderTargetFormat::R32G32_SINT:
115 return PixelFormat::RGBA16S; 114 return PixelFormat::R32G32_SINT;
116 case Tegra::RenderTargetFormat::RGBA16_UINT: 115 case Tegra::RenderTargetFormat::R32G32_UINT:
117 return PixelFormat::RGBA16UI; 116 return PixelFormat::R32G32_UINT;
118 case Tegra::RenderTargetFormat::RGBA32_FLOAT: 117 case Tegra::RenderTargetFormat::R16G16B16X16_FLOAT:
119 return PixelFormat::RGBA32F; 118 return PixelFormat::R16G16B16X16_FLOAT;
120 case Tegra::RenderTargetFormat::RG32_FLOAT: 119 case Tegra::RenderTargetFormat::B8G8R8A8_UNORM:
121 return PixelFormat::RG32F; 120 return PixelFormat::B8G8R8A8_UNORM;
122 case Tegra::RenderTargetFormat::R11G11B10_FLOAT: 121 case Tegra::RenderTargetFormat::B8G8R8A8_SRGB:
123 return PixelFormat::R11FG11FB10F; 122 return PixelFormat::B8G8R8A8_SRGB;
124 case Tegra::RenderTargetFormat::B5G6R5_UNORM: 123 case Tegra::RenderTargetFormat::A2B10G10R10_UNORM:
125 return PixelFormat::B5G6R5U; 124 return PixelFormat::A2B10G10R10_UNORM;
126 case Tegra::RenderTargetFormat::BGR5A1_UNORM: 125 case Tegra::RenderTargetFormat::A2B10G10R10_UINT:
127 return PixelFormat::A1B5G5R5U; 126 return PixelFormat::A2B10G10R10_UINT;
128 case Tegra::RenderTargetFormat::RGBA32_UINT: 127 case Tegra::RenderTargetFormat::A8B8G8R8_UNORM:
129 return PixelFormat::RGBA32UI; 128 return PixelFormat::A8B8G8R8_UNORM;
130 case Tegra::RenderTargetFormat::R8_UNORM: 129 case Tegra::RenderTargetFormat::A8B8G8R8_SRGB:
131 return PixelFormat::R8U; 130 return PixelFormat::A8B8G8R8_SRGB;
132 case Tegra::RenderTargetFormat::R8_UINT: 131 case Tegra::RenderTargetFormat::A8B8G8R8_SNORM:
133 return PixelFormat::R8UI; 132 return PixelFormat::A8B8G8R8_SNORM;
134 case Tegra::RenderTargetFormat::RG16_FLOAT: 133 case Tegra::RenderTargetFormat::A8B8G8R8_SINT:
135 return PixelFormat::RG16F; 134 return PixelFormat::A8B8G8R8_SINT;
136 case Tegra::RenderTargetFormat::RG16_UINT: 135 case Tegra::RenderTargetFormat::A8B8G8R8_UINT:
137 return PixelFormat::RG16UI; 136 return PixelFormat::A8B8G8R8_UINT;
138 case Tegra::RenderTargetFormat::RG16_SINT: 137 case Tegra::RenderTargetFormat::R16G16_UNORM:
139 return PixelFormat::RG16I; 138 return PixelFormat::R16G16_UNORM;
140 case Tegra::RenderTargetFormat::RG16_UNORM: 139 case Tegra::RenderTargetFormat::R16G16_SNORM:
141 return PixelFormat::RG16; 140 return PixelFormat::R16G16_SNORM;
142 case Tegra::RenderTargetFormat::RG16_SNORM: 141 case Tegra::RenderTargetFormat::R16G16_SINT:
143 return PixelFormat::RG16S; 142 return PixelFormat::R16G16_SINT;
144 case Tegra::RenderTargetFormat::RG8_UNORM: 143 case Tegra::RenderTargetFormat::R16G16_UINT:
145 return PixelFormat::RG8U; 144 return PixelFormat::R16G16_UINT;
146 case Tegra::RenderTargetFormat::RG8_SNORM: 145 case Tegra::RenderTargetFormat::R16G16_FLOAT:
147 return PixelFormat::RG8S; 146 return PixelFormat::R16G16_FLOAT;
148 case Tegra::RenderTargetFormat::RG8_UINT: 147 case Tegra::RenderTargetFormat::B10G11R11_FLOAT:
149 return PixelFormat::RG8UI; 148 return PixelFormat::B10G11R11_FLOAT;
150 case Tegra::RenderTargetFormat::R16_FLOAT: 149 case Tegra::RenderTargetFormat::R32_SINT:
151 return PixelFormat::R16F; 150 return PixelFormat::R32_SINT;
151 case Tegra::RenderTargetFormat::R32_UINT:
152 return PixelFormat::R32_UINT;
153 case Tegra::RenderTargetFormat::R32_FLOAT:
154 return PixelFormat::R32_FLOAT;
155 case Tegra::RenderTargetFormat::R5G6B5_UNORM:
156 return PixelFormat::R5G6B5_UNORM;
157 case Tegra::RenderTargetFormat::A1R5G5B5_UNORM:
158 return PixelFormat::A1R5G5B5_UNORM;
159 case Tegra::RenderTargetFormat::R8G8_UNORM:
160 return PixelFormat::R8G8_UNORM;
161 case Tegra::RenderTargetFormat::R8G8_SNORM:
162 return PixelFormat::R8G8_SNORM;
163 case Tegra::RenderTargetFormat::R8G8_SINT:
164 return PixelFormat::R8G8_SINT;
165 case Tegra::RenderTargetFormat::R8G8_UINT:
166 return PixelFormat::R8G8_UINT;
152 case Tegra::RenderTargetFormat::R16_UNORM: 167 case Tegra::RenderTargetFormat::R16_UNORM:
153 return PixelFormat::R16U; 168 return PixelFormat::R16_UNORM;
154 case Tegra::RenderTargetFormat::R16_SNORM: 169 case Tegra::RenderTargetFormat::R16_SNORM:
155 return PixelFormat::R16S; 170 return PixelFormat::R16_SNORM;
156 case Tegra::RenderTargetFormat::R16_UINT:
157 return PixelFormat::R16UI;
158 case Tegra::RenderTargetFormat::R16_SINT: 171 case Tegra::RenderTargetFormat::R16_SINT:
159 return PixelFormat::R16I; 172 return PixelFormat::R16_SINT;
160 case Tegra::RenderTargetFormat::R32_FLOAT: 173 case Tegra::RenderTargetFormat::R16_UINT:
161 return PixelFormat::R32F; 174 return PixelFormat::R16_UINT;
162 case Tegra::RenderTargetFormat::R32_SINT: 175 case Tegra::RenderTargetFormat::R16_FLOAT:
163 return PixelFormat::R32I; 176 return PixelFormat::R16_FLOAT;
164 case Tegra::RenderTargetFormat::R32_UINT: 177 case Tegra::RenderTargetFormat::R8_UNORM:
165 return PixelFormat::R32UI; 178 return PixelFormat::R8_UNORM;
166 case Tegra::RenderTargetFormat::RG32_UINT: 179 case Tegra::RenderTargetFormat::R8_SNORM:
167 return PixelFormat::RG32UI; 180 return PixelFormat::R8_SNORM;
168 case Tegra::RenderTargetFormat::RGBX16_FLOAT: 181 case Tegra::RenderTargetFormat::R8_SINT:
169 return PixelFormat::RGBX16F; 182 return PixelFormat::R8_SINT;
183 case Tegra::RenderTargetFormat::R8_UINT:
184 return PixelFormat::R8_UINT;
170 default: 185 default:
171 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); 186 UNIMPLEMENTED_MSG("Unimplemented format={}", static_cast<int>(format));
172 UNREACHABLE(); 187 return PixelFormat::A8B8G8R8_UNORM;
173 return PixelFormat::RGBA8_SRGB;
174 } 188 }
175} 189}
176 190
177PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format) { 191PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format) {
178 switch (format) { 192 switch (format) {
179 case Tegra::FramebufferConfig::PixelFormat::ABGR8: 193 case Tegra::FramebufferConfig::PixelFormat::A8B8G8R8_UNORM:
180 return PixelFormat::ABGR8U; 194 return PixelFormat::A8B8G8R8_UNORM;
181 case Tegra::FramebufferConfig::PixelFormat::RGB565: 195 case Tegra::FramebufferConfig::PixelFormat::RGB565_UNORM:
182 return PixelFormat::B5G6R5U; 196 return PixelFormat::R5G6B5_UNORM;
183 case Tegra::FramebufferConfig::PixelFormat::BGRA8: 197 case Tegra::FramebufferConfig::PixelFormat::B8G8R8A8_UNORM:
184 return PixelFormat::BGRA8; 198 return PixelFormat::B8G8R8A8_UNORM;
185 default: 199 default:
186 UNIMPLEMENTED_MSG("Unimplemented format={}", static_cast<u32>(format)); 200 UNIMPLEMENTED_MSG("Unimplemented format={}", static_cast<u32>(format));
187 return PixelFormat::ABGR8U; 201 return PixelFormat::A8B8G8R8_UNORM;
188 } 202 }
189} 203}
190 204
@@ -212,27 +226,27 @@ SurfaceType GetFormatType(PixelFormat pixel_format) {
212 226
213bool IsPixelFormatASTC(PixelFormat format) { 227bool IsPixelFormatASTC(PixelFormat format) {
214 switch (format) { 228 switch (format) {
215 case PixelFormat::ASTC_2D_4X4: 229 case PixelFormat::ASTC_2D_4X4_UNORM:
216 case PixelFormat::ASTC_2D_5X4: 230 case PixelFormat::ASTC_2D_5X4_UNORM:
217 case PixelFormat::ASTC_2D_5X5: 231 case PixelFormat::ASTC_2D_5X5_UNORM:
218 case PixelFormat::ASTC_2D_8X8: 232 case PixelFormat::ASTC_2D_8X8_UNORM:
219 case PixelFormat::ASTC_2D_8X5: 233 case PixelFormat::ASTC_2D_8X5_UNORM:
220 case PixelFormat::ASTC_2D_4X4_SRGB: 234 case PixelFormat::ASTC_2D_4X4_SRGB:
221 case PixelFormat::ASTC_2D_5X4_SRGB: 235 case PixelFormat::ASTC_2D_5X4_SRGB:
222 case PixelFormat::ASTC_2D_5X5_SRGB: 236 case PixelFormat::ASTC_2D_5X5_SRGB:
223 case PixelFormat::ASTC_2D_8X8_SRGB: 237 case PixelFormat::ASTC_2D_8X8_SRGB:
224 case PixelFormat::ASTC_2D_8X5_SRGB: 238 case PixelFormat::ASTC_2D_8X5_SRGB:
225 case PixelFormat::ASTC_2D_10X8: 239 case PixelFormat::ASTC_2D_10X8_UNORM:
226 case PixelFormat::ASTC_2D_10X8_SRGB: 240 case PixelFormat::ASTC_2D_10X8_SRGB:
227 case PixelFormat::ASTC_2D_6X6: 241 case PixelFormat::ASTC_2D_6X6_UNORM:
228 case PixelFormat::ASTC_2D_6X6_SRGB: 242 case PixelFormat::ASTC_2D_6X6_SRGB:
229 case PixelFormat::ASTC_2D_10X10: 243 case PixelFormat::ASTC_2D_10X10_UNORM:
230 case PixelFormat::ASTC_2D_10X10_SRGB: 244 case PixelFormat::ASTC_2D_10X10_SRGB:
231 case PixelFormat::ASTC_2D_12X12: 245 case PixelFormat::ASTC_2D_12X12_UNORM:
232 case PixelFormat::ASTC_2D_12X12_SRGB: 246 case PixelFormat::ASTC_2D_12X12_SRGB:
233 case PixelFormat::ASTC_2D_8X6: 247 case PixelFormat::ASTC_2D_8X6_UNORM:
234 case PixelFormat::ASTC_2D_8X6_SRGB: 248 case PixelFormat::ASTC_2D_8X6_SRGB:
235 case PixelFormat::ASTC_2D_6X5: 249 case PixelFormat::ASTC_2D_6X5_UNORM:
236 case PixelFormat::ASTC_2D_6X5_SRGB: 250 case PixelFormat::ASTC_2D_6X5_SRGB:
237 return true; 251 return true;
238 default: 252 default:
@@ -242,12 +256,12 @@ bool IsPixelFormatASTC(PixelFormat format) {
242 256
243bool IsPixelFormatSRGB(PixelFormat format) { 257bool IsPixelFormatSRGB(PixelFormat format) {
244 switch (format) { 258 switch (format) {
245 case PixelFormat::RGBA8_SRGB: 259 case PixelFormat::A8B8G8R8_SRGB:
246 case PixelFormat::BGRA8_SRGB: 260 case PixelFormat::B8G8R8A8_SRGB:
247 case PixelFormat::DXT1_SRGB: 261 case PixelFormat::BC1_RGBA_SRGB:
248 case PixelFormat::DXT23_SRGB: 262 case PixelFormat::BC2_SRGB:
249 case PixelFormat::DXT45_SRGB: 263 case PixelFormat::BC3_SRGB:
250 case PixelFormat::BC7U_SRGB: 264 case PixelFormat::BC7_SRGB:
251 case PixelFormat::ASTC_2D_4X4_SRGB: 265 case PixelFormat::ASTC_2D_4X4_SRGB:
252 case PixelFormat::ASTC_2D_8X8_SRGB: 266 case PixelFormat::ASTC_2D_8X8_SRGB:
253 case PixelFormat::ASTC_2D_8X5_SRGB: 267 case PixelFormat::ASTC_2D_8X5_SRGB:
@@ -269,25 +283,4 @@ std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) {
269 return {GetDefaultBlockWidth(format), GetDefaultBlockHeight(format)}; 283 return {GetDefaultBlockWidth(format), GetDefaultBlockHeight(format)};
270} 284}
271 285
272bool IsFormatBCn(PixelFormat format) {
273 switch (format) {
274 case PixelFormat::DXT1:
275 case PixelFormat::DXT23:
276 case PixelFormat::DXT45:
277 case PixelFormat::DXN1:
278 case PixelFormat::DXN2SNORM:
279 case PixelFormat::DXN2UNORM:
280 case PixelFormat::BC7U:
281 case PixelFormat::BC6H_UF16:
282 case PixelFormat::BC6H_SF16:
283 case PixelFormat::DXT1_SRGB:
284 case PixelFormat::DXT23_SRGB:
285 case PixelFormat::DXT45_SRGB:
286 case PixelFormat::BC7U_SRGB:
287 return true;
288 default:
289 return false;
290 }
291}
292
293} // namespace VideoCore::Surface 286} // namespace VideoCore::Surface
diff --git a/src/video_core/surface.h b/src/video_core/surface.h
index 6da6a1b97..cfd12fa61 100644
--- a/src/video_core/surface.h
+++ b/src/video_core/surface.h
@@ -15,94 +15,105 @@
15namespace VideoCore::Surface { 15namespace VideoCore::Surface {
16 16
17enum class PixelFormat { 17enum class PixelFormat {
18 ABGR8U = 0, 18 A8B8G8R8_UNORM,
19 ABGR8S = 1, 19 A8B8G8R8_SNORM,
20 ABGR8UI = 2, 20 A8B8G8R8_SINT,
21 B5G6R5U = 3, 21 A8B8G8R8_UINT,
22 A2B10G10R10U = 4, 22 R5G6B5_UNORM,
23 A1B5G5R5U = 5, 23 B5G6R5_UNORM,
24 R8U = 6, 24 A1R5G5B5_UNORM,
25 R8UI = 7, 25 A2B10G10R10_UNORM,
26 RGBA16F = 8, 26 A2B10G10R10_UINT,
27 RGBA16U = 9, 27 A1B5G5R5_UNORM,
28 RGBA16S = 10, 28 R8_UNORM,
29 RGBA16UI = 11, 29 R8_SNORM,
30 R11FG11FB10F = 12, 30 R8_SINT,
31 RGBA32UI = 13, 31 R8_UINT,
32 DXT1 = 14, 32 R16G16B16A16_FLOAT,
33 DXT23 = 15, 33 R16G16B16A16_UNORM,
34 DXT45 = 16, 34 R16G16B16A16_SNORM,
35 DXN1 = 17, // This is also known as BC4 35 R16G16B16A16_SINT,
36 DXN2UNORM = 18, 36 R16G16B16A16_UINT,
37 DXN2SNORM = 19, 37 B10G11R11_FLOAT,
38 BC7U = 20, 38 R32G32B32A32_UINT,
39 BC6H_UF16 = 21, 39 BC1_RGBA_UNORM,
40 BC6H_SF16 = 22, 40 BC2_UNORM,
41 ASTC_2D_4X4 = 23, 41 BC3_UNORM,
42 BGRA8 = 24, 42 BC4_UNORM,
43 RGBA32F = 25, 43 BC4_SNORM,
44 RG32F = 26, 44 BC5_UNORM,
45 R32F = 27, 45 BC5_SNORM,
46 R16F = 28, 46 BC7_UNORM,
47 R16U = 29, 47 BC6H_UFLOAT,
48 R16S = 30, 48 BC6H_SFLOAT,
49 R16UI = 31, 49 ASTC_2D_4X4_UNORM,
50 R16I = 32, 50 B8G8R8A8_UNORM,
51 RG16 = 33, 51 R32G32B32A32_FLOAT,
52 RG16F = 34, 52 R32G32B32A32_SINT,
53 RG16UI = 35, 53 R32G32_FLOAT,
54 RG16I = 36, 54 R32G32_SINT,
55 RG16S = 37, 55 R32_FLOAT,
56 RGB32F = 38, 56 R16_FLOAT,
57 RGBA8_SRGB = 39, 57 R16_UNORM,
58 RG8U = 40, 58 R16_SNORM,
59 RG8S = 41, 59 R16_UINT,
60 RG8UI = 42, 60 R16_SINT,
61 RG32UI = 43, 61 R16G16_UNORM,
62 RGBX16F = 44, 62 R16G16_FLOAT,
63 R32UI = 45, 63 R16G16_UINT,
64 R32I = 46, 64 R16G16_SINT,
65 ASTC_2D_8X8 = 47, 65 R16G16_SNORM,
66 ASTC_2D_8X5 = 48, 66 R32G32B32_FLOAT,
67 ASTC_2D_5X4 = 49, 67 A8B8G8R8_SRGB,
68 BGRA8_SRGB = 50, 68 R8G8_UNORM,
69 DXT1_SRGB = 51, 69 R8G8_SNORM,
70 DXT23_SRGB = 52, 70 R8G8_SINT,
71 DXT45_SRGB = 53, 71 R8G8_UINT,
72 BC7U_SRGB = 54, 72 R32G32_UINT,
73 R4G4B4A4U = 55, 73 R16G16B16X16_FLOAT,
74 ASTC_2D_4X4_SRGB = 56, 74 R32_UINT,
75 ASTC_2D_8X8_SRGB = 57, 75 R32_SINT,
76 ASTC_2D_8X5_SRGB = 58, 76 ASTC_2D_8X8_UNORM,
77 ASTC_2D_5X4_SRGB = 59, 77 ASTC_2D_8X5_UNORM,
78 ASTC_2D_5X5 = 60, 78 ASTC_2D_5X4_UNORM,
79 ASTC_2D_5X5_SRGB = 61, 79 B8G8R8A8_SRGB,
80 ASTC_2D_10X8 = 62, 80 BC1_RGBA_SRGB,
81 ASTC_2D_10X8_SRGB = 63, 81 BC2_SRGB,
82 ASTC_2D_6X6 = 64, 82 BC3_SRGB,
83 ASTC_2D_6X6_SRGB = 65, 83 BC7_SRGB,
84 ASTC_2D_10X10 = 66, 84 A4B4G4R4_UNORM,
85 ASTC_2D_10X10_SRGB = 67, 85 ASTC_2D_4X4_SRGB,
86 ASTC_2D_12X12 = 68, 86 ASTC_2D_8X8_SRGB,
87 ASTC_2D_12X12_SRGB = 69, 87 ASTC_2D_8X5_SRGB,
88 ASTC_2D_8X6 = 70, 88 ASTC_2D_5X4_SRGB,
89 ASTC_2D_8X6_SRGB = 71, 89 ASTC_2D_5X5_UNORM,
90 ASTC_2D_6X5 = 72, 90 ASTC_2D_5X5_SRGB,
91 ASTC_2D_6X5_SRGB = 73, 91 ASTC_2D_10X8_UNORM,
92 E5B9G9R9F = 74, 92 ASTC_2D_10X8_SRGB,
93 ASTC_2D_6X6_UNORM,
94 ASTC_2D_6X6_SRGB,
95 ASTC_2D_10X10_UNORM,
96 ASTC_2D_10X10_SRGB,
97 ASTC_2D_12X12_UNORM,
98 ASTC_2D_12X12_SRGB,
99 ASTC_2D_8X6_UNORM,
100 ASTC_2D_8X6_SRGB,
101 ASTC_2D_6X5_UNORM,
102 ASTC_2D_6X5_SRGB,
103 E5B9G9R9_FLOAT,
93 104
94 MaxColorFormat, 105 MaxColorFormat,
95 106
96 // Depth formats 107 // Depth formats
97 Z32F = 75, 108 D32_FLOAT = MaxColorFormat,
98 Z16 = 76, 109 D16_UNORM,
99 110
100 MaxDepthFormat, 111 MaxDepthFormat,
101 112
102 // DepthStencil formats 113 // DepthStencil formats
103 Z24S8 = 77, 114 D24_UNORM_S8_UINT = MaxDepthFormat,
104 S8Z24 = 78, 115 S8_UINT_D24_UNORM,
105 Z32FS8 = 79, 116 D32_FLOAT_S8_UINT,
106 117
107 MaxDepthStencilFormat, 118 MaxDepthStencilFormat,
108 119
@@ -130,86 +141,97 @@ enum class SurfaceTarget {
130}; 141};
131 142
132constexpr std::array<u32, MaxPixelFormat> compression_factor_shift_table = {{ 143constexpr std::array<u32, MaxPixelFormat> compression_factor_shift_table = {{
133 0, // ABGR8U 144 0, // A8B8G8R8_UNORM
134 0, // ABGR8S 145 0, // A8B8G8R8_SNORM
135 0, // ABGR8UI 146 0, // A8B8G8R8_SINT
136 0, // B5G6R5U 147 0, // A8B8G8R8_UINT
137 0, // A2B10G10R10U 148 0, // R5G6B5_UNORM
138 0, // A1B5G5R5U 149 0, // B5G6R5_UNORM
139 0, // R8U 150 0, // A1R5G5B5_UNORM
140 0, // R8UI 151 0, // A2B10G10R10_UNORM
141 0, // RGBA16F 152 0, // A2B10G10R10_UINT
142 0, // RGBA16U 153 0, // A1B5G5R5_UNORM
143 0, // RGBA16S 154 0, // R8_UNORM
144 0, // RGBA16UI 155 0, // R8_SNORM
145 0, // R11FG11FB10F 156 0, // R8_SINT
146 0, // RGBA32UI 157 0, // R8_UINT
147 2, // DXT1 158 0, // R16G16B16A16_FLOAT
148 2, // DXT23 159 0, // R16G16B16A16_UNORM
149 2, // DXT45 160 0, // R16G16B16A16_SNORM
150 2, // DXN1 161 0, // R16G16B16A16_SINT
151 2, // DXN2UNORM 162 0, // R16G16B16A16_UINT
152 2, // DXN2SNORM 163 0, // B10G11R11_FLOAT
153 2, // BC7U 164 0, // R32G32B32A32_UINT
154 2, // BC6H_UF16 165 2, // BC1_RGBA_UNORM
155 2, // BC6H_SF16 166 2, // BC2_UNORM
156 2, // ASTC_2D_4X4 167 2, // BC3_UNORM
157 0, // BGRA8 168 2, // BC4_UNORM
158 0, // RGBA32F 169 2, // BC4_SNORM
159 0, // RG32F 170 2, // BC5_UNORM
160 0, // R32F 171 2, // BC5_SNORM
161 0, // R16F 172 2, // BC7_UNORM
162 0, // R16U 173 2, // BC6H_UFLOAT
163 0, // R16S 174 2, // BC6H_SFLOAT
164 0, // R16UI 175 2, // ASTC_2D_4X4_UNORM
165 0, // R16I 176 0, // B8G8R8A8_UNORM
166 0, // RG16 177 0, // R32G32B32A32_FLOAT
167 0, // RG16F 178 0, // R32G32B32A32_SINT
168 0, // RG16UI 179 0, // R32G32_FLOAT
169 0, // RG16I 180 0, // R32G32_SINT
170 0, // RG16S 181 0, // R32_FLOAT
171 0, // RGB32F 182 0, // R16_FLOAT
172 0, // RGBA8_SRGB 183 0, // R16_UNORM
173 0, // RG8U 184 0, // R16_SNORM
174 0, // RG8S 185 0, // R16_UINT
175 0, // RG8UI 186 0, // R16_SINT
176 0, // RG32UI 187 0, // R16G16_UNORM
177 0, // RGBX16F 188 0, // R16G16_FLOAT
178 0, // R32UI 189 0, // R16G16_UINT
179 0, // R32I 190 0, // R16G16_SINT
180 2, // ASTC_2D_8X8 191 0, // R16G16_SNORM
181 2, // ASTC_2D_8X5 192 0, // R32G32B32_FLOAT
182 2, // ASTC_2D_5X4 193 0, // A8B8G8R8_SRGB
183 0, // BGRA8_SRGB 194 0, // R8G8_UNORM
184 2, // DXT1_SRGB 195 0, // R8G8_SNORM
185 2, // DXT23_SRGB 196 0, // R8G8_SINT
186 2, // DXT45_SRGB 197 0, // R8G8_UINT
187 2, // BC7U_SRGB 198 0, // R32G32_UINT
188 0, // R4G4B4A4U 199 0, // R16G16B16X16_FLOAT
200 0, // R32_UINT
201 0, // R32_SINT
202 2, // ASTC_2D_8X8_UNORM
203 2, // ASTC_2D_8X5_UNORM
204 2, // ASTC_2D_5X4_UNORM
205 0, // B8G8R8A8_SRGB
206 2, // BC1_RGBA_SRGB
207 2, // BC2_SRGB
208 2, // BC3_SRGB
209 2, // BC7_SRGB
210 0, // A4B4G4R4_UNORM
189 2, // ASTC_2D_4X4_SRGB 211 2, // ASTC_2D_4X4_SRGB
190 2, // ASTC_2D_8X8_SRGB 212 2, // ASTC_2D_8X8_SRGB
191 2, // ASTC_2D_8X5_SRGB 213 2, // ASTC_2D_8X5_SRGB
192 2, // ASTC_2D_5X4_SRGB 214 2, // ASTC_2D_5X4_SRGB
193 2, // ASTC_2D_5X5 215 2, // ASTC_2D_5X5_UNORM
194 2, // ASTC_2D_5X5_SRGB 216 2, // ASTC_2D_5X5_SRGB
195 2, // ASTC_2D_10X8 217 2, // ASTC_2D_10X8_UNORM
196 2, // ASTC_2D_10X8_SRGB 218 2, // ASTC_2D_10X8_SRGB
197 2, // ASTC_2D_6X6 219 2, // ASTC_2D_6X6_UNORM
198 2, // ASTC_2D_6X6_SRGB 220 2, // ASTC_2D_6X6_SRGB
199 2, // ASTC_2D_10X10 221 2, // ASTC_2D_10X10_UNORM
200 2, // ASTC_2D_10X10_SRGB 222 2, // ASTC_2D_10X10_SRGB
201 2, // ASTC_2D_12X12 223 2, // ASTC_2D_12X12_UNORM
202 2, // ASTC_2D_12X12_SRGB 224 2, // ASTC_2D_12X12_SRGB
203 2, // ASTC_2D_8X6 225 2, // ASTC_2D_8X6_UNORM
204 2, // ASTC_2D_8X6_SRGB 226 2, // ASTC_2D_8X6_SRGB
205 2, // ASTC_2D_6X5 227 2, // ASTC_2D_6X5_UNORM
206 2, // ASTC_2D_6X5_SRGB 228 2, // ASTC_2D_6X5_SRGB
207 0, // E5B9G9R9F 229 0, // E5B9G9R9_FLOAT
208 0, // Z32F 230 0, // D32_FLOAT
209 0, // Z16 231 0, // D16_UNORM
210 0, // Z24S8 232 0, // D24_UNORM_S8_UINT
211 0, // S8Z24 233 0, // S8_UINT_D24_UNORM
212 0, // Z32FS8 234 0, // D32_FLOAT_S8_UINT
213}}; 235}};
214 236
215/** 237/**
@@ -229,86 +251,97 @@ inline constexpr u32 GetCompressionFactor(PixelFormat format) {
229} 251}
230 252
231constexpr std::array<u32, MaxPixelFormat> block_width_table = {{ 253constexpr std::array<u32, MaxPixelFormat> block_width_table = {{
232 1, // ABGR8U 254 1, // A8B8G8R8_UNORM
233 1, // ABGR8S 255 1, // A8B8G8R8_SNORM
234 1, // ABGR8UI 256 1, // A8B8G8R8_SINT
235 1, // B5G6R5U 257 1, // A8B8G8R8_UINT
236 1, // A2B10G10R10U 258 1, // R5G6B5_UNORM
237 1, // A1B5G5R5U 259 1, // B5G6R5_UNORM
238 1, // R8U 260 1, // A1R5G5B5_UNORM
239 1, // R8UI 261 1, // A2B10G10R10_UNORM
240 1, // RGBA16F 262 1, // A2B10G10R10_UINT
241 1, // RGBA16U 263 1, // A1B5G5R5_UNORM
242 1, // RGBA16S 264 1, // R8_UNORM
243 1, // RGBA16UI 265 1, // R8_SNORM
244 1, // R11FG11FB10F 266 1, // R8_SINT
245 1, // RGBA32UI 267 1, // R8_UINT
246 4, // DXT1 268 1, // R16G16B16A16_FLOAT
247 4, // DXT23 269 1, // R16G16B16A16_UNORM
248 4, // DXT45 270 1, // R16G16B16A16_SNORM
249 4, // DXN1 271 1, // R16G16B16A16_SINT
250 4, // DXN2UNORM 272 1, // R16G16B16A16_UINT
251 4, // DXN2SNORM 273 1, // B10G11R11_FLOAT
252 4, // BC7U 274 1, // R32G32B32A32_UINT
253 4, // BC6H_UF16 275 4, // BC1_RGBA_UNORM
254 4, // BC6H_SF16 276 4, // BC2_UNORM
255 4, // ASTC_2D_4X4 277 4, // BC3_UNORM
256 1, // BGRA8 278 4, // BC4_UNORM
257 1, // RGBA32F 279 4, // BC4_SNORM
258 1, // RG32F 280 4, // BC5_UNORM
259 1, // R32F 281 4, // BC5_SNORM
260 1, // R16F 282 4, // BC7_UNORM
261 1, // R16U 283 4, // BC6H_UFLOAT
262 1, // R16S 284 4, // BC6H_SFLOAT
263 1, // R16UI 285 4, // ASTC_2D_4X4_UNORM
264 1, // R16I 286 1, // B8G8R8A8_UNORM
265 1, // RG16 287 1, // R32G32B32A32_FLOAT
266 1, // RG16F 288 1, // R32G32B32A32_SINT
267 1, // RG16UI 289 1, // R32G32_FLOAT
268 1, // RG16I 290 1, // R32G32_SINT
269 1, // RG16S 291 1, // R32_FLOAT
270 1, // RGB32F 292 1, // R16_FLOAT
271 1, // RGBA8_SRGB 293 1, // R16_UNORM
272 1, // RG8U 294 1, // R16_SNORM
273 1, // RG8S 295 1, // R16_UINT
274 1, // RG8UI 296 1, // R16_SINT
275 1, // RG32UI 297 1, // R16G16_UNORM
276 1, // RGBX16F 298 1, // R16G16_FLOAT
277 1, // R32UI 299 1, // R16G16_UINT
278 1, // R32I 300 1, // R16G16_SINT
279 8, // ASTC_2D_8X8 301 1, // R16G16_SNORM
280 8, // ASTC_2D_8X5 302 1, // R32G32B32_FLOAT
281 5, // ASTC_2D_5X4 303 1, // A8B8G8R8_SRGB
282 1, // BGRA8_SRGB 304 1, // R8G8_UNORM
283 4, // DXT1_SRGB 305 1, // R8G8_SNORM
284 4, // DXT23_SRGB 306 1, // R8G8_SINT
285 4, // DXT45_SRGB 307 1, // R8G8_UINT
286 4, // BC7U_SRGB 308 1, // R32G32_UINT
287 1, // R4G4B4A4U 309 1, // R16G16B16X16_FLOAT
310 1, // R32_UINT
311 1, // R32_SINT
312 8, // ASTC_2D_8X8_UNORM
313 8, // ASTC_2D_8X5_UNORM
314 5, // ASTC_2D_5X4_UNORM
315 1, // B8G8R8A8_SRGB
316 4, // BC1_RGBA_SRGB
317 4, // BC2_SRGB
318 4, // BC3_SRGB
319 4, // BC7_SRGB
320 1, // A4B4G4R4_UNORM
288 4, // ASTC_2D_4X4_SRGB 321 4, // ASTC_2D_4X4_SRGB
289 8, // ASTC_2D_8X8_SRGB 322 8, // ASTC_2D_8X8_SRGB
290 8, // ASTC_2D_8X5_SRGB 323 8, // ASTC_2D_8X5_SRGB
291 5, // ASTC_2D_5X4_SRGB 324 5, // ASTC_2D_5X4_SRGB
292 5, // ASTC_2D_5X5 325 5, // ASTC_2D_5X5_UNORM
293 5, // ASTC_2D_5X5_SRGB 326 5, // ASTC_2D_5X5_SRGB
294 10, // ASTC_2D_10X8 327 10, // ASTC_2D_10X8_UNORM
295 10, // ASTC_2D_10X8_SRGB 328 10, // ASTC_2D_10X8_SRGB
296 6, // ASTC_2D_6X6 329 6, // ASTC_2D_6X6_UNORM
297 6, // ASTC_2D_6X6_SRGB 330 6, // ASTC_2D_6X6_SRGB
298 10, // ASTC_2D_10X10 331 10, // ASTC_2D_10X10_UNORM
299 10, // ASTC_2D_10X10_SRGB 332 10, // ASTC_2D_10X10_SRGB
300 12, // ASTC_2D_12X12 333 12, // ASTC_2D_12X12_UNORM
301 12, // ASTC_2D_12X12_SRGB 334 12, // ASTC_2D_12X12_SRGB
302 8, // ASTC_2D_8X6 335 8, // ASTC_2D_8X6_UNORM
303 8, // ASTC_2D_8X6_SRGB 336 8, // ASTC_2D_8X6_SRGB
304 6, // ASTC_2D_6X5 337 6, // ASTC_2D_6X5_UNORM
305 6, // ASTC_2D_6X5_SRGB 338 6, // ASTC_2D_6X5_SRGB
306 1, // E5B9G9R9F 339 1, // E5B9G9R9_FLOAT
307 1, // Z32F 340 1, // D32_FLOAT
308 1, // Z16 341 1, // D16_UNORM
309 1, // Z24S8 342 1, // D24_UNORM_S8_UINT
310 1, // S8Z24 343 1, // S8_UINT_D24_UNORM
311 1, // Z32FS8 344 1, // D32_FLOAT_S8_UINT
312}}; 345}};
313 346
314static constexpr u32 GetDefaultBlockWidth(PixelFormat format) { 347static constexpr u32 GetDefaultBlockWidth(PixelFormat format) {
@@ -320,86 +353,97 @@ static constexpr u32 GetDefaultBlockWidth(PixelFormat format) {
320} 353}
321 354
322constexpr std::array<u32, MaxPixelFormat> block_height_table = {{ 355constexpr std::array<u32, MaxPixelFormat> block_height_table = {{
323 1, // ABGR8U 356 1, // A8B8G8R8_UNORM
324 1, // ABGR8S 357 1, // A8B8G8R8_SNORM
325 1, // ABGR8UI 358 1, // A8B8G8R8_SINT
326 1, // B5G6R5U 359 1, // A8B8G8R8_UINT
327 1, // A2B10G10R10U 360 1, // R5G6B5_UNORM
328 1, // A1B5G5R5U 361 1, // B5G6R5_UNORM
329 1, // R8U 362 1, // A1R5G5B5_UNORM
330 1, // R8UI 363 1, // A2B10G10R10_UNORM
331 1, // RGBA16F 364 1, // A2B10G10R10_UINT
332 1, // RGBA16U 365 1, // A1B5G5R5_UNORM
333 1, // RGBA16S 366 1, // R8_UNORM
334 1, // RGBA16UI 367 1, // R8_SNORM
335 1, // R11FG11FB10F 368 1, // R8_SINT
336 1, // RGBA32UI 369 1, // R8_UINT
337 4, // DXT1 370 1, // R16G16B16A16_FLOAT
338 4, // DXT23 371 1, // R16G16B16A16_UNORM
339 4, // DXT45 372 1, // R16G16B16A16_SNORM
340 4, // DXN1 373 1, // R16G16B16A16_SINT
341 4, // DXN2UNORM 374 1, // R16G16B16A16_UINT
342 4, // DXN2SNORM 375 1, // B10G11R11_FLOAT
343 4, // BC7U 376 1, // R32G32B32A32_UINT
344 4, // BC6H_UF16 377 4, // BC1_RGBA_UNORM
345 4, // BC6H_SF16 378 4, // BC2_UNORM
346 4, // ASTC_2D_4X4 379 4, // BC3_UNORM
347 1, // BGRA8 380 4, // BC4_UNORM
348 1, // RGBA32F 381 4, // BC4_SNORM
349 1, // RG32F 382 4, // BC5_UNORM
350 1, // R32F 383 4, // BC5_SNORM
351 1, // R16F 384 4, // BC7_UNORM
352 1, // R16U 385 4, // BC6H_UFLOAT
353 1, // R16S 386 4, // BC6H_SFLOAT
354 1, // R16UI 387 4, // ASTC_2D_4X4_UNORM
355 1, // R16I 388 1, // B8G8R8A8_UNORM
356 1, // RG16 389 1, // R32G32B32A32_FLOAT
357 1, // RG16F 390 1, // R32G32B32A32_SINT
358 1, // RG16UI 391 1, // R32G32_FLOAT
359 1, // RG16I 392 1, // R32G32_SINT
360 1, // RG16S 393 1, // R32_FLOAT
361 1, // RGB32F 394 1, // R16_FLOAT
362 1, // RGBA8_SRGB 395 1, // R16_UNORM
363 1, // RG8U 396 1, // R16_SNORM
364 1, // RG8S 397 1, // R16_UINT
365 1, // RG8UI 398 1, // R16_SINT
366 1, // RG32UI 399 1, // R16G16_UNORM
367 1, // RGBX16F 400 1, // R16G16_FLOAT
368 1, // R32UI 401 1, // R16G16_UINT
369 1, // R32I 402 1, // R16G16_SINT
370 8, // ASTC_2D_8X8 403 1, // R16G16_SNORM
371 5, // ASTC_2D_8X5 404 1, // R32G32B32_FLOAT
372 4, // ASTC_2D_5X4 405 1, // A8B8G8R8_SRGB
373 1, // BGRA8_SRGB 406 1, // R8G8_UNORM
374 4, // DXT1_SRGB 407 1, // R8G8_SNORM
375 4, // DXT23_SRGB 408 1, // R8G8_SINT
376 4, // DXT45_SRGB 409 1, // R8G8_UINT
377 4, // BC7U_SRGB 410 1, // R32G32_UINT
378 1, // R4G4B4A4U 411 1, // R16G16B16X16_FLOAT
412 1, // R32_UINT
413 1, // R32_SINT
414 8, // ASTC_2D_8X8_UNORM
415 5, // ASTC_2D_8X5_UNORM
416 4, // ASTC_2D_5X4_UNORM
417 1, // B8G8R8A8_SRGB
418 4, // BC1_RGBA_SRGB
419 4, // BC2_SRGB
420 4, // BC3_SRGB
421 4, // BC7_SRGB
422 1, // A4B4G4R4_UNORM
379 4, // ASTC_2D_4X4_SRGB 423 4, // ASTC_2D_4X4_SRGB
380 8, // ASTC_2D_8X8_SRGB 424 8, // ASTC_2D_8X8_SRGB
381 5, // ASTC_2D_8X5_SRGB 425 5, // ASTC_2D_8X5_SRGB
382 4, // ASTC_2D_5X4_SRGB 426 4, // ASTC_2D_5X4_SRGB
383 5, // ASTC_2D_5X5 427 5, // ASTC_2D_5X5_UNORM
384 5, // ASTC_2D_5X5_SRGB 428 5, // ASTC_2D_5X5_SRGB
385 8, // ASTC_2D_10X8 429 8, // ASTC_2D_10X8_UNORM
386 8, // ASTC_2D_10X8_SRGB 430 8, // ASTC_2D_10X8_SRGB
387 6, // ASTC_2D_6X6 431 6, // ASTC_2D_6X6_UNORM
388 6, // ASTC_2D_6X6_SRGB 432 6, // ASTC_2D_6X6_SRGB
389 10, // ASTC_2D_10X10 433 10, // ASTC_2D_10X10_UNORM
390 10, // ASTC_2D_10X10_SRGB 434 10, // ASTC_2D_10X10_SRGB
391 12, // ASTC_2D_12X12 435 12, // ASTC_2D_12X12_UNORM
392 12, // ASTC_2D_12X12_SRGB 436 12, // ASTC_2D_12X12_SRGB
393 6, // ASTC_2D_8X6 437 6, // ASTC_2D_8X6_UNORM
394 6, // ASTC_2D_8X6_SRGB 438 6, // ASTC_2D_8X6_SRGB
395 5, // ASTC_2D_6X5 439 5, // ASTC_2D_6X5_UNORM
396 5, // ASTC_2D_6X5_SRGB 440 5, // ASTC_2D_6X5_SRGB
397 1, // E5B9G9R9F 441 1, // E5B9G9R9_FLOAT
398 1, // Z32F 442 1, // D32_FLOAT
399 1, // Z16 443 1, // D16_UNORM
400 1, // Z24S8 444 1, // D24_UNORM_S8_UINT
401 1, // S8Z24 445 1, // S8_UINT_D24_UNORM
402 1, // Z32FS8 446 1, // D32_FLOAT_S8_UINT
403}}; 447}};
404 448
405static constexpr u32 GetDefaultBlockHeight(PixelFormat format) { 449static constexpr u32 GetDefaultBlockHeight(PixelFormat format) {
@@ -411,86 +455,97 @@ static constexpr u32 GetDefaultBlockHeight(PixelFormat format) {
411} 455}
412 456
413constexpr std::array<u32, MaxPixelFormat> bpp_table = {{ 457constexpr std::array<u32, MaxPixelFormat> bpp_table = {{
414 32, // ABGR8U 458 32, // A8B8G8R8_UNORM
415 32, // ABGR8S 459 32, // A8B8G8R8_SNORM
416 32, // ABGR8UI 460 32, // A8B8G8R8_SINT
417 16, // B5G6R5U 461 32, // A8B8G8R8_UINT
418 32, // A2B10G10R10U 462 16, // R5G6B5_UNORM
419 16, // A1B5G5R5U 463 16, // B5G6R5_UNORM
420 8, // R8U 464 16, // A1R5G5B5_UNORM
421 8, // R8UI 465 32, // A2B10G10R10_UNORM
422 64, // RGBA16F 466 32, // A2B10G10R10_UINT
423 64, // RGBA16U 467 16, // A1B5G5R5_UNORM
424 64, // RGBA16S 468 8, // R8_UNORM
425 64, // RGBA16UI 469 8, // R8_SNORM
426 32, // R11FG11FB10F 470 8, // R8_SINT
427 128, // RGBA32UI 471 8, // R8_UINT
428 64, // DXT1 472 64, // R16G16B16A16_FLOAT
429 128, // DXT23 473 64, // R16G16B16A16_UNORM
430 128, // DXT45 474 64, // R16G16B16A16_SNORM
431 64, // DXN1 475 64, // R16G16B16A16_SINT
432 128, // DXN2UNORM 476 64, // R16G16B16A16_UINT
433 128, // DXN2SNORM 477 32, // B10G11R11_FLOAT
434 128, // BC7U 478 128, // R32G32B32A32_UINT
435 128, // BC6H_UF16 479 64, // BC1_RGBA_UNORM
436 128, // BC6H_SF16 480 128, // BC2_UNORM
437 128, // ASTC_2D_4X4 481 128, // BC3_UNORM
438 32, // BGRA8 482 64, // BC4_UNORM
439 128, // RGBA32F 483 64, // BC4_SNORM
440 64, // RG32F 484 128, // BC5_UNORM
441 32, // R32F 485 128, // BC5_SNORM
442 16, // R16F 486 128, // BC7_UNORM
443 16, // R16U 487 128, // BC6H_UFLOAT
444 16, // R16S 488 128, // BC6H_SFLOAT
445 16, // R16UI 489 128, // ASTC_2D_4X4_UNORM
446 16, // R16I 490 32, // B8G8R8A8_UNORM
447 32, // RG16 491 128, // R32G32B32A32_FLOAT
448 32, // RG16F 492 128, // R32G32B32A32_SINT
449 32, // RG16UI 493 64, // R32G32_FLOAT
450 32, // RG16I 494 64, // R32G32_SINT
451 32, // RG16S 495 32, // R32_FLOAT
452 96, // RGB32F 496 16, // R16_FLOAT
453 32, // RGBA8_SRGB 497 16, // R16_UNORM
454 16, // RG8U 498 16, // R16_SNORM
455 16, // RG8S 499 16, // R16_UINT
456 16, // RG8UI 500 16, // R16_SINT
457 64, // RG32UI 501 32, // R16G16_UNORM
458 64, // RGBX16F 502 32, // R16G16_FLOAT
459 32, // R32UI 503 32, // R16G16_UINT
460 32, // R32I 504 32, // R16G16_SINT
461 128, // ASTC_2D_8X8 505 32, // R16G16_SNORM
462 128, // ASTC_2D_8X5 506 96, // R32G32B32_FLOAT
463 128, // ASTC_2D_5X4 507 32, // A8B8G8R8_SRGB
464 32, // BGRA8_SRGB 508 16, // R8G8_UNORM
465 64, // DXT1_SRGB 509 16, // R8G8_SNORM
466 128, // DXT23_SRGB 510 16, // R8G8_SINT
467 128, // DXT45_SRGB 511 16, // R8G8_UINT
468 128, // BC7U 512 64, // R32G32_UINT
469 16, // R4G4B4A4U 513 64, // R16G16B16X16_FLOAT
514 32, // R32_UINT
515 32, // R32_SINT
516 128, // ASTC_2D_8X8_UNORM
517 128, // ASTC_2D_8X5_UNORM
518 128, // ASTC_2D_5X4_UNORM
519 32, // B8G8R8A8_SRGB
520 64, // BC1_RGBA_SRGB
521 128, // BC2_SRGB
522 128, // BC3_SRGB
523 128, // BC7_UNORM
524 16, // A4B4G4R4_UNORM
470 128, // ASTC_2D_4X4_SRGB 525 128, // ASTC_2D_4X4_SRGB
471 128, // ASTC_2D_8X8_SRGB 526 128, // ASTC_2D_8X8_SRGB
472 128, // ASTC_2D_8X5_SRGB 527 128, // ASTC_2D_8X5_SRGB
473 128, // ASTC_2D_5X4_SRGB 528 128, // ASTC_2D_5X4_SRGB
474 128, // ASTC_2D_5X5 529 128, // ASTC_2D_5X5_UNORM
475 128, // ASTC_2D_5X5_SRGB 530 128, // ASTC_2D_5X5_SRGB
476 128, // ASTC_2D_10X8 531 128, // ASTC_2D_10X8_UNORM
477 128, // ASTC_2D_10X8_SRGB 532 128, // ASTC_2D_10X8_SRGB
478 128, // ASTC_2D_6X6 533 128, // ASTC_2D_6X6_UNORM
479 128, // ASTC_2D_6X6_SRGB 534 128, // ASTC_2D_6X6_SRGB
480 128, // ASTC_2D_10X10 535 128, // ASTC_2D_10X10_UNORM
481 128, // ASTC_2D_10X10_SRGB 536 128, // ASTC_2D_10X10_SRGB
482 128, // ASTC_2D_12X12 537 128, // ASTC_2D_12X12_UNORM
483 128, // ASTC_2D_12X12_SRGB 538 128, // ASTC_2D_12X12_SRGB
484 128, // ASTC_2D_8X6 539 128, // ASTC_2D_8X6_UNORM
485 128, // ASTC_2D_8X6_SRGB 540 128, // ASTC_2D_8X6_SRGB
486 128, // ASTC_2D_6X5 541 128, // ASTC_2D_6X5_UNORM
487 128, // ASTC_2D_6X5_SRGB 542 128, // ASTC_2D_6X5_SRGB
488 32, // E5B9G9R9F 543 32, // E5B9G9R9_FLOAT
489 32, // Z32F 544 32, // D32_FLOAT
490 16, // Z16 545 16, // D16_UNORM
491 32, // Z24S8 546 32, // D24_UNORM_S8_UINT
492 32, // S8Z24 547 32, // S8_UINT_D24_UNORM
493 64, // Z32FS8 548 64, // D32_FLOAT_S8_UINT
494}}; 549}};
495 550
496static constexpr u32 GetFormatBpp(PixelFormat format) { 551static constexpr u32 GetFormatBpp(PixelFormat format) {
@@ -529,7 +584,4 @@ bool IsPixelFormatSRGB(PixelFormat format);
529 584
530std::pair<u32, u32> GetASTCBlockSize(PixelFormat format); 585std::pair<u32, u32> GetASTCBlockSize(PixelFormat format);
531 586
532/// Returns true if the specified PixelFormat is a BCn format, e.g. DXT or DXN
533bool IsFormatBCn(PixelFormat format);
534
535} // namespace VideoCore::Surface 587} // namespace VideoCore::Surface
diff --git a/src/video_core/texture_cache/format_lookup_table.cpp b/src/video_core/texture_cache/format_lookup_table.cpp
index f476f03b0..7d5a75648 100644
--- a/src/video_core/texture_cache/format_lookup_table.cpp
+++ b/src/video_core/texture_cache/format_lookup_table.cpp
@@ -19,8 +19,6 @@ constexpr auto SNORM = ComponentType::SNORM;
19constexpr auto UNORM = ComponentType::UNORM; 19constexpr auto UNORM = ComponentType::UNORM;
20constexpr auto SINT = ComponentType::SINT; 20constexpr auto SINT = ComponentType::SINT;
21constexpr auto UINT = ComponentType::UINT; 21constexpr auto UINT = ComponentType::UINT;
22constexpr auto SNORM_FORCE_FP16 = ComponentType::SNORM_FORCE_FP16;
23constexpr auto UNORM_FORCE_FP16 = ComponentType::UNORM_FORCE_FP16;
24constexpr auto FLOAT = ComponentType::FLOAT; 22constexpr auto FLOAT = ComponentType::FLOAT;
25constexpr bool C = false; // Normal color 23constexpr bool C = false; // Normal color
26constexpr bool S = true; // Srgb 24constexpr bool S = true; // Srgb
@@ -41,119 +39,126 @@ struct Table {
41 ComponentType alpha_component; 39 ComponentType alpha_component;
42 bool is_srgb; 40 bool is_srgb;
43}; 41};
44constexpr std::array<Table, 78> DefinitionTable = {{ 42constexpr std::array<Table, 86> DefinitionTable = {{
45 {TextureFormat::A8R8G8B8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ABGR8U}, 43 {TextureFormat::A8R8G8B8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::A8B8G8R8_UNORM},
46 {TextureFormat::A8R8G8B8, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::ABGR8S}, 44 {TextureFormat::A8R8G8B8, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::A8B8G8R8_SNORM},
47 {TextureFormat::A8R8G8B8, C, UINT, UINT, UINT, UINT, PixelFormat::ABGR8UI}, 45 {TextureFormat::A8R8G8B8, C, UINT, UINT, UINT, UINT, PixelFormat::A8B8G8R8_UINT},
48 {TextureFormat::A8R8G8B8, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::RGBA8_SRGB}, 46 {TextureFormat::A8R8G8B8, C, SINT, SINT, SINT, SINT, PixelFormat::A8B8G8R8_SINT},
47 {TextureFormat::A8R8G8B8, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::A8B8G8R8_SRGB},
49 48
50 {TextureFormat::B5G6R5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::B5G6R5U}, 49 {TextureFormat::B5G6R5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::B5G6R5_UNORM},
51 50
52 {TextureFormat::A2B10G10R10, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::A2B10G10R10U}, 51 {TextureFormat::A2B10G10R10, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::A2B10G10R10_UNORM},
52 {TextureFormat::A2B10G10R10, C, UINT, UINT, UINT, UINT, PixelFormat::A2B10G10R10_UINT},
53 53
54 {TextureFormat::A1B5G5R5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::A1B5G5R5U}, 54 {TextureFormat::A1B5G5R5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::A1B5G5R5_UNORM},
55 55
56 {TextureFormat::A4B4G4R4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R4G4B4A4U}, 56 {TextureFormat::A4B4G4R4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::A4B4G4R4_UNORM},
57 57
58 {TextureFormat::R8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R8U}, 58 {TextureFormat::R8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R8_UNORM},
59 {TextureFormat::R8, C, UINT, UINT, UINT, UINT, PixelFormat::R8UI}, 59 {TextureFormat::R8, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::R8_SNORM},
60 {TextureFormat::R8, C, UINT, UINT, UINT, UINT, PixelFormat::R8_UINT},
61 {TextureFormat::R8, C, SINT, SINT, SINT, SINT, PixelFormat::R8_SINT},
60 62
61 {TextureFormat::G8R8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::RG8U}, 63 {TextureFormat::R8G8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R8G8_UNORM},
62 {TextureFormat::G8R8, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::RG8S}, 64 {TextureFormat::R8G8, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::R8G8_SNORM},
63 {TextureFormat::G8R8, C, UINT, UINT, UINT, UINT, PixelFormat::RG8UI}, 65 {TextureFormat::R8G8, C, UINT, UINT, UINT, UINT, PixelFormat::R8G8_UINT},
66 {TextureFormat::R8G8, C, SINT, SINT, SINT, SINT, PixelFormat::R8G8_SINT},
64 67
65 {TextureFormat::R16_G16_B16_A16, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::RGBA16S}, 68 {TextureFormat::R16G16B16A16, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::R16G16B16A16_SNORM},
66 {TextureFormat::R16_G16_B16_A16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::RGBA16U}, 69 {TextureFormat::R16G16B16A16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R16G16B16A16_UNORM},
67 {TextureFormat::R16_G16_B16_A16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RGBA16F}, 70 {TextureFormat::R16G16B16A16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R16G16B16A16_FLOAT},
68 {TextureFormat::R16_G16_B16_A16, C, UINT, UINT, UINT, UINT, PixelFormat::RGBA16UI}, 71 {TextureFormat::R16G16B16A16, C, UINT, UINT, UINT, UINT, PixelFormat::R16G16B16A16_UINT},
72 {TextureFormat::R16G16B16A16, C, SINT, SINT, SINT, SINT, PixelFormat::R16G16B16A16_SINT},
69 73
70 {TextureFormat::R16_G16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RG16F}, 74 {TextureFormat::R16G16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R16G16_FLOAT},
71 {TextureFormat::R16_G16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::RG16}, 75 {TextureFormat::R16G16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R16G16_UNORM},
72 {TextureFormat::R16_G16, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::RG16S}, 76 {TextureFormat::R16G16, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::R16G16_SNORM},
73 {TextureFormat::R16_G16, C, UINT, UINT, UINT, UINT, PixelFormat::RG16UI}, 77 {TextureFormat::R16G16, C, UINT, UINT, UINT, UINT, PixelFormat::R16G16_UINT},
74 {TextureFormat::R16_G16, C, SINT, SINT, SINT, SINT, PixelFormat::RG16I}, 78 {TextureFormat::R16G16, C, SINT, SINT, SINT, SINT, PixelFormat::R16G16_SINT},
75 79
76 {TextureFormat::R16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R16F}, 80 {TextureFormat::R16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R16_FLOAT},
77 {TextureFormat::R16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R16U}, 81 {TextureFormat::R16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R16_UNORM},
78 {TextureFormat::R16, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::R16S}, 82 {TextureFormat::R16, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::R16_SNORM},
79 {TextureFormat::R16, C, UINT, UINT, UINT, UINT, PixelFormat::R16UI}, 83 {TextureFormat::R16, C, UINT, UINT, UINT, UINT, PixelFormat::R16_UINT},
80 {TextureFormat::R16, C, SINT, SINT, SINT, SINT, PixelFormat::R16I}, 84 {TextureFormat::R16, C, SINT, SINT, SINT, SINT, PixelFormat::R16_SINT},
81 85
82 {TextureFormat::BF10GF11RF11, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R11FG11FB10F}, 86 {TextureFormat::B10G11R11, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::B10G11R11_FLOAT},
83 87
84 {TextureFormat::R32_G32_B32_A32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RGBA32F}, 88 {TextureFormat::R32G32B32A32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R32G32B32A32_FLOAT},
85 {TextureFormat::R32_G32_B32_A32, C, UINT, UINT, UINT, UINT, PixelFormat::RGBA32UI}, 89 {TextureFormat::R32G32B32A32, C, UINT, UINT, UINT, UINT, PixelFormat::R32G32B32A32_UINT},
90 {TextureFormat::R32G32B32A32, C, SINT, SINT, SINT, SINT, PixelFormat::R32G32B32A32_SINT},
86 91
87 {TextureFormat::R32_G32_B32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RGB32F}, 92 {TextureFormat::R32G32B32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R32G32B32_FLOAT},
88 93
89 {TextureFormat::R32_G32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RG32F}, 94 {TextureFormat::R32G32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R32G32_FLOAT},
90 {TextureFormat::R32_G32, C, UINT, UINT, UINT, UINT, PixelFormat::RG32UI}, 95 {TextureFormat::R32G32, C, UINT, UINT, UINT, UINT, PixelFormat::R32G32_UINT},
96 {TextureFormat::R32G32, C, SINT, SINT, SINT, SINT, PixelFormat::R32G32_SINT},
91 97
92 {TextureFormat::R32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R32F}, 98 {TextureFormat::R32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R32_FLOAT},
93 {TextureFormat::R32, C, UINT, UINT, UINT, UINT, PixelFormat::R32UI}, 99 {TextureFormat::R32, C, UINT, UINT, UINT, UINT, PixelFormat::R32_UINT},
94 {TextureFormat::R32, C, SINT, SINT, SINT, SINT, PixelFormat::R32I}, 100 {TextureFormat::R32, C, SINT, SINT, SINT, SINT, PixelFormat::R32_SINT},
95 101
96 {TextureFormat::E5B9G9R9_SHAREDEXP, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::E5B9G9R9F}, 102 {TextureFormat::E5B9G9R9, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::E5B9G9R9_FLOAT},
97 103
98 {TextureFormat::ZF32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::Z32F}, 104 {TextureFormat::D32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::D32_FLOAT},
99 {TextureFormat::Z16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::Z16}, 105 {TextureFormat::D16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::D16_UNORM},
100 {TextureFormat::S8Z24, C, UINT, UNORM, UNORM, UNORM, PixelFormat::S8Z24}, 106 {TextureFormat::S8D24, C, UINT, UNORM, UNORM, UNORM, PixelFormat::S8_UINT_D24_UNORM},
101 {TextureFormat::G24R8, C, UINT, UNORM, UNORM, UNORM, PixelFormat::S8Z24}, 107 {TextureFormat::R8G24, C, UINT, UNORM, UNORM, UNORM, PixelFormat::S8_UINT_D24_UNORM},
102 {TextureFormat::ZF32_X24S8, C, FLOAT, UINT, UNORM, UNORM, PixelFormat::Z32FS8}, 108 {TextureFormat::D32S8, C, FLOAT, UINT, UNORM, UNORM, PixelFormat::D32_FLOAT_S8_UINT},
103 109
104 {TextureFormat::DXT1, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT1}, 110 {TextureFormat::BC1_RGBA, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC1_RGBA_UNORM},
105 {TextureFormat::DXT1, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT1_SRGB}, 111 {TextureFormat::BC1_RGBA, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC1_RGBA_SRGB},
106 112
107 {TextureFormat::DXT23, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT23}, 113 {TextureFormat::BC2, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC2_UNORM},
108 {TextureFormat::DXT23, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT23_SRGB}, 114 {TextureFormat::BC2, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC2_SRGB},
109 115
110 {TextureFormat::DXT45, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT45}, 116 {TextureFormat::BC3, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC3_UNORM},
111 {TextureFormat::DXT45, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT45_SRGB}, 117 {TextureFormat::BC3, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC3_SRGB},
112 118
113 // TODO: Use a different pixel format for SNORM 119 {TextureFormat::BC4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC4_UNORM},
114 {TextureFormat::DXN1, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXN1}, 120 {TextureFormat::BC4, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::BC4_SNORM},
115 {TextureFormat::DXN1, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::DXN1},
116 121
117 {TextureFormat::DXN2, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXN2UNORM}, 122 {TextureFormat::BC5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC5_UNORM},
118 {TextureFormat::DXN2, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::DXN2SNORM}, 123 {TextureFormat::BC5, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::BC5_SNORM},
119 124
120 {TextureFormat::BC7U, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC7U}, 125 {TextureFormat::BC7, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC7_UNORM},
121 {TextureFormat::BC7U, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC7U_SRGB}, 126 {TextureFormat::BC7, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC7_SRGB},
122 127
123 {TextureFormat::BC6H_SF16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::BC6H_SF16}, 128 {TextureFormat::BC6H_SFLOAT, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::BC6H_SFLOAT},
124 {TextureFormat::BC6H_UF16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::BC6H_UF16}, 129 {TextureFormat::BC6H_UFLOAT, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::BC6H_UFLOAT},
125 130
126 {TextureFormat::ASTC_2D_4X4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_4X4}, 131 {TextureFormat::ASTC_2D_4X4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_4X4_UNORM},
127 {TextureFormat::ASTC_2D_4X4, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_4X4_SRGB}, 132 {TextureFormat::ASTC_2D_4X4, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_4X4_SRGB},
128 133
129 {TextureFormat::ASTC_2D_5X4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X4}, 134 {TextureFormat::ASTC_2D_5X4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X4_UNORM},
130 {TextureFormat::ASTC_2D_5X4, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X4_SRGB}, 135 {TextureFormat::ASTC_2D_5X4, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X4_SRGB},
131 136
132 {TextureFormat::ASTC_2D_5X5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X5}, 137 {TextureFormat::ASTC_2D_5X5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X5_UNORM},
133 {TextureFormat::ASTC_2D_5X5, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X5_SRGB}, 138 {TextureFormat::ASTC_2D_5X5, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X5_SRGB},
134 139
135 {TextureFormat::ASTC_2D_8X8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X8}, 140 {TextureFormat::ASTC_2D_8X8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X8_UNORM},
136 {TextureFormat::ASTC_2D_8X8, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X8_SRGB}, 141 {TextureFormat::ASTC_2D_8X8, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X8_SRGB},
137 142
138 {TextureFormat::ASTC_2D_8X5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X5}, 143 {TextureFormat::ASTC_2D_8X5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X5_UNORM},
139 {TextureFormat::ASTC_2D_8X5, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X5_SRGB}, 144 {TextureFormat::ASTC_2D_8X5, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X5_SRGB},
140 145
141 {TextureFormat::ASTC_2D_10X8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X8}, 146 {TextureFormat::ASTC_2D_10X8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X8_UNORM},
142 {TextureFormat::ASTC_2D_10X8, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X8_SRGB}, 147 {TextureFormat::ASTC_2D_10X8, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X8_SRGB},
143 148
144 {TextureFormat::ASTC_2D_6X6, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X6}, 149 {TextureFormat::ASTC_2D_6X6, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X6_UNORM},
145 {TextureFormat::ASTC_2D_6X6, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X6_SRGB}, 150 {TextureFormat::ASTC_2D_6X6, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X6_SRGB},
146 151
147 {TextureFormat::ASTC_2D_10X10, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X10}, 152 {TextureFormat::ASTC_2D_10X10, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X10_UNORM},
148 {TextureFormat::ASTC_2D_10X10, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X10_SRGB}, 153 {TextureFormat::ASTC_2D_10X10, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X10_SRGB},
149 154
150 {TextureFormat::ASTC_2D_12X12, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_12X12}, 155 {TextureFormat::ASTC_2D_12X12, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_12X12_UNORM},
151 {TextureFormat::ASTC_2D_12X12, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_12X12_SRGB}, 156 {TextureFormat::ASTC_2D_12X12, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_12X12_SRGB},
152 157
153 {TextureFormat::ASTC_2D_8X6, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X6}, 158 {TextureFormat::ASTC_2D_8X6, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X6_UNORM},
154 {TextureFormat::ASTC_2D_8X6, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X6_SRGB}, 159 {TextureFormat::ASTC_2D_8X6, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X6_SRGB},
155 160
156 {TextureFormat::ASTC_2D_6X5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X5}, 161 {TextureFormat::ASTC_2D_6X5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X5_UNORM},
157 {TextureFormat::ASTC_2D_6X5, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X5_SRGB}, 162 {TextureFormat::ASTC_2D_6X5, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X5_SRGB},
158}}; 163}};
159 164
@@ -184,7 +189,7 @@ PixelFormat FormatLookupTable::GetPixelFormat(TextureFormat format, bool is_srgb
184 static_cast<int>(format), is_srgb, static_cast<int>(red_component), 189 static_cast<int>(format), is_srgb, static_cast<int>(red_component),
185 static_cast<int>(green_component), static_cast<int>(blue_component), 190 static_cast<int>(green_component), static_cast<int>(blue_component),
186 static_cast<int>(alpha_component)); 191 static_cast<int>(alpha_component));
187 return PixelFormat::ABGR8U; 192 return PixelFormat::A8B8G8R8_UNORM;
188} 193}
189 194
190void FormatLookupTable::Set(TextureFormat format, bool is_srgb, ComponentType red_component, 195void FormatLookupTable::Set(TextureFormat format, bool is_srgb, ComponentType red_component,
diff --git a/src/video_core/texture_cache/surface_base.cpp b/src/video_core/texture_cache/surface_base.cpp
index 0caf3b4f0..dfcf36e0b 100644
--- a/src/video_core/texture_cache/surface_base.cpp
+++ b/src/video_core/texture_cache/surface_base.cpp
@@ -228,7 +228,7 @@ void SurfaceBaseImpl::LoadBuffer(Tegra::MemoryManager& memory_manager,
228 } 228 }
229 } 229 }
230 230
231 if (!is_converted && params.pixel_format != PixelFormat::S8Z24) { 231 if (!is_converted && params.pixel_format != PixelFormat::S8_UINT_D24_UNORM) {
232 return; 232 return;
233 } 233 }
234 234
diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp
index 921562c1f..9a98f0e98 100644
--- a/src/video_core/texture_cache/surface_params.cpp
+++ b/src/video_core/texture_cache/surface_params.cpp
@@ -74,21 +74,21 @@ SurfaceParams SurfaceParams::CreateForTexture(const FormatLookupTable& lookup_ta
74 SurfaceParams params; 74 SurfaceParams params;
75 params.is_tiled = tic.IsTiled(); 75 params.is_tiled = tic.IsTiled();
76 params.srgb_conversion = tic.IsSrgbConversionEnabled(); 76 params.srgb_conversion = tic.IsSrgbConversionEnabled();
77 params.block_width = params.is_tiled ? tic.BlockWidth() : 0, 77 params.block_width = params.is_tiled ? tic.BlockWidth() : 0;
78 params.block_height = params.is_tiled ? tic.BlockHeight() : 0, 78 params.block_height = params.is_tiled ? tic.BlockHeight() : 0;
79 params.block_depth = params.is_tiled ? tic.BlockDepth() : 0, 79 params.block_depth = params.is_tiled ? tic.BlockDepth() : 0;
80 params.tile_width_spacing = params.is_tiled ? (1 << tic.tile_width_spacing.Value()) : 1; 80 params.tile_width_spacing = params.is_tiled ? (1 << tic.tile_width_spacing.Value()) : 1;
81 params.pixel_format = lookup_table.GetPixelFormat( 81 params.pixel_format = lookup_table.GetPixelFormat(
82 tic.format, params.srgb_conversion, tic.r_type, tic.g_type, tic.b_type, tic.a_type); 82 tic.format, params.srgb_conversion, tic.r_type, tic.g_type, tic.b_type, tic.a_type);
83 params.type = GetFormatType(params.pixel_format); 83 params.type = GetFormatType(params.pixel_format);
84 if (entry.is_shadow && params.type == SurfaceType::ColorTexture) { 84 if (entry.is_shadow && params.type == SurfaceType::ColorTexture) {
85 switch (params.pixel_format) { 85 switch (params.pixel_format) {
86 case PixelFormat::R16U: 86 case PixelFormat::R16_UNORM:
87 case PixelFormat::R16F: 87 case PixelFormat::R16_FLOAT:
88 params.pixel_format = PixelFormat::Z16; 88 params.pixel_format = PixelFormat::D16_UNORM;
89 break; 89 break;
90 case PixelFormat::R32F: 90 case PixelFormat::R32_FLOAT:
91 params.pixel_format = PixelFormat::Z32F; 91 params.pixel_format = PixelFormat::D32_FLOAT;
92 break; 92 break;
93 default: 93 default:
94 UNIMPLEMENTED_MSG("Unimplemented shadow convert format: {}", 94 UNIMPLEMENTED_MSG("Unimplemented shadow convert format: {}",
@@ -130,14 +130,13 @@ SurfaceParams SurfaceParams::CreateForImage(const FormatLookupTable& lookup_tabl
130 SurfaceParams params; 130 SurfaceParams params;
131 params.is_tiled = tic.IsTiled(); 131 params.is_tiled = tic.IsTiled();
132 params.srgb_conversion = tic.IsSrgbConversionEnabled(); 132 params.srgb_conversion = tic.IsSrgbConversionEnabled();
133 params.block_width = params.is_tiled ? tic.BlockWidth() : 0, 133 params.block_width = params.is_tiled ? tic.BlockWidth() : 0;
134 params.block_height = params.is_tiled ? tic.BlockHeight() : 0, 134 params.block_height = params.is_tiled ? tic.BlockHeight() : 0;
135 params.block_depth = params.is_tiled ? tic.BlockDepth() : 0, 135 params.block_depth = params.is_tiled ? tic.BlockDepth() : 0;
136 params.tile_width_spacing = params.is_tiled ? (1 << tic.tile_width_spacing.Value()) : 1; 136 params.tile_width_spacing = params.is_tiled ? (1 << tic.tile_width_spacing.Value()) : 1;
137 params.pixel_format = lookup_table.GetPixelFormat( 137 params.pixel_format = lookup_table.GetPixelFormat(
138 tic.format, params.srgb_conversion, tic.r_type, tic.g_type, tic.b_type, tic.a_type); 138 tic.format, params.srgb_conversion, tic.r_type, tic.g_type, tic.b_type, tic.a_type);
139 params.type = GetFormatType(params.pixel_format); 139 params.type = GetFormatType(params.pixel_format);
140 params.type = GetFormatType(params.pixel_format);
141 params.target = ImageTypeToSurfaceTarget(entry.type); 140 params.target = ImageTypeToSurfaceTarget(entry.type);
142 // TODO: on 1DBuffer we should use the tic info. 141 // TODO: on 1DBuffer we should use the tic info.
143 if (tic.IsBuffer()) { 142 if (tic.IsBuffer()) {
@@ -167,27 +166,30 @@ SurfaceParams SurfaceParams::CreateForImage(const FormatLookupTable& lookup_tabl
167 166
168SurfaceParams SurfaceParams::CreateForDepthBuffer(Core::System& system) { 167SurfaceParams SurfaceParams::CreateForDepthBuffer(Core::System& system) {
169 const auto& regs = system.GPU().Maxwell3D().regs; 168 const auto& regs = system.GPU().Maxwell3D().regs;
170 SurfaceParams params;
171 params.is_tiled = regs.zeta.memory_layout.type ==
172 Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear;
173 params.srgb_conversion = false;
174 params.block_width = std::min(regs.zeta.memory_layout.block_width.Value(), 5U);
175 params.block_height = std::min(regs.zeta.memory_layout.block_height.Value(), 5U);
176 params.block_depth = std::min(regs.zeta.memory_layout.block_depth.Value(), 5U);
177 params.tile_width_spacing = 1;
178 params.pixel_format = PixelFormatFromDepthFormat(regs.zeta.format);
179 params.type = GetFormatType(params.pixel_format);
180 params.width = regs.zeta_width;
181 params.height = regs.zeta_height;
182 params.pitch = 0;
183 params.num_levels = 1;
184 params.emulated_levels = 1;
185 169
186 const bool is_layered = regs.zeta_layers > 1 && params.block_depth == 0; 170 const auto block_depth = std::min(regs.zeta.memory_layout.block_depth.Value(), 5U);
187 params.is_layered = is_layered; 171 const bool is_layered = regs.zeta_layers > 1 && block_depth == 0;
188 params.target = is_layered ? SurfaceTarget::Texture2DArray : SurfaceTarget::Texture2D; 172 const auto pixel_format = PixelFormatFromDepthFormat(regs.zeta.format);
189 params.depth = is_layered ? regs.zeta_layers.Value() : 1U; 173
190 return params; 174 return {
175 .is_tiled = regs.zeta.memory_layout.type ==
176 Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear,
177 .srgb_conversion = false,
178 .is_layered = is_layered,
179 .block_width = std::min(regs.zeta.memory_layout.block_width.Value(), 5U),
180 .block_height = std::min(regs.zeta.memory_layout.block_height.Value(), 5U),
181 .block_depth = block_depth,
182 .tile_width_spacing = 1,
183 .width = regs.zeta_width,
184 .height = regs.zeta_height,
185 .depth = is_layered ? regs.zeta_layers.Value() : 1U,
186 .pitch = 0,
187 .num_levels = 1,
188 .emulated_levels = 1,
189 .pixel_format = pixel_format,
190 .type = GetFormatType(pixel_format),
191 .target = is_layered ? SurfaceTarget::Texture2DArray : SurfaceTarget::Texture2D,
192 };
191} 193}
192 194
193SurfaceParams SurfaceParams::CreateForFramebuffer(Core::System& system, std::size_t index) { 195SurfaceParams SurfaceParams::CreateForFramebuffer(Core::System& system, std::size_t index) {
@@ -195,8 +197,8 @@ SurfaceParams SurfaceParams::CreateForFramebuffer(Core::System& system, std::siz
195 SurfaceParams params; 197 SurfaceParams params;
196 params.is_tiled = 198 params.is_tiled =
197 config.memory_layout.type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; 199 config.memory_layout.type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear;
198 params.srgb_conversion = config.format == Tegra::RenderTargetFormat::BGRA8_SRGB || 200 params.srgb_conversion = config.format == Tegra::RenderTargetFormat::B8G8R8A8_SRGB ||
199 config.format == Tegra::RenderTargetFormat::RGBA8_SRGB; 201 config.format == Tegra::RenderTargetFormat::A8B8G8R8_SRGB;
200 params.block_width = config.memory_layout.block_width; 202 params.block_width = config.memory_layout.block_width;
201 params.block_height = config.memory_layout.block_height; 203 params.block_height = config.memory_layout.block_height;
202 params.block_depth = config.memory_layout.block_depth; 204 params.block_depth = config.memory_layout.block_depth;
@@ -233,24 +235,29 @@ SurfaceParams SurfaceParams::CreateForFramebuffer(Core::System& system, std::siz
233 235
234SurfaceParams SurfaceParams::CreateForFermiCopySurface( 236SurfaceParams SurfaceParams::CreateForFermiCopySurface(
235 const Tegra::Engines::Fermi2D::Regs::Surface& config) { 237 const Tegra::Engines::Fermi2D::Regs::Surface& config) {
236 SurfaceParams params{}; 238 const bool is_tiled = !config.linear;
237 params.is_tiled = !config.linear; 239 const auto pixel_format = PixelFormatFromRenderTargetFormat(config.format);
238 params.srgb_conversion = config.format == Tegra::RenderTargetFormat::BGRA8_SRGB || 240
239 config.format == Tegra::RenderTargetFormat::RGBA8_SRGB; 241 SurfaceParams params{
240 params.block_width = params.is_tiled ? std::min(config.BlockWidth(), 5U) : 0, 242 .is_tiled = is_tiled,
241 params.block_height = params.is_tiled ? std::min(config.BlockHeight(), 5U) : 0, 243 .srgb_conversion = config.format == Tegra::RenderTargetFormat::B8G8R8A8_SRGB ||
242 params.block_depth = params.is_tiled ? std::min(config.BlockDepth(), 5U) : 0, 244 config.format == Tegra::RenderTargetFormat::A8B8G8R8_SRGB,
243 params.tile_width_spacing = 1; 245 .block_width = is_tiled ? std::min(config.BlockWidth(), 5U) : 0U,
244 params.pixel_format = PixelFormatFromRenderTargetFormat(config.format); 246 .block_height = is_tiled ? std::min(config.BlockHeight(), 5U) : 0U,
245 params.type = GetFormatType(params.pixel_format); 247 .block_depth = is_tiled ? std::min(config.BlockDepth(), 5U) : 0U,
246 params.width = config.width; 248 .tile_width_spacing = 1,
247 params.height = config.height; 249 .width = config.width,
248 params.pitch = config.pitch; 250 .height = config.height,
249 // TODO(Rodrigo): Try to guess texture arrays from parameters 251 .depth = 1,
250 params.target = SurfaceTarget::Texture2D; 252 .pitch = config.pitch,
251 params.depth = 1; 253 .num_levels = 1,
252 params.num_levels = 1; 254 .emulated_levels = 1,
253 params.emulated_levels = 1; 255 .pixel_format = pixel_format,
256 .type = GetFormatType(pixel_format),
257 // TODO(Rodrigo): Try to guess texture arrays from parameters
258 .target = SurfaceTarget::Texture2D,
259 };
260
254 params.is_layered = params.IsLayered(); 261 params.is_layered = params.IsLayered();
255 return params; 262 return params;
256} 263}
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index cdcddb225..96c4e4cc2 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -373,9 +373,9 @@ protected:
373 siblings_table[static_cast<std::size_t>(b)] = a; 373 siblings_table[static_cast<std::size_t>(b)] = a;
374 }; 374 };
375 std::fill(siblings_table.begin(), siblings_table.end(), PixelFormat::Invalid); 375 std::fill(siblings_table.begin(), siblings_table.end(), PixelFormat::Invalid);
376 make_siblings(PixelFormat::Z16, PixelFormat::R16U); 376 make_siblings(PixelFormat::D16_UNORM, PixelFormat::R16_UNORM);
377 make_siblings(PixelFormat::Z32F, PixelFormat::R32F); 377 make_siblings(PixelFormat::D32_FLOAT, PixelFormat::R32_FLOAT);
378 make_siblings(PixelFormat::Z32FS8, PixelFormat::RG32F); 378 make_siblings(PixelFormat::D32_FLOAT_S8_UINT, PixelFormat::R32G32_FLOAT);
379 379
380 sampled_textures.reserve(64); 380 sampled_textures.reserve(64);
381 } 381 }
@@ -1031,7 +1031,7 @@ private:
1031 params.pitch = 4; 1031 params.pitch = 4;
1032 params.num_levels = 1; 1032 params.num_levels = 1;
1033 params.emulated_levels = 1; 1033 params.emulated_levels = 1;
1034 params.pixel_format = VideoCore::Surface::PixelFormat::R8U; 1034 params.pixel_format = VideoCore::Surface::PixelFormat::R8_UNORM;
1035 params.type = VideoCore::Surface::SurfaceType::ColorTexture; 1035 params.type = VideoCore::Surface::SurfaceType::ColorTexture;
1036 auto surface = CreateSurface(0ULL, params); 1036 auto surface = CreateSurface(0ULL, params);
1037 invalid_memory.resize(surface->GetHostSizeInBytes(), 0U); 1037 invalid_memory.resize(surface->GetHostSizeInBytes(), 0U);
diff --git a/src/video_core/textures/convert.cpp b/src/video_core/textures/convert.cpp
index f3efa7eb0..962921483 100644
--- a/src/video_core/textures/convert.cpp
+++ b/src/video_core/textures/convert.cpp
@@ -35,7 +35,7 @@ void SwapS8Z24ToZ24S8(u8* data, u32 width, u32 height) {
35 S8Z24 s8z24_pixel{}; 35 S8Z24 s8z24_pixel{};
36 Z24S8 z24s8_pixel{}; 36 Z24S8 z24s8_pixel{};
37 constexpr auto bpp{ 37 constexpr auto bpp{
38 VideoCore::Surface::GetBytesPerPixel(VideoCore::Surface::PixelFormat::S8Z24)}; 38 VideoCore::Surface::GetBytesPerPixel(VideoCore::Surface::PixelFormat::S8_UINT_D24_UNORM)};
39 for (std::size_t y = 0; y < height; ++y) { 39 for (std::size_t y = 0; y < height; ++y) {
40 for (std::size_t x = 0; x < width; ++x) { 40 for (std::size_t x = 0; x < width; ++x) {
41 const std::size_t offset{bpp * (y * width + x)}; 41 const std::size_t offset{bpp * (y * width + x)};
@@ -73,7 +73,7 @@ void ConvertFromGuestToHost(u8* in_data, u8* out_data, PixelFormat pixel_format,
73 in_data, width, height, depth, block_width, block_height); 73 in_data, width, height, depth, block_width, block_height);
74 std::copy(rgba8_data.begin(), rgba8_data.end(), out_data); 74 std::copy(rgba8_data.begin(), rgba8_data.end(), out_data);
75 75
76 } else if (convert_s8z24 && pixel_format == PixelFormat::S8Z24) { 76 } else if (convert_s8z24 && pixel_format == PixelFormat::S8_UINT_D24_UNORM) {
77 Tegra::Texture::ConvertS8Z24ToZ24S8(in_data, width, height); 77 Tegra::Texture::ConvertS8Z24ToZ24S8(in_data, width, height);
78 } 78 }
79} 79}
@@ -85,7 +85,7 @@ void ConvertFromHostToGuest(u8* data, PixelFormat pixel_format, u32 width, u32 h
85 static_cast<u32>(pixel_format)); 85 static_cast<u32>(pixel_format));
86 UNREACHABLE(); 86 UNREACHABLE();
87 87
88 } else if (convert_s8z24 && pixel_format == PixelFormat::S8Z24) { 88 } else if (convert_s8z24 && pixel_format == PixelFormat::S8_UINT_D24_UNORM) {
89 Tegra::Texture::ConvertZ24S8ToS8Z24(data, width, height); 89 Tegra::Texture::ConvertZ24S8ToS8Z24(data, width, height);
90 } 90 }
91} 91}
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp
index 98beabef1..474ae620a 100644
--- a/src/video_core/textures/decoders.cpp
+++ b/src/video_core/textures/decoders.cpp
@@ -184,53 +184,6 @@ void CopySwizzledData(u32 width, u32 height, u32 depth, u32 bytes_per_pixel,
184 } 184 }
185} 185}
186 186
187u32 BytesPerPixel(TextureFormat format) {
188 switch (format) {
189 case TextureFormat::DXT1:
190 case TextureFormat::DXN1:
191 // In this case a 'pixel' actually refers to a 4x4 tile.
192 return 8;
193 case TextureFormat::DXT23:
194 case TextureFormat::DXT45:
195 case TextureFormat::DXN2:
196 case TextureFormat::BC7U:
197 case TextureFormat::BC6H_UF16:
198 case TextureFormat::BC6H_SF16:
199 // In this case a 'pixel' actually refers to a 4x4 tile.
200 return 16;
201 case TextureFormat::R32_G32_B32:
202 return 12;
203 case TextureFormat::ASTC_2D_4X4:
204 case TextureFormat::ASTC_2D_5X4:
205 case TextureFormat::ASTC_2D_8X8:
206 case TextureFormat::ASTC_2D_8X5:
207 case TextureFormat::ASTC_2D_10X8:
208 case TextureFormat::ASTC_2D_5X5:
209 case TextureFormat::A8R8G8B8:
210 case TextureFormat::A2B10G10R10:
211 case TextureFormat::BF10GF11RF11:
212 case TextureFormat::R32:
213 case TextureFormat::R16_G16:
214 return 4;
215 case TextureFormat::A1B5G5R5:
216 case TextureFormat::B5G6R5:
217 case TextureFormat::G8R8:
218 case TextureFormat::R16:
219 return 2;
220 case TextureFormat::R8:
221 return 1;
222 case TextureFormat::R16_G16_B16_A16:
223 return 8;
224 case TextureFormat::R32_G32_B32_A32:
225 return 16;
226 case TextureFormat::R32_G32:
227 return 8;
228 default:
229 UNIMPLEMENTED_MSG("Format not implemented");
230 return 1;
231 }
232}
233
234void UnswizzleTexture(u8* const unswizzled_data, u8* address, u32 tile_size_x, u32 tile_size_y, 187void UnswizzleTexture(u8* const unswizzled_data, u8* address, u32 tile_size_x, u32 tile_size_y,
235 u32 bytes_per_pixel, u32 width, u32 height, u32 depth, u32 block_height, 188 u32 bytes_per_pixel, u32 width, u32 height, u32 depth, u32 block_height,
236 u32 block_depth, u32 width_spacing) { 189 u32 block_depth, u32 width_spacing) {
@@ -348,48 +301,6 @@ void SwizzleKepler(const u32 width, const u32 height, const u32 dst_x, const u32
348 } 301 }
349} 302}
350 303
351std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat format, u32 width,
352 u32 height) {
353 std::vector<u8> rgba_data;
354
355 // TODO(Subv): Implement.
356 switch (format) {
357 case TextureFormat::DXT1:
358 case TextureFormat::DXT23:
359 case TextureFormat::DXT45:
360 case TextureFormat::DXN1:
361 case TextureFormat::DXN2:
362 case TextureFormat::BC7U:
363 case TextureFormat::BC6H_UF16:
364 case TextureFormat::BC6H_SF16:
365 case TextureFormat::ASTC_2D_4X4:
366 case TextureFormat::ASTC_2D_8X8:
367 case TextureFormat::ASTC_2D_5X5:
368 case TextureFormat::ASTC_2D_10X8:
369 case TextureFormat::A8R8G8B8:
370 case TextureFormat::A2B10G10R10:
371 case TextureFormat::A1B5G5R5:
372 case TextureFormat::B5G6R5:
373 case TextureFormat::R8:
374 case TextureFormat::G8R8:
375 case TextureFormat::BF10GF11RF11:
376 case TextureFormat::R32_G32_B32_A32:
377 case TextureFormat::R32_G32:
378 case TextureFormat::R32:
379 case TextureFormat::R16:
380 case TextureFormat::R16_G16:
381 case TextureFormat::R32_G32_B32:
382 // TODO(Subv): For the time being just forward the same data without any decoding.
383 rgba_data = texture_data;
384 break;
385 default:
386 UNIMPLEMENTED_MSG("Format not implemented");
387 break;
388 }
389
390 return rgba_data;
391}
392
393std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, 304std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth,
394 u32 block_height, u32 block_depth) { 305 u32 block_height, u32 block_depth) {
395 if (tiled) { 306 if (tiled) {
diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h
index 232b696b3..d6fe35d37 100644
--- a/src/video_core/textures/decoders.h
+++ b/src/video_core/textures/decoders.h
@@ -38,10 +38,6 @@ void CopySwizzledData(u32 width, u32 height, u32 depth, u32 bytes_per_pixel,
38 u32 out_bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, 38 u32 out_bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data,
39 bool unswizzle, u32 block_height, u32 block_depth, u32 width_spacing); 39 bool unswizzle, u32 block_height, u32 block_depth, u32 width_spacing);
40 40
41/// Decodes an unswizzled texture into a A8R8G8B8 texture.
42std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat format, u32 width,
43 u32 height);
44
45/// This function calculates the correct size of a texture depending if it's tiled or not. 41/// This function calculates the correct size of a texture depending if it's tiled or not.
46std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, 42std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth,
47 u32 block_height, u32 block_depth); 43 u32 block_height, u32 block_depth);
diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h
index eba05aced..0574fef12 100644
--- a/src/video_core/textures/texture.h
+++ b/src/video_core/textures/texture.h
@@ -12,10 +12,10 @@
12namespace Tegra::Texture { 12namespace Tegra::Texture {
13 13
14enum class TextureFormat : u32 { 14enum class TextureFormat : u32 {
15 R32_G32_B32_A32 = 0x01, 15 R32G32B32A32 = 0x01,
16 R32_G32_B32 = 0x02, 16 R32G32B32 = 0x02,
17 R16_G16_B16_A16 = 0x03, 17 R16G16B16A16 = 0x03,
18 R32_G32 = 0x04, 18 R32G32 = 0x04,
19 R32_B24G8 = 0x05, 19 R32_B24G8 = 0x05,
20 ETC2_RGB = 0x06, 20 ETC2_RGB = 0x06,
21 X8B8G8R8 = 0x07, 21 X8B8G8R8 = 0x07,
@@ -23,19 +23,19 @@ enum class TextureFormat : u32 {
23 A2B10G10R10 = 0x09, 23 A2B10G10R10 = 0x09,
24 ETC2_RGB_PTA = 0x0a, 24 ETC2_RGB_PTA = 0x0a,
25 ETC2_RGBA = 0x0b, 25 ETC2_RGBA = 0x0b,
26 R16_G16 = 0x0c, 26 R16G16 = 0x0c,
27 G8R24 = 0x0d, 27 R24G8 = 0x0d,
28 G24R8 = 0x0e, 28 R8G24 = 0x0e,
29 R32 = 0x0f, 29 R32 = 0x0f,
30 BC6H_SF16 = 0x10, 30 BC6H_SFLOAT = 0x10,
31 BC6H_UF16 = 0x11, 31 BC6H_UFLOAT = 0x11,
32 A4B4G4R4 = 0x12, 32 A4B4G4R4 = 0x12,
33 A5B5G5R1 = 0x13, 33 A5B5G5R1 = 0x13,
34 A1B5G5R5 = 0x14, 34 A1B5G5R5 = 0x14,
35 B5G6R5 = 0x15, 35 B5G6R5 = 0x15,
36 B6G5R5 = 0x16, 36 B6G5R5 = 0x16,
37 BC7U = 0x17, 37 BC7 = 0x17,
38 G8R8 = 0x18, 38 R8G8 = 0x18,
39 EAC = 0x19, 39 EAC = 0x19,
40 EACX2 = 0x1a, 40 EACX2 = 0x1a,
41 R16 = 0x1b, 41 R16 = 0x1b,
@@ -43,23 +43,23 @@ enum class TextureFormat : u32 {
43 R8 = 0x1d, 43 R8 = 0x1d,
44 G4R4 = 0x1e, 44 G4R4 = 0x1e,
45 R1 = 0x1f, 45 R1 = 0x1f,
46 E5B9G9R9_SHAREDEXP = 0x20, 46 E5B9G9R9 = 0x20,
47 BF10GF11RF11 = 0x21, 47 B10G11R11 = 0x21,
48 G8B8G8R8 = 0x22, 48 G8B8G8R8 = 0x22,
49 B8G8R8G8 = 0x23, 49 B8G8R8G8 = 0x23,
50 DXT1 = 0x24, 50 BC1_RGBA = 0x24,
51 DXT23 = 0x25, 51 BC2 = 0x25,
52 DXT45 = 0x26, 52 BC3 = 0x26,
53 DXN1 = 0x27, 53 BC4 = 0x27,
54 DXN2 = 0x28, 54 BC5 = 0x28,
55 S8Z24 = 0x29, 55 S8D24 = 0x29,
56 X8Z24 = 0x2a, 56 X8Z24 = 0x2a,
57 Z24S8 = 0x2b, 57 D24S8 = 0x2b,
58 X4V4Z24__COV4R4V = 0x2c, 58 X4V4Z24__COV4R4V = 0x2c,
59 X4V4Z24__COV8R8V = 0x2d, 59 X4V4Z24__COV8R8V = 0x2d,
60 V8Z24__COV4R12V = 0x2e, 60 V8Z24__COV4R12V = 0x2e,
61 ZF32 = 0x2f, 61 D32 = 0x2f,
62 ZF32_X24S8 = 0x30, 62 D32S8 = 0x30,
63 X8Z24_X20V4S8__COV4R4V = 0x31, 63 X8Z24_X20V4S8__COV4R4V = 0x31,
64 X8Z24_X20V4S8__COV8R8V = 0x32, 64 X8Z24_X20V4S8__COV8R8V = 0x32,
65 ZF32_X20V4X8__COV4R4V = 0x33, 65 ZF32_X20V4X8__COV4R4V = 0x33,
@@ -69,7 +69,7 @@ enum class TextureFormat : u32 {
69 X8Z24_X16V8S8__COV4R12V = 0x37, 69 X8Z24_X16V8S8__COV4R12V = 0x37,
70 ZF32_X16V8X8__COV4R12V = 0x38, 70 ZF32_X16V8X8__COV4R12V = 0x38,
71 ZF32_X16V8S8__COV4R12V = 0x39, 71 ZF32_X16V8S8__COV4R12V = 0x39,
72 Z16 = 0x3a, 72 D16 = 0x3a,
73 V8Z24__COV8R24V = 0x3b, 73 V8Z24__COV8R24V = 0x3b,
74 X8Z24_X16V8S8__COV8R24V = 0x3c, 74 X8Z24_X16V8S8__COV8R24V = 0x3c,
75 ZF32_X16V8X8__COV8R24V = 0x3d, 75 ZF32_X16V8X8__COV8R24V = 0x3d,
@@ -375,7 +375,4 @@ struct FullTextureInfo {
375 TSCEntry tsc; 375 TSCEntry tsc;
376}; 376};
377 377
378/// Returns the number of bytes per pixel of the input texture format.
379u32 BytesPerPixel(TextureFormat format);
380
381} // namespace Tegra::Texture 378} // namespace Tegra::Texture
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 59a193edd..94b96afb4 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -666,8 +666,6 @@ void Config::ReadRendererValues() {
666 QStringLiteral("use_asynchronous_shaders"), false); 666 QStringLiteral("use_asynchronous_shaders"), false);
667 ReadSettingGlobal(Settings::values.use_fast_gpu_time, QStringLiteral("use_fast_gpu_time"), 667 ReadSettingGlobal(Settings::values.use_fast_gpu_time, QStringLiteral("use_fast_gpu_time"),
668 true); 668 true);
669 ReadSettingGlobal(Settings::values.force_30fps_mode, QStringLiteral("force_30fps_mode"), false);
670
671 ReadSettingGlobal(Settings::values.bg_red, QStringLiteral("bg_red"), 0.0); 669 ReadSettingGlobal(Settings::values.bg_red, QStringLiteral("bg_red"), 0.0);
672 ReadSettingGlobal(Settings::values.bg_green, QStringLiteral("bg_green"), 0.0); 670 ReadSettingGlobal(Settings::values.bg_green, QStringLiteral("bg_green"), 0.0);
673 ReadSettingGlobal(Settings::values.bg_blue, QStringLiteral("bg_blue"), 0.0); 671 ReadSettingGlobal(Settings::values.bg_blue, QStringLiteral("bg_blue"), 0.0);
@@ -1153,9 +1151,6 @@ void Config::SaveRendererValues() {
1153 Settings::values.use_asynchronous_shaders, false); 1151 Settings::values.use_asynchronous_shaders, false);
1154 WriteSettingGlobal(QStringLiteral("use_fast_gpu_time"), Settings::values.use_fast_gpu_time, 1152 WriteSettingGlobal(QStringLiteral("use_fast_gpu_time"), Settings::values.use_fast_gpu_time,
1155 true); 1153 true);
1156 WriteSettingGlobal(QStringLiteral("force_30fps_mode"), Settings::values.force_30fps_mode,
1157 false);
1158
1159 // Cast to double because Qt's written float values are not human-readable 1154 // Cast to double because Qt's written float values are not human-readable
1160 WriteSettingGlobal(QStringLiteral("bg_red"), Settings::values.bg_red, 0.0); 1155 WriteSettingGlobal(QStringLiteral("bg_red"), Settings::values.bg_red, 0.0);
1161 WriteSettingGlobal(QStringLiteral("bg_green"), Settings::values.bg_green, 0.0); 1156 WriteSettingGlobal(QStringLiteral("bg_green"), Settings::values.bg_green, 0.0);
diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp
index bb47c3933..f9becab6e 100644
--- a/src/yuzu/configuration/configuration_shared.cpp
+++ b/src/yuzu/configuration/configuration_shared.cpp
@@ -4,17 +4,20 @@
4 4
5#include <QCheckBox> 5#include <QCheckBox>
6#include <QComboBox> 6#include <QComboBox>
7#include <QObject>
8#include <QString>
7#include "core/settings.h" 9#include "core/settings.h"
8#include "yuzu/configuration/configuration_shared.h" 10#include "yuzu/configuration/configuration_shared.h"
9#include "yuzu/configuration/configure_per_game.h" 11#include "yuzu/configuration/configure_per_game.h"
10 12
11void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<bool>* setting, 13void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<bool>* setting,
12 const QCheckBox* checkbox) { 14 const QCheckBox* checkbox,
13 if (checkbox->checkState() == Qt::PartiallyChecked) { 15 const CheckState& tracker) {
16 if (tracker == CheckState::Global) {
14 setting->SetGlobal(true); 17 setting->SetGlobal(true);
15 } else { 18 } else {
16 setting->SetGlobal(false); 19 setting->SetGlobal(false);
17 setting->SetValue(checkbox->checkState() == Qt::Checked); 20 setting->SetValue(checkbox->checkState());
18 } 21 }
19} 22}
20 23
@@ -69,8 +72,69 @@ void ConfigurationShared::SetPerGameSetting(
69 ConfigurationShared::USE_GLOBAL_OFFSET); 72 ConfigurationShared::USE_GLOBAL_OFFSET);
70} 73}
71 74
72void ConfigurationShared::InsertGlobalItem(QComboBox* combobox) { 75void ConfigurationShared::SetHighlight(QWidget* widget, const std::string& name, bool highlighted) {
73 const QString use_global_text = ConfigurePerGame::tr("Use global configuration"); 76 if (highlighted) {
77 widget->setStyleSheet(QStringLiteral("QWidget#%1 { background-color:rgba(0,203,255,0.5) }")
78 .arg(QString::fromStdString(name)));
79 } else {
80 widget->setStyleSheet(QStringLiteral("QWidget#%1 { background-color:rgba(0,0,0,0) }")
81 .arg(QString::fromStdString(name)));
82 }
83 widget->show();
84}
85
86void ConfigurationShared::SetColoredTristate(QCheckBox* checkbox, const std::string& name,
87 const Settings::Setting<bool>& setting,
88 CheckState& tracker) {
89 if (setting.UsingGlobal()) {
90 tracker = CheckState::Global;
91 } else {
92 tracker = (setting.GetValue() == setting.GetValue(true)) ? CheckState::On : CheckState::Off;
93 }
94 SetHighlight(checkbox, name, tracker != CheckState::Global);
95 QObject::connect(checkbox, &QCheckBox::clicked, checkbox,
96 [checkbox, name, setting, &tracker]() {
97 tracker = static_cast<CheckState>((static_cast<int>(tracker) + 1) %
98 static_cast<int>(CheckState::Count));
99 if (tracker == CheckState::Global) {
100 checkbox->setChecked(setting.GetValue(true));
101 }
102 SetHighlight(checkbox, name, tracker != CheckState::Global);
103 });
104}
105
106void ConfigurationShared::SetColoredTristate(QCheckBox* checkbox, const std::string& name,
107 bool global, bool state, bool global_state,
108 CheckState& tracker) {
109 if (global) {
110 tracker = CheckState::Global;
111 } else {
112 tracker = (state == global_state) ? CheckState::On : CheckState::Off;
113 }
114 SetHighlight(checkbox, name, tracker != CheckState::Global);
115 QObject::connect(checkbox, &QCheckBox::clicked, checkbox,
116 [checkbox, name, global_state, &tracker]() {
117 tracker = static_cast<CheckState>((static_cast<int>(tracker) + 1) %
118 static_cast<int>(CheckState::Count));
119 if (tracker == CheckState::Global) {
120 checkbox->setChecked(global_state);
121 }
122 SetHighlight(checkbox, name, tracker != CheckState::Global);
123 });
124}
125
126void ConfigurationShared::SetColoredComboBox(QComboBox* combobox, QWidget* target,
127 const std::string& target_name, int global) {
128 InsertGlobalItem(combobox, global);
129 QObject::connect(combobox, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), target,
130 [target, target_name](int index) {
131 ConfigurationShared::SetHighlight(target, target_name, index != 0);
132 });
133}
134
135void ConfigurationShared::InsertGlobalItem(QComboBox* combobox, int global_index) {
136 const QString use_global_text =
137 ConfigurePerGame::tr("Use global configuration (%1)").arg(combobox->itemText(global_index));
74 combobox->insertItem(ConfigurationShared::USE_GLOBAL_INDEX, use_global_text); 138 combobox->insertItem(ConfigurationShared::USE_GLOBAL_INDEX, use_global_text);
75 combobox->insertSeparator(ConfigurationShared::USE_GLOBAL_SEPARATOR_INDEX); 139 combobox->insertSeparator(ConfigurationShared::USE_GLOBAL_SEPARATOR_INDEX);
76} 140}
diff --git a/src/yuzu/configuration/configuration_shared.h b/src/yuzu/configuration/configuration_shared.h
index b11b1b950..003148c68 100644
--- a/src/yuzu/configuration/configuration_shared.h
+++ b/src/yuzu/configuration/configuration_shared.h
@@ -15,9 +15,17 @@ constexpr int USE_GLOBAL_INDEX = 0;
15constexpr int USE_GLOBAL_SEPARATOR_INDEX = 1; 15constexpr int USE_GLOBAL_SEPARATOR_INDEX = 1;
16constexpr int USE_GLOBAL_OFFSET = 2; 16constexpr int USE_GLOBAL_OFFSET = 2;
17 17
18enum class CheckState {
19 Off,
20 On,
21 Global,
22 Count,
23};
24
18// Global-aware apply and set functions 25// Global-aware apply and set functions
19 26
20void ApplyPerGameSetting(Settings::Setting<bool>* setting, const QCheckBox* checkbox); 27void ApplyPerGameSetting(Settings::Setting<bool>* setting, const QCheckBox* checkbox,
28 const CheckState& tracker);
21void ApplyPerGameSetting(Settings::Setting<int>* setting, const QComboBox* combobox); 29void ApplyPerGameSetting(Settings::Setting<int>* setting, const QComboBox* combobox);
22void ApplyPerGameSetting(Settings::Setting<Settings::RendererBackend>* setting, 30void ApplyPerGameSetting(Settings::Setting<Settings::RendererBackend>* setting,
23 const QComboBox* combobox); 31 const QComboBox* combobox);
@@ -31,6 +39,14 @@ void SetPerGameSetting(QComboBox* combobox,
31void SetPerGameSetting(QComboBox* combobox, 39void SetPerGameSetting(QComboBox* combobox,
32 const Settings::Setting<Settings::GPUAccuracy>* setting); 40 const Settings::Setting<Settings::GPUAccuracy>* setting);
33 41
34void InsertGlobalItem(QComboBox* combobox); 42void SetHighlight(QWidget* widget, const std::string& name, bool highlighted);
43void SetColoredTristate(QCheckBox* checkbox, const std::string& name,
44 const Settings::Setting<bool>& setting, CheckState& tracker);
45void SetColoredTristate(QCheckBox* checkbox, const std::string& name, bool global, bool state,
46 bool global_state, CheckState& tracker);
47void SetColoredComboBox(QComboBox* combobox, QWidget* target, const std::string& target_name,
48 int global);
49
50void InsertGlobalItem(QComboBox* combobox, int global_index);
35 51
36} // namespace ConfigurationShared 52} // namespace ConfigurationShared
diff --git a/src/yuzu/configuration/configure_audio.cpp b/src/yuzu/configuration/configure_audio.cpp
index cc021beec..fea632531 100644
--- a/src/yuzu/configuration/configure_audio.cpp
+++ b/src/yuzu/configuration/configure_audio.cpp
@@ -49,12 +49,9 @@ void ConfigureAudio::SetConfiguration() {
49 49
50 ui->volume_slider->setValue(Settings::values.volume.GetValue() * ui->volume_slider->maximum()); 50 ui->volume_slider->setValue(Settings::values.volume.GetValue() * ui->volume_slider->maximum());
51 51
52 if (Settings::configuring_global) { 52 ui->toggle_audio_stretching->setChecked(Settings::values.enable_audio_stretching.GetValue());
53 ui->toggle_audio_stretching->setChecked( 53
54 Settings::values.enable_audio_stretching.GetValue()); 54 if (!Settings::configuring_global) {
55 } else {
56 ConfigurationShared::SetPerGameSetting(ui->toggle_audio_stretching,
57 &Settings::values.enable_audio_stretching);
58 if (Settings::values.volume.UsingGlobal()) { 55 if (Settings::values.volume.UsingGlobal()) {
59 ui->volume_combo_box->setCurrentIndex(0); 56 ui->volume_combo_box->setCurrentIndex(0);
60 ui->volume_slider->setEnabled(false); 57 ui->volume_slider->setEnabled(false);
@@ -62,6 +59,8 @@ void ConfigureAudio::SetConfiguration() {
62 ui->volume_combo_box->setCurrentIndex(1); 59 ui->volume_combo_box->setCurrentIndex(1);
63 ui->volume_slider->setEnabled(true); 60 ui->volume_slider->setEnabled(true);
64 } 61 }
62 ConfigurationShared::SetHighlight(ui->volume_layout, "volume_layout",
63 !Settings::values.volume.UsingGlobal());
65 } 64 }
66 SetVolumeIndicatorText(ui->volume_slider->sliderPosition()); 65 SetVolumeIndicatorText(ui->volume_slider->sliderPosition());
67} 66}
@@ -120,7 +119,8 @@ void ConfigureAudio::ApplyConfiguration() {
120 } 119 }
121 } else { 120 } else {
122 ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_audio_stretching, 121 ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_audio_stretching,
123 ui->toggle_audio_stretching); 122 ui->toggle_audio_stretching,
123 enable_audio_stretching);
124 if (ui->volume_combo_box->currentIndex() == 0) { 124 if (ui->volume_combo_box->currentIndex() == 0) {
125 Settings::values.volume.SetGlobal(true); 125 Settings::values.volume.SetGlobal(true);
126 } else { 126 } else {
@@ -173,9 +173,14 @@ void ConfigureAudio::SetupPerGameUI() {
173 return; 173 return;
174 } 174 }
175 175
176 ui->toggle_audio_stretching->setTristate(true); 176 ConfigurationShared::SetColoredTristate(ui->toggle_audio_stretching, "toggle_audio_stretching",
177 Settings::values.enable_audio_stretching,
178 enable_audio_stretching);
177 connect(ui->volume_combo_box, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), 179 connect(ui->volume_combo_box, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
178 this, [this](int index) { ui->volume_slider->setEnabled(index == 1); }); 180 this, [this](int index) {
181 ui->volume_slider->setEnabled(index == 1);
182 ConfigurationShared::SetHighlight(ui->volume_layout, "volume_layout", index == 1);
183 });
179 184
180 ui->output_sink_combo_box->setVisible(false); 185 ui->output_sink_combo_box->setVisible(false);
181 ui->output_sink_label->setVisible(false); 186 ui->output_sink_label->setVisible(false);
diff --git a/src/yuzu/configuration/configure_audio.h b/src/yuzu/configuration/configure_audio.h
index d84f4a682..9dbd3d93e 100644
--- a/src/yuzu/configuration/configure_audio.h
+++ b/src/yuzu/configuration/configure_audio.h
@@ -7,6 +7,10 @@
7#include <memory> 7#include <memory>
8#include <QWidget> 8#include <QWidget>
9 9
10namespace ConfigurationShared {
11enum class CheckState;
12}
13
10namespace Ui { 14namespace Ui {
11class ConfigureAudio; 15class ConfigureAudio;
12} 16}
@@ -37,4 +41,6 @@ private:
37 void SetupPerGameUI(); 41 void SetupPerGameUI();
38 42
39 std::unique_ptr<Ui::ConfigureAudio> ui; 43 std::unique_ptr<Ui::ConfigureAudio> ui;
44
45 ConfigurationShared::CheckState enable_audio_stretching;
40}; 46};
diff --git a/src/yuzu/configuration/configure_audio.ui b/src/yuzu/configuration/configure_audio.ui
index 862ccb988..9bd0cca96 100644
--- a/src/yuzu/configuration/configure_audio.ui
+++ b/src/yuzu/configuration/configure_audio.ui
@@ -56,80 +56,91 @@
56 </layout> 56 </layout>
57 </item> 57 </item>
58 <item> 58 <item>
59 <layout class="QHBoxLayout" name="horizontalLayout_2"> 59 <widget class="QWidget" name="volume_layout" native="true">
60 <property name="topMargin"> 60 <layout class="QHBoxLayout" name="horizontalLayout_2">
61 <number>0</number> 61 <property name="leftMargin">
62 </property> 62 <number>0</number>
63 <item> 63 </property>
64 <widget class="QComboBox" name="volume_combo_box"> 64 <property name="topMargin">
65 <item> 65 <number>0</number>
66 </property>
67 <property name="rightMargin">
68 <number>0</number>
69 </property>
70 <property name="bottomMargin">
71 <number>0</number>
72 </property>
73 <item>
74 <widget class="QComboBox" name="volume_combo_box">
75 <item>
76 <property name="text">
77 <string>Use global volume</string>
78 </property>
79 </item>
80 <item>
81 <property name="text">
82 <string>Set volume:</string>
83 </property>
84 </item>
85 </widget>
86 </item>
87 <item>
88 <widget class="QLabel" name="volume_label">
66 <property name="text"> 89 <property name="text">
67 <string>Use global volume</string> 90 <string>Volume:</string>
91 </property>
92 </widget>
93 </item>
94 <item>
95 <spacer name="horizontalSpacer">
96 <property name="orientation">
97 <enum>Qt::Horizontal</enum>
98 </property>
99 <property name="sizeHint" stdset="0">
100 <size>
101 <width>30</width>
102 <height>20</height>
103 </size>
104 </property>
105 </spacer>
106 </item>
107 <item>
108 <widget class="QSlider" name="volume_slider">
109 <property name="sizePolicy">
110 <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
111 <horstretch>0</horstretch>
112 <verstretch>0</verstretch>
113 </sizepolicy>
114 </property>
115 <property name="maximum">
116 <number>100</number>
117 </property>
118 <property name="pageStep">
119 <number>10</number>
120 </property>
121 <property name="orientation">
122 <enum>Qt::Horizontal</enum>
123 </property>
124 </widget>
125 </item>
126 <item>
127 <widget class="QLabel" name="volume_indicator">
128 <property name="minimumSize">
129 <size>
130 <width>32</width>
131 <height>0</height>
132 </size>
68 </property> 133 </property>
69 </item>
70 <item>
71 <property name="text"> 134 <property name="text">
72 <string>Set volume:</string> 135 <string>0 %</string>
73 </property> 136 </property>
74 </item> 137 <property name="alignment">
75 </widget> 138 <set>Qt::AlignCenter</set>
76 </item> 139 </property>
77 <item> 140 </widget>
78 <widget class="QLabel" name="volume_label"> 141 </item>
79 <property name="text"> 142 </layout>
80 <string>Volume:</string> 143 </widget>
81 </property>
82 </widget>
83 </item>
84 <item>
85 <spacer name="horizontalSpacer">
86 <property name="orientation">
87 <enum>Qt::Horizontal</enum>
88 </property>
89 <property name="sizeHint" stdset="0">
90 <size>
91 <width>30</width>
92 <height>20</height>
93 </size>
94 </property>
95 </spacer>
96 </item>
97 <item>
98 <widget class="QSlider" name="volume_slider">
99 <property name="sizePolicy">
100 <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
101 <horstretch>0</horstretch>
102 <verstretch>0</verstretch>
103 </sizepolicy>
104 </property>
105 <property name="maximum">
106 <number>100</number>
107 </property>
108 <property name="pageStep">
109 <number>10</number>
110 </property>
111 <property name="orientation">
112 <enum>Qt::Horizontal</enum>
113 </property>
114 </widget>
115 </item>
116 <item>
117 <widget class="QLabel" name="volume_indicator">
118 <property name="minimumSize">
119 <size>
120 <width>32</width>
121 <height>0</height>
122 </size>
123 </property>
124 <property name="text">
125 <string>0 %</string>
126 </property>
127 <property name="alignment">
128 <set>Qt::AlignCenter</set>
129 </property>
130 </widget>
131 </item>
132 </layout>
133 </item> 144 </item>
134 </layout> 145 </layout>
135 </widget> 146 </widget>
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui
index 272bdd6b8..9d6feb9f7 100644
--- a/src/yuzu/configuration/configure_debug.ui
+++ b/src/yuzu/configuration/configure_debug.ui
@@ -171,26 +171,6 @@
171 </property> 171 </property>
172 <layout class="QVBoxLayout" name="verticalLayout_6"> 172 <layout class="QVBoxLayout" name="verticalLayout_6">
173 <item> 173 <item>
174 <widget class="QCheckBox" name="dump_decompressed_nso">
175 <property name="whatsThis">
176 <string>When checked, any NSO yuzu tries to load or patch will be copied decompressed to the yuzu/dump directory.</string>
177 </property>
178 <property name="text">
179 <string>Dump Decompressed NSOs</string>
180 </property>
181 </widget>
182 </item>
183 <item>
184 <widget class="QCheckBox" name="dump_exefs">
185 <property name="whatsThis">
186 <string>When checked, any game that yuzu loads will have its ExeFS dumped to the yuzu/dump directory.</string>
187 </property>
188 <property name="text">
189 <string>Dump ExeFS</string>
190 </property>
191 </widget>
192 </item>
193 <item>
194 <widget class="QCheckBox" name="reporting_services"> 174 <widget class="QCheckBox" name="reporting_services">
195 <property name="text"> 175 <property name="text">
196 <string>Enable Verbose Reporting Services</string> 176 <string>Enable Verbose Reporting Services</string>
@@ -257,8 +237,6 @@
257 <tabstop>open_log_button</tabstop> 237 <tabstop>open_log_button</tabstop>
258 <tabstop>homebrew_args_edit</tabstop> 238 <tabstop>homebrew_args_edit</tabstop>
259 <tabstop>enable_graphics_debugging</tabstop> 239 <tabstop>enable_graphics_debugging</tabstop>
260 <tabstop>dump_decompressed_nso</tabstop>
261 <tabstop>dump_exefs</tabstop>
262 <tabstop>reporting_services</tabstop> 240 <tabstop>reporting_services</tabstop>
263 <tabstop>quest_flag</tabstop> 241 <tabstop>quest_flag</tabstop>
264 </tabstops> 242 </tabstops>
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp
index 20316c9cc..c0dbd9855 100644
--- a/src/yuzu/configuration/configure_general.cpp
+++ b/src/yuzu/configuration/configure_general.cpp
@@ -19,9 +19,10 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
19 19
20 SetConfiguration(); 20 SetConfiguration();
21 21
22 connect(ui->toggle_frame_limit, &QCheckBox::stateChanged, ui->frame_limit, [this]() { 22 if (Settings::configuring_global) {
23 ui->frame_limit->setEnabled(ui->toggle_frame_limit->checkState() == Qt::Checked); 23 connect(ui->toggle_frame_limit, &QCheckBox::clicked, ui->frame_limit,
24 }); 24 [this]() { ui->frame_limit->setEnabled(ui->toggle_frame_limit->isChecked()); });
25 }
25} 26}
26 27
27ConfigureGeneral::~ConfigureGeneral() = default; 28ConfigureGeneral::~ConfigureGeneral() = default;
@@ -40,17 +41,12 @@ void ConfigureGeneral::SetConfiguration() {
40 ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit.GetValue()); 41 ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit.GetValue());
41 ui->frame_limit->setValue(Settings::values.frame_limit.GetValue()); 42 ui->frame_limit->setValue(Settings::values.frame_limit.GetValue());
42 43
43 if (!Settings::configuring_global) { 44 if (Settings::configuring_global) {
44 if (Settings::values.use_multi_core.UsingGlobal()) { 45 ui->frame_limit->setEnabled(Settings::values.use_frame_limit.GetValue());
45 ui->use_multi_core->setCheckState(Qt::PartiallyChecked); 46 } else {
46 } 47 ui->frame_limit->setEnabled(Settings::values.use_frame_limit.GetValue() &&
47 if (Settings::values.use_frame_limit.UsingGlobal()) { 48 use_frame_limit != ConfigurationShared::CheckState::Global);
48 ui->toggle_frame_limit->setCheckState(Qt::PartiallyChecked);
49 }
50 } 49 }
51
52 ui->frame_limit->setEnabled(ui->toggle_frame_limit->checkState() == Qt::Checked &&
53 ui->toggle_frame_limit->isEnabled());
54} 50}
55 51
56void ConfigureGeneral::ApplyConfiguration() { 52void ConfigureGeneral::ApplyConfiguration() {
@@ -71,9 +67,9 @@ void ConfigureGeneral::ApplyConfiguration() {
71 } 67 }
72 } else { 68 } else {
73 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_multi_core, 69 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_multi_core,
74 ui->use_multi_core); 70 ui->use_multi_core, use_multi_core);
75 71
76 bool global_frame_limit = ui->toggle_frame_limit->checkState() == Qt::PartiallyChecked; 72 bool global_frame_limit = use_frame_limit == ConfigurationShared::CheckState::Global;
77 Settings::values.use_frame_limit.SetGlobal(global_frame_limit); 73 Settings::values.use_frame_limit.SetGlobal(global_frame_limit);
78 Settings::values.frame_limit.SetGlobal(global_frame_limit); 74 Settings::values.frame_limit.SetGlobal(global_frame_limit);
79 if (!global_frame_limit) { 75 if (!global_frame_limit) {
@@ -109,6 +105,13 @@ void ConfigureGeneral::SetupPerGameUI() {
109 ui->toggle_background_pause->setVisible(false); 105 ui->toggle_background_pause->setVisible(false);
110 ui->toggle_hide_mouse->setVisible(false); 106 ui->toggle_hide_mouse->setVisible(false);
111 107
112 ui->toggle_frame_limit->setTristate(true); 108 ConfigurationShared::SetColoredTristate(ui->toggle_frame_limit, "toggle_frame_limit",
113 ui->use_multi_core->setTristate(true); 109 Settings::values.use_frame_limit, use_frame_limit);
110 ConfigurationShared::SetColoredTristate(ui->use_multi_core, "use_multi_core",
111 Settings::values.use_multi_core, use_multi_core);
112
113 connect(ui->toggle_frame_limit, &QCheckBox::clicked, ui->frame_limit, [this]() {
114 ui->frame_limit->setEnabled(ui->toggle_frame_limit->isChecked() &&
115 (use_frame_limit != ConfigurationShared::CheckState::Global));
116 });
114} 117}
diff --git a/src/yuzu/configuration/configure_general.h b/src/yuzu/configuration/configure_general.h
index 9c785c22e..323ffbd8f 100644
--- a/src/yuzu/configuration/configure_general.h
+++ b/src/yuzu/configuration/configure_general.h
@@ -7,6 +7,10 @@
7#include <memory> 7#include <memory>
8#include <QWidget> 8#include <QWidget>
9 9
10namespace ConfigurationShared {
11enum class CheckState;
12}
13
10class HotkeyRegistry; 14class HotkeyRegistry;
11 15
12namespace Ui { 16namespace Ui {
@@ -31,4 +35,7 @@ private:
31 void SetupPerGameUI(); 35 void SetupPerGameUI();
32 36
33 std::unique_ptr<Ui::ConfigureGeneral> ui; 37 std::unique_ptr<Ui::ConfigureGeneral> ui;
38
39 ConfigurationShared::CheckState use_frame_limit;
40 ConfigurationShared::CheckState use_multi_core;
34}; 41};
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index cb4706bd6..3e42531c3 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -31,8 +31,14 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)
31 31
32 SetConfiguration(); 32 SetConfiguration();
33 33
34 connect(ui->api, qOverload<int>(&QComboBox::currentIndexChanged), this, 34 connect(ui->api, qOverload<int>(&QComboBox::currentIndexChanged), this, [this] {
35 [this] { UpdateDeviceComboBox(); }); 35 UpdateDeviceComboBox();
36 if (!Settings::configuring_global) {
37 ConfigurationShared::SetHighlight(ui->api_layout, "api_layout",
38 ui->api->currentIndex() !=
39 ConfigurationShared::USE_GLOBAL_INDEX);
40 }
41 });
36 connect(ui->device, qOverload<int>(&QComboBox::activated), this, 42 connect(ui->device, qOverload<int>(&QComboBox::activated), this,
37 [this](int device) { UpdateDeviceSelection(device); }); 43 [this](int device) { UpdateDeviceSelection(device); });
38 44
@@ -65,25 +71,26 @@ void ConfigureGraphics::SetConfiguration() {
65 ui->api->setEnabled(runtime_lock); 71 ui->api->setEnabled(runtime_lock);
66 ui->use_asynchronous_gpu_emulation->setEnabled(runtime_lock); 72 ui->use_asynchronous_gpu_emulation->setEnabled(runtime_lock);
67 ui->use_disk_shader_cache->setEnabled(runtime_lock); 73 ui->use_disk_shader_cache->setEnabled(runtime_lock);
74 ui->use_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache.GetValue());
75 ui->use_asynchronous_gpu_emulation->setChecked(
76 Settings::values.use_asynchronous_gpu_emulation.GetValue());
68 77
69 if (Settings::configuring_global) { 78 if (Settings::configuring_global) {
70 ui->api->setCurrentIndex(static_cast<int>(Settings::values.renderer_backend.GetValue())); 79 ui->api->setCurrentIndex(static_cast<int>(Settings::values.renderer_backend.GetValue()));
71 ui->aspect_ratio_combobox->setCurrentIndex(Settings::values.aspect_ratio.GetValue()); 80 ui->aspect_ratio_combobox->setCurrentIndex(Settings::values.aspect_ratio.GetValue());
72 ui->use_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache.GetValue());
73 ui->use_asynchronous_gpu_emulation->setChecked(
74 Settings::values.use_asynchronous_gpu_emulation.GetValue());
75 } else { 81 } else {
76 ConfigurationShared::SetPerGameSetting(ui->use_disk_shader_cache,
77 &Settings::values.use_disk_shader_cache);
78 ConfigurationShared::SetPerGameSetting(ui->use_asynchronous_gpu_emulation,
79 &Settings::values.use_asynchronous_gpu_emulation);
80
81 ConfigurationShared::SetPerGameSetting(ui->api, &Settings::values.renderer_backend); 82 ConfigurationShared::SetPerGameSetting(ui->api, &Settings::values.renderer_backend);
83 ConfigurationShared::SetHighlight(ui->api_layout, "api_layout",
84 !Settings::values.renderer_backend.UsingGlobal());
82 ConfigurationShared::SetPerGameSetting(ui->aspect_ratio_combobox, 85 ConfigurationShared::SetPerGameSetting(ui->aspect_ratio_combobox,
83 &Settings::values.aspect_ratio); 86 &Settings::values.aspect_ratio);
84 87
85 ui->bg_combobox->setCurrentIndex(Settings::values.bg_red.UsingGlobal() ? 0 : 1); 88 ui->bg_combobox->setCurrentIndex(Settings::values.bg_red.UsingGlobal() ? 0 : 1);
86 ui->bg_button->setEnabled(!Settings::values.bg_red.UsingGlobal()); 89 ui->bg_button->setEnabled(!Settings::values.bg_red.UsingGlobal());
90 ConfigurationShared::SetHighlight(ui->ar_label, "ar_label",
91 !Settings::values.aspect_ratio.UsingGlobal());
92 ConfigurationShared::SetHighlight(ui->bg_layout, "bg_layout",
93 !Settings::values.bg_red.UsingGlobal());
87 } 94 }
88 95
89 UpdateBackgroundColorButton(QColor::fromRgbF(Settings::values.bg_red.GetValue(), 96 UpdateBackgroundColorButton(QColor::fromRgbF(Settings::values.bg_red.GetValue(),
@@ -135,9 +142,10 @@ void ConfigureGraphics::ApplyConfiguration() {
135 ui->aspect_ratio_combobox); 142 ui->aspect_ratio_combobox);
136 143
137 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_disk_shader_cache, 144 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_disk_shader_cache,
138 ui->use_disk_shader_cache); 145 ui->use_disk_shader_cache, use_disk_shader_cache);
139 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_gpu_emulation, 146 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_gpu_emulation,
140 ui->use_asynchronous_gpu_emulation); 147 ui->use_asynchronous_gpu_emulation,
148 use_asynchronous_gpu_emulation);
141 149
142 if (ui->bg_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { 150 if (ui->bg_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
143 Settings::values.bg_red.SetGlobal(true); 151 Settings::values.bg_red.SetGlobal(true);
@@ -241,10 +249,20 @@ void ConfigureGraphics::SetupPerGameUI() {
241 } 249 }
242 250
243 connect(ui->bg_combobox, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), this, 251 connect(ui->bg_combobox, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), this,
244 [this](int index) { ui->bg_button->setEnabled(index == 1); }); 252 [this](int index) {
245 253 ui->bg_button->setEnabled(index == 1);
246 ui->use_disk_shader_cache->setTristate(true); 254 ConfigurationShared::SetHighlight(ui->bg_layout, "bg_layout", index == 1);
247 ui->use_asynchronous_gpu_emulation->setTristate(true); 255 });
248 ConfigurationShared::InsertGlobalItem(ui->aspect_ratio_combobox); 256
249 ConfigurationShared::InsertGlobalItem(ui->api); 257 ConfigurationShared::SetColoredTristate(ui->use_disk_shader_cache, "use_disk_shader_cache",
258 Settings::values.use_disk_shader_cache,
259 use_disk_shader_cache);
260 ConfigurationShared::SetColoredTristate(
261 ui->use_asynchronous_gpu_emulation, "use_asynchronous_gpu_emulation",
262 Settings::values.use_asynchronous_gpu_emulation, use_asynchronous_gpu_emulation);
263
264 ConfigurationShared::SetColoredComboBox(ui->aspect_ratio_combobox, ui->ar_label, "ar_label",
265 Settings::values.aspect_ratio.GetValue(true));
266 ConfigurationShared::InsertGlobalItem(
267 ui->api, static_cast<int>(Settings::values.renderer_backend.GetValue(true)));
250} 268}
diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h
index 24f01c739..b4961f719 100644
--- a/src/yuzu/configuration/configure_graphics.h
+++ b/src/yuzu/configuration/configure_graphics.h
@@ -10,6 +10,10 @@
10#include <QWidget> 10#include <QWidget>
11#include "core/settings.h" 11#include "core/settings.h"
12 12
13namespace ConfigurationShared {
14enum class CheckState;
15}
16
13namespace Ui { 17namespace Ui {
14class ConfigureGraphics; 18class ConfigureGraphics;
15} 19}
@@ -42,6 +46,9 @@ private:
42 std::unique_ptr<Ui::ConfigureGraphics> ui; 46 std::unique_ptr<Ui::ConfigureGraphics> ui;
43 QColor bg_color; 47 QColor bg_color;
44 48
49 ConfigurationShared::CheckState use_disk_shader_cache;
50 ConfigurationShared::CheckState use_asynchronous_gpu_emulation;
51
45 std::vector<QString> vulkan_devices; 52 std::vector<QString> vulkan_devices;
46 u32 vulkan_device{}; 53 u32 vulkan_device{};
47}; 54};
diff --git a/src/yuzu/configuration/configure_graphics.ui b/src/yuzu/configuration/configure_graphics.ui
index 62418fc14..62aa337e7 100644
--- a/src/yuzu/configuration/configure_graphics.ui
+++ b/src/yuzu/configuration/configure_graphics.ui
@@ -6,7 +6,7 @@
6 <rect> 6 <rect>
7 <x>0</x> 7 <x>0</x>
8 <y>0</y> 8 <y>0</y>
9 <width>400</width> 9 <width>437</width>
10 <height>321</height> 10 <height>321</height>
11 </rect> 11 </rect>
12 </property> 12 </property>
@@ -23,43 +23,56 @@
23 </property> 23 </property>
24 <layout class="QVBoxLayout" name="verticalLayout_3"> 24 <layout class="QVBoxLayout" name="verticalLayout_3">
25 <item> 25 <item>
26 <layout class="QHBoxLayout" name="horizontalLayout_4"> 26 <widget class="QWidget" name="api_layout" native="true">
27 <item> 27 <layout class="QGridLayout" name="gridLayout">
28 <widget class="QLabel" name="label_2"> 28 <property name="leftMargin">
29 <property name="text"> 29 <number>0</number>
30 <string>API:</string> 30 </property>
31 </property> 31 <property name="topMargin">
32 </widget> 32 <number>0</number>
33 </item> 33 </property>
34 <item> 34 <property name="rightMargin">
35 <widget class="QComboBox" name="api"> 35 <number>0</number>
36 <item> 36 </property>
37 <property name="bottomMargin">
38 <number>0</number>
39 </property>
40 <property name="horizontalSpacing">
41 <number>6</number>
42 </property>
43 <item row="0" column="0">
44 <widget class="QLabel" name="api_label">
37 <property name="text"> 45 <property name="text">
38 <string notr="true">OpenGL</string> 46 <string>API:</string>
39 </property> 47 </property>
40 </item> 48 </widget>
41 <item> 49 </item>
50 <item row="0" column="1">
51 <widget class="QComboBox" name="api">
52 <item>
53 <property name="text">
54 <string notr="true">OpenGL</string>
55 </property>
56 </item>
57 <item>
58 <property name="text">
59 <string notr="true">Vulkan</string>
60 </property>
61 </item>
62 </widget>
63 </item>
64 <item row="1" column="0">
65 <widget class="QLabel" name="device_label">
42 <property name="text"> 66 <property name="text">
43 <string notr="true">Vulkan</string> 67 <string>Device:</string>
44 </property> 68 </property>
45 </item> 69 </widget>
46 </widget> 70 </item>
47 </item> 71 <item row="1" column="1">
48 </layout> 72 <widget class="QComboBox" name="device"/>
49 </item> 73 </item>
50 <item> 74 </layout>
51 <layout class="QHBoxLayout" name="horizontalLayout_5"> 75 </widget>
52 <item>
53 <widget class="QLabel" name="label_3">
54 <property name="text">
55 <string>Device:</string>
56 </property>
57 </widget>
58 </item>
59 <item>
60 <widget class="QComboBox" name="device"/>
61 </item>
62 </layout>
63 </item> 76 </item>
64 </layout> 77 </layout>
65 </widget> 78 </widget>
@@ -85,96 +98,133 @@
85 </widget> 98 </widget>
86 </item> 99 </item>
87 <item> 100 <item>
88 <layout class="QHBoxLayout" name="horizontalLayout_6"> 101 <widget class="QWidget" name="aspect_ratio_layout" native="true">
89 <item> 102 <layout class="QHBoxLayout" name="horizontalLayout_6">
90 <widget class="QLabel" name="ar_label"> 103 <property name="leftMargin">
91 <property name="text"> 104 <number>0</number>
92 <string>Aspect Ratio:</string> 105 </property>
93 </property> 106 <property name="topMargin">
94 </widget> 107 <number>0</number>
95 </item> 108 </property>
96 <item> 109 <property name="rightMargin">
97 <widget class="QComboBox" name="aspect_ratio_combobox"> 110 <number>0</number>
98 <item> 111 </property>
99 <property name="text"> 112 <property name="bottomMargin">
100 <string>Default (16:9)</string> 113 <number>0</number>
101 </property> 114 </property>
102 </item> 115 <item>
103 <item> 116 <widget class="QLabel" name="ar_label">
104 <property name="text">
105 <string>Force 4:3</string>
106 </property>
107 </item>
108 <item>
109 <property name="text">
110 <string>Force 21:9</string>
111 </property>
112 </item>
113 <item>
114 <property name="text"> 117 <property name="text">
115 <string>Stretch to Window</string> 118 <string>Aspect Ratio:</string>
116 </property> 119 </property>
117 </item> 120 </widget>
118 </widget> 121 </item>
119 </item> 122 <item>
120 </layout> 123 <widget class="QComboBox" name="aspect_ratio_combobox">
124 <item>
125 <property name="text">
126 <string>Default (16:9)</string>
127 </property>
128 </item>
129 <item>
130 <property name="text">
131 <string>Force 4:3</string>
132 </property>
133 </item>
134 <item>
135 <property name="text">
136 <string>Force 21:9</string>
137 </property>
138 </item>
139 <item>
140 <property name="text">
141 <string>Stretch to Window</string>
142 </property>
143 </item>
144 </widget>
145 </item>
146 </layout>
147 </widget>
121 </item> 148 </item>
122 <item> 149 <item>
123 <layout class="QHBoxLayout" name="horizontalLayout_3"> 150 <widget class="QWidget" name="bg_layout" native="true">
124 <item> 151 <property name="sizePolicy">
125 <widget class="QComboBox" name="bg_combobox"> 152 <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
126 <property name="currentText"> 153 <horstretch>0</horstretch>
127 <string>Use global background color</string> 154 <verstretch>0</verstretch>
128 </property> 155 </sizepolicy>
129 <property name="currentIndex"> 156 </property>
130 <number>0</number> 157 <layout class="QHBoxLayout" name="horizontalLayout_3">
131 </property> 158 <property name="spacing">
132 <property name="maxVisibleItems"> 159 <number>6</number>
133 <number>10</number> 160 </property>
134 </property> 161 <property name="leftMargin">
135 <item> 162 <number>0</number>
136 <property name="text"> 163 </property>
164 <property name="topMargin">
165 <number>0</number>
166 </property>
167 <property name="rightMargin">
168 <number>0</number>
169 </property>
170 <property name="bottomMargin">
171 <number>0</number>
172 </property>
173 <item>
174 <widget class="QComboBox" name="bg_combobox">
175 <property name="currentText">
137 <string>Use global background color</string> 176 <string>Use global background color</string>
138 </property> 177 </property>
139 </item> 178 <property name="currentIndex">
140 <item> 179 <number>0</number>
180 </property>
181 <property name="maxVisibleItems">
182 <number>10</number>
183 </property>
184 <item>
185 <property name="text">
186 <string>Use global background color</string>
187 </property>
188 </item>
189 <item>
190 <property name="text">
191 <string>Set background color:</string>
192 </property>
193 </item>
194 </widget>
195 </item>
196 <item>
197 <widget class="QLabel" name="bg_label">
141 <property name="text"> 198 <property name="text">
142 <string>Set background color:</string> 199 <string>Background Color:</string>
143 </property> 200 </property>
144 </item> 201 </widget>
145 </widget> 202 </item>
146 </item> 203 <item>
147 <item> 204 <spacer name="horizontalSpacer">
148 <widget class="QLabel" name="bg_label"> 205 <property name="orientation">
149 <property name="text"> 206 <enum>Qt::Horizontal</enum>
150 <string>Background Color:</string> 207 </property>
151 </property> 208 <property name="sizeHint" stdset="0">
152 </widget> 209 <size>
153 </item> 210 <width>40</width>
154 <item> 211 <height>20</height>
155 <spacer name="horizontalSpacer"> 212 </size>
156 <property name="orientation"> 213 </property>
157 <enum>Qt::Horizontal</enum> 214 </spacer>
158 </property> 215 </item>
159 <property name="sizeHint" stdset="0"> 216 <item>
160 <size> 217 <widget class="QPushButton" name="bg_button">
161 <width>40</width> 218 <property name="maximumSize">
162 <height>20</height> 219 <size>
163 </size> 220 <width>40</width>
164 </property> 221 <height>16777215</height>
165 </spacer> 222 </size>
166 </item> 223 </property>
167 <item> 224 </widget>
168 <widget class="QPushButton" name="bg_button"> 225 </item>
169 <property name="maximumSize"> 226 </layout>
170 <size> 227 </widget>
171 <width>40</width>
172 <height>16777215</height>
173 </size>
174 </property>
175 </widget>
176 </item>
177 </layout>
178 </item> 228 </item>
179 </layout> 229 </layout>
180 </widget> 230 </widget>
diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp
index ce30188cd..c5d1a778c 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.cpp
+++ b/src/yuzu/configuration/configure_graphics_advanced.cpp
@@ -25,35 +25,26 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
25 ui->use_vsync->setEnabled(runtime_lock); 25 ui->use_vsync->setEnabled(runtime_lock);
26 ui->use_assembly_shaders->setEnabled(runtime_lock); 26 ui->use_assembly_shaders->setEnabled(runtime_lock);
27 ui->use_asynchronous_shaders->setEnabled(runtime_lock); 27 ui->use_asynchronous_shaders->setEnabled(runtime_lock);
28 ui->force_30fps_mode->setEnabled(runtime_lock);
29 ui->anisotropic_filtering_combobox->setEnabled(runtime_lock); 28 ui->anisotropic_filtering_combobox->setEnabled(runtime_lock);
30 29
30 ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue());
31 ui->use_assembly_shaders->setChecked(Settings::values.use_assembly_shaders.GetValue());
32 ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue());
33 ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue());
34
31 if (Settings::configuring_global) { 35 if (Settings::configuring_global) {
32 ui->gpu_accuracy->setCurrentIndex( 36 ui->gpu_accuracy->setCurrentIndex(
33 static_cast<int>(Settings::values.gpu_accuracy.GetValue())); 37 static_cast<int>(Settings::values.gpu_accuracy.GetValue()));
34 ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue());
35 ui->use_assembly_shaders->setChecked(Settings::values.use_assembly_shaders.GetValue());
36 ui->use_asynchronous_shaders->setChecked(
37 Settings::values.use_asynchronous_shaders.GetValue());
38 ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue());
39 ui->force_30fps_mode->setChecked(Settings::values.force_30fps_mode.GetValue());
40 ui->anisotropic_filtering_combobox->setCurrentIndex( 38 ui->anisotropic_filtering_combobox->setCurrentIndex(
41 Settings::values.max_anisotropy.GetValue()); 39 Settings::values.max_anisotropy.GetValue());
42 } else { 40 } else {
43 ConfigurationShared::SetPerGameSetting(ui->gpu_accuracy, &Settings::values.gpu_accuracy); 41 ConfigurationShared::SetPerGameSetting(ui->gpu_accuracy, &Settings::values.gpu_accuracy);
44 ConfigurationShared::SetPerGameSetting(ui->use_vsync, &Settings::values.use_vsync);
45 ConfigurationShared::SetPerGameSetting(ui->use_assembly_shaders,
46 &Settings::values.use_assembly_shaders);
47 ConfigurationShared::SetPerGameSetting(ui->use_asynchronous_shaders,
48 &Settings::values.use_asynchronous_shaders);
49 ConfigurationShared::SetPerGameSetting(ui->use_asynchronous_shaders,
50 &Settings::values.use_asynchronous_shaders);
51 ConfigurationShared::SetPerGameSetting(ui->use_fast_gpu_time,
52 &Settings::values.use_fast_gpu_time);
53 ConfigurationShared::SetPerGameSetting(ui->force_30fps_mode,
54 &Settings::values.force_30fps_mode);
55 ConfigurationShared::SetPerGameSetting(ui->anisotropic_filtering_combobox, 42 ConfigurationShared::SetPerGameSetting(ui->anisotropic_filtering_combobox,
56 &Settings::values.max_anisotropy); 43 &Settings::values.max_anisotropy);
44 ConfigurationShared::SetHighlight(ui->label_gpu_accuracy, "label_gpu_accuracy",
45 !Settings::values.gpu_accuracy.UsingGlobal());
46 ConfigurationShared::SetHighlight(ui->af_label, "af_label",
47 !Settings::values.max_anisotropy.UsingGlobal());
57 } 48 }
58} 49}
59 50
@@ -85,9 +76,6 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() {
85 if (Settings::values.use_fast_gpu_time.UsingGlobal()) { 76 if (Settings::values.use_fast_gpu_time.UsingGlobal()) {
86 Settings::values.use_fast_gpu_time.SetValue(ui->use_fast_gpu_time->isChecked()); 77 Settings::values.use_fast_gpu_time.SetValue(ui->use_fast_gpu_time->isChecked());
87 } 78 }
88 if (Settings::values.force_30fps_mode.UsingGlobal()) {
89 Settings::values.force_30fps_mode.SetValue(ui->force_30fps_mode->isChecked());
90 }
91 if (Settings::values.max_anisotropy.UsingGlobal()) { 79 if (Settings::values.max_anisotropy.UsingGlobal()) {
92 Settings::values.max_anisotropy.SetValue( 80 Settings::values.max_anisotropy.SetValue(
93 ui->anisotropic_filtering_combobox->currentIndex()); 81 ui->anisotropic_filtering_combobox->currentIndex());
@@ -95,17 +83,15 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() {
95 } else { 83 } else {
96 ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy, 84 ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy,
97 ui->anisotropic_filtering_combobox); 85 ui->anisotropic_filtering_combobox);
98 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync, ui->use_vsync); 86 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync, ui->use_vsync,
87 use_vsync);
99 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_assembly_shaders, 88 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_assembly_shaders,
100 ui->use_assembly_shaders); 89 ui->use_assembly_shaders, use_assembly_shaders);
101 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders,
102 ui->use_asynchronous_shaders);
103 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders, 90 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders,
104 ui->use_asynchronous_shaders); 91 ui->use_asynchronous_shaders,
92 use_asynchronous_shaders);
105 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_fast_gpu_time, 93 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_fast_gpu_time,
106 ui->use_fast_gpu_time); 94 ui->use_fast_gpu_time, use_fast_gpu_time);
107 ConfigurationShared::ApplyPerGameSetting(&Settings::values.force_30fps_mode,
108 ui->force_30fps_mode);
109 ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy, 95 ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy,
110 ui->anisotropic_filtering_combobox); 96 ui->anisotropic_filtering_combobox);
111 97
@@ -139,18 +125,26 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
139 ui->use_asynchronous_shaders->setEnabled( 125 ui->use_asynchronous_shaders->setEnabled(
140 Settings::values.use_asynchronous_shaders.UsingGlobal()); 126 Settings::values.use_asynchronous_shaders.UsingGlobal());
141 ui->use_fast_gpu_time->setEnabled(Settings::values.use_fast_gpu_time.UsingGlobal()); 127 ui->use_fast_gpu_time->setEnabled(Settings::values.use_fast_gpu_time.UsingGlobal());
142 ui->force_30fps_mode->setEnabled(Settings::values.force_30fps_mode.UsingGlobal());
143 ui->anisotropic_filtering_combobox->setEnabled( 128 ui->anisotropic_filtering_combobox->setEnabled(
144 Settings::values.max_anisotropy.UsingGlobal()); 129 Settings::values.max_anisotropy.UsingGlobal());
145 130
146 return; 131 return;
147 } 132 }
148 133
149 ConfigurationShared::InsertGlobalItem(ui->gpu_accuracy); 134 ConfigurationShared::SetColoredTristate(ui->use_vsync, "use_vsync", Settings::values.use_vsync,
150 ui->use_vsync->setTristate(true); 135 use_vsync);
151 ui->use_assembly_shaders->setTristate(true); 136 ConfigurationShared::SetColoredTristate(ui->use_assembly_shaders, "use_assembly_shaders",
152 ui->use_asynchronous_shaders->setTristate(true); 137 Settings::values.use_assembly_shaders,
153 ui->use_fast_gpu_time->setTristate(true); 138 use_assembly_shaders);
154 ui->force_30fps_mode->setTristate(true); 139 ConfigurationShared::SetColoredTristate(
155 ConfigurationShared::InsertGlobalItem(ui->anisotropic_filtering_combobox); 140 ui->use_asynchronous_shaders, "use_asynchronous_shaders",
141 Settings::values.use_asynchronous_shaders, use_asynchronous_shaders);
142 ConfigurationShared::SetColoredTristate(ui->use_fast_gpu_time, "use_fast_gpu_time",
143 Settings::values.use_fast_gpu_time, use_fast_gpu_time);
144 ConfigurationShared::SetColoredComboBox(
145 ui->gpu_accuracy, ui->label_gpu_accuracy, "label_gpu_accuracy",
146 static_cast<int>(Settings::values.gpu_accuracy.GetValue(true)));
147 ConfigurationShared::SetColoredComboBox(
148 ui->anisotropic_filtering_combobox, ui->af_label, "af_label",
149 static_cast<int>(Settings::values.max_anisotropy.GetValue(true)));
156} 150}
diff --git a/src/yuzu/configuration/configure_graphics_advanced.h b/src/yuzu/configuration/configure_graphics_advanced.h
index c043588ff..e61b571c7 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.h
+++ b/src/yuzu/configuration/configure_graphics_advanced.h
@@ -7,6 +7,10 @@
7#include <memory> 7#include <memory>
8#include <QWidget> 8#include <QWidget>
9 9
10namespace ConfigurationShared {
11enum class CheckState;
12}
13
10namespace Ui { 14namespace Ui {
11class ConfigureGraphicsAdvanced; 15class ConfigureGraphicsAdvanced;
12} 16}
@@ -29,4 +33,9 @@ private:
29 void SetupPerGameUI(); 33 void SetupPerGameUI();
30 34
31 std::unique_ptr<Ui::ConfigureGraphicsAdvanced> ui; 35 std::unique_ptr<Ui::ConfigureGraphicsAdvanced> ui;
36
37 ConfigurationShared::CheckState use_vsync;
38 ConfigurationShared::CheckState use_assembly_shaders;
39 ConfigurationShared::CheckState use_asynchronous_shaders;
40 ConfigurationShared::CheckState use_fast_gpu_time;
32}; 41};
diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui
index 71e7dfe5e..a793c803d 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.ui
+++ b/src/yuzu/configuration/configure_graphics_advanced.ui
@@ -6,7 +6,7 @@
6 <rect> 6 <rect>
7 <x>0</x> 7 <x>0</x>
8 <y>0</y> 8 <y>0</y>
9 <width>400</width> 9 <width>404</width>
10 <height>321</height> 10 <height>321</height>
11 </rect> 11 </rect>
12 </property> 12 </property>
@@ -23,34 +23,48 @@
23 </property> 23 </property>
24 <layout class="QVBoxLayout" name="verticalLayout_3"> 24 <layout class="QVBoxLayout" name="verticalLayout_3">
25 <item> 25 <item>
26 <layout class="QHBoxLayout" name="horizontalLayout_2"> 26 <widget class="QWidget" name="gpu_accuracy_layout" native="true">
27 <item> 27 <layout class="QHBoxLayout" name="horizontalLayout_2">
28 <widget class="QLabel" name="label_gpu_accuracy"> 28 <property name="leftMargin">
29 <property name="text"> 29 <number>0</number>
30 <string>Accuracy Level:</string> 30 </property>
31 </property> 31 <property name="topMargin">
32 </widget> 32 <number>0</number>
33 </item> 33 </property>
34 <item> 34 <property name="rightMargin">
35 <widget class="QComboBox" name="gpu_accuracy"> 35 <number>0</number>
36 <item> 36 </property>
37 <property name="bottomMargin">
38 <number>0</number>
39 </property>
40 <item>
41 <widget class="QLabel" name="label_gpu_accuracy">
37 <property name="text"> 42 <property name="text">
38 <string notr="true">Normal</string> 43 <string>Accuracy Level:</string>
39 </property> 44 </property>
40 </item> 45 </widget>
41 <item> 46 </item>
42 <property name="text"> 47 <item>
43 <string notr="true">High</string> 48 <widget class="QComboBox" name="gpu_accuracy">
44 </property> 49 <item>
45 </item> 50 <property name="text">
46 <item> 51 <string notr="true">Normal</string>
47 <property name="text"> 52 </property>
48 <string notr="true">Extreme(very slow)</string> 53 </item>
49 </property> 54 <item>
50 </item> 55 <property name="text">
51 </widget> 56 <string notr="true">High</string>
52 </item> 57 </property>
53 </layout> 58 </item>
59 <item>
60 <property name="text">
61 <string notr="true">Extreme(very slow)</string>
62 </property>
63 </item>
64 </widget>
65 </item>
66 </layout>
67 </widget>
54 </item> 68 </item>
55 <item> 69 <item>
56 <widget class="QCheckBox" name="use_vsync"> 70 <widget class="QCheckBox" name="use_vsync">
@@ -83,13 +97,6 @@
83 </widget> 97 </widget>
84 </item> 98 </item>
85 <item> 99 <item>
86 <widget class="QCheckBox" name="force_30fps_mode">
87 <property name="text">
88 <string>Force 30 FPS mode</string>
89 </property>
90 </widget>
91 </item>
92 <item>
93 <widget class="QCheckBox" name="use_fast_gpu_time"> 100 <widget class="QCheckBox" name="use_fast_gpu_time">
94 <property name="text"> 101 <property name="text">
95 <string>Use Fast GPU Time</string> 102 <string>Use Fast GPU Time</string>
@@ -97,44 +104,58 @@
97 </widget> 104 </widget>
98 </item> 105 </item>
99 <item> 106 <item>
100 <layout class="QHBoxLayout" name="horizontalLayout_1"> 107 <widget class="QWidget" name="af_layout" native="true">
101 <item> 108 <layout class="QHBoxLayout" name="horizontalLayout_1">
102 <widget class="QLabel" name="af_label"> 109 <property name="leftMargin">
103 <property name="text"> 110 <number>0</number>
104 <string>Anisotropic Filtering:</string> 111 </property>
105 </property> 112 <property name="topMargin">
106 </widget> 113 <number>0</number>
107 </item> 114 </property>
108 <item> 115 <property name="rightMargin">
109 <widget class="QComboBox" name="anisotropic_filtering_combobox"> 116 <number>0</number>
110 <item> 117 </property>
118 <property name="bottomMargin">
119 <number>0</number>
120 </property>
121 <item>
122 <widget class="QLabel" name="af_label">
111 <property name="text"> 123 <property name="text">
112 <string>Default</string> 124 <string>Anisotropic Filtering:</string>
113 </property> 125 </property>
114 </item> 126 </widget>
115 <item> 127 </item>
116 <property name="text"> 128 <item>
117 <string>2x</string> 129 <widget class="QComboBox" name="anisotropic_filtering_combobox">
118 </property> 130 <item>
119 </item> 131 <property name="text">
120 <item> 132 <string>Default</string>
121 <property name="text"> 133 </property>
122 <string>4x</string> 134 </item>
123 </property> 135 <item>
124 </item> 136 <property name="text">
125 <item> 137 <string>2x</string>
126 <property name="text"> 138 </property>
127 <string>8x</string> 139 </item>
128 </property> 140 <item>
129 </item> 141 <property name="text">
130 <item> 142 <string>4x</string>
131 <property name="text"> 143 </property>
132 <string>16x</string> 144 </item>
133 </property> 145 <item>
134 </item> 146 <property name="text">
135 </widget> 147 <string>8x</string>
136 </item> 148 </property>
137 </layout> 149 </item>
150 <item>
151 <property name="text">
152 <string>16x</string>
153 </property>
154 </item>
155 </widget>
156 </item>
157 </layout>
158 </widget>
138 </item> 159 </item>
139 </layout> 160 </layout>
140 </widget> 161 </widget>
diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp
index 68e02738b..0c4daf147 100644
--- a/src/yuzu/configuration/configure_system.cpp
+++ b/src/yuzu/configuration/configure_system.cpp
@@ -67,21 +67,21 @@ void ConfigureSystem::SetConfiguration() {
67 const auto rtc_time = Settings::values.custom_rtc.GetValue().value_or( 67 const auto rtc_time = Settings::values.custom_rtc.GetValue().value_or(
68 std::chrono::seconds(QDateTime::currentSecsSinceEpoch())); 68 std::chrono::seconds(QDateTime::currentSecsSinceEpoch()));
69 69
70 ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.GetValue().has_value());
71 ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.GetValue().has_value() &&
72 Settings::values.rng_seed.UsingGlobal());
73 ui->rng_seed_edit->setText(rng_seed);
74
75 ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc.GetValue().has_value());
76 ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.GetValue().has_value() &&
77 Settings::values.rng_seed.UsingGlobal());
78 ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time.count()));
79
70 if (Settings::configuring_global) { 80 if (Settings::configuring_global) {
71 ui->combo_language->setCurrentIndex(Settings::values.language_index.GetValue()); 81 ui->combo_language->setCurrentIndex(Settings::values.language_index.GetValue());
72 ui->combo_region->setCurrentIndex(Settings::values.region_index.GetValue()); 82 ui->combo_region->setCurrentIndex(Settings::values.region_index.GetValue());
73 ui->combo_time_zone->setCurrentIndex(Settings::values.time_zone_index.GetValue()); 83 ui->combo_time_zone->setCurrentIndex(Settings::values.time_zone_index.GetValue());
74 ui->combo_sound->setCurrentIndex(Settings::values.sound_index.GetValue()); 84 ui->combo_sound->setCurrentIndex(Settings::values.sound_index.GetValue());
75
76 ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.GetValue().has_value());
77 ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.GetValue().has_value() &&
78 Settings::values.rng_seed.UsingGlobal());
79 ui->rng_seed_edit->setText(rng_seed);
80
81 ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc.GetValue().has_value());
82 ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.GetValue().has_value() &&
83 Settings::values.rng_seed.UsingGlobal());
84 ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time.count()));
85 } else { 85 } else {
86 ConfigurationShared::SetPerGameSetting(ui->combo_language, 86 ConfigurationShared::SetPerGameSetting(ui->combo_language,
87 &Settings::values.language_index); 87 &Settings::values.language_index);
@@ -90,27 +90,14 @@ void ConfigureSystem::SetConfiguration() {
90 &Settings::values.time_zone_index); 90 &Settings::values.time_zone_index);
91 ConfigurationShared::SetPerGameSetting(ui->combo_sound, &Settings::values.sound_index); 91 ConfigurationShared::SetPerGameSetting(ui->combo_sound, &Settings::values.sound_index);
92 92
93 if (Settings::values.rng_seed.UsingGlobal()) { 93 ConfigurationShared::SetHighlight(ui->label_language, "label_language",
94 ui->rng_seed_checkbox->setCheckState(Qt::PartiallyChecked); 94 !Settings::values.language_index.UsingGlobal());
95 } else { 95 ConfigurationShared::SetHighlight(ui->label_region, "label_region",
96 ui->rng_seed_checkbox->setCheckState( 96 !Settings::values.region_index.UsingGlobal());
97 Settings::values.rng_seed.GetValue().has_value() ? Qt::Checked : Qt::Unchecked); 97 ConfigurationShared::SetHighlight(ui->label_timezone, "label_timezone",
98 ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.GetValue().has_value()); 98 !Settings::values.time_zone_index.UsingGlobal());
99 if (Settings::values.rng_seed.GetValue().has_value()) { 99 ConfigurationShared::SetHighlight(ui->label_sound, "label_sound",
100 ui->rng_seed_edit->setText(rng_seed); 100 !Settings::values.sound_index.UsingGlobal());
101 }
102 }
103
104 if (Settings::values.custom_rtc.UsingGlobal()) {
105 ui->custom_rtc_checkbox->setCheckState(Qt::PartiallyChecked);
106 } else {
107 ui->custom_rtc_checkbox->setCheckState(
108 Settings::values.custom_rtc.GetValue().has_value() ? Qt::Checked : Qt::Unchecked);
109 ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.GetValue().has_value());
110 if (Settings::values.custom_rtc.GetValue().has_value()) {
111 ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time.count()));
112 }
113 }
114 } 101 }
115} 102}
116 103
@@ -161,37 +148,44 @@ void ConfigureSystem::ApplyConfiguration() {
161 ui->combo_time_zone); 148 ui->combo_time_zone);
162 ConfigurationShared::ApplyPerGameSetting(&Settings::values.sound_index, ui->combo_sound); 149 ConfigurationShared::ApplyPerGameSetting(&Settings::values.sound_index, ui->combo_sound);
163 150
164 switch (ui->rng_seed_checkbox->checkState()) { 151 switch (use_rng_seed) {
165 case Qt::Checked: 152 case ConfigurationShared::CheckState::On:
166 Settings::values.rng_seed.SetGlobal(false); 153 case ConfigurationShared::CheckState::Off:
167 Settings::values.rng_seed.SetValue(ui->rng_seed_edit->text().toULongLong(nullptr, 16));
168 break;
169 case Qt::Unchecked:
170 Settings::values.rng_seed.SetGlobal(false); 154 Settings::values.rng_seed.SetGlobal(false);
171 Settings::values.rng_seed.SetValue(std::nullopt); 155 if (ui->rng_seed_checkbox->isChecked()) {
156 Settings::values.rng_seed.SetValue(
157 ui->rng_seed_edit->text().toULongLong(nullptr, 16));
158 } else {
159 Settings::values.rng_seed.SetValue(std::nullopt);
160 }
172 break; 161 break;
173 case Qt::PartiallyChecked: 162 case ConfigurationShared::CheckState::Global:
174 Settings::values.rng_seed.SetGlobal(false); 163 Settings::values.rng_seed.SetGlobal(false);
175 Settings::values.rng_seed.SetValue(std::nullopt); 164 Settings::values.rng_seed.SetValue(std::nullopt);
176 Settings::values.rng_seed.SetGlobal(true); 165 Settings::values.rng_seed.SetGlobal(true);
177 break; 166 break;
167 case ConfigurationShared::CheckState::Count:
168 break;
178 } 169 }
179 170
180 switch (ui->custom_rtc_checkbox->checkState()) { 171 switch (use_custom_rtc) {
181 case Qt::Checked: 172 case ConfigurationShared::CheckState::On:
182 Settings::values.custom_rtc.SetGlobal(false); 173 case ConfigurationShared::CheckState::Off:
183 Settings::values.custom_rtc.SetValue(
184 std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch()));
185 break;
186 case Qt::Unchecked:
187 Settings::values.custom_rtc.SetGlobal(false); 174 Settings::values.custom_rtc.SetGlobal(false);
188 Settings::values.custom_rtc.SetValue(std::nullopt); 175 if (ui->custom_rtc_checkbox->isChecked()) {
176 Settings::values.custom_rtc.SetValue(
177 std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch()));
178 } else {
179 Settings::values.custom_rtc.SetValue(std::nullopt);
180 }
189 break; 181 break;
190 case Qt::PartiallyChecked: 182 case ConfigurationShared::CheckState::Global:
191 Settings::values.custom_rtc.SetGlobal(false); 183 Settings::values.custom_rtc.SetGlobal(false);
192 Settings::values.custom_rtc.SetValue(std::nullopt); 184 Settings::values.custom_rtc.SetValue(std::nullopt);
193 Settings::values.custom_rtc.SetGlobal(true); 185 Settings::values.custom_rtc.SetGlobal(true);
194 break; 186 break;
187 case ConfigurationShared::CheckState::Count:
188 break;
195 } 189 }
196 } 190 }
197 191
@@ -229,10 +223,23 @@ void ConfigureSystem::SetupPerGameUI() {
229 return; 223 return;
230 } 224 }
231 225
232 ConfigurationShared::InsertGlobalItem(ui->combo_language); 226 ConfigurationShared::SetColoredComboBox(ui->combo_language, ui->label_language,
233 ConfigurationShared::InsertGlobalItem(ui->combo_region); 227 "label_language",
234 ConfigurationShared::InsertGlobalItem(ui->combo_time_zone); 228 Settings::values.language_index.GetValue(true));
235 ConfigurationShared::InsertGlobalItem(ui->combo_sound); 229 ConfigurationShared::SetColoredComboBox(ui->combo_region, ui->label_region, "label_region",
236 ui->rng_seed_checkbox->setTristate(true); 230 Settings::values.region_index.GetValue(true));
237 ui->custom_rtc_checkbox->setTristate(true); 231 ConfigurationShared::SetColoredComboBox(ui->combo_time_zone, ui->label_timezone,
232 "label_timezone",
233 Settings::values.time_zone_index.GetValue(true));
234 ConfigurationShared::SetColoredComboBox(ui->combo_sound, ui->label_sound, "label_sound",
235 Settings::values.sound_index.GetValue(true));
236
237 ConfigurationShared::SetColoredTristate(
238 ui->rng_seed_checkbox, "rng_seed_checkbox", Settings::values.rng_seed.UsingGlobal(),
239 Settings::values.rng_seed.GetValue().has_value(),
240 Settings::values.rng_seed.GetValue(true).has_value(), use_rng_seed);
241 ConfigurationShared::SetColoredTristate(
242 ui->custom_rtc_checkbox, "custom_rtc_checkbox", Settings::values.custom_rtc.UsingGlobal(),
243 Settings::values.custom_rtc.GetValue().has_value(),
244 Settings::values.custom_rtc.GetValue(true).has_value(), use_custom_rtc);
238} 245}
diff --git a/src/yuzu/configuration/configure_system.h b/src/yuzu/configuration/configure_system.h
index f317ef8b5..fc5cd2945 100644
--- a/src/yuzu/configuration/configure_system.h
+++ b/src/yuzu/configuration/configure_system.h
@@ -9,6 +9,10 @@
9#include <QList> 9#include <QList>
10#include <QWidget> 10#include <QWidget>
11 11
12namespace ConfigurationShared {
13enum class CheckState;
14}
15
12namespace Ui { 16namespace Ui {
13class ConfigureSystem; 17class ConfigureSystem;
14} 18}
@@ -41,4 +45,7 @@ private:
41 int region_index = 0; 45 int region_index = 0;
42 int time_zone_index = 0; 46 int time_zone_index = 0;
43 int sound_index = 0; 47 int sound_index = 0;
48
49 ConfigurationShared::CheckState use_rng_seed;
50 ConfigurationShared::CheckState use_custom_rtc;
44}; 51};
diff --git a/src/yuzu/configuration/configure_system.ui b/src/yuzu/configuration/configure_system.ui
index 9c8cca6dc..53b95658b 100644
--- a/src/yuzu/configuration/configure_system.ui
+++ b/src/yuzu/configuration/configure_system.ui
@@ -21,490 +21,494 @@
21 <property name="title"> 21 <property name="title">
22 <string>System Settings</string> 22 <string>System Settings</string>
23 </property> 23 </property>
24 <layout class="QGridLayout" name="gridLayout"> 24 <layout class="QVBoxLayout" name="verticalLayout_2">
25 <item row="3" column="0"> 25 <item>
26 <widget class="QLabel" name="label_sound"> 26 <layout class="QGridLayout" name="gridLayout_2">
27 <property name="text"> 27 <item row="1" column="0">
28 <string>Sound output mode</string> 28 <widget class="QLabel" name="label_region">
29 </property> 29 <property name="text">
30 </widget> 30 <string>Region:</string>
31 </item> 31 </property>
32 <item row="4" column="0"> 32 </widget>
33 <widget class="QLabel" name="label_console_id"> 33 </item>
34 <property name="text"> 34 <item row="2" column="1">
35 <string>Console ID:</string> 35 <widget class="QComboBox" name="combo_time_zone">
36 </property> 36 <item>
37 </widget> 37 <property name="text">
38 </item> 38 <string>Auto</string>
39 <item row="0" column="1"> 39 </property>
40 <widget class="QComboBox" name="combo_language"> 40 </item>
41 <property name="toolTip"> 41 <item>
42 <string>Note: this can be overridden when region setting is auto-select</string> 42 <property name="text">
43 </property> 43 <string>Default</string>
44 <item> 44 </property>
45 <property name="text"> 45 </item>
46 <string>Japanese (日本語)</string> 46 <item>
47 </property> 47 <property name="text">
48 </item> 48 <string>CET</string>
49 <item> 49 </property>
50 <property name="text"> 50 </item>
51 <string>English</string> 51 <item>
52 </property> 52 <property name="text">
53 </item> 53 <string>CST6CDT</string>
54 <item> 54 </property>
55 <property name="text"> 55 </item>
56 <string>French (français)</string> 56 <item>
57 </property> 57 <property name="text">
58 </item> 58 <string>Cuba</string>
59 <item> 59 </property>
60 <property name="text"> 60 </item>
61 <string>German (Deutsch)</string> 61 <item>
62 </property> 62 <property name="text">
63 </item> 63 <string>EET</string>
64 <item> 64 </property>
65 <property name="text"> 65 </item>
66 <string>Italian (italiano)</string> 66 <item>
67 </property> 67 <property name="text">
68 </item> 68 <string>Egypt</string>
69 <item> 69 </property>
70 <property name="text"> 70 </item>
71 <string>Spanish (español)</string> 71 <item>
72 </property> 72 <property name="text">
73 </item> 73 <string>Eire</string>
74 <item> 74 </property>
75 <property name="text"> 75 </item>
76 <string>Chinese</string> 76 <item>
77 </property> 77 <property name="text">
78 </item> 78 <string>EST</string>
79 <item> 79 </property>
80 <property name="text"> 80 </item>
81 <string>Korean (한국어)</string> 81 <item>
82 </property> 82 <property name="text">
83 </item> 83 <string>EST5EDT</string>
84 <item> 84 </property>
85 <property name="text"> 85 </item>
86 <string>Dutch (Nederlands)</string> 86 <item>
87 </property> 87 <property name="text">
88 </item> 88 <string>GB</string>
89 <item> 89 </property>
90 <property name="text"> 90 </item>
91 <string>Portuguese (português)</string> 91 <item>
92 </property> 92 <property name="text">
93 </item> 93 <string>GB-Eire</string>
94 <item> 94 </property>
95 <property name="text"> 95 </item>
96 <string>Russian (Русский)</string> 96 <item>
97 </property> 97 <property name="text">
98 </item> 98 <string>GMT</string>
99 <item> 99 </property>
100 <property name="text"> 100 </item>
101 <string>Taiwanese</string> 101 <item>
102 </property> 102 <property name="text">
103 </item> 103 <string>GMT+0</string>
104 <item> 104 </property>
105 <property name="text"> 105 </item>
106 <string>British English</string> 106 <item>
107 </property> 107 <property name="text">
108 </item> 108 <string>GMT-0</string>
109 <item> 109 </property>
110 <property name="text"> 110 </item>
111 <string>Canadian French</string> 111 <item>
112 </property> 112 <property name="text">
113 </item> 113 <string>GMT0</string>
114 <item> 114 </property>
115 <property name="text"> 115 </item>
116 <string>Latin American Spanish</string> 116 <item>
117 </property> 117 <property name="text">
118 </item> 118 <string>Greenwich</string>
119 <item> 119 </property>
120 <property name="text"> 120 </item>
121 <string>Simplified Chinese</string> 121 <item>
122 </property> 122 <property name="text">
123 </item> 123 <string>Hongkong</string>
124 <item> 124 </property>
125 <property name="text"> 125 </item>
126 <string>Traditional Chinese (正體中文)</string> 126 <item>
127 </property> 127 <property name="text">
128 </item> 128 <string>HST</string>
129 </widget> 129 </property>
130 </item> 130 </item>
131 <item row="1" column="0"> 131 <item>
132 <widget class="QLabel" name="label_region"> 132 <property name="text">
133 <property name="text"> 133 <string>Iceland</string>
134 <string>Region:</string> 134 </property>
135 </property> 135 </item>
136 </widget> 136 <item>
137 </item> 137 <property name="text">
138 <item row="1" column="1"> 138 <string>Iran</string>
139 <widget class="QComboBox" name="combo_region"> 139 </property>
140 <item> 140 </item>
141 <property name="text"> 141 <item>
142 <string>Japan</string> 142 <property name="text">
143 </property> 143 <string>Israel</string>
144 </item> 144 </property>
145 <item> 145 </item>
146 <property name="text"> 146 <item>
147 <string>USA</string> 147 <property name="text">
148 </property> 148 <string>Jamaica</string>
149 </item> 149 </property>
150 <item> 150 </item>
151 <property name="text"> 151 <item>
152 <string>Europe</string> 152 <property name="text">
153 </property> 153 <string>Japan</string>
154 </item> 154 </property>
155 <item> 155 </item>
156 <property name="text"> 156 <item>
157 <string>Australia</string> 157 <property name="text">
158 </property> 158 <string>Kwajalein</string>
159 </item> 159 </property>
160 <item> 160 </item>
161 <property name="text"> 161 <item>
162 <string>China</string> 162 <property name="text">
163 </property> 163 <string>Libya</string>
164 </item> 164 </property>
165 <item> 165 </item>
166 <property name="text"> 166 <item>
167 <string>Korea</string> 167 <property name="text">
168 </property> 168 <string>MET</string>
169 </item> 169 </property>
170 <item> 170 </item>
171 <property name="text"> 171 <item>
172 <string>Taiwan</string> 172 <property name="text">
173 </property> 173 <string>MST</string>
174 </item> 174 </property>
175 </widget> 175 </item>
176 </item> 176 <item>
177 <item row="2" column="0"> 177 <property name="text">
178 <widget class="QLabel" name="label_timezone"> 178 <string>MST7MDT</string>
179 <property name="text"> 179 </property>
180 <string>Time Zone:</string> 180 </item>
181 </property> 181 <item>
182 </widget> 182 <property name="text">
183 </item> 183 <string>Navajo</string>
184 <item row="2" column="1"> 184 </property>
185 <widget class="QComboBox" name="combo_time_zone"> 185 </item>
186 <item> 186 <item>
187 <property name="text"> 187 <property name="text">
188 <string>Auto</string> 188 <string>NZ</string>
189 </property> 189 </property>
190 </item> 190 </item>
191 <item> 191 <item>
192 <property name="text"> 192 <property name="text">
193 <string>Default</string> 193 <string>NZ-CHAT</string>
194 </property> 194 </property>
195 </item> 195 </item>
196 <item> 196 <item>
197 <property name="text"> 197 <property name="text">
198 <string>CET</string> 198 <string>Poland</string>
199 </property> 199 </property>
200 </item> 200 </item>
201 <item> 201 <item>
202 <property name="text"> 202 <property name="text">
203 <string>CST6CDT</string> 203 <string>Portugal</string>
204 </property> 204 </property>
205 </item> 205 </item>
206 <item> 206 <item>
207 <property name="text"> 207 <property name="text">
208 <string>Cuba</string> 208 <string>PRC</string>
209 </property> 209 </property>
210 </item> 210 </item>
211 <item> 211 <item>
212 <property name="text"> 212 <property name="text">
213 <string>EET</string> 213 <string>PST8PDT</string>
214 </property> 214 </property>
215 </item> 215 </item>
216 <item> 216 <item>
217 <property name="text"> 217 <property name="text">
218 <string>Egypt</string> 218 <string>ROC</string>
219 </property> 219 </property>
220 </item> 220 </item>
221 <item> 221 <item>
222 <property name="text"> 222 <property name="text">
223 <string>Eire</string> 223 <string>ROK</string>
224 </property> 224 </property>
225 </item> 225 </item>
226 <item> 226 <item>
227 <property name="text"> 227 <property name="text">
228 <string>EST</string> 228 <string>Singapore</string>
229 </property> 229 </property>
230 </item> 230 </item>
231 <item> 231 <item>
232 <property name="text"> 232 <property name="text">
233 <string>EST5EDT</string> 233 <string>Turkey</string>
234 </property> 234 </property>
235 </item> 235 </item>
236 <item> 236 <item>
237 <property name="text"> 237 <property name="text">
238 <string>GB</string> 238 <string>UCT</string>
239 </property> 239 </property>
240 </item> 240 </item>
241 <item> 241 <item>
242 <property name="text"> 242 <property name="text">
243 <string>GB-Eire</string> 243 <string>Universal</string>
244 </property> 244 </property>
245 </item> 245 </item>
246 <item> 246 <item>
247 <property name="text"> 247 <property name="text">
248 <string>GMT</string> 248 <string>UTC</string>
249 </property> 249 </property>
250 </item> 250 </item>
251 <item> 251 <item>
252 <property name="text"> 252 <property name="text">
253 <string>GMT+0</string> 253 <string>W-SU</string>
254 </property> 254 </property>
255 </item> 255 </item>
256 <item> 256 <item>
257 <property name="text"> 257 <property name="text">
258 <string>GMT-0</string> 258 <string>WET</string>
259 </property> 259 </property>
260 </item> 260 </item>
261 <item> 261 <item>
262 <property name="text"> 262 <property name="text">
263 <string>GMT0</string> 263 <string>Zulu</string>
264 </property> 264 </property>
265 </item> 265 </item>
266 <item> 266 </widget>
267 <property name="text"> 267 </item>
268 <string>Greenwich</string> 268 <item row="1" column="1">
269 </property> 269 <widget class="QComboBox" name="combo_region">
270 </item> 270 <item>
271 <item> 271 <property name="text">
272 <property name="text"> 272 <string>Japan</string>
273 <string>Hongkong</string> 273 </property>
274 </property> 274 </item>
275 </item> 275 <item>
276 <item> 276 <property name="text">
277 <property name="text"> 277 <string>USA</string>
278 <string>HST</string> 278 </property>
279 </property> 279 </item>
280 </item> 280 <item>
281 <item> 281 <property name="text">
282 <property name="text"> 282 <string>Europe</string>
283 <string>Iceland</string> 283 </property>
284 </property> 284 </item>
285 </item> 285 <item>
286 <item> 286 <property name="text">
287 <property name="text"> 287 <string>Australia</string>
288 <string>Iran</string> 288 </property>
289 </property> 289 </item>
290 </item> 290 <item>
291 <item> 291 <property name="text">
292 <property name="text"> 292 <string>China</string>
293 <string>Israel</string> 293 </property>
294 </property> 294 </item>
295 </item> 295 <item>
296 <item> 296 <property name="text">
297 <property name="text"> 297 <string>Korea</string>
298 <string>Jamaica</string> 298 </property>
299 </property> 299 </item>
300 </item> 300 <item>
301 <item> 301 <property name="text">
302 <property name="text"> 302 <string>Taiwan</string>
303 <string>Japan</string> 303 </property>
304 </property> 304 </item>
305 </item> 305 </widget>
306 <item> 306 </item>
307 <property name="text"> 307 <item row="2" column="0">
308 <string>Kwajalein</string> 308 <widget class="QLabel" name="label_timezone">
309 </property> 309 <property name="text">
310 </item> 310 <string>Time Zone:</string>
311 <item> 311 </property>
312 <property name="text"> 312 </widget>
313 <string>Libya</string> 313 </item>
314 </property> 314 <item row="0" column="1">
315 </item> 315 <widget class="QComboBox" name="combo_language">
316 <item> 316 <property name="toolTip">
317 <property name="text"> 317 <string>Note: this can be overridden when region setting is auto-select</string>
318 <string>MET</string> 318 </property>
319 </property> 319 <item>
320 </item> 320 <property name="text">
321 <item> 321 <string>Japanese (日本語)</string>
322 <property name="text"> 322 </property>
323 <string>MST</string> 323 </item>
324 </property> 324 <item>
325 </item> 325 <property name="text">
326 <item> 326 <string>English</string>
327 <property name="text"> 327 </property>
328 <string>MST7MDT</string> 328 </item>
329 </property> 329 <item>
330 </item> 330 <property name="text">
331 <item> 331 <string>French (français)</string>
332 <property name="text"> 332 </property>
333 <string>Navajo</string> 333 </item>
334 </property> 334 <item>
335 </item> 335 <property name="text">
336 <item> 336 <string>German (Deutsch)</string>
337 <property name="text"> 337 </property>
338 <string>NZ</string> 338 </item>
339 </property> 339 <item>
340 </item> 340 <property name="text">
341 <item> 341 <string>Italian (italiano)</string>
342 <property name="text"> 342 </property>
343 <string>NZ-CHAT</string> 343 </item>
344 </property> 344 <item>
345 </item> 345 <property name="text">
346 <item> 346 <string>Spanish (español)</string>
347 <property name="text"> 347 </property>
348 <string>Poland</string> 348 </item>
349 </property> 349 <item>
350 </item> 350 <property name="text">
351 <item> 351 <string>Chinese</string>
352 <property name="text"> 352 </property>
353 <string>Portugal</string> 353 </item>
354 </property> 354 <item>
355 </item> 355 <property name="text">
356 <item> 356 <string>Korean (한국어)</string>
357 <property name="text"> 357 </property>
358 <string>PRC</string> 358 </item>
359 </property> 359 <item>
360 </item> 360 <property name="text">
361 <item> 361 <string>Dutch (Nederlands)</string>
362 <property name="text"> 362 </property>
363 <string>PST8PDT</string> 363 </item>
364 </property> 364 <item>
365 </item> 365 <property name="text">
366 <item> 366 <string>Portuguese (português)</string>
367 <property name="text"> 367 </property>
368 <string>ROC</string> 368 </item>
369 </property> 369 <item>
370 </item> 370 <property name="text">
371 <item> 371 <string>Russian (Русский)</string>
372 <property name="text"> 372 </property>
373 <string>ROK</string> 373 </item>
374 </property> 374 <item>
375 </item> 375 <property name="text">
376 <item> 376 <string>Taiwanese</string>
377 <property name="text"> 377 </property>
378 <string>Singapore</string> 378 </item>
379 </property> 379 <item>
380 </item> 380 <property name="text">
381 <item> 381 <string>British English</string>
382 <property name="text"> 382 </property>
383 <string>Turkey</string> 383 </item>
384 </property> 384 <item>
385 </item> 385 <property name="text">
386 <item> 386 <string>Canadian French</string>
387 <property name="text"> 387 </property>
388 <string>UCT</string> 388 </item>
389 </property> 389 <item>
390 </item> 390 <property name="text">
391 <item> 391 <string>Latin American Spanish</string>
392 <property name="text"> 392 </property>
393 <string>Universal</string> 393 </item>
394 </property> 394 <item>
395 </item> 395 <property name="text">
396 <item> 396 <string>Simplified Chinese</string>
397 <property name="text"> 397 </property>
398 <string>UTC</string> 398 </item>
399 </property> 399 <item>
400 </item> 400 <property name="text">
401 <item> 401 <string>Traditional Chinese (正體中文)</string>
402 <property name="text"> 402 </property>
403 <string>W-SU</string> 403 </item>
404 </property> 404 </widget>
405 </item> 405 </item>
406 <item> 406 <item row="5" column="0">
407 <property name="text"> 407 <widget class="QCheckBox" name="custom_rtc_checkbox">
408 <string>WET</string> 408 <property name="text">
409 </property> 409 <string>Custom RTC</string>
410 </item> 410 </property>
411 <item> 411 </widget>
412 <property name="text"> 412 </item>
413 <string>Zulu</string> 413 <item row="0" column="0">
414 </property> 414 <widget class="QLabel" name="label_language">
415 </item> 415 <property name="text">
416 </widget> 416 <string>Language</string>
417 </item> 417 </property>
418 <item row="6" column="0"> 418 </widget>
419 <widget class="QCheckBox" name="rng_seed_checkbox"> 419 </item>
420 <property name="text"> 420 <item row="6" column="0">
421 <string>RNG Seed</string> 421 <widget class="QCheckBox" name="rng_seed_checkbox">
422 </property> 422 <property name="text">
423 </widget> 423 <string>RNG Seed</string>
424 </item> 424 </property>
425 <item row="3" column="1"> 425 </widget>
426 <widget class="QComboBox" name="combo_sound"> 426 </item>
427 <item> 427 <item row="3" column="1">
428 <property name="text"> 428 <widget class="QComboBox" name="combo_sound">
429 <string>Mono</string> 429 <item>
430 </property> 430 <property name="text">
431 </item> 431 <string>Mono</string>
432 <item> 432 </property>
433 <property name="text"> 433 </item>
434 <string>Stereo</string> 434 <item>
435 </property> 435 <property name="text">
436 </item> 436 <string>Stereo</string>
437 <item> 437 </property>
438 <property name="text"> 438 </item>
439 <string>Surround</string> 439 <item>
440 </property> 440 <property name="text">
441 </item> 441 <string>Surround</string>
442 </widget> 442 </property>
443 </item> 443 </item>
444 <item row="0" column="0"> 444 </widget>
445 <widget class="QLabel" name="label_language"> 445 </item>
446 <property name="text"> 446 <item row="4" column="0">
447 <string>Language</string> 447 <widget class="QLabel" name="label_console_id">
448 </property> 448 <property name="text">
449 </widget> 449 <string>Console ID:</string>
450 </item> 450 </property>
451 <item row="4" column="1"> 451 </widget>
452 <widget class="QPushButton" name="button_regenerate_console_id"> 452 </item>
453 <property name="sizePolicy"> 453 <item row="3" column="0">
454 <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> 454 <widget class="QLabel" name="label_sound">
455 <horstretch>0</horstretch> 455 <property name="text">
456 <verstretch>0</verstretch> 456 <string>Sound output mode</string>
457 </sizepolicy> 457 </property>
458 </property> 458 </widget>
459 <property name="layoutDirection"> 459 </item>
460 <enum>Qt::RightToLeft</enum> 460 <item row="5" column="1">
461 </property> 461 <widget class="QDateTimeEdit" name="custom_rtc_edit">
462 <property name="text"> 462 <property name="minimumDate">
463 <string>Regenerate</string> 463 <date>
464 </property> 464 <year>1970</year>
465 </widget> 465 <month>1</month>
466 </item> 466 <day>1</day>
467 <item row="5" column="0"> 467 </date>
468 <widget class="QCheckBox" name="custom_rtc_checkbox"> 468 </property>
469 <property name="text"> 469 <property name="displayFormat">
470 <string>Custom RTC</string> 470 <string>d MMM yyyy h:mm:ss AP</string>
471 </property> 471 </property>
472 </widget> 472 </widget>
473 </item> 473 </item>
474 <item row="5" column="1"> 474 <item row="6" column="1">
475 <widget class="QDateTimeEdit" name="custom_rtc_edit"> 475 <widget class="QLineEdit" name="rng_seed_edit">
476 <property name="minimumDate"> 476 <property name="sizePolicy">
477 <date> 477 <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
478 <year>1970</year> 478 <horstretch>0</horstretch>
479 <month>1</month> 479 <verstretch>0</verstretch>
480 <day>1</day> 480 </sizepolicy>
481 </date> 481 </property>
482 </property> 482 <property name="font">
483 <property name="displayFormat"> 483 <font>
484 <string>d MMM yyyy h:mm:ss AP</string> 484 <family>Lucida Console</family>
485 </property> 485 </font>
486 </widget> 486 </property>
487 </item> 487 <property name="inputMask">
488 <item row="6" column="1"> 488 <string notr="true">HHHHHHHH</string>
489 <widget class="QLineEdit" name="rng_seed_edit"> 489 </property>
490 <property name="sizePolicy"> 490 <property name="maxLength">
491 <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> 491 <number>8</number>
492 <horstretch>0</horstretch> 492 </property>
493 <verstretch>0</verstretch> 493 </widget>
494 </sizepolicy> 494 </item>
495 </property> 495 <item row="4" column="1">
496 <property name="font"> 496 <widget class="QPushButton" name="button_regenerate_console_id">
497 <font> 497 <property name="sizePolicy">
498 <family>Lucida Console</family> 498 <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
499 </font> 499 <horstretch>0</horstretch>
500 </property> 500 <verstretch>0</verstretch>
501 <property name="inputMask"> 501 </sizepolicy>
502 <string notr="true">HHHHHHHH</string> 502 </property>
503 </property> 503 <property name="layoutDirection">
504 <property name="maxLength"> 504 <enum>Qt::RightToLeft</enum>
505 <number>8</number> 505 </property>
506 </property> 506 <property name="text">
507 </widget> 507 <string>Regenerate</string>
508 </property>
509 </widget>
510 </item>
511 </layout>
508 </item> 512 </item>
509 </layout> 513 </layout>
510 </widget> 514 </widget>
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
index f391a41a9..3439cb333 100644
--- a/src/yuzu/debugger/wait_tree.cpp
+++ b/src/yuzu/debugger/wait_tree.cpp
@@ -38,7 +38,10 @@ constexpr std::array<std::array<Qt::GlobalColor, 2>, 10> WaitTreeColors{{
38 38
39bool IsDarkTheme() { 39bool IsDarkTheme() {
40 const auto& theme = UISettings::values.theme; 40 const auto& theme = UISettings::values.theme;
41 return theme == QStringLiteral("qdarkstyle") || theme == QStringLiteral("colorful_dark"); 41 return theme == QStringLiteral("qdarkstyle") ||
42 theme == QStringLiteral("qdarkstyle_midnight_blue") ||
43 theme == QStringLiteral("colorful_dark") ||
44 theme == QStringLiteral("colorful_midnight_blue");
42} 45}
43 46
44} // namespace 47} // namespace
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index ab7fc7a24..62acc3720 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -474,28 +474,56 @@ void GameList::PopupContextMenu(const QPoint& menu_location) {
474 474
475void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, std::string path) { 475void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, std::string path) {
476 QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location")); 476 QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location"));
477 QAction* open_lfs_location = context_menu.addAction(tr("Open Mod Data Location")); 477 QAction* open_mod_location = context_menu.addAction(tr("Open Mod Data Location"));
478 QAction* open_transferable_shader_cache = 478 QAction* open_transferable_shader_cache =
479 context_menu.addAction(tr("Open Transferable Shader Cache")); 479 context_menu.addAction(tr("Open Transferable Shader Cache"));
480 context_menu.addSeparator(); 480 context_menu.addSeparator();
481 QMenu* remove_menu = context_menu.addMenu(tr("Remove"));
482 QAction* remove_update = remove_menu->addAction(tr("Remove Installed Update"));
483 QAction* remove_dlc = remove_menu->addAction(tr("Remove All Installed DLC"));
484 QAction* remove_shader_cache = remove_menu->addAction(tr("Remove Shader Cache"));
485 QAction* remove_custom_config = remove_menu->addAction(tr("Remove Custom Configuration"));
486 remove_menu->addSeparator();
487 QAction* remove_all_content = remove_menu->addAction(tr("Remove All Installed Contents"));
481 QAction* dump_romfs = context_menu.addAction(tr("Dump RomFS")); 488 QAction* dump_romfs = context_menu.addAction(tr("Dump RomFS"));
482 QAction* copy_tid = context_menu.addAction(tr("Copy Title ID to Clipboard")); 489 QAction* copy_tid = context_menu.addAction(tr("Copy Title ID to Clipboard"));
483 QAction* navigate_to_gamedb_entry = context_menu.addAction(tr("Navigate to GameDB entry")); 490 QAction* navigate_to_gamedb_entry = context_menu.addAction(tr("Navigate to GameDB entry"));
484 context_menu.addSeparator(); 491 context_menu.addSeparator();
485 QAction* properties = context_menu.addAction(tr("Properties")); 492 QAction* properties = context_menu.addAction(tr("Properties"));
486 493
487 open_save_location->setEnabled(program_id != 0); 494 open_save_location->setVisible(program_id != 0);
495 open_mod_location->setVisible(program_id != 0);
496 open_transferable_shader_cache->setVisible(program_id != 0);
497 remove_update->setVisible(program_id != 0);
498 remove_dlc->setVisible(program_id != 0);
499 remove_shader_cache->setVisible(program_id != 0);
500 remove_all_content->setVisible(program_id != 0);
488 auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); 501 auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
489 navigate_to_gamedb_entry->setVisible(it != compatibility_list.end() && program_id != 0); 502 navigate_to_gamedb_entry->setVisible(it != compatibility_list.end() && program_id != 0);
490 503
491 connect(open_save_location, &QAction::triggered, [this, program_id, path]() { 504 connect(open_save_location, &QAction::triggered, [this, program_id, path]() {
492 emit OpenFolderRequested(GameListOpenTarget::SaveData, path); 505 emit OpenFolderRequested(GameListOpenTarget::SaveData, path);
493 }); 506 });
494 connect(open_lfs_location, &QAction::triggered, [this, program_id, path]() { 507 connect(open_mod_location, &QAction::triggered, [this, program_id, path]() {
495 emit OpenFolderRequested(GameListOpenTarget::ModData, path); 508 emit OpenFolderRequested(GameListOpenTarget::ModData, path);
496 }); 509 });
497 connect(open_transferable_shader_cache, &QAction::triggered, 510 connect(open_transferable_shader_cache, &QAction::triggered,
498 [this, program_id]() { emit OpenTransferableShaderCacheRequested(program_id); }); 511 [this, program_id]() { emit OpenTransferableShaderCacheRequested(program_id); });
512 connect(remove_all_content, &QAction::triggered, [this, program_id]() {
513 emit RemoveInstalledEntryRequested(program_id, InstalledEntryType::Game);
514 });
515 connect(remove_update, &QAction::triggered, [this, program_id]() {
516 emit RemoveInstalledEntryRequested(program_id, InstalledEntryType::Update);
517 });
518 connect(remove_dlc, &QAction::triggered, [this, program_id]() {
519 emit RemoveInstalledEntryRequested(program_id, InstalledEntryType::AddOnContent);
520 });
521 connect(remove_shader_cache, &QAction::triggered, [this, program_id]() {
522 emit RemoveFileRequested(program_id, GameListRemoveTarget::ShaderCache);
523 });
524 connect(remove_custom_config, &QAction::triggered, [this, program_id]() {
525 emit RemoveFileRequested(program_id, GameListRemoveTarget::CustomConfiguration);
526 });
499 connect(dump_romfs, &QAction::triggered, 527 connect(dump_romfs, &QAction::triggered,
500 [this, program_id, path]() { emit DumpRomFSRequested(program_id, path); }); 528 [this, program_id, path]() { emit DumpRomFSRequested(program_id, path); });
501 connect(copy_tid, &QAction::triggered, 529 connect(copy_tid, &QAction::triggered,
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h
index a38cb2fc3..483835cce 100644
--- a/src/yuzu/game_list.h
+++ b/src/yuzu/game_list.h
@@ -39,6 +39,17 @@ enum class GameListOpenTarget {
39 ModData, 39 ModData,
40}; 40};
41 41
42enum class GameListRemoveTarget {
43 ShaderCache,
44 CustomConfiguration,
45};
46
47enum class InstalledEntryType {
48 Game,
49 Update,
50 AddOnContent,
51};
52
42class GameList : public QWidget { 53class GameList : public QWidget {
43 Q_OBJECT 54 Q_OBJECT
44 55
@@ -75,6 +86,8 @@ signals:
75 void ShouldCancelWorker(); 86 void ShouldCancelWorker();
76 void OpenFolderRequested(GameListOpenTarget target, const std::string& game_path); 87 void OpenFolderRequested(GameListOpenTarget target, const std::string& game_path);
77 void OpenTransferableShaderCacheRequested(u64 program_id); 88 void OpenTransferableShaderCacheRequested(u64 program_id);
89 void RemoveInstalledEntryRequested(u64 program_id, InstalledEntryType type);
90 void RemoveFileRequested(u64 program_id, GameListRemoveTarget target);
78 void DumpRomFSRequested(u64 program_id, const std::string& game_path); 91 void DumpRomFSRequested(u64 program_id, const std::string& game_path);
79 void CopyTIDRequested(u64 program_id); 92 void CopyTIDRequested(u64 program_id);
80 void NavigateToGamedbEntryRequested(u64 program_id, 93 void NavigateToGamedbEntryRequested(u64 program_id,
@@ -117,8 +130,6 @@ private:
117 friend class GameListSearchField; 130 friend class GameListSearchField;
118}; 131};
119 132
120Q_DECLARE_METATYPE(GameListOpenTarget);
121
122class GameListPlaceholder : public QWidget { 133class GameListPlaceholder : public QWidget {
123 Q_OBJECT 134 Q_OBJECT
124public: 135public:
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 31a635176..276658c9e 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -847,6 +847,9 @@ void GMainWindow::ConnectWidgetEvents() {
847 connect(game_list, &GameList::OpenFolderRequested, this, &GMainWindow::OnGameListOpenFolder); 847 connect(game_list, &GameList::OpenFolderRequested, this, &GMainWindow::OnGameListOpenFolder);
848 connect(game_list, &GameList::OpenTransferableShaderCacheRequested, this, 848 connect(game_list, &GameList::OpenTransferableShaderCacheRequested, this,
849 &GMainWindow::OnTransferableShaderCacheOpenFile); 849 &GMainWindow::OnTransferableShaderCacheOpenFile);
850 connect(game_list, &GameList::RemoveInstalledEntryRequested, this,
851 &GMainWindow::OnGameListRemoveInstalledEntry);
852 connect(game_list, &GameList::RemoveFileRequested, this, &GMainWindow::OnGameListRemoveFile);
850 connect(game_list, &GameList::DumpRomFSRequested, this, &GMainWindow::OnGameListDumpRomFS); 853 connect(game_list, &GameList::DumpRomFSRequested, this, &GMainWindow::OnGameListDumpRomFS);
851 connect(game_list, &GameList::CopyTIDRequested, this, &GMainWindow::OnGameListCopyTID); 854 connect(game_list, &GameList::CopyTIDRequested, this, &GMainWindow::OnGameListCopyTID);
852 connect(game_list, &GameList::NavigateToGamedbEntryRequested, this, 855 connect(game_list, &GameList::NavigateToGamedbEntryRequested, this,
@@ -1257,7 +1260,6 @@ void GMainWindow::OnGameListOpenFolder(GameListOpenTarget target, const std::str
1257 case GameListOpenTarget::SaveData: { 1260 case GameListOpenTarget::SaveData: {
1258 open_target = tr("Save Data"); 1261 open_target = tr("Save Data");
1259 const std::string nand_dir = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir); 1262 const std::string nand_dir = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);
1260 ASSERT(program_id != 0);
1261 1263
1262 if (has_user_save) { 1264 if (has_user_save) {
1263 // User save data 1265 // User save data
@@ -1322,14 +1324,12 @@ void GMainWindow::OnGameListOpenFolder(GameListOpenTarget target, const std::str
1322} 1324}
1323 1325
1324void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) { 1326void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
1325 ASSERT(program_id != 0);
1326
1327 const QString shader_dir = 1327 const QString shader_dir =
1328 QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir)); 1328 QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir));
1329 const QString tranferable_shader_cache_folder_path = 1329 const QString transferable_shader_cache_folder_path =
1330 shader_dir + QStringLiteral("opengl") + QDir::separator() + QStringLiteral("transferable"); 1330 shader_dir + QStringLiteral("opengl") + QDir::separator() + QStringLiteral("transferable");
1331 const QString transferable_shader_cache_file_path = 1331 const QString transferable_shader_cache_file_path =
1332 tranferable_shader_cache_folder_path + QDir::separator() + 1332 transferable_shader_cache_folder_path + QDir::separator() +
1333 QString::fromStdString(fmt::format("{:016X}.bin", program_id)); 1333 QString::fromStdString(fmt::format("{:016X}.bin", program_id));
1334 1334
1335 if (!QFile::exists(transferable_shader_cache_file_path)) { 1335 if (!QFile::exists(transferable_shader_cache_file_path)) {
@@ -1350,7 +1350,7 @@ void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
1350 param << QDir::toNativeSeparators(transferable_shader_cache_file_path); 1350 param << QDir::toNativeSeparators(transferable_shader_cache_file_path);
1351 QProcess::startDetached(explorer, param); 1351 QProcess::startDetached(explorer, param);
1352#else 1352#else
1353 QDesktopServices::openUrl(QUrl::fromLocalFile(tranferable_shader_cache_folder_path)); 1353 QDesktopServices::openUrl(QUrl::fromLocalFile(transferable_shader_cache_folder_path));
1354#endif 1354#endif
1355} 1355}
1356 1356
@@ -1394,6 +1394,174 @@ static bool RomFSRawCopy(QProgressDialog& dialog, const FileSys::VirtualDir& src
1394 return true; 1394 return true;
1395} 1395}
1396 1396
1397void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryType type) {
1398 const QString entry_type = [this, type] {
1399 switch (type) {
1400 case InstalledEntryType::Game:
1401 return tr("Contents");
1402 case InstalledEntryType::Update:
1403 return tr("Update");
1404 case InstalledEntryType::AddOnContent:
1405 return tr("DLC");
1406 default:
1407 return QString{};
1408 }
1409 }();
1410
1411 if (QMessageBox::question(
1412 this, tr("Remove Entry"), tr("Remove Installed Game %1?").arg(entry_type),
1413 QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes) {
1414 return;
1415 }
1416
1417 switch (type) {
1418 case InstalledEntryType::Game:
1419 RemoveBaseContent(program_id, entry_type);
1420 [[fallthrough]];
1421 case InstalledEntryType::Update:
1422 RemoveUpdateContent(program_id, entry_type);
1423 if (type != InstalledEntryType::Game) {
1424 break;
1425 }
1426 [[fallthrough]];
1427 case InstalledEntryType::AddOnContent:
1428 RemoveAddOnContent(program_id, entry_type);
1429 break;
1430 }
1431 FileUtil::DeleteDirRecursively(FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) + DIR_SEP +
1432 "game_list");
1433 game_list->PopulateAsync(UISettings::values.game_dirs);
1434}
1435
1436void GMainWindow::RemoveBaseContent(u64 program_id, const QString& entry_type) {
1437 const auto& fs_controller = Core::System::GetInstance().GetFileSystemController();
1438 const auto res = fs_controller.GetUserNANDContents()->RemoveExistingEntry(program_id) ||
1439 fs_controller.GetSDMCContents()->RemoveExistingEntry(program_id);
1440
1441 if (res) {
1442 QMessageBox::information(this, tr("Successfully Removed"),
1443 tr("Successfully removed the installed base game."));
1444 } else {
1445 QMessageBox::warning(
1446 this, tr("Error Removing %1").arg(entry_type),
1447 tr("The base game is not installed in the NAND and cannot be removed."));
1448 }
1449}
1450
1451void GMainWindow::RemoveUpdateContent(u64 program_id, const QString& entry_type) {
1452 const auto update_id = program_id | 0x800;
1453 const auto& fs_controller = Core::System::GetInstance().GetFileSystemController();
1454 const auto res = fs_controller.GetUserNANDContents()->RemoveExistingEntry(update_id) ||
1455 fs_controller.GetSDMCContents()->RemoveExistingEntry(update_id);
1456
1457 if (res) {
1458 QMessageBox::information(this, tr("Successfully Removed"),
1459 tr("Successfully removed the installed update."));
1460 } else {
1461 QMessageBox::warning(this, tr("Error Removing %1").arg(entry_type),
1462 tr("There is no update installed for this title."));
1463 }
1464}
1465
1466void GMainWindow::RemoveAddOnContent(u64 program_id, const QString& entry_type) {
1467 u32 count{};
1468 const auto& fs_controller = Core::System::GetInstance().GetFileSystemController();
1469 const auto dlc_entries = Core::System::GetInstance().GetContentProvider().ListEntriesFilter(
1470 FileSys::TitleType::AOC, FileSys::ContentRecordType::Data);
1471
1472 for (const auto& entry : dlc_entries) {
1473 if ((entry.title_id & DLC_BASE_TITLE_ID_MASK) == program_id) {
1474 const auto res =
1475 fs_controller.GetUserNANDContents()->RemoveExistingEntry(entry.title_id) ||
1476 fs_controller.GetSDMCContents()->RemoveExistingEntry(entry.title_id);
1477 if (res) {
1478 ++count;
1479 }
1480 }
1481 }
1482
1483 if (count == 0) {
1484 QMessageBox::warning(this, tr("Error Removing %1").arg(entry_type),
1485 tr("There are no DLC installed for this title."));
1486 return;
1487 }
1488
1489 QMessageBox::information(this, tr("Successfully Removed"),
1490 tr("Successfully removed %1 installed DLC.").arg(count));
1491}
1492
1493void GMainWindow::OnGameListRemoveFile(u64 program_id, GameListRemoveTarget target) {
1494 const QString question = [this, target] {
1495 switch (target) {
1496 case GameListRemoveTarget::ShaderCache:
1497 return tr("Delete Transferable Shader Cache?");
1498 case GameListRemoveTarget::CustomConfiguration:
1499 return tr("Remove Custom Game Configuration?");
1500 default:
1501 return QString{};
1502 }
1503 }();
1504
1505 if (QMessageBox::question(this, tr("Remove File"), question, QMessageBox::Yes | QMessageBox::No,
1506 QMessageBox::No) != QMessageBox::Yes) {
1507 return;
1508 }
1509
1510 switch (target) {
1511 case GameListRemoveTarget::ShaderCache:
1512 RemoveTransferableShaderCache(program_id);
1513 break;
1514 case GameListRemoveTarget::CustomConfiguration:
1515 RemoveCustomConfiguration(program_id);
1516 break;
1517 }
1518}
1519
1520void GMainWindow::RemoveTransferableShaderCache(u64 program_id) {
1521 const QString shader_dir =
1522 QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir));
1523 const QString transferable_shader_cache_folder_path =
1524 shader_dir + QStringLiteral("opengl") + QDir::separator() + QStringLiteral("transferable");
1525 const QString transferable_shader_cache_file_path =
1526 transferable_shader_cache_folder_path + QDir::separator() +
1527 QString::fromStdString(fmt::format("{:016X}.bin", program_id));
1528
1529 if (!QFile::exists(transferable_shader_cache_file_path)) {
1530 QMessageBox::warning(this, tr("Error Removing Transferable Shader Cache"),
1531 tr("A shader cache for this title does not exist."));
1532 return;
1533 }
1534
1535 if (QFile::remove(transferable_shader_cache_file_path)) {
1536 QMessageBox::information(this, tr("Successfully Removed"),
1537 tr("Successfully removed the transferable shader cache."));
1538 } else {
1539 QMessageBox::warning(this, tr("Error Removing Transferable Shader Cache"),
1540 tr("Failed to remove the transferable shader cache."));
1541 }
1542}
1543
1544void GMainWindow::RemoveCustomConfiguration(u64 program_id) {
1545 const QString config_dir =
1546 QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::ConfigDir));
1547 const QString custom_config_file_path =
1548 config_dir + QString::fromStdString(fmt::format("{:016X}.ini", program_id));
1549
1550 if (!QFile::exists(custom_config_file_path)) {
1551 QMessageBox::warning(this, tr("Error Removing Custom Configuration"),
1552 tr("A custom configuration for this title does not exist."));
1553 return;
1554 }
1555
1556 if (QFile::remove(custom_config_file_path)) {
1557 QMessageBox::information(this, tr("Successfully Removed"),
1558 tr("Successfully removed the custom game configuration."));
1559 } else {
1560 QMessageBox::warning(this, tr("Error Removing Custom Configuration"),
1561 tr("Failed to remove the custom game configuration."));
1562 }
1563}
1564
1397void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_path) { 1565void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_path) {
1398 const auto failed = [this] { 1566 const auto failed = [this] {
1399 QMessageBox::warning(this, tr("RomFS Extraction Failed!"), 1567 QMessageBox::warning(this, tr("RomFS Extraction Failed!"),
@@ -1714,9 +1882,9 @@ void GMainWindow::OnMenuInstallToNAND() {
1714 : tr("%n file(s) failed to install\n", "", failed_files.size())); 1882 : tr("%n file(s) failed to install\n", "", failed_files.size()));
1715 1883
1716 QMessageBox::information(this, tr("Install Results"), install_results); 1884 QMessageBox::information(this, tr("Install Results"), install_results);
1717 game_list->PopulateAsync(UISettings::values.game_dirs);
1718 FileUtil::DeleteDirRecursively(FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) + DIR_SEP + 1885 FileUtil::DeleteDirRecursively(FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) + DIR_SEP +
1719 "game_list"); 1886 "game_list");
1887 game_list->PopulateAsync(UISettings::values.game_dirs);
1720 ui.action_Install_File_NAND->setEnabled(true); 1888 ui.action_Install_File_NAND->setEnabled(true);
1721} 1889}
1722 1890
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index db573d606..73a44a3bf 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -32,6 +32,8 @@ class QPushButton;
32class QProgressDialog; 32class QProgressDialog;
33class WaitTreeWidget; 33class WaitTreeWidget;
34enum class GameListOpenTarget; 34enum class GameListOpenTarget;
35enum class GameListRemoveTarget;
36enum class InstalledEntryType;
35class GameListPlaceholder; 37class GameListPlaceholder;
36 38
37namespace Core::Frontend { 39namespace Core::Frontend {
@@ -198,6 +200,8 @@ private slots:
198 void OnGameListLoadFile(QString game_path); 200 void OnGameListLoadFile(QString game_path);
199 void OnGameListOpenFolder(GameListOpenTarget target, const std::string& game_path); 201 void OnGameListOpenFolder(GameListOpenTarget target, const std::string& game_path);
200 void OnTransferableShaderCacheOpenFile(u64 program_id); 202 void OnTransferableShaderCacheOpenFile(u64 program_id);
203 void OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryType type);
204 void OnGameListRemoveFile(u64 program_id, GameListRemoveTarget target);
201 void OnGameListDumpRomFS(u64 program_id, const std::string& game_path); 205 void OnGameListDumpRomFS(u64 program_id, const std::string& game_path);
202 void OnGameListCopyTID(u64 program_id); 206 void OnGameListCopyTID(u64 program_id);
203 void OnGameListNavigateToGamedbEntry(u64 program_id, 207 void OnGameListNavigateToGamedbEntry(u64 program_id,
@@ -229,6 +233,11 @@ private slots:
229 void OnLanguageChanged(const QString& locale); 233 void OnLanguageChanged(const QString& locale);
230 234
231private: 235private:
236 void RemoveBaseContent(u64 program_id, const QString& entry_type);
237 void RemoveUpdateContent(u64 program_id, const QString& entry_type);
238 void RemoveAddOnContent(u64 program_id, const QString& entry_type);
239 void RemoveTransferableShaderCache(u64 program_id);
240 void RemoveCustomConfiguration(u64 program_id);
232 std::optional<u64> SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id); 241 std::optional<u64> SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id);
233 InstallResult InstallNSPXCI(const QString& filename); 242 InstallResult InstallNSPXCI(const QString& filename);
234 InstallResult InstallNCA(const QString& filename); 243 InstallResult InstallNCA(const QString& filename);
diff --git a/src/yuzu/uisettings.cpp b/src/yuzu/uisettings.cpp
index 738c4b2fc..a51175f36 100644
--- a/src/yuzu/uisettings.cpp
+++ b/src/yuzu/uisettings.cpp
@@ -11,6 +11,8 @@ const Themes themes{{
11 {"Light Colorful", "colorful"}, 11 {"Light Colorful", "colorful"},
12 {"Dark", "qdarkstyle"}, 12 {"Dark", "qdarkstyle"},
13 {"Dark Colorful", "colorful_dark"}, 13 {"Dark Colorful", "colorful_dark"},
14 {"Midnight Blue", "qdarkstyle_midnight_blue"},
15 {"Midnight Blue Colorful", "colorful_midnight_blue"},
14}}; 16}};
15 17
16Values values = {}; 18Values values = {};
diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h
index 6cc65736d..ac7b9aef6 100644
--- a/src/yuzu/uisettings.h
+++ b/src/yuzu/uisettings.h
@@ -24,7 +24,7 @@ struct Shortcut {
24 ContextualShortcut shortcut; 24 ContextualShortcut shortcut;
25}; 25};
26 26
27using Themes = std::array<std::pair<const char*, const char*>, 4>; 27using Themes = std::array<std::pair<const char*, const char*>, 6>;
28extern const Themes themes; 28extern const Themes themes;
29 29
30struct GameDir { 30struct GameDir {