early-access version 4174

This commit is contained in:
pineappleEA 2024-02-26 21:15:57 +01:00
parent 6cc741a886
commit f6fd2265b1
17 changed files with 66 additions and 30 deletions

View file

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 4173. This is the source code for early-access 4174.
## Legal Notice ## Legal Notice

View file

@ -435,8 +435,6 @@ struct Values {
linkage, false, "disable_shader_loop_safety_checks", Category::RendererDebug}; linkage, false, "disable_shader_loop_safety_checks", Category::RendererDebug};
Setting<bool> enable_renderdoc_hotkey{linkage, false, "renderdoc_hotkey", Setting<bool> enable_renderdoc_hotkey{linkage, false, "renderdoc_hotkey",
Category::RendererDebug}; 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", Setting<bool> disable_buffer_reorder{linkage, false, "disable_buffer_reorder",
Category::RendererDebug}; Category::RendererDebug};

View file

@ -394,11 +394,6 @@ struct System::Impl {
room_member->SendGameInfo(game_info); 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; status = SystemResultStatus::Success;
return status; return status;
} }
@ -457,9 +452,6 @@ struct System::Impl {
room_member->SendGameInfo(game_info); room_member->SendGameInfo(game_info);
} }
// Workarounds
Settings::values.renderer_amdvlk_depth_bias_workaround = false;
// Reset all glue registrations // Reset all glue registrations
arp_manager.ResetAll(); arp_manager.ResetAll();

View file

@ -5,6 +5,7 @@
#include "common/assert.h" #include "common/assert.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/core.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/container.h"
#include "core/hle/service/nvdrv/core/nvmap.h" #include "core/hle/service/nvdrv/core/nvmap.h"
#include "core/hle/service/nvdrv/core/syncpoint_manager.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: case 0xd:
return WrapFixed(this, &nvhost_gpu::SetChannelPriority, input, output); return WrapFixed(this, &nvhost_gpu::SetChannelPriority, input, output);
case 0x1a: case 0x1a:
return WrapFixed(this, &nvhost_gpu::AllocGPFIFOEx2, input, output); return WrapFixed(this, &nvhost_gpu::AllocGPFIFOEx2, input, output, fd);
case 0x1b: case 0x1b:
return WrapFixedVariable(this, &nvhost_gpu::SubmitGPFIFOBase1, input, output, true); return WrapFixedVariable(this, &nvhost_gpu::SubmitGPFIFOBase1, input, output, true);
case 0x1d: case 0x1d:
@ -120,8 +121,13 @@ NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> inpu
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
void nvhost_gpu::OnOpen(NvCore::SessionId session_id, DeviceFD fd) {} void nvhost_gpu::OnOpen(NvCore::SessionId session_id, DeviceFD fd) {
void nvhost_gpu::OnClose(DeviceFD fd) {} sessions[fd] = session_id;
}
void nvhost_gpu::OnClose(DeviceFD fd) {
sessions.erase(fd);
}
NvResult nvhost_gpu::SetNVMAPfd(IoctlSetNvmapFD& params) { NvResult nvhost_gpu::SetNVMAPfd(IoctlSetNvmapFD& params) {
LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
@ -161,7 +167,7 @@ NvResult nvhost_gpu::SetChannelPriority(IoctlChannelSetPriority& params) {
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params) { NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params, DeviceFD fd) {
LOG_WARNING(Service_NVDRV, LOG_WARNING(Service_NVDRV,
"(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, " "(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, "
"unk1={:X}, unk2={:X}, unk3={:X}", "unk1={:X}, unk2={:X}, unk3={:X}",
@ -173,7 +179,12 @@ NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params) {
return NvResult::AlreadyAllocated; 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); params.fence_out = syncpoint_manager.GetSyncpointFence(channel_syncpoint);

View file

@ -192,7 +192,7 @@ private:
NvResult ZCullBind(IoctlZCullBind& params); NvResult ZCullBind(IoctlZCullBind& params);
NvResult SetErrorNotifier(IoctlSetErrorNotifier& params); NvResult SetErrorNotifier(IoctlSetErrorNotifier& params);
NvResult SetChannelPriority(IoctlChannelSetPriority& params); NvResult SetChannelPriority(IoctlChannelSetPriority& params);
NvResult AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params); NvResult AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params, DeviceFD fd);
NvResult AllocateObjectContext(IoctlAllocObjCtx& params); NvResult AllocateObjectContext(IoctlAllocObjCtx& params);
NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandList&& entries); NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandList&& entries);
@ -210,6 +210,7 @@ private:
NvCore::SyncpointManager& syncpoint_manager; NvCore::SyncpointManager& syncpoint_manager;
NvCore::NvMap& nvmap; NvCore::NvMap& nvmap;
std::shared_ptr<Tegra::Control::ChannelState> channel_state; std::shared_ptr<Tegra::Control::ChannelState> channel_state;
std::unordered_map<DeviceFD, NvCore::SessionId> sessions;
u32 channel_syncpoint; u32 channel_syncpoint;
std::mutex channel_mutex; std::mutex channel_mutex;

