summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt3
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt10
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt1
-rw-r--r--src/android/app/src/main/res/layout/list_item_setting_switch.xml2
-rw-r--r--src/android/app/src/main/res/values/arrays.xml17
-rw-r--r--src/android/app/src/main/res/values/strings.xml8
-rw-r--r--src/shader_recompiler/backend/spirv/spirv_emit_context.cpp60
-rw-r--r--src/video_core/texture_cache/decode_bc.cpp50
-rw-r--r--src/video_core/texture_cache/decode_bc.h2
-rw-r--r--src/video_core/texture_cache/util.cpp16
-rw-r--r--src/yuzu/main.cpp4
11 files changed, 116 insertions, 57 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt
index 21e4e1afd..df760440f 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt
@@ -18,7 +18,8 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
18 RENDERER_ANTI_ALIASING("anti_aliasing"), 18 RENDERER_ANTI_ALIASING("anti_aliasing"),
19 RENDERER_SCREEN_LAYOUT("screen_layout"), 19 RENDERER_SCREEN_LAYOUT("screen_layout"),
20 RENDERER_ASPECT_RATIO("aspect_ratio"), 20 RENDERER_ASPECT_RATIO("aspect_ratio"),
21 AUDIO_OUTPUT_ENGINE("output_engine"); 21 AUDIO_OUTPUT_ENGINE("output_engine"),
22 MAX_ANISOTROPY("max_anisotropy");
22 23
23 override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal) 24 override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal)
24 25
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
index 2e97aee2c..12f7aa1ab 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
@@ -245,6 +245,15 @@ abstract class SettingsItem(
245 ) 245 )
246 put( 246 put(
247 SingleChoiceSetting( 247 SingleChoiceSetting(
248 IntSetting.MAX_ANISOTROPY,
249 R.string.anisotropic_filtering,
250 R.string.anisotropic_filtering_description,
251 R.array.anisoEntries,
252 R.array.anisoValues
253 )
254 )
255 put(
256 SingleChoiceSetting(
248 IntSetting.AUDIO_OUTPUT_ENGINE, 257 IntSetting.AUDIO_OUTPUT_ENGINE,
249 R.string.audio_output_engine, 258 R.string.audio_output_engine,
250 0, 259 0,
@@ -298,6 +307,7 @@ abstract class SettingsItem(
298 307
299 override val key: String = FASTMEM_COMBINED 308 override val key: String = FASTMEM_COMBINED
300 override val isRuntimeModifiable: Boolean = false 309 override val isRuntimeModifiable: Boolean = false
310 override val pairedSettingKey = BooleanSetting.CPU_DEBUG_MODE.key
301 override val defaultValue: Boolean = true 311 override val defaultValue: Boolean = true
302 override val isSwitchable: Boolean = true 312 override val isSwitchable: Boolean = true
303 override var global: Boolean 313 override var global: Boolean
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
index a7e965589..db1a1076c 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
@@ -149,6 +149,7 @@ class SettingsFragmentPresenter(
149 add(IntSetting.RENDERER_VSYNC.key) 149 add(IntSetting.RENDERER_VSYNC.key)
150 add(IntSetting.RENDERER_SCALING_FILTER.key) 150 add(IntSetting.RENDERER_SCALING_FILTER.key)
151 add(IntSetting.RENDERER_ANTI_ALIASING.key) 151 add(IntSetting.RENDERER_ANTI_ALIASING.key)
152 add(IntSetting.MAX_ANISOTROPY.key)
152 add(IntSetting.RENDERER_SCREEN_LAYOUT.key) 153 add(IntSetting.RENDERER_SCREEN_LAYOUT.key)
153 add(IntSetting.RENDERER_ASPECT_RATIO.key) 154 add(IntSetting.RENDERER_ASPECT_RATIO.key)
154 add(BooleanSetting.PICTURE_IN_PICTURE.key) 155 add(BooleanSetting.PICTURE_IN_PICTURE.key)
diff --git a/src/android/app/src/main/res/layout/list_item_setting_switch.xml b/src/android/app/src/main/res/layout/list_item_setting_switch.xml
index 5cb84182e..1c08e2e1b 100644
--- a/src/android/app/src/main/res/layout/list_item_setting_switch.xml
+++ b/src/android/app/src/main/res/layout/list_item_setting_switch.xml
@@ -24,7 +24,7 @@
24 android:layout_width="0dp" 24 android:layout_width="0dp"
25 android:layout_height="wrap_content" 25 android:layout_height="wrap_content"
26 android:layout_marginEnd="24dp" 26 android:layout_marginEnd="24dp"
27 android:gravity="center_vertical" 27 android:layout_gravity="center_vertical"
28 android:orientation="vertical" 28 android:orientation="vertical"
29 android:layout_weight="1"> 29 android:layout_weight="1">
30 30
diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml
index e3915ef4f..c882a8e62 100644
--- a/src/android/app/src/main/res/values/arrays.xml
+++ b/src/android/app/src/main/res/values/arrays.xml
@@ -267,4 +267,21 @@
267 <item>3</item> 267 <item>3</item>
268 </integer-array> 268 </integer-array>
269 269
270 <string-array name="anisoEntries">
271 <item>@string/auto</item>
272 <item>@string/slider_default</item>
273 <item>@string/multiplier_two</item>
274 <item>@string/multiplier_four</item>
275 <item>@string/multiplier_eight</item>
276 <item>@string/multiplier_sixteen</item>
277 </string-array>
278 <integer-array name="anisoValues">
279 <item>0</item>
280 <item>1</item>
281 <item>2</item>
282 <item>3</item>
283 <item>4</item>
284 <item>5</item>
285 </integer-array>
286
270</resources> 287</resources>
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index 0b80b04a4..4d5c268fe 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -225,6 +225,8 @@
225 <string name="renderer_reactive_flushing_description">Improves rendering accuracy in some games at the cost of performance.</string> 225 <string name="renderer_reactive_flushing_description">Improves rendering accuracy in some games at the cost of performance.</string>
226 <string name="use_disk_shader_cache">Disk shader cache</string> 226 <string name="use_disk_shader_cache">Disk shader cache</string>
227 <string name="use_disk_shader_cache_description">Reduces stuttering by locally storing and loading generated shaders.</string> 227 <string name="use_disk_shader_cache_description">Reduces stuttering by locally storing and loading generated shaders.</string>
228 <string name="anisotropic_filtering">Anisotropic filtering</string>
229 <string name="anisotropic_filtering_description">Improves the quality of textures when viewed at oblique angles</string>
228 230
229 <!-- Debug settings strings --> 231 <!-- Debug settings strings -->
230 <string name="cpu">CPU</string> 232 <string name="cpu">CPU</string>
@@ -506,6 +508,12 @@
506 <string name="oboe">oboe</string> 508 <string name="oboe">oboe</string>
507 <string name="cubeb">cubeb</string> 509 <string name="cubeb">cubeb</string>
508 510
511 <!-- Anisotropic filtering options -->
512 <string name="multiplier_two">2x</string>
513 <string name="multiplier_four">4x</string>
514 <string name="multiplier_eight">8x</string>
515 <string name="multiplier_sixteen">16x</string>
516
509 <!-- Black backgrounds theme --> 517 <!-- Black backgrounds theme -->
510 <string name="use_black_backgrounds">Black backgrounds</string> 518 <string name="use_black_backgrounds">Black backgrounds</string>
511 <string name="use_black_backgrounds_description">When using the dark theme, apply black backgrounds.</string> 519 <string name="use_black_backgrounds_description">When using the dark theme, apply black backgrounds.</string>
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
index ed023fcfe..89ebab08e 100644
--- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
+++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
@@ -96,9 +96,9 @@ Id ImageType(EmitContext& ctx, const ImageDescriptor& desc, Id sampled_type) {
96} 96}
97 97
98Id DefineVariable(EmitContext& ctx, Id type, std::optional<spv::BuiltIn> builtin, 98Id DefineVariable(EmitContext& ctx, Id type, std::optional<spv::BuiltIn> builtin,
99 spv::StorageClass storage_class) { 99 spv::StorageClass storage_class, std::optional<Id> initializer = std::nullopt) {
100 const Id pointer_type{ctx.TypePointer(storage_class, type)}; 100 const Id pointer_type{ctx.TypePointer(storage_class, type)};
101 const Id id{ctx.AddGlobalVariable(pointer_type, storage_class)}; 101 const Id id{ctx.AddGlobalVariable(pointer_type, storage_class, initializer)};
102 if (builtin) { 102 if (builtin) {
103 ctx.Decorate(id, spv::Decoration::BuiltIn, *builtin); 103 ctx.Decorate(id, spv::Decoration::BuiltIn, *builtin);
104 } 104 }
@@ -144,11 +144,12 @@ Id DefineInput(EmitContext& ctx, Id type, bool per_invocation,
144} 144}
145 145
146Id DefineOutput(EmitContext& ctx, Id type, std::optional<u32> invocations, 146Id DefineOutput(EmitContext& ctx, Id type, std::optional<u32> invocations,
147 std::optional<spv::BuiltIn> builtin = std::nullopt) { 147 std::optional<spv::BuiltIn> builtin = std::nullopt,
148 std::optional<Id> initializer = std::nullopt) {
148 if (invocations && ctx.stage == Stage::TessellationControl) { 149 if (invocations && ctx.stage == Stage::TessellationControl) {
149 type = ctx.TypeArray(type, ctx.Const(*invocations)); 150 type = ctx.TypeArray(type, ctx.Const(*invocations));
150 } 151 }
151 return DefineVariable(ctx, type, builtin, spv::StorageClass::Output); 152 return DefineVariable(ctx, type, builtin, spv::StorageClass::Output, initializer);
152} 153}
153 154
154void DefineGenericOutput(EmitContext& ctx, size_t index, std::optional<u32> invocations) { 155void DefineGenericOutput(EmitContext& ctx, size_t index, std::optional<u32> invocations) {
@@ -811,10 +812,14 @@ void EmitContext::DefineAttributeMemAccess(const Info& info) {
811 labels.push_back(OpLabel()); 812 labels.push_back(OpLabel());
812 } 813 }
813 if (info.stores.ClipDistances()) { 814 if (info.stores.ClipDistances()) {
814 literals.push_back(static_cast<u32>(IR::Attribute::ClipDistance0) >> 2); 815 if (profile.max_user_clip_distances >= 4) {
815 labels.push_back(OpLabel()); 816 literals.push_back(static_cast<u32>(IR::Attribute::ClipDistance0) >> 2);
816 literals.push_back(static_cast<u32>(IR::Attribute::ClipDistance4) >> 2); 817 labels.push_back(OpLabel());
817 labels.push_back(OpLabel()); 818 }
819 if (profile.max_user_clip_distances >= 8) {
820 literals.push_back(static_cast<u32>(IR::Attribute::ClipDistance4) >> 2);
821 labels.push_back(OpLabel());
822 }
818 } 823 }
819 OpSelectionMerge(end_block, spv::SelectionControlMask::MaskNone); 824 OpSelectionMerge(end_block, spv::SelectionControlMask::MaskNone);
820 OpSwitch(compare_index, default_label, literals, labels); 825 OpSwitch(compare_index, default_label, literals, labels);
@@ -843,17 +848,21 @@ void EmitContext::DefineAttributeMemAccess(const Info& info) {
843 ++label_index; 848 ++label_index;
844 } 849 }
845 if (info.stores.ClipDistances()) { 850 if (info.stores.ClipDistances()) {
846 AddLabel(labels[label_index]); 851 if (profile.max_user_clip_distances >= 4) {
847 const Id pointer{OpAccessChain(output_f32, clip_distances, masked_index)}; 852 AddLabel(labels[label_index]);
848 OpStore(pointer, store_value); 853 const Id pointer{OpAccessChain(output_f32, clip_distances, masked_index)};
849 OpReturn(); 854 OpStore(pointer, store_value);
850 ++label_index; 855 OpReturn();
851 AddLabel(labels[label_index]); 856 ++label_index;
852 const Id fixed_index{OpIAdd(U32[1], masked_index, Const(4U))}; 857 }
853 const Id pointer2{OpAccessChain(output_f32, clip_distances, fixed_index)}; 858 if (profile.max_user_clip_distances >= 8) {
854 OpStore(pointer2, store_value); 859 AddLabel(labels[label_index]);
855 OpReturn(); 860 const Id fixed_index{OpIAdd(U32[1], masked_index, Const(4U))};
856 ++label_index; 861 const Id pointer{OpAccessChain(output_f32, clip_distances, fixed_index)};
862 OpStore(pointer, store_value);
863 OpReturn();
864 ++label_index;
865 }
857 } 866 }
858 AddLabel(end_block); 867 AddLabel(end_block);
859 OpUnreachable(); 868 OpUnreachable();
@@ -1532,9 +1541,16 @@ void EmitContext::DefineOutputs(const IR::Program& program) {
1532 if (stage == Stage::Fragment) { 1541 if (stage == Stage::Fragment) {
1533 throw NotImplementedException("Storing ClipDistance in fragment stage"); 1542 throw NotImplementedException("Storing ClipDistance in fragment stage");
1534 } 1543 }
1535 const Id type{TypeArray( 1544 if (profile.max_user_clip_distances > 0) {
1536 F32[1], Const(std::min(info.used_clip_distances, profile.max_user_clip_distances)))}; 1545 const u32 used{std::min(profile.max_user_clip_distances, 8u)};
1537 clip_distances = DefineOutput(*this, type, invocations, spv::BuiltIn::ClipDistance); 1546 const std::array<Id, 8> zero{f32_zero_value, f32_zero_value, f32_zero_value,
1547 f32_zero_value, f32_zero_value, f32_zero_value,
1548 f32_zero_value, f32_zero_value};
1549 const Id type{TypeArray(F32[1], Const(used))};
1550 const Id initializer{ConstantComposite(type, std::span(zero).subspan(0, used))};
1551 clip_distances =
1552 DefineOutput(*this, type, invocations, spv::BuiltIn::ClipDistance, initializer);
1553 }
1538 } 1554 }
1539 if (info.stores[IR::Attribute::Layer] && 1555 if (info.stores[IR::Attribute::Layer] &&
1540 (profile.support_viewport_index_layer_non_geometry || stage == Stage::Geometry)) { 1556 (profile.support_viewport_index_layer_non_geometry || stage == Stage::Geometry)) {
diff --git a/src/video_core/texture_cache/decode_bc.cpp b/src/video_core/texture_cache/decode_bc.cpp
index 3e26474a3..a018c6df4 100644
--- a/src/video_core/texture_cache/decode_bc.cpp
+++ b/src/video_core/texture_cache/decode_bc.cpp
@@ -60,66 +60,72 @@ u32 ConvertedBytesPerBlock(VideoCore::Surface::PixelFormat pixel_format) {
60} 60}
61 61
62template <auto decompress, PixelFormat pixel_format> 62template <auto decompress, PixelFormat pixel_format>
63void DecompressBlocks(std::span<const u8> input, std::span<u8> output, Extent3D extent, 63void DecompressBlocks(std::span<const u8> input, std::span<u8> output, BufferImageCopy& copy,
64 bool is_signed = false) { 64 bool is_signed = false) {
65 const u32 out_bpp = ConvertedBytesPerBlock(pixel_format); 65 const u32 out_bpp = ConvertedBytesPerBlock(pixel_format);
66 const u32 block_width = std::min(extent.width, BLOCK_SIZE); 66 const u32 block_size = BlockSize(pixel_format);
67 const u32 block_height = std::min(extent.height, BLOCK_SIZE); 67 const u32 width = copy.image_extent.width;
68 const u32 pitch = extent.width * out_bpp; 68 const u32 height = copy.image_extent.height * copy.image_subresource.num_layers;
69 const u32 depth = copy.image_extent.depth;
70 const u32 block_width = std::min(width, BLOCK_SIZE);
71 const u32 block_height = std::min(height, BLOCK_SIZE);
72 const u32 pitch = width * out_bpp;
69 size_t input_offset = 0; 73 size_t input_offset = 0;
70 size_t output_offset = 0; 74 size_t output_offset = 0;
71 for (u32 slice = 0; slice < extent.depth; ++slice) { 75 for (u32 slice = 0; slice < depth; ++slice) {
72 for (u32 y = 0; y < extent.height; y += block_height) { 76 for (u32 y = 0; y < height; y += block_height) {
73 size_t row_offset = 0; 77 size_t src_offset = input_offset;
74 for (u32 x = 0; x < extent.width; 78 size_t dst_offset = output_offset;
75 x += block_width, row_offset += block_width * out_bpp) { 79 for (u32 x = 0; x < width; x += block_width) {
76 const u8* src = input.data() + input_offset; 80 const u8* src = input.data() + src_offset;
77 u8* const dst = output.data() + output_offset + row_offset; 81 u8* const dst = output.data() + dst_offset;
78 if constexpr (IsSigned(pixel_format)) { 82 if constexpr (IsSigned(pixel_format)) {
79 decompress(src, dst, x, y, extent.width, extent.height, is_signed); 83 decompress(src, dst, x, y, width, height, is_signed);
80 } else { 84 } else {
81 decompress(src, dst, x, y, extent.width, extent.height); 85 decompress(src, dst, x, y, width, height);
82 } 86 }
83 input_offset += BlockSize(pixel_format); 87 src_offset += block_size;
88 dst_offset += block_width * out_bpp;
84 } 89 }
90 input_offset += copy.buffer_row_length * block_size / block_width;
85 output_offset += block_height * pitch; 91 output_offset += block_height * pitch;
86 } 92 }
87 } 93 }
88} 94}
89 95
90void DecompressBCn(std::span<const u8> input, std::span<u8> output, Extent3D extent, 96void DecompressBCn(std::span<const u8> input, std::span<u8> output, BufferImageCopy& copy,
91 VideoCore::Surface::PixelFormat pixel_format) { 97 VideoCore::Surface::PixelFormat pixel_format) {
92 switch (pixel_format) { 98 switch (pixel_format) {
93 case PixelFormat::BC1_RGBA_UNORM: 99 case PixelFormat::BC1_RGBA_UNORM:
94 case PixelFormat::BC1_RGBA_SRGB: 100 case PixelFormat::BC1_RGBA_SRGB:
95 DecompressBlocks<bcn::DecodeBc1, PixelFormat::BC1_RGBA_UNORM>(input, output, extent); 101 DecompressBlocks<bcn::DecodeBc1, PixelFormat::BC1_RGBA_UNORM>(input, output, copy);
96 break; 102 break;
97 case PixelFormat::BC2_UNORM: 103 case PixelFormat::BC2_UNORM:
98 case PixelFormat::BC2_SRGB: 104 case PixelFormat::BC2_SRGB:
99 DecompressBlocks<bcn::DecodeBc2, PixelFormat::BC2_UNORM>(input, output, extent); 105 DecompressBlocks<bcn::DecodeBc2, PixelFormat::BC2_UNORM>(input, output, copy);
100 break; 106 break;
101 case PixelFormat::BC3_UNORM: 107 case PixelFormat::BC3_UNORM:
102 case PixelFormat::BC3_SRGB: 108 case PixelFormat::BC3_SRGB:
103 DecompressBlocks<bcn::DecodeBc3, PixelFormat::BC3_UNORM>(input, output, extent); 109 DecompressBlocks<bcn::DecodeBc3, PixelFormat::BC3_UNORM>(input, output, copy);
104 break; 110 break;
105 case PixelFormat::BC4_SNORM: 111 case PixelFormat::BC4_SNORM:
106 case PixelFormat::BC4_UNORM: 112 case PixelFormat::BC4_UNORM:
107 DecompressBlocks<bcn::DecodeBc4, PixelFormat::BC4_UNORM>( 113 DecompressBlocks<bcn::DecodeBc4, PixelFormat::BC4_UNORM>(
108 input, output, extent, pixel_format == PixelFormat::BC4_SNORM); 114 input, output, copy, pixel_format == PixelFormat::BC4_SNORM);
109 break; 115 break;
110 case PixelFormat::BC5_SNORM: 116 case PixelFormat::BC5_SNORM:
111 case PixelFormat::BC5_UNORM: 117 case PixelFormat::BC5_UNORM:
112 DecompressBlocks<bcn::DecodeBc5, PixelFormat::BC5_UNORM>( 118 DecompressBlocks<bcn::DecodeBc5, PixelFormat::BC5_UNORM>(
113 input, output, extent, pixel_format == PixelFormat::BC5_SNORM); 119 input, output, copy, pixel_format == PixelFormat::BC5_SNORM);
114 break; 120 break;
115 case PixelFormat::BC6H_SFLOAT: 121 case PixelFormat::BC6H_SFLOAT:
116 case PixelFormat::BC6H_UFLOAT: 122 case PixelFormat::BC6H_UFLOAT:
117 DecompressBlocks<bcn::DecodeBc6, PixelFormat::BC6H_UFLOAT>( 123 DecompressBlocks<bcn::DecodeBc6, PixelFormat::BC6H_UFLOAT>(
118 input, output, extent, pixel_format == PixelFormat::BC6H_SFLOAT); 124 input, output, copy, pixel_format == PixelFormat::BC6H_SFLOAT);
119 break; 125 break;
120 case PixelFormat::BC7_SRGB: 126 case PixelFormat::BC7_SRGB:
121 case PixelFormat::BC7_UNORM: 127 case PixelFormat::BC7_UNORM:
122 DecompressBlocks<bcn::DecodeBc7, PixelFormat::BC7_UNORM>(input, output, extent); 128 DecompressBlocks<bcn::DecodeBc7, PixelFormat::BC7_UNORM>(input, output, copy);
123 break; 129 break;
124 default: 130 default:
125 LOG_WARNING(HW_GPU, "Unimplemented BCn decompression {}", pixel_format); 131 LOG_WARNING(HW_GPU, "Unimplemented BCn decompression {}", pixel_format);
diff --git a/src/video_core/texture_cache/decode_bc.h b/src/video_core/texture_cache/decode_bc.h
index 41d1ec0a3..4e3b9b8ac 100644
--- a/src/video_core/texture_cache/decode_bc.h
+++ b/src/video_core/texture_cache/decode_bc.h
@@ -13,7 +13,7 @@ namespace VideoCommon {
13 13
14[[nodiscard]] u32 ConvertedBytesPerBlock(VideoCore::Surface::PixelFormat pixel_format); 14[[nodiscard]] u32 ConvertedBytesPerBlock(VideoCore::Surface::PixelFormat pixel_format);
15 15
16void DecompressBCn(std::span<const u8> input, std::span<u8> output, Extent3D extent, 16void DecompressBCn(std::span<const u8> input, std::span<u8> output, BufferImageCopy& copy,
17 VideoCore::Surface::PixelFormat pixel_format); 17 VideoCore::Surface::PixelFormat pixel_format);
18 18
19} // namespace VideoCommon 19} // namespace VideoCommon
diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp
index 15596c925..fcf70068e 100644
--- a/src/video_core/texture_cache/util.cpp
+++ b/src/video_core/texture_cache/util.cpp
@@ -837,6 +837,7 @@ boost::container::small_vector<BufferImageCopy, 16> UnswizzleImage(Tegra::Memory
837 std::span<u8> output) { 837 std::span<u8> output) {
838 const size_t guest_size_bytes = input.size_bytes(); 838 const size_t guest_size_bytes = input.size_bytes();
839 const u32 bpp_log2 = BytesPerBlockLog2(info.format); 839 const u32 bpp_log2 = BytesPerBlockLog2(info.format);
840 const Extent2D tile_size = DefaultBlockSize(info.format);
840 const Extent3D size = info.size; 841 const Extent3D size = info.size;
841 842
842 if (info.type == ImageType::Linear) { 843 if (info.type == ImageType::Linear) {
@@ -847,7 +848,7 @@ boost::container::small_vector<BufferImageCopy, 16> UnswizzleImage(Tegra::Memory
847 return {{ 848 return {{
848 .buffer_offset = 0, 849 .buffer_offset = 0,
849 .buffer_size = guest_size_bytes, 850 .buffer_size = guest_size_bytes,
850 .buffer_row_length = info.pitch >> bpp_log2, 851 .buffer_row_length = info.pitch * tile_size.width >> bpp_log2,
851 .buffer_image_height = size.height, 852 .buffer_image_height = size.height,
852 .image_subresource = 853 .image_subresource =
853 { 854 {
@@ -862,7 +863,6 @@ boost::container::small_vector<BufferImageCopy, 16> UnswizzleImage(Tegra::Memory
862 const LevelInfo level_info = MakeLevelInfo(info); 863 const LevelInfo level_info = MakeLevelInfo(info);
863 const s32 num_layers = info.resources.layers; 864 const s32 num_layers = info.resources.layers;
864 const s32 num_levels = info.resources.levels; 865 const s32 num_levels = info.resources.levels;
865 const Extent2D tile_size = DefaultBlockSize(info.format);
866 const std::array level_sizes = CalculateLevelSizes(level_info, num_levels); 866 const std::array level_sizes = CalculateLevelSizes(level_info, num_levels);
867 const Extent2D gob = GobSize(bpp_log2, info.block.height, info.tile_width_spacing); 867 const Extent2D gob = GobSize(bpp_log2, info.block.height, info.tile_width_spacing);
868 const u32 layer_size = CalculateLevelBytes(level_sizes, num_levels); 868 const u32 layer_size = CalculateLevelBytes(level_sizes, num_levels);
@@ -926,8 +926,6 @@ void ConvertImage(std::span<const u8> input, const ImageInfo& info, std::span<u8
926 926
927 const auto input_offset = input.subspan(copy.buffer_offset); 927 const auto input_offset = input.subspan(copy.buffer_offset);
928 copy.buffer_offset = output_offset; 928 copy.buffer_offset = output_offset;
929 copy.buffer_row_length = mip_size.width;
930 copy.buffer_image_height = mip_size.height;
931 929
932 const auto recompression_setting = Settings::values.astc_recompression.GetValue(); 930 const auto recompression_setting = Settings::values.astc_recompression.GetValue();
933 const bool astc = IsPixelFormatASTC(info.format); 931 const bool astc = IsPixelFormatASTC(info.format);
@@ -972,16 +970,14 @@ void ConvertImage(std::span<const u8> input, const ImageInfo& info, std::span<u8
972 bpp_div; 970 bpp_div;
973 output_offset += static_cast<u32>(copy.buffer_size); 971 output_offset += static_cast<u32>(copy.buffer_size);
974 } else { 972 } else {
975 const Extent3D image_extent{ 973 DecompressBCn(input_offset, output.subspan(output_offset), copy, info.format);
976 .width = copy.image_extent.width,
977 .height = copy.image_extent.height * copy.image_subresource.num_layers,
978 .depth = copy.image_extent.depth,
979 };
980 DecompressBCn(input_offset, output.subspan(output_offset), image_extent, info.format);
981 output_offset += copy.image_extent.width * copy.image_extent.height * 974 output_offset += copy.image_extent.width * copy.image_extent.height *
982 copy.image_subresource.num_layers * 975 copy.image_subresource.num_layers *
983 ConvertedBytesPerBlock(info.format); 976 ConvertedBytesPerBlock(info.format);
984 } 977 }
978
979 copy.buffer_row_length = mip_size.width;
980 copy.buffer_image_height = mip_size.height;
985 } 981 }
986} 982}
987 983
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 059fcf041..c789c1e59 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -5342,6 +5342,10 @@ int main(int argc, char* argv[]) {
5342 if (QString::fromLocal8Bit(qgetenv("DISPLAY")).isEmpty()) { 5342 if (QString::fromLocal8Bit(qgetenv("DISPLAY")).isEmpty()) {
5343 qputenv("DISPLAY", ":0"); 5343 qputenv("DISPLAY", ":0");
5344 } 5344 }
5345
5346 // Fix the Wayland appId. This needs to match the name of the .desktop file without the .desktop
5347 // suffix.
5348 QGuiApplication::setDesktopFileName(QStringLiteral("org.yuzu_emu.yuzu"));
5345#endif 5349#endif
5346 5350
5347 SetHighDPIAttributes(); 5351 SetHighDPIAttributes();