early-access version 4174
This commit is contained in:
		@@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 =
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user