From 7a77957f8bdad7e8bef66ac7d9891db6cfd97665 Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Fri, 16 Feb 2024 03:52:15 +0100 Subject: [PATCH] early-access version 4142 --- README.md | 2 +- .../backend/spirv/emit_spirv_image.cpp | 47 +++++++++++++++++-- .../backend/spirv/emit_spirv_instructions.h | 4 +- src/video_core/buffer_cache/buffer_cache.h | 2 +- src/video_core/surface.cpp | 14 +++++- src/video_core/surface.h | 2 +- src/video_core/texture_cache/texture_cache.h | 6 +-- .../vulkan_common/vulkan_device.cpp | 5 ++ 8 files changed, 67 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 2cd872097..a895006e4 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 4141. +This is the source code for early-access 4142. ## Legal Notice diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index ad33210f2..b53e1f446 100755 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp @@ -60,11 +60,10 @@ public: Add(spv::ImageOperandsMask::ConstOffsets, offsets); } - explicit ImageOperands(EmitContext& ctx, const IR::Value& offset, Id lod, Id ms) { + explicit ImageOperands(Id lod, Id ms) { if (Sirit::ValidId(lod)) { Add(spv::ImageOperandsMask::Lod, lod); } - AddOffset(ctx, offset, ImageFetchOffsetAllowed); if (Sirit::ValidId(ms)) { Add(spv::ImageOperandsMask::Sample, ms); } @@ -312,6 +311,43 @@ Id ImageGatherSubpixelOffset(EmitContext& ctx, const IR::TextureInstInfo& info, return coords; } } + +void AddOffsetToCoordinates(EmitContext& ctx, const IR::TextureInstInfo& info, Id& coords, + Id offset) { + if (!Sirit::ValidId(offset)) { + return; + } + + Id result_type{}; + switch (info.type) { + case TextureType::Buffer: + case TextureType::Color1D: { + result_type = ctx.U32[1]; + break; + } + case TextureType::ColorArray1D: + offset = ctx.OpCompositeConstruct(ctx.U32[2], offset, ctx.u32_zero_value); + [[fallthrough]]; + case TextureType::Color2D: + case TextureType::Color2DRect: { + result_type = ctx.U32[2]; + break; + } + case TextureType::ColorArray2D: + offset = ctx.OpCompositeConstruct(ctx.U32[3], ctx.OpCompositeExtract(ctx.U32[1], coords, 0), + ctx.OpCompositeExtract(ctx.U32[1], coords, 1), + ctx.u32_zero_value); + [[fallthrough]]; + case TextureType::Color3D: { + result_type = ctx.U32[3]; + break; + } + case TextureType::ColorCube: + case TextureType::ColorArrayCube: + return; + } + coords = ctx.OpIAdd(result_type, coords, offset); +} } // Anonymous namespace Id EmitBindlessImageSampleImplicitLod(EmitContext&) { @@ -494,9 +530,10 @@ Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, operands.Span()); } -Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, - const IR::Value& offset, Id lod, Id ms) { +Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, + Id lod, Id ms) { const auto info{inst->Flags()}; + AddOffsetToCoordinates(ctx, info, coords, offset); if (info.type == TextureType::Buffer) { lod = Id{}; } @@ -504,7 +541,7 @@ Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id c // This image is multisampled, lod must be implicit lod = Id{}; } - const ImageOperands operands(ctx, offset, lod, ms); + const ImageOperands operands(lod, ms); return Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst, ctx.F32[4], TextureImage(ctx, info, index), coords, operands.MaskOptional(), operands.Span()); } diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h index 9465b0f32..7a3300b33 100755 --- a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h @@ -537,8 +537,8 @@ Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id const IR::Value& offset, const IR::Value& offset2); Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, const IR::Value& offset, const IR::Value& offset2, Id dref); -Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, - const IR::Value& offset, Id lod, Id ms); +Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, + Id lod, Id ms); Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod, const IR::Value& skip_mips); Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords); diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 1f33301b7..1d6c117b1 100755 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -35,7 +35,7 @@ BufferCache

::BufferCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, R const s64 min_spacing_critical = device_local_memory - 512_MiB; const s64 mem_threshold = std::min(device_local_memory, TARGET_THRESHOLD); const s64 min_vacancy_expected = (6 * mem_threshold) / 10; - const s64 min_vacancy_critical = (3 * mem_threshold) / 10; + const s64 min_vacancy_critical = (2 * mem_threshold) / 10; minimum_memory = static_cast( std::max(std::min(device_local_memory - min_vacancy_expected, min_spacing_expected), DEFAULT_EXPECTED_MEMORY)); diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index c48e19ffa..a94d2371a 100755 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp @@ -3,6 +3,7 @@ #include "common/common_types.h" #include "common/math_util.h" +#include "common/settings.h" #include "video_core/surface.h" namespace VideoCore::Surface { @@ -400,11 +401,20 @@ std::pair GetASTCBlockSize(PixelFormat format) { return {DefaultBlockWidth(format), DefaultBlockHeight(format)}; } -u64 EstimatedDecompressedSize(u64 base_size, PixelFormat format) { +u64 TranscodedAstcSize(u64 base_size, PixelFormat format) { constexpr u64 RGBA8_PIXEL_SIZE = 4; const u64 base_block_size = static_cast(DefaultBlockWidth(format)) * static_cast(DefaultBlockHeight(format)) * RGBA8_PIXEL_SIZE; - return (base_size * base_block_size) / BytesPerBlock(format); + const u64 uncompressed_size = (base_size * base_block_size) / BytesPerBlock(format); + + switch (Settings::values.astc_recompression.GetValue()) { + case Settings::AstcRecompression::Bc1: + return uncompressed_size / 8; + case Settings::AstcRecompression::Bc3: + return uncompressed_size / 4; + default: + return uncompressed_size; + } } } // namespace VideoCore::Surface diff --git a/src/video_core/surface.h b/src/video_core/surface.h index 9ac9b6343..2c212a6b1 100755 --- a/src/video_core/surface.h +++ b/src/video_core/surface.h @@ -517,6 +517,6 @@ size_t PixelComponentSizeBitsInteger(PixelFormat format); std::pair GetASTCBlockSize(PixelFormat format); -u64 EstimatedDecompressedSize(u64 base_size, PixelFormat format); +u64 TranscodedAstcSize(u64 base_size, PixelFormat format); } // namespace VideoCore::Surface diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 47ea0bd96..f790897ef 100755 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -55,7 +55,7 @@ TextureCache

::TextureCache(Runtime& runtime_, Tegra::MaxwellDeviceMemoryManag const s64 min_spacing_critical = device_local_memory - 512_MiB; const s64 mem_threshold = std::min(device_local_memory, TARGET_THRESHOLD); const s64 min_vacancy_expected = (6 * mem_threshold) / 10; - const s64 min_vacancy_critical = (3 * mem_threshold) / 10; + const s64 min_vacancy_critical = (2 * mem_threshold) / 10; expected_memory = static_cast( std::max(std::min(device_local_memory - min_vacancy_expected, min_spacing_expected), DEFAULT_EXPECTED_MEMORY)); @@ -1979,7 +1979,7 @@ void TextureCache

::RegisterImage(ImageId image_id) { if ((IsPixelFormatASTC(image.info.format) && True(image.flags & ImageFlagBits::AcceleratedUpload)) || True(image.flags & ImageFlagBits::Converted)) { - tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format); + tentative_size = TranscodedAstcSize(tentative_size, image.info.format); } total_used_memory += Common::AlignUp(tentative_size, 1024); image.lru_index = lru_cache.Insert(image_id, frame_tick); @@ -2149,7 +2149,7 @@ void TextureCache

::DeleteImage(ImageId image_id, bool immediate_delete) { if ((IsPixelFormatASTC(image.info.format) && True(image.flags & ImageFlagBits::AcceleratedUpload)) || True(image.flags & ImageFlagBits::Converted)) { - tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format); + tentative_size = TranscodedAstcSize(tentative_size, image.info.format); } total_used_memory -= Common::AlignUp(tentative_size, 1024); const GPUVAddr gpu_addr = image.gpu_addr; diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 940cc0a54..bd77057b0 100755 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -1290,6 +1290,10 @@ u64 Device::GetDeviceMemoryUsage() const { } void Device::CollectPhysicalMemoryInfo() { + // Account for resolution scaling in memory limits + const size_t normal_memory = 6_GiB; + const size_t scaler_memory = 1_GiB * Settings::values.resolution_info.ScaleUp(1); + // Calculate limits using memory budget VkPhysicalDeviceMemoryBudgetPropertiesEXT budget{}; budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; @@ -1320,6 +1324,7 @@ void Device::CollectPhysicalMemoryInfo() { if (!is_integrated) { const u64 reserve_memory = std::min(device_access_memory / 8, 1_GiB); device_access_memory -= reserve_memory; + device_access_memory = std::min(device_access_memory, normal_memory + scaler_memory); return; } const s64 available_memory = static_cast(device_access_memory - device_initial_usage);