View file

@ -26,6 +26,9 @@ public:
void Track(u64 offset, u64 size) noexcept { void Track(u64 offset, u64 size) noexcept {
const size_t page = offset >> PAGE_SHIFT; const size_t page = offset >> PAGE_SHIFT;
const size_t page_end = (offset + size) >> PAGE_SHIFT; const size_t page_end = (offset + size) >> PAGE_SHIFT;
if (page_end < page || page_end >= pages.size()) {
return;
}
TrackPage(page, offset, size); TrackPage(page, offset, size);
if (page == page_end) { if (page == page_end) {
return; return;
@ -41,6 +44,9 @@ public:
[[nodiscard]] bool IsUsed(u64 offset, u64 size) const noexcept { [[nodiscard]] bool IsUsed(u64 offset, u64 size) const noexcept {
const size_t page = offset >> PAGE_SHIFT; const size_t page = offset >> PAGE_SHIFT;
const size_t page_end = (offset + size) >> 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)) { if (IsPageUsed(page, offset, size)) {
return true; return true;
} }

View file

@ -16,8 +16,9 @@ namespace Tegra::Control {
ChannelState::ChannelState(s32 bind_id_) : bind_id{bind_id_}, initialized{} {} 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); ASSERT(memory_manager);
program_id = program_id_;
dma_pusher = std::make_unique<Tegra::DmaPusher>(system, gpu, *memory_manager, *this); dma_pusher = std::make_unique<Tegra::DmaPusher>(system, gpu, *memory_manager, *this);
maxwell_3d = std::make_unique<Engines::Maxwell3D>(system, *memory_manager); maxwell_3d = std::make_unique<Engines::Maxwell3D>(system, *memory_manager);
fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager); fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager);

View file

@ -40,11 +40,12 @@ struct ChannelState {
ChannelState(ChannelState&& other) noexcept = default; ChannelState(ChannelState&& other) noexcept = default;
ChannelState& operator=(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); void BindRasterizer(VideoCore::RasterizerInterface* rasterizer);
s32 bind_id = -1; s32 bind_id = -1;
u64 program_id = 0;
/// 3D engine /// 3D engine
std::unique_ptr<Engines::Maxwell3D> maxwell_3d; std::unique_ptr<Engines::Maxwell3D> maxwell_3d;
/// 2D engine /// 2D engine

View file

@ -7,7 +7,7 @@ namespace VideoCommon {
ChannelInfo::ChannelInfo(Tegra::Control::ChannelState& channel_state) ChannelInfo::ChannelInfo(Tegra::Control::ChannelState& channel_state)
: maxwell3d{*channel_state.maxwell_3d}, kepler_compute{*channel_state.kepler_compute}, : 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>; template class VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo>;

View file

@ -39,6 +39,7 @@ public:
Tegra::Engines::Maxwell3D& maxwell3d; Tegra::Engines::Maxwell3D& maxwell3d;
Tegra::Engines::KeplerCompute& kepler_compute; Tegra::Engines::KeplerCompute& kepler_compute;
Tegra::MemoryManager& gpu_memory; Tegra::MemoryManager& gpu_memory;
u64 program_id;
}; };
template <class P> template <class P>
@ -77,9 +78,10 @@ protected:
P* channel_state; P* channel_state;
size_t current_channel_id{UNSET_CHANNEL}; size_t current_channel_id{UNSET_CHANNEL};
size_t current_address_space{}; size_t current_address_space{};
Tegra::Engines::Maxwell3D* maxwell3d; Tegra::Engines::Maxwell3D* maxwell3d{};
Tegra::Engines::KeplerCompute* kepler_compute; Tegra::Engines::KeplerCompute* kepler_compute{};
Tegra::MemoryManager* gpu_memory; Tegra::MemoryManager* gpu_memory{};
u64 program_id{};
std::deque<P> channel_storage; std::deque<P> channel_storage;
std::deque<size_t> free_channel_ids; std::deque<size_t> free_channel_ids;

View file

@ -58,6 +58,7 @@ void ChannelSetupCaches<P>::BindToChannel(s32 id) {
maxwell3d = &channel_state->maxwell3d; maxwell3d = &channel_state->maxwell3d;
kepler_compute = &channel_state->kepler_compute; kepler_compute = &channel_state->kepler_compute;
gpu_memory = &channel_state->gpu_memory; gpu_memory = &channel_state->gpu_memory;
program_id = channel_state->program_id;
current_address_space = gpu_memory->GetID(); current_address_space = gpu_memory->GetID();
} }
@ -76,6 +77,7 @@ void ChannelSetupCaches<P>::EraseChannel(s32 id) {
maxwell3d = nullptr; maxwell3d = nullptr;
kepler_compute = nullptr; kepler_compute = nullptr;
gpu_memory = nullptr; gpu_memory = nullptr;
program_id = 0;
} else if (current_channel_id != UNSET_CHANNEL) { } else if (current_channel_id != UNSET_CHANNEL) {
channel_state = &channel_storage[current_channel_id]; channel_state = &channel_storage[current_channel_id];
} }

