From f6fd2265b1bbcc8cd4dfe59e735dda1ceaafc6f9 Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Mon, 26 Feb 2024 21:15:57 +0100 Subject: [PATCH] early-access version 4174 --- README.md | 2 +- src/common/settings.h | 2 -- src/core/core.cpp | 8 ------- .../hle/service/nvdrv/devices/nvhost_gpu.cpp | 21 ++++++++++++++----- .../hle/service/nvdrv/devices/nvhost_gpu.h | 3 ++- src/video_core/buffer_cache/usage_tracker.h | 6 ++++++ src/video_core/control/channel_state.cpp | 3 ++- src/video_core/control/channel_state.h | 3 ++- .../control/channel_state_cache.cpp | 2 +- src/video_core/control/channel_state_cache.h | 8 ++++--- .../control/channel_state_cache.inc | 2 ++ src/video_core/gpu.cpp | 8 +++---- src/video_core/gpu.h | 2 +- .../renderer_opengl/gl_shader_cache.cpp | 1 + .../renderer_vulkan/vk_rasterizer.cpp | 4 ++-- .../vulkan_common/vulkan_device.cpp | 7 +++++++ src/video_core/vulkan_common/vulkan_device.h | 14 +++++++++++++ 17 files changed, 66 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 0bcbbc551..08db4df06 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 4173. +This is the source code for early-access 4174. ## Legal Notice diff --git a/src/common/settings.h b/src/common/settings.h index 4e4071189..0c7d22073 100755 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -435,8 +435,6 @@ struct Values { linkage, false, "disable_shader_loop_safety_checks", Category::RendererDebug}; Setting enable_renderdoc_hotkey{linkage, false, "renderdoc_hotkey", Category::RendererDebug}; - // TODO: remove this once AMDVLK supports VK_EXT_depth_bias_control - bool renderer_amdvlk_depth_bias_workaround{}; Setting disable_buffer_reorder{linkage, false, "disable_buffer_reorder", Category::RendererDebug}; diff --git a/src/core/core.cpp b/src/core/core.cpp index 6ea4c7849..ee06615d5 100755 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -394,11 +394,6 @@ struct System::Impl { room_member->SendGameInfo(game_info); } - // Workarounds: - // Activate this in Super Smash Brothers Ultimate, it only affects AMD cards using AMDVLK - Settings::values.renderer_amdvlk_depth_bias_workaround = - params.program_id == 0x1006A800016E000ULL; - status = SystemResultStatus::Success; return status; } @@ -457,9 +452,6 @@ struct System::Impl { room_member->SendGameInfo(game_info); } - // Workarounds - Settings::values.renderer_amdvlk_depth_bias_workaround = false; - // Reset all glue registrations arp_manager.ResetAll(); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index e71c58aa9..616c387e9 100755 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -5,6 +5,7 @@ #include "common/assert.h" #include "common/logging/log.h" #include "core/core.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/service/nvdrv/core/container.h" #include "core/hle/service/nvdrv/core/nvmap.h" #include "core/hle/service/nvdrv/core/syncpoint_manager.h" @@ -75,7 +76,7 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span inpu case 0xd: return WrapFixed(this, &nvhost_gpu::SetChannelPriority, input, output); case 0x1a: - return WrapFixed(this, &nvhost_gpu::AllocGPFIFOEx2, input, output); + return WrapFixed(this, &nvhost_gpu::AllocGPFIFOEx2, input, output, fd); case 0x1b: return WrapFixedVariable(this, &nvhost_gpu::SubmitGPFIFOBase1, input, output, true); case 0x1d: @@ -120,8 +121,13 @@ NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span inpu return NvResult::NotImplemented; } -void nvhost_gpu::OnOpen(NvCore::SessionId session_id, DeviceFD fd) {} -void nvhost_gpu::OnClose(DeviceFD fd) {} +void nvhost_gpu::OnOpen(NvCore::SessionId session_id, DeviceFD fd) { + sessions[fd] = session_id; +} + +void nvhost_gpu::OnClose(DeviceFD fd) { + sessions.erase(fd); +} NvResult nvhost_gpu::SetNVMAPfd(IoctlSetNvmapFD& params) { LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); @@ -161,7 +167,7 @@ NvResult nvhost_gpu::SetChannelPriority(IoctlChannelSetPriority& params) { return NvResult::Success; } -NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params) { +NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params, DeviceFD fd) { LOG_WARNING(Service_NVDRV, "(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, " "unk1={:X}, unk2={:X}, unk3={:X}", @@ -173,7 +179,12 @@ NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params) { return NvResult::AlreadyAllocated; } - system.GPU().InitChannel(*channel_state); + u64 program_id{}; + if (auto* const session = core.GetSession(sessions[fd]); session != nullptr) { + program_id = session->process->GetProgramId(); + } + + system.GPU().InitChannel(*channel_state, program_id); params.fence_out = syncpoint_manager.GetSyncpointFence(channel_syncpoint); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index 40c2291b1..cde3418ad 100755 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h @@ -192,7 +192,7 @@ private: NvResult ZCullBind(IoctlZCullBind& params); NvResult SetErrorNotifier(IoctlSetErrorNotifier& params); NvResult SetChannelPriority(IoctlChannelSetPriority& params); - NvResult AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params); + NvResult AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params, DeviceFD fd); NvResult AllocateObjectContext(IoctlAllocObjCtx& params); NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandList&& entries); @@ -210,6 +210,7 @@ private: NvCore::SyncpointManager& syncpoint_manager; NvCore::NvMap& nvmap; std::shared_ptr channel_state; + std::unordered_map sessions; u32 channel_syncpoint; std::mutex channel_mutex; diff --git a/src/video_core/buffer_cache/usage_tracker.h b/src/video_core/buffer_cache/usage_tracker.h index 5f8688d31..ae511ccb6 100755 --- a/src/video_core/buffer_cache/usage_tracker.h +++ b/src/video_core/buffer_cache/usage_tracker.h @@ -26,6 +26,9 @@ public: void Track(u64 offset, u64 size) noexcept { const size_t page = offset >> PAGE_SHIFT; const size_t page_end = (offset + size) >> PAGE_SHIFT; + if (page_end < page || page_end >= pages.size()) { + return; + } TrackPage(page, offset, size); if (page == page_end) { return; @@ -41,6 +44,9 @@ public: [[nodiscard]] bool IsUsed(u64 offset, u64 size) const noexcept { const size_t page = offset >> PAGE_SHIFT; const size_t page_end = (offset + size) >> PAGE_SHIFT; + if (page_end < page || page_end >= pages.size()) { + return false; + } if (IsPageUsed(page, offset, size)) { return true; } diff --git a/src/video_core/control/channel_state.cpp b/src/video_core/control/channel_state.cpp index d182bad57..a3780a046 100755 --- a/src/video_core/control/channel_state.cpp +++ b/src/video_core/control/channel_state.cpp @@ -16,8 +16,9 @@ namespace Tegra::Control { ChannelState::ChannelState(s32 bind_id_) : bind_id{bind_id_}, initialized{} {} -void ChannelState::Init(Core::System& system, GPU& gpu) { +void ChannelState::Init(Core::System& system, GPU& gpu, u64 program_id_) { ASSERT(memory_manager); + program_id = program_id_; dma_pusher = std::make_unique(system, gpu, *memory_manager, *this); maxwell_3d = std::make_unique(system, *memory_manager); fermi_2d = std::make_unique(*memory_manager); diff --git a/src/video_core/control/channel_state.h b/src/video_core/control/channel_state.h index ceaa92647..12fb84811 100755 --- a/src/video_core/control/channel_state.h +++ b/src/video_core/control/channel_state.h @@ -40,11 +40,12 @@ struct ChannelState { ChannelState(ChannelState&& other) noexcept = default; ChannelState& operator=(ChannelState&& other) noexcept = default; - void Init(Core::System& system, GPU& gpu); + void Init(Core::System& system, GPU& gpu, u64 program_id); void BindRasterizer(VideoCore::RasterizerInterface* rasterizer); s32 bind_id = -1; + u64 program_id = 0; /// 3D engine std::unique_ptr maxwell_3d; /// 2D engine diff --git a/src/video_core/control/channel_state_cache.cpp b/src/video_core/control/channel_state_cache.cpp index eb59d65c5..d225de7ac 100755 --- a/src/video_core/control/channel_state_cache.cpp +++ b/src/video_core/control/channel_state_cache.cpp @@ -7,7 +7,7 @@ namespace VideoCommon { ChannelInfo::ChannelInfo(Tegra::Control::ChannelState& channel_state) : maxwell3d{*channel_state.maxwell_3d}, kepler_compute{*channel_state.kepler_compute}, - gpu_memory{*channel_state.memory_manager} {} + gpu_memory{*channel_state.memory_manager}, program_id{channel_state.program_id} {} template class VideoCommon::ChannelSetupCaches; diff --git a/src/video_core/control/channel_state_cache.h b/src/video_core/control/channel_state_cache.h index efc992d83..5d7c411b9 100755 --- a/src/video_core/control/channel_state_cache.h +++ b/src/video_core/control/channel_state_cache.h @@ -39,6 +39,7 @@ public: Tegra::Engines::Maxwell3D& maxwell3d; Tegra::Engines::KeplerCompute& kepler_compute; Tegra::MemoryManager& gpu_memory; + u64 program_id; }; template @@ -77,9 +78,10 @@ protected: P* channel_state; size_t current_channel_id{UNSET_CHANNEL}; size_t current_address_space{}; - Tegra::Engines::Maxwell3D* maxwell3d; - Tegra::Engines::KeplerCompute* kepler_compute; - Tegra::MemoryManager* gpu_memory; + Tegra::Engines::Maxwell3D* maxwell3d{}; + Tegra::Engines::KeplerCompute* kepler_compute{}; + Tegra::MemoryManager* gpu_memory{}; + u64 program_id{}; std::deque

