Browse Source

Added setting to change size of texture GPU swizzle runs for

pull/3246/head
Forrest Keller 4 weeks ago
committed by crueter
parent
commit
252fc2f1bc
  1. 1
      src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt
  2. 9
      src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
  3. 1
      src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
  4. 18
      src/android/app/src/main/res/values/arrays.xml
  5. 19
      src/android/app/src/main/res/values/strings.xml
  6. 6
      src/common/settings.h
  7. 1
      src/common/settings_enums.h
  8. 24
      src/qt_common/config/shared_translation.cpp
  9. 57
      src/video_core/texture_cache/texture_cache.h
  10. 3
      src/video_core/texture_cache/texture_cache_base.h

1
src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt

@ -47,6 +47,7 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
FAST_CPU_TIME("fast_cpu_time"), FAST_CPU_TIME("fast_cpu_time"),
CPU_TICKS("cpu_ticks"), CPU_TICKS("cpu_ticks"),
FAST_GPU_TIME("fast_gpu_time"), FAST_GPU_TIME("fast_gpu_time"),
GPU_UNZWIZZLE_MAXTEXTURE_SIZE("gpu_unzwizzle_maxtexture_size"),
GPU_UNZWIZZLE_STREAM_SIZE("gpu_unzwizzle_stream_size"), GPU_UNZWIZZLE_STREAM_SIZE("gpu_unzwizzle_stream_size"),
GPU_UNZWIZZLE_CHUNK_SIZE("gpu_unzwizzle_chunk_size"), GPU_UNZWIZZLE_CHUNK_SIZE("gpu_unzwizzle_chunk_size"),
BAT_TEMPERATURE_UNIT("bat_temperature_unit"), BAT_TEMPERATURE_UNIT("bat_temperature_unit"),

9
src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt

@ -655,6 +655,15 @@ abstract class SettingsItem(
valuesId = R.array.gpuValues valuesId = R.array.gpuValues
) )
) )
put(
SingleChoiceSetting(
IntSetting.GPU_UNZWIZZLE_MAXTEXTURE_SIZE,
titleId = R.string.gpu_unzwizzle_maxtexture_size,
descriptionId = R.string.gpu_unzwizzle_maxtexture_size_description,
choicesId = R.array.gpuTextureSizeSwizzleEntries,
valuesId = R.array.gpuTextureSizeSwizzleValues
)
)
put( put(
SingleChoiceSetting( SingleChoiceSetting(
IntSetting.GPU_UNZWIZZLE_STREAM_SIZE, IntSetting.GPU_UNZWIZZLE_STREAM_SIZE,

1
src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt

@ -280,6 +280,7 @@ class SettingsFragmentPresenter(
add(IntSetting.FAST_GPU_TIME.key) add(IntSetting.FAST_GPU_TIME.key)
add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key) add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key)
add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key) add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key)
add(IntSetting.GPU_UNZWIZZLE_MAXTEXTURE_SIZE.key)
add(IntSetting.GPU_UNZWIZZLE_STREAM_SIZE.key) add(IntSetting.GPU_UNZWIZZLE_STREAM_SIZE.key)
add(IntSetting.GPU_UNZWIZZLE_CHUNK_SIZE.key) add(IntSetting.GPU_UNZWIZZLE_CHUNK_SIZE.key)

18
src/android/app/src/main/res/values/arrays.xml

@ -563,7 +563,23 @@
<item>1</item> <item>1</item>
<item>2</item> <item>2</item>
</integer-array> </integer-array>
<string-array name="gpuTextureSizeSwizzleEntries">
<item>@string/gpu_texturesizeswizzle_verysmall</item>
<item>@string/gpu_texturesizeswizzle_small</item>
<item>@string/gpu_texturesizeswizzle_normal</item>
<item>@string/gpu_texturesizeswizzle_large</item>
<item>@string/gpu_texturesizeswizzle_verylarge</item>
</string-array>
<integer-array name="gpuTextureSizeSwizzleValues">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
</integer-array>
<string-array name="gpuSwizzleEntries"> <string-array name="gpuSwizzleEntries">
<item>@string/gpu_swizzle_verylow</item> <item>@string/gpu_swizzle_verylow</item>
<item>@string/gpu_swizzle_low</item> <item>@string/gpu_swizzle_low</item>

19
src/android/app/src/main/res/values/strings.xml

@ -504,6 +504,8 @@
<string name="skip_cpu_inner_invalidation_description">Skips certain CPU-side cache invalidations during memory updates, reducing CPU usage and improving it\'s performance. This may cause glitches or crashes on some games.</string> <string name="skip_cpu_inner_invalidation_description">Skips certain CPU-side cache invalidations during memory updates, reducing CPU usage and improving it\'s performance. This may cause glitches or crashes on some games.</string>
<string name="renderer_asynchronous_shaders">Use asynchronous shaders</string> <string name="renderer_asynchronous_shaders">Use asynchronous shaders</string>
<string name="renderer_asynchronous_shaders_description">Compiles shaders asynchronously. This may reduce stutters but may also introduce glitches.</string> <string name="renderer_asynchronous_shaders_description">Compiles shaders asynchronously. This may reduce stutters but may also introduce glitches.</string>
<string name="gpu_unzwizzle_maxtexture_size">GPU Unswizzle Max Texture Size</string>
<string name="gpu_unzwizzle_maxtexture_size_description">Sets the maximum size (MB) for GPU-based texture unswizzling. While the GPU is faster for medium and large textures, the CPU may be more efficient for very small ones. Adjust this to find the balance between GPU acceleration and CPU overhead.</string>
<string name="gpu_unzwizzle_stream_size">GPU Unswizzle Stream Size</string> <string name="gpu_unzwizzle_stream_size">GPU Unswizzle Stream Size</string>
<string name="gpu_unzwizzle_stream_size_description">Sets the data limit per frame for unswizzling large textures. Higher values speed up texture loading at the cost of higher frame latency; lower values reduce GPU overhead but may cause visible texture pop-in.</string> <string name="gpu_unzwizzle_stream_size_description">Sets the data limit per frame for unswizzling large textures. Higher values speed up texture loading at the cost of higher frame latency; lower values reduce GPU overhead but may cause visible texture pop-in.</string>
<string name="gpu_unzwizzle_chunk_size">GPU Unswizzle Chunk Size</string> <string name="gpu_unzwizzle_chunk_size">GPU Unswizzle Chunk Size</string>
@ -929,12 +931,19 @@
<string name="fast_gpu_medium">Medium (256)</string> <string name="fast_gpu_medium">Medium (256)</string>
<string name="fast_gpu_high">High (512)</string> <string name="fast_gpu_high">High (512)</string>
<!-- GPU swizzle texture size -->
<string name="gpu_texturesizeswizzle_verysmall">Very Small (16 MB)</string>
<string name="gpu_texturesizeswizzle_small">Small (32 MB)</string>
<string name="gpu_texturesizeswizzle_normal">Normal (128 MB)</string>
<string name="gpu_texturesizeswizzle_large">Large (256 MB)</string>
<string name="gpu_texturesizeswizzle_verylarge">Very Large (512 MB)</string>
<!-- GPU swizzle streams --> <!-- GPU swizzle streams -->
<string name="gpu_swizzle_verylow">Very Low (4)</string>
<string name="gpu_swizzle_low">Low (8)</string>
<string name="gpu_swizzle_normal">Normal (16)</string>
<string name="gpu_swizzle_medium">Medium (32)</string>
<string name="gpu_swizzle_high">High (64)</string>
<string name="gpu_swizzle_verylow">Very Low (4 MB)</string>
<string name="gpu_swizzle_low">Low (8 MB)</string>
<string name="gpu_swizzle_normal">Normal (16 MB)</string>
<string name="gpu_swizzle_medium">Medium (32 MB)</string>
<string name="gpu_swizzle_high">High (64 MB)</string>
<!-- GPU swizzle chunks --> <!-- GPU swizzle chunks -->
<string name="gpu_swizzlechunk_verylow">Very Low (32)</string> <string name="gpu_swizzlechunk_verylow">Very Low (32)</string>

6
src/common/settings.h

@ -513,6 +513,12 @@ struct Values {
SwitchableSetting<bool> use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders", SwitchableSetting<bool> use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders",
Category::RendererHacks}; Category::RendererHacks};
SwitchableSetting<GpuUnswizzleSize> gpu_unzwizzle_texture_size{linkage,
GpuUnswizzleSize::Large,
"gpu_unzwizzle_texture_size",
Category::RendererHacks,
Specialization::Default};
SwitchableSetting<GpuUnswizzle> gpu_unzwizzle_stream_size{linkage, SwitchableSetting<GpuUnswizzle> gpu_unzwizzle_stream_size{linkage,
GpuUnswizzle::Medium, GpuUnswizzle::Medium,
"gpu_unzwizzle_stream_size", "gpu_unzwizzle_stream_size",

1
src/common/settings_enums.h

@ -150,6 +150,7 @@ ENUM(ConsoleMode, Handheld, Docked);
ENUM(AppletMode, HLE, LLE); ENUM(AppletMode, HLE, LLE);
ENUM(SpirvOptimizeMode, Never, OnLoad, Always); ENUM(SpirvOptimizeMode, Never, OnLoad, Always);
ENUM(GpuOverclock, Normal, Medium, High) ENUM(GpuOverclock, Normal, Medium, High)
ENUM(GpuUnswizzleSize, VerySmall, Small, Normal, Large, VeryLarge)
ENUM(GpuUnswizzle, VeryLow, Low, Normal, Medium, High) ENUM(GpuUnswizzle, VeryLow, Low, Normal, Medium, High)
ENUM(GpuUnswizzleChunk, VeryLow, Low, Normal, Medium, High) ENUM(GpuUnswizzleChunk, VeryLow, Low, Normal, Medium, High)
ENUM(TemperatureUnits, Celsius, Fahrenheit) ENUM(TemperatureUnits, Celsius, Fahrenheit)

24
src/qt_common/config/shared_translation.cpp

@ -288,6 +288,12 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent)
tr("Fast GPU Time"), tr("Fast GPU Time"),
tr("Overclocks the emulated GPU to increase dynamic resolution and render " tr("Overclocks the emulated GPU to increase dynamic resolution and render "
"distance.\nUse 256 for maximal performance and 512 for maximal graphics fidelity.")); "distance.\nUse 256 for maximal performance and 512 for maximal graphics fidelity."));
INSERT(Settings,
gpu_unzwizzle_texture_size,
tr("GPU Unswizzle Max Texture Size"),
tr("Sets the maximum size (MiB) for GPU-based texture unswizzling.\n"
"While the GPU is faster for medium and large textures, the CPU may be more efficient for very small ones.\n"
"Adjust this to find the balance between GPU acceleration and CPU overhead."));
INSERT(Settings, INSERT(Settings,
gpu_unzwizzle_stream_size, gpu_unzwizzle_stream_size,
tr("GPU Unswizzle Stream Size"), tr("GPU Unswizzle Stream Size"),
@ -729,13 +735,21 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent)
PAIR(GpuOverclock, Medium, tr("Medium (256)")), PAIR(GpuOverclock, Medium, tr("Medium (256)")),
PAIR(GpuOverclock, High, tr("High (512)")), PAIR(GpuOverclock, High, tr("High (512)")),
}}); }});
translations->insert({Settings::EnumMetadata<Settings::GpuUnswizzleSize>::Index(),
{
PAIR(GpuUnswizzleSize, VerySmall, tr("Very Small (16 MB)")),
PAIR(GpuUnswizzleSize, Small, tr("Small (32 MB)")),
PAIR(GpuUnswizzleSize, Normal, tr("Normal (128 MB)")),
PAIR(GpuUnswizzleSize, Large, tr("Large (256 MB)")),
PAIR(GpuUnswizzleSize, VeryLarge, tr("Very Large (512 MB)")),
}});
translations->insert({Settings::EnumMetadata<Settings::GpuUnswizzle>::Index(), translations->insert({Settings::EnumMetadata<Settings::GpuUnswizzle>::Index(),
{ {
PAIR(GpuUnswizzle, VeryLow, tr("Very Low (4)")),
PAIR(GpuUnswizzle, Low, tr("Low (8)")),
PAIR(GpuUnswizzle, Normal, tr("Normal (16)")),
PAIR(GpuUnswizzle, Medium, tr("Medium (32)")),
PAIR(GpuUnswizzle, High, tr("High (64)")),
PAIR(GpuUnswizzle, VeryLow, tr("Very Low (4 MB)")),
PAIR(GpuUnswizzle, Low, tr("Low (8 MB)")),
PAIR(GpuUnswizzle, Normal, tr("Normal (16 MB)")),
PAIR(GpuUnswizzle, Medium, tr("Medium (32 MB)")),
PAIR(GpuUnswizzle, High, tr("High (64 MB)")),
}}); }});
translations->insert({Settings::EnumMetadata<Settings::GpuUnswizzleChunk>::Index(), translations->insert({Settings::EnumMetadata<Settings::GpuUnswizzleChunk>::Index(),
{ {

57
src/video_core/texture_cache/texture_cache.h

@ -77,6 +77,33 @@ TextureCache<P>::TextureCache(Runtime& runtime_, Tegra::MaxwellDeviceMemoryManag
} }
lowmemorydevice = Settings::values.enable_low_memory.GetValue(); lowmemorydevice = Settings::values.enable_low_memory.GetValue();
switch (Settings::values.gpu_unzwizzle_texture_size.GetValue()) {
case Settings::GpuUnswizzleSize::VerySmall: gpu_unswizzle_maxsize = 16_MiB; break;
case Settings::GpuUnswizzleSize::Small: gpu_unswizzle_maxsize = 32_MiB; break;
case Settings::GpuUnswizzleSize::Normal: gpu_unswizzle_maxsize = 128_MiB; break;
case Settings::GpuUnswizzleSize::Large: gpu_unswizzle_maxsize = 256_MiB; break;
case Settings::GpuUnswizzleSize::VeryLarge: gpu_unswizzle_maxsize = 512_MiB; break;
default: gpu_unswizzle_maxsize = 128_MiB; break;
}
switch (Settings::values.gpu_unzwizzle_stream_size.GetValue()) {
case Settings::GpuUnswizzle::VeryLow: swizzle_chunk_size = 4_MiB; break;
case Settings::GpuUnswizzle::Low: swizzle_chunk_size = 8_MiB; break;
case Settings::GpuUnswizzle::Normal: swizzle_chunk_size = 16_MiB; break;
case Settings::GpuUnswizzle::Medium: swizzle_chunk_size = 32_MiB; break;
case Settings::GpuUnswizzle::High: swizzle_chunk_size = 64_MiB; break;
default: swizzle_chunk_size = 16_MiB;
}
switch (Settings::values.gpu_unzwizzle_chunk_size.GetValue()) {
case Settings::GpuUnswizzleChunk::VeryLow: swizzle_slices_per_batch = 32; break;
case Settings::GpuUnswizzleChunk::Low: swizzle_slices_per_batch = 64; break;
case Settings::GpuUnswizzleChunk::Normal: swizzle_slices_per_batch = 128; break;
case Settings::GpuUnswizzleChunk::Medium: swizzle_slices_per_batch = 256; break;
case Settings::GpuUnswizzleChunk::High: swizzle_slices_per_batch = 512; break;
default: swizzle_slices_per_batch = 128;
}
} }
template <class P> template <class P>
@ -1152,7 +1179,7 @@ void TextureCache<P>::RefreshContents(Image& image, ImageId image_id) {
image.info.type == ImageType::e3D && image.info.type == ImageType::e3D &&
image.info.resources.levels == 1 && image.info.resources.levels == 1 &&
image.info.resources.layers == 1 && image.info.resources.layers == 1 &&
MapSizeBytes(image) >= 128_MiB &&
MapSizeBytes(image) >= gpu_unswizzle_maxsize &&
False(image.flags & ImageFlagBits::GpuModified)) { False(image.flags & ImageFlagBits::GpuModified)) {
QueueAsyncUnswizzle(image, image_id); QueueAsyncUnswizzle(image, image_id);
@ -1471,33 +1498,13 @@ void TextureCache<P>::TickAsyncUnswizzle() {
task.initialized = true; task.initialized = true;
} }
size_t CHUNK_SIZE;
switch (Settings::values.gpu_unzwizzle_stream_size.GetValue()) {
case Settings::GpuUnswizzle::VeryLow: CHUNK_SIZE = 4_MiB; break;
case Settings::GpuUnswizzle::Low: CHUNK_SIZE = 8_MiB; break;
case Settings::GpuUnswizzle::Normal: CHUNK_SIZE = 16_MiB; break;
case Settings::GpuUnswizzle::Medium: CHUNK_SIZE = 32_MiB; break;
case Settings::GpuUnswizzle::High: CHUNK_SIZE = 64_MiB; break;
default: CHUNK_SIZE = 16_MiB;
}
u32 SLICES_PER_BATCH;
switch (Settings::values.gpu_unzwizzle_chunk_size.GetValue()) {
case Settings::GpuUnswizzleChunk::VeryLow: SLICES_PER_BATCH = 32; break;
case Settings::GpuUnswizzleChunk::Low: SLICES_PER_BATCH = 64; break;
case Settings::GpuUnswizzleChunk::Normal: SLICES_PER_BATCH = 128; break;
case Settings::GpuUnswizzleChunk::Medium: SLICES_PER_BATCH = 256; break;
case Settings::GpuUnswizzleChunk::High: SLICES_PER_BATCH = 512; break;
default: SLICES_PER_BATCH = 128;
}
// Read data // Read data
if (task.current_offset < task.total_size) { if (task.current_offset < task.total_size) {
const size_t remaining = task.total_size - task.current_offset; const size_t remaining = task.total_size - task.current_offset;
size_t copy_amount = std::min(CHUNK_SIZE, remaining);
size_t copy_amount = std::min(swizzle_chunk_size, remaining);
if (remaining > CHUNK_SIZE) {
if (remaining > swizzle_chunk_size) {
copy_amount = (copy_amount / task.bytes_per_slice) * task.bytes_per_slice; copy_amount = (copy_amount / task.bytes_per_slice) * task.bytes_per_slice;
if (copy_amount == 0) copy_amount = task.bytes_per_slice; if (copy_amount == 0) copy_amount = task.bytes_per_slice;
} }
@ -1512,9 +1519,9 @@ void TextureCache<P>::TickAsyncUnswizzle() {
const size_t bytes_ready = task.current_offset - task.last_submitted_offset; const size_t bytes_ready = task.current_offset - task.last_submitted_offset;
const u32 complete_slices = static_cast<u32>(bytes_ready / task.bytes_per_slice); const u32 complete_slices = static_cast<u32>(bytes_ready / task.bytes_per_slice);
if (complete_slices >= SLICES_PER_BATCH || (is_final_batch && complete_slices > 0)) {
if (complete_slices >= swizzle_slices_per_batch || (is_final_batch && complete_slices > 0)) {
const u32 z_start = static_cast<u32>(task.last_submitted_offset / task.bytes_per_slice); const u32 z_start = static_cast<u32>(task.last_submitted_offset / task.bytes_per_slice);
const u32 slices_to_process = std::min(complete_slices, SLICES_PER_BATCH);
const u32 slices_to_process = std::min(complete_slices, swizzle_slices_per_batch);
const u32 z_count = std::min(slices_to_process, image.info.size.depth - z_start); const u32 z_count = std::min(slices_to_process, image.info.size.depth - z_start);
if (z_count > 0) { if (z_count > 0) {

3
src/video_core/texture_cache/texture_cache_base.h

@ -472,6 +472,9 @@ private:
u64 expected_memory; u64 expected_memory;
u64 critical_memory; u64 critical_memory;
bool lowmemorydevice = false; bool lowmemorydevice = false;
size_t gpu_unswizzle_maxsize = 0;
size_t swizzle_chunk_size = 0;
u32 swizzle_slices_per_batch = 0;
struct BufferDownload { struct BufferDownload {
GPUVAddr address; GPUVAddr address;

Loading…
Cancel
Save