View file

@ -67,8 +67,8 @@ struct GPU::Impl {
return CreateChannel(new_channel_id++); return CreateChannel(new_channel_id++);
} }
void InitChannel(Control::ChannelState& to_init) { void InitChannel(Control::ChannelState& to_init, u64 program_id) {
to_init.Init(system, gpu); to_init.Init(system, gpu, program_id);
to_init.BindRasterizer(rasterizer); to_init.BindRasterizer(rasterizer);
rasterizer->InitializeChannel(to_init); rasterizer->InitializeChannel(to_init);
} }
@ -387,8 +387,8 @@ std::shared_ptr<Control::ChannelState> GPU::AllocateChannel() {
return impl->AllocateChannel(); return impl->AllocateChannel();
} }
void GPU::InitChannel(Control::ChannelState& to_init) { void GPU::InitChannel(Control::ChannelState& to_init, u64 program_id) {
impl->InitChannel(to_init); impl->InitChannel(to_init, program_id);
} }
void GPU::BindChannel(s32 channel_id) { void GPU::BindChannel(s32 channel_id) {

View file

@ -149,7 +149,7 @@ public:
std::shared_ptr<Control::ChannelState> AllocateChannel(); 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); void BindChannel(s32 channel_id);

View file

@ -215,6 +215,7 @@ ShaderCache::ShaderCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
.support_gl_variable_aoffi = device.HasVariableAoffi(), .support_gl_variable_aoffi = device.HasVariableAoffi(),
.support_gl_sparse_textures = device.HasSparseTexture2(), .support_gl_sparse_textures = device.HasSparseTexture2(),
.support_gl_derivative_control = device.HasDerivativeControl(), .support_gl_derivative_control = device.HasDerivativeControl(),
.support_geometry_streams = true,
.warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyLargerThanGuest(), .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyLargerThanGuest(),

View file

@ -1082,8 +1082,8 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) {
regs.zeta.format == Tegra::DepthFormat::X8Z24_UNORM || regs.zeta.format == Tegra::DepthFormat::X8Z24_UNORM ||
regs.zeta.format == Tegra::DepthFormat::S8Z24_UNORM || regs.zeta.format == Tegra::DepthFormat::S8Z24_UNORM ||
regs.zeta.format == Tegra::DepthFormat::V8Z24_UNORM; regs.zeta.format == Tegra::DepthFormat::V8Z24_UNORM;
if (is_d24 && !device.SupportsD24DepthBuffer() && if (is_d24 && !device.SupportsD24DepthBuffer() && program_id == 0x1006A800016E000ULL) {
Settings::values.renderer_amdvlk_depth_bias_workaround) { // Only activate this in Super Smash Brothers Ultimate
// the base formulas can be obtained from here: // 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 // https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-output-merger-stage-depth-bias
const double rescale_factor = const double rescale_factor =

View file

@ -1137,6 +1137,13 @@ void Device::RemoveUnsuitableExtensions() {
RemoveExtensionFeatureIfUnsuitable(extensions.custom_border_color, features.custom_border_color, RemoveExtensionFeatureIfUnsuitable(extensions.custom_border_color, features.custom_border_color,
VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); 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 // VK_EXT_depth_clip_control
extensions.depth_clip_control = features.depth_clip_control.depthClipControl; extensions.depth_clip_control = features.depth_clip_control.depthClipControl;
RemoveExtensionFeatureIfUnsuitable(extensions.depth_clip_control, features.depth_clip_control, RemoveExtensionFeatureIfUnsuitable(extensions.depth_clip_control, features.depth_clip_control,

View file

@ -41,6 +41,7 @@ VK_DEFINE_HANDLE(VmaAllocator)
// Define all features which may be used by the implementation and require an extension here. // Define all features which may be used by the implementation and require an extension here.
#define FOR_EACH_VK_FEATURE_EXT(FEATURE) \ #define FOR_EACH_VK_FEATURE_EXT(FEATURE) \
FEATURE(EXT, CustomBorderColor, CUSTOM_BORDER_COLOR, custom_border_color) \ 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, DepthClipControl, DEPTH_CLIP_CONTROL, depth_clip_control) \
FEATURE(EXT, ExtendedDynamicState, EXTENDED_DYNAMIC_STATE, extended_dynamic_state) \ FEATURE(EXT, ExtendedDynamicState, EXTENDED_DYNAMIC_STATE, extended_dynamic_state) \
FEATURE(EXT, ExtendedDynamicState2, EXTENDED_DYNAMIC_STATE_2, extended_dynamic_state2) \ 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) \ #define FOR_EACH_VK_RECOMMENDED_EXTENSION(EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_CONSERVATIVE_RASTERIZATION_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_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_2_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 features where the absence of the feature may result in a degraded experience.
#define FOR_EACH_VK_RECOMMENDED_FEATURE(FEATURE_NAME) \ #define FOR_EACH_VK_RECOMMENDED_FEATURE(FEATURE_NAME) \
FEATURE_NAME(custom_border_color, customBorderColors) \ 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(extended_dynamic_state, extendedDynamicState) \
FEATURE_NAME(format_a4b4g4r4, formatA4B4G4R4) \ FEATURE_NAME(format_a4b4g4r4, formatA4B4G4R4) \
FEATURE_NAME(index_type_uint8, indexTypeUint8) \ FEATURE_NAME(index_type_uint8, indexTypeUint8) \
@ -474,6 +479,11 @@ public:
return extensions.depth_clip_control; 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. /// Returns true if the device supports VK_EXT_shader_viewport_index_layer.
bool IsExtShaderViewportIndexLayerSupported() const { bool IsExtShaderViewportIndexLayerSupported() const {
return extensions.shader_viewport_index_layer; return extensions.shader_viewport_index_layer;
@ -644,6 +654,10 @@ public:
return features.robustness2.nullDescriptor; return features.robustness2.nullDescriptor;
} }
bool HasExactDepthBiasControl() const {
return features.depth_bias_control.depthBiasExact;
}
u32 GetMaxVertexInputAttributes() const { u32 GetMaxVertexInputAttributes() const {
return properties.properties.limits.maxVertexInputAttributes; return properties.properties.limits.maxVertexInputAttributes;
} }