channel_storage; std::deque free_channel_ids; diff --git a/src/video_core/control/channel_state_cache.inc b/src/video_core/control/channel_state_cache.inc index 5a6ab0052..e3d2b4447 100755 --- a/src/video_core/control/channel_state_cache.inc +++ b/src/video_core/control/channel_state_cache.inc @@ -58,6 +58,7 @@ void ChannelSetupCaches

::BindToChannel(s32 id) { maxwell3d = &channel_state->maxwell3d; kepler_compute = &channel_state->kepler_compute; gpu_memory = &channel_state->gpu_memory; + program_id = channel_state->program_id; current_address_space = gpu_memory->GetID(); } @@ -76,6 +77,7 @@ void ChannelSetupCaches

::EraseChannel(s32 id) { maxwell3d = nullptr; kepler_compute = nullptr; gpu_memory = nullptr; + program_id = 0; } else if (current_channel_id != UNSET_CHANNEL) { channel_state = &channel_storage[current_channel_id]; } diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 59356015b..d325608c9 100755 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -67,8 +67,8 @@ struct GPU::Impl { return CreateChannel(new_channel_id++); } - void InitChannel(Control::ChannelState& to_init) { - to_init.Init(system, gpu); + void InitChannel(Control::ChannelState& to_init, u64 program_id) { + to_init.Init(system, gpu, program_id); to_init.BindRasterizer(rasterizer); rasterizer->InitializeChannel(to_init); } @@ -387,8 +387,8 @@ std::shared_ptr GPU::AllocateChannel() { return impl->AllocateChannel(); } -void GPU::InitChannel(Control::ChannelState& to_init) { - impl->InitChannel(to_init); +void GPU::InitChannel(Control::ChannelState& to_init, u64 program_id) { + impl->InitChannel(to_init, program_id); } void GPU::BindChannel(s32 channel_id) { diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 25c75a109..a4726ce13 100755 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -149,7 +149,7 @@ public: std::shared_ptr AllocateChannel(); - void InitChannel(Control::ChannelState& to_init); + void InitChannel(Control::ChannelState& to_init, u64 program_id); void BindChannel(s32 channel_id); diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 5ada85685..c3530c79c 100755 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -215,6 +215,7 @@ ShaderCache::ShaderCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, .support_gl_variable_aoffi = device.HasVariableAoffi(), .support_gl_sparse_textures = device.HasSparseTexture2(), .support_gl_derivative_control = device.HasDerivativeControl(), + .support_geometry_streams = true, .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyLargerThanGuest(), diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index d9b43379c..cc47eb345 100755 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1082,8 +1082,8 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) { regs.zeta.format == Tegra::DepthFormat::X8Z24_UNORM || regs.zeta.format == Tegra::DepthFormat::S8Z24_UNORM || regs.zeta.format == Tegra::DepthFormat::V8Z24_UNORM; - if (is_d24 && !device.SupportsD24DepthBuffer() && - Settings::values.renderer_amdvlk_depth_bias_workaround) { + if (is_d24 && !device.SupportsD24DepthBuffer() && program_id == 0x1006A800016E000ULL) { + // Only activate this in Super Smash Brothers Ultimate // the base formulas can be obtained from here: // https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-output-merger-stage-depth-bias const double rescale_factor = diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 7f183bacc..f11d0ba16 100755 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -1137,6 +1137,13 @@ void Device::RemoveUnsuitableExtensions() { RemoveExtensionFeatureIfUnsuitable(extensions.custom_border_color, features.custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); + // VK_EXT_depth_bias_control + extensions.depth_bias_control = + features.depth_bias_control.depthBiasControl && + features.depth_bias_control.leastRepresentableValueForceUnormRepresentation; + RemoveExtensionFeatureIfUnsuitable(extensions.depth_bias_control, features.depth_bias_control, + VK_EXT_DEPTH_BIAS_CONTROL_EXTENSION_NAME); + // VK_EXT_depth_clip_control extensions.depth_clip_control = features.depth_clip_control.depthClipControl; RemoveExtensionFeatureIfUnsuitable(extensions.depth_clip_control, features.depth_clip_control, diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index f0cb2b2dc..e6e4a3089 100755 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -41,6 +41,7 @@ VK_DEFINE_HANDLE(VmaAllocator) // Define all features which may be used by the implementation and require an extension here. #define FOR_EACH_VK_FEATURE_EXT(FEATURE) \ FEATURE(EXT, CustomBorderColor, CUSTOM_BORDER_COLOR, custom_border_color) \ + FEATURE(EXT, DepthBiasControl, DEPTH_BIAS_CONTROL, depth_bias_control) \ FEATURE(EXT, DepthClipControl, DEPTH_CLIP_CONTROL, depth_clip_control) \ FEATURE(EXT, ExtendedDynamicState, EXTENDED_DYNAMIC_STATE, extended_dynamic_state) \ FEATURE(EXT, ExtendedDynamicState2, EXTENDED_DYNAMIC_STATE_2, extended_dynamic_state2) \ @@ -96,6 +97,7 @@ VK_DEFINE_HANDLE(VmaAllocator) #define FOR_EACH_VK_RECOMMENDED_EXTENSION(EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME) \ + EXTENSION_NAME(VK_EXT_DEPTH_BIAS_CONTROL_EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME) \ @@ -148,6 +150,9 @@ VK_DEFINE_HANDLE(VmaAllocator) // Define features where the absence of the feature may result in a degraded experience. #define FOR_EACH_VK_RECOMMENDED_FEATURE(FEATURE_NAME) \ FEATURE_NAME(custom_border_color, customBorderColors) \ + FEATURE_NAME(depth_bias_control, depthBiasControl) \ + FEATURE_NAME(depth_bias_control, leastRepresentableValueForceUnormRepresentation) \ + FEATURE_NAME(depth_bias_control, depthBiasExact) \ FEATURE_NAME(extended_dynamic_state, extendedDynamicState) \ FEATURE_NAME(format_a4b4g4r4, formatA4B4G4R4) \ FEATURE_NAME(index_type_uint8, indexTypeUint8) \ @@ -474,6 +479,11 @@ public: return extensions.depth_clip_control; } + /// Returns true if the device supports VK_EXT_depth_bias_control. + bool IsExtDepthBiasControlSupported() const { + return extensions.depth_bias_control; + } + /// Returns true if the device supports VK_EXT_shader_viewport_index_layer. bool IsExtShaderViewportIndexLayerSupported() const { return extensions.shader_viewport_index_layer; @@ -644,6 +654,10 @@ public: return features.robustness2.nullDescriptor; } + bool HasExactDepthBiasControl() const { + return features.depth_bias_control.depthBiasExact; + } + u32 GetMaxVertexInputAttributes() const { return properties.properties.limits.maxVertexInputAttributes; }