early-access version 4174
This commit is contained in:
		| @@ -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 | ||||
|  | ||||
|   | ||||
| @@ -435,8 +435,6 @@ struct Values { | ||||
|         linkage, false, "disable_shader_loop_safety_checks", Category::RendererDebug}; | ||||
|     Setting<bool> 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<bool> disable_buffer_reorder{linkage, false, "disable_buffer_reorder", | ||||
|                                          Category::RendererDebug}; | ||||
|  | ||||
|   | ||||
| @@ -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(); | ||||
|  | ||||
|   | ||||
| @@ -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<const u8> 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<const u8> 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); | ||||
|  | ||||
|   | ||||
| @@ -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<Tegra::Control::ChannelState> channel_state; | ||||
|     std::unordered_map<DeviceFD, NvCore::SessionId> sessions; | ||||
|     u32 channel_syncpoint; | ||||
|     std::mutex channel_mutex; | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|         } | ||||
|   | ||||
| @@ -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<Tegra::DmaPusher>(system, gpu, *memory_manager, *this); | ||||
|     maxwell_3d = std::make_unique<Engines::Maxwell3D>(system, *memory_manager); | ||||
|     fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager); | ||||
|   | ||||
| @@ -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<Engines::Maxwell3D> maxwell_3d; | ||||
|     /// 2D engine | ||||
|   | ||||
| @@ -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<VideoCommon::ChannelInfo>; | ||||
|  | ||||
|   | ||||
| @@ -39,6 +39,7 @@ public: | ||||
|     Tegra::Engines::Maxwell3D& maxwell3d; | ||||
|     Tegra::Engines::KeplerCompute& kepler_compute; | ||||
|     Tegra::MemoryManager& gpu_memory; | ||||
|     u64 program_id; | ||||
| }; | ||||
|  | ||||
| template <class P> | ||||
| @@ -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<P> channel_storage; | ||||
|     std::deque<size_t> free_channel_ids; | ||||
|   | ||||
| @@ -58,6 +58,7 @@ void ChannelSetupCaches<P>::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<P>::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]; | ||||
|     } | ||||
|   | ||||
| @@ -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<Control::ChannelState> 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) { | ||||
|   | ||||
| @@ -149,7 +149,7 @@ public: | ||||
|  | ||||
|     std::shared_ptr<Control::ChannelState> AllocateChannel(); | ||||
|  | ||||
|     void InitChannel(Control::ChannelState& to_init); | ||||
|     void InitChannel(Control::ChannelState& to_init, u64 program_id); | ||||
|  | ||||
|     void BindChannel(s32 channel_id); | ||||
|  | ||||
|   | ||||
| @@ -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(), | ||||
|  | ||||
|   | ||||
| @@ -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 = | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user