From 614f3e6a00aaa925049ed1d027ff0456b4cc6deb Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Wed, 6 Apr 2022 01:05:42 +0200 Subject: [PATCH] early-access version 2647 --- README.md | 2 +- src/CMakeLists.txt | 6 -- src/core/arm/dynarmic/arm_dynarmic_32.cpp | 2 + src/core/arm/dynarmic/arm_dynarmic_64.cpp | 2 + .../renderer_vulkan/vk_compute_pipeline.cpp | 2 +- .../renderer_vulkan/vk_graphics_pipeline.cpp | 14 ++-- .../renderer_vulkan/vk_graphics_pipeline.h | 1 - .../renderer_vulkan/vk_rasterizer.cpp | 18 ++++-- .../vk_staging_buffer_pool.cpp | 64 ++++++++----------- .../renderer_vulkan/vk_staging_buffer_pool.h | 10 +-- src/video_core/texture_cache/texture_cache.h | 11 ++-- 11 files changed, 61 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index 99077d540..5710a3a05 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 2645. +This is the source code for early-access 2647. ## Legal Notice diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1bdf70b76..3ad2c0950 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -103,12 +103,6 @@ else() -Wno-unused-parameter ) - # TODO: Remove when we update to a GCC compiler that enables this - # by default (i.e. GCC 10 or newer). - if (CMAKE_CXX_COMPILER_ID STREQUAL GNU) - add_compile_options(-fconcepts) - endif() - if (ARCHITECTURE_x86_64) add_compile_options("-mcx16") endif() diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 581536509..ab3210d84 100755 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -73,11 +73,13 @@ public: } void InterpreterFallback(u32 pc, std::size_t num_instructions) override { + parent.LogBacktrace(); UNIMPLEMENTED_MSG("This should never happen, pc = {:08X}, code = {:08X}", pc, MemoryReadCode(pc)); } void ExceptionRaised(u32 pc, Dynarmic::A32::Exception exception) override { + parent.LogBacktrace(); LOG_CRITICAL(Core_ARM, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X}, thumb = {})", exception, pc, MemoryReadCode(pc), parent.IsInThumbMode()); diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 9715de70e..68822a1fc 100755 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -84,6 +84,7 @@ public: } void InterpreterFallback(u64 pc, std::size_t num_instructions) override { + parent.LogBacktrace(); LOG_ERROR(Core_ARM, "Unimplemented instruction @ 0x{:X} for {} instructions (instr = {:08X})", pc, num_instructions, MemoryReadCode(pc)); @@ -121,6 +122,7 @@ public: return; case Dynarmic::A64::Exception::Breakpoint: default: + parent.LogBacktrace(); ASSERT_MSG(false, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})", static_cast(exception), pc, MemoryReadCode(pc)); } diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index 902a0319c..de36bcdb7 100755 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp @@ -200,7 +200,7 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, }); } const void* const descriptor_data{update_descriptor_queue.UpdateData()}; - const bool is_rescaling = info.uses_rescaling_uniform; + const bool is_rescaling = !info.texture_descriptors.empty() || !info.image_descriptors.empty(); scheduler.Record([this, descriptor_data, is_rescaling, rescaling_data = rescaling.Data()](vk::CommandBuffer cmdbuf) { cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline); diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 15d3ec480..d514b71d0 100755 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -238,7 +238,6 @@ GraphicsPipeline::GraphicsPipeline( enabled_uniform_buffer_masks[stage] = info->constant_buffer_mask; std::ranges::copy(info->constant_buffer_used_sizes, uniform_buffer_sizes[stage].begin()); num_textures += Shader::NumDescriptors(info->texture_descriptors); - uses_rescale_unfiorm |= info->uses_rescaling_uniform; } auto func{[this, shader_notify, &render_pass_cache, &descriptor_pool, pipeline_statistics] { DescriptorLayoutBuilder builder{MakeBuilder(device, stage_infos)}; @@ -472,8 +471,7 @@ void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling) { }); } const bool is_rescaling{texture_cache.IsRescaling()}; - const bool update_rescaling{uses_rescale_unfiorm ? scheduler.UpdateRescaling(is_rescaling) - : false}; + const bool update_rescaling{scheduler.UpdateRescaling(is_rescaling)}; const bool bind_pipeline{scheduler.UpdateGraphicsPipeline(this)}; const void* const descriptor_data{update_descriptor_queue.UpdateData()}; scheduler.Record([this, descriptor_data, bind_pipeline, rescaling_data = rescaling.Data(), @@ -481,12 +479,10 @@ void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling) { if (bind_pipeline) { cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); } - if (uses_rescale_unfiorm) { - cmdbuf.PushConstants(*pipeline_layout, VK_SHADER_STAGE_ALL_GRAPHICS, - RESCALING_LAYOUT_WORDS_OFFSET, sizeof(rescaling_data), - rescaling_data.data()); - } - if (uses_rescale_unfiorm && update_rescaling) { + cmdbuf.PushConstants(*pipeline_layout, VK_SHADER_STAGE_ALL_GRAPHICS, + RESCALING_LAYOUT_WORDS_OFFSET, sizeof(rescaling_data), + rescaling_data.data()); + if (update_rescaling) { const f32 config_down_factor{Settings::values.resolution_info.down_factor}; const f32 scale_down_factor{is_rescaling ? config_down_factor : 1.0f}; cmdbuf.PushConstants(*pipeline_layout, VK_SHADER_STAGE_ALL_GRAPHICS, diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index 934b8da8e..a0c1d8f07 100755 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h @@ -151,7 +151,6 @@ private: std::mutex build_mutex; std::atomic_bool is_built{false}; bool uses_push_descriptor{false}; - bool uses_rescale_unfiorm{false}; }; } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 4b5ee151f..fa87d37f8 100755 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -234,9 +234,12 @@ void RasterizerVulkan::Clear() { const VkExtent2D render_area = framebuffer->RenderArea(); scheduler.RequestRenderpass(framebuffer); - const bool is_rescaling = texture_cache.IsRescaling(); - const u32 up_scale = is_rescaling ? Settings::values.resolution_info.up_scale : 1U; - const u32 down_shift = is_rescaling ? Settings::values.resolution_info.down_shift : 0U; + u32 up_scale = 1; + u32 down_shift = 0; + if (texture_cache.IsRescaling()) { + up_scale = Settings::values.resolution_info.up_scale; + down_shift = Settings::values.resolution_info.down_shift; + } UpdateViewportsState(regs); VkClearRect clear_rect{ @@ -692,9 +695,12 @@ void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs if (!state_tracker.TouchScissors()) { return; } - const bool is_rescaling = texture_cache.IsRescaling(); - const u32 up_scale = is_rescaling ? Settings::values.resolution_info.up_scale : 1U; - const u32 down_shift = is_rescaling ? Settings::values.resolution_info.down_shift : 0U; + u32 up_scale = 1; + u32 down_shift = 0; + if (texture_cache.IsRescaling()) { + up_scale = Settings::values.resolution_info.up_scale; + down_shift = Settings::values.resolution_info.down_shift; + } const std::array scissors{ GetScissorState(regs, 0, up_scale, down_shift), GetScissorState(regs, 1, up_scale, down_shift), diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp index d6bc02426..64a58304b 100755 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp @@ -29,10 +29,7 @@ constexpr VkDeviceSize MAX_ALIGNMENT = 256; constexpr VkDeviceSize MAX_STREAM_BUFFER_REQUEST_SIZE = 8_MiB; // Stream buffer size in bytes constexpr VkDeviceSize STREAM_BUFFER_SIZE = 128_MiB; - -constexpr VkDeviceSize REGION_SIZE = STREAM_BUFFER_SIZE / StagingBufferPool::NUM_STREAM_REGIONS; -static_assert(Common::IsAligned(REGION_SIZE, MAX_ALIGNMENT), - "Stream buffer region size must be VK buffer aligned"); +constexpr VkDeviceSize REGION_SIZE = STREAM_BUFFER_SIZE / StagingBufferPool::NUM_SYNCS; constexpr VkMemoryPropertyFlags HOST_FLAGS = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; @@ -86,17 +83,6 @@ u32 FindMemoryTypeIndex(const VkPhysicalDeviceMemoryProperties& props, u32 type_ size_t Region(size_t iterator) noexcept { return iterator / REGION_SIZE; } - -constexpr std::array MakeStreamBufferOffset() { - std::array offsets{}; - for (size_t i = 0; i < StagingBufferPool::NUM_STREAM_REGIONS; ++i) { - offsets[i] = static_cast(i * REGION_SIZE); - } - return offsets; -} - -constexpr auto STREAM_BUFFER_OFFSETS_LUT = MakeStreamBufferOffset(); - } // Anonymous namespace StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& memory_allocator_, @@ -173,19 +159,31 @@ void StagingBufferPool::TickFrame() { } StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) { - const auto num_requested_regions = Region(size) + 1; - const auto available_index = NextAvailableStreamIndex(num_requested_regions); - if (!available_index) { + if (AreRegionsActive(Region(free_iterator) + 1, + std::min(Region(iterator + size) + 1, NUM_SYNCS))) { // Avoid waiting for the previous usages to be free return GetStagingBuffer(size, MemoryUsage::Upload); } const u64 current_tick = scheduler.CurrentTick(); - const auto begin_itr = sync_ticks.begin() + *available_index; - std::fill(begin_itr, begin_itr + num_requested_regions, current_tick); + std::fill(sync_ticks.begin() + Region(used_iterator), sync_ticks.begin() + Region(iterator), + current_tick); + used_iterator = iterator; + free_iterator = std::max(free_iterator, iterator + size); - const VkDeviceSize offset = STREAM_BUFFER_OFFSETS_LUT[*available_index]; - ASSERT(offset + size <= STREAM_BUFFER_SIZE); - next_index = (*available_index + num_requested_regions) % NUM_STREAM_REGIONS; + if (iterator + size >= STREAM_BUFFER_SIZE) { + std::fill(sync_ticks.begin() + Region(used_iterator), sync_ticks.begin() + NUM_SYNCS, + current_tick); + used_iterator = 0; + iterator = 0; + free_iterator = size; + + if (AreRegionsActive(0, Region(size) + 1)) { + // Avoid waiting for the previous usages to be free + return GetStagingBuffer(size, MemoryUsage::Upload); + } + } + const size_t offset = iterator; + iterator = Common::AlignUp(iterator + size, MAX_ALIGNMENT); return StagingBufferRef{ .buffer = *stream_buffer, .offset = static_cast(offset), @@ -193,22 +191,10 @@ StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) { }; } -std::optional StagingBufferPool::NextAvailableStreamIndex(size_t num_regions) const { - const auto is_index_available = [this, num_regions](size_t begin_offset) { - const u64 gpu_tick = scheduler.GetMasterSemaphore().KnownGpuTick(); - const auto tick_check = [gpu_tick](u64 sync_tick) { return gpu_tick >= sync_tick; }; - - const auto begin_itr = sync_ticks.begin() + begin_offset; - const bool is_available = std::all_of(begin_itr, begin_itr + num_regions, tick_check); - return is_available ? std::optional(begin_offset) : std::nullopt; - }; - // Avoid overflow - if (next_index + num_regions <= NUM_STREAM_REGIONS) { - return is_index_available(next_index); - } - // Not enough contiguous regions at the next_index, - // Check if the contiguous range in the front is available - return is_index_available(0); +bool StagingBufferPool::AreRegionsActive(size_t region_begin, size_t region_end) const { + const u64 gpu_tick = scheduler.GetMasterSemaphore().KnownGpuTick(); + return std::any_of(sync_ticks.begin() + region_begin, sync_ticks.begin() + region_end, + [gpu_tick](u64 sync_tick) { return gpu_tick < sync_tick; }); }; StagingBufferRef StagingBufferPool::GetStagingBuffer(size_t size, MemoryUsage usage) { diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h index 4b57e3ca4..69f7618de 100755 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h @@ -25,7 +25,7 @@ struct StagingBufferRef { class StagingBufferPool { public: - static constexpr size_t NUM_STREAM_REGIONS = 0x8000; + static constexpr size_t NUM_SYNCS = 16; explicit StagingBufferPool(const Device& device, MemoryAllocator& memory_allocator, VKScheduler& scheduler); @@ -67,7 +67,7 @@ private: StagingBufferRef GetStreamBuffer(size_t size); - std::optional NextAvailableStreamIndex(size_t num_regions) const; + bool AreRegionsActive(size_t region_begin, size_t region_end) const; StagingBufferRef GetStagingBuffer(size_t size, MemoryUsage usage); @@ -89,8 +89,10 @@ private: vk::DeviceMemory stream_memory; u8* stream_pointer = nullptr; - size_t next_index = 0; - std::array sync_ticks{}; + size_t iterator = 0; + size_t used_iterator = 0; + size_t free_iterator = 0; + std::array sync_ticks{}; StagingBuffersCache device_local_cache; StagingBuffersCache upload_cache; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 959f6f228..8fef74117 100755 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -328,8 +328,7 @@ void TextureCache

::UpdateRenderTargets(bool is_clear) { } const bool rescaled = RescaleRenderTargets(is_clear); - const auto& resolution_info = Settings::values.resolution_info; - if (resolution_info.active && is_rescaling != rescaled) { + if (is_rescaling != rescaled) { flags[Dirty::RescaleViewports] = true; flags[Dirty::RescaleScissors] = true; is_rescaling = rescaled; @@ -346,8 +345,12 @@ void TextureCache

::UpdateRenderTargets(bool is_clear) { for (size_t index = 0; index < NUM_RT; ++index) { render_targets.draw_buffers[index] = static_cast(maxwell3d.regs.rt_control.Map(index)); } - const u32 up_scale = is_rescaling ? resolution_info.up_scale : 1U; - const u32 down_shift = is_rescaling ? resolution_info.down_shift : 0U; + u32 up_scale = 1; + u32 down_shift = 0; + if (is_rescaling) { + up_scale = Settings::values.resolution_info.up_scale; + down_shift = Settings::values.resolution_info.down_shift; + } render_targets.size = Extent2D{ (maxwell3d.regs.render_area.width * up_scale) >> down_shift, (maxwell3d.regs.render_area.height * up_scale) >> down_shift,