diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp | 70 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_nvdec.h | 52 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_vic.cpp | 74 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_vic.h | 63 | 
4 files changed, 256 insertions, 3 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index bdae8b887..fcb612864 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp @@ -22,6 +22,18 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::      switch (static_cast<IoctlCommand>(command.raw)) {      case IoctlCommand::IocSetNVMAPfdCommand:          return SetNVMAPfd(input, output); +    case IoctlCommand::IocSubmit: +        return Submit(input, output); +    case IoctlCommand::IocGetSyncpoint: +        return GetSyncpoint(input, output); +    case IoctlCommand::IocGetWaitbase: +        return GetWaitbase(input, output); +    case IoctlCommand::IocMapBuffer: +        return MapBuffer(input, output); +    case IoctlCommand::IocMapBufferEx: +        return MapBufferEx(input, output); +    case IoctlCommand::IocUnmapBufferEx: +        return UnmapBufferEx(input, output);      }      UNIMPLEMENTED_MSG("Unimplemented ioctl"); @@ -30,11 +42,67 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::  u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {      IoctlSetNvmapFD params{}; -    std::memcpy(¶ms, input.data(), input.size()); +    std::memcpy(¶ms, input.data(), sizeof(IoctlSetNvmapFD));      LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);      nvmap_fd = params.nvmap_fd;      return 0;  } +u32 nvhost_nvdec::Submit(const std::vector<u8>& input, std::vector<u8>& output) { +    IoctlSubmit params{}; +    std::memcpy(¶ms, input.data(), sizeof(IoctlSubmit)); +    LOG_WARNING(Service_NVDRV, "(STUBBED) called"); +    std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); +    return 0; +} + +u32 nvhost_nvdec::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) { +    IoctlGetSyncpoint params{}; +    std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint)); +    LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); +    params.value = 0; // Seems to be hard coded at 0 +    std::memcpy(output.data(), ¶ms, sizeof(IoctlGetSyncpoint)); +    return 0; +} + +u32 nvhost_nvdec::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) { +    IoctlGetWaitbase params{}; +    std::memcpy(¶ms, input.data(), sizeof(IoctlGetWaitbase)); +    LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); +    params.value = 0; // Seems to be hard coded at 0 +    std::memcpy(output.data(), ¶ms, sizeof(IoctlGetWaitbase)); +    return 0; +} + +u32 nvhost_nvdec::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) { +    IoctlMapBuffer params{}; +    std::memcpy(¶ms, input.data(), sizeof(IoctlMapBuffer)); +    LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2, +                params.address_1); +    params.address_1 = 0; +    params.address_2 = 0; +    std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBuffer)); +    return 0; +} + +u32 nvhost_nvdec::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { +    IoctlMapBufferEx params{}; +    std::memcpy(¶ms, input.data(), sizeof(IoctlMapBufferEx)); +    LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2, +                params.address_1); +    params.address_1 = 0; +    params.address_2 = 0; +    std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBufferEx)); +    return 0; +} + +u32 nvhost_nvdec::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { +    IoctlUnmapBufferEx params{}; +    std::memcpy(¶ms, input.data(), sizeof(IoctlUnmapBufferEx)); +    LOG_WARNING(Service_NVDRV, "(STUBBED) called"); +    std::memcpy(output.data(), ¶ms, sizeof(IoctlUnmapBufferEx)); +    return 0; +} +  } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h index cbdac8069..4332db118 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h @@ -23,16 +23,66 @@ public:  private:      enum class IoctlCommand : u32_le {          IocSetNVMAPfdCommand = 0x40044801, +        IocSubmit = 0xC0400001, +        IocGetSyncpoint = 0xC0080002, +        IocGetWaitbase = 0xC0080003, +        IocMapBuffer = 0xC01C0009, +        IocMapBufferEx = 0xC0A40009, +        IocUnmapBufferEx = 0xC0A4000A,      };      struct IoctlSetNvmapFD {          u32_le nvmap_fd;      }; -    static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size"); +    static_assert(sizeof(IoctlSetNvmapFD) == 0x4, "IoctlSetNvmapFD is incorrect size"); + +    struct IoctlSubmit { +        INSERT_PADDING_BYTES(0x40); // TODO(DarkLordZach): RE this structure +    }; +    static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit has incorrect size"); + +    struct IoctlGetSyncpoint { +        u32 unknown; // seems to be ignored? Nintendo added this +        u32 value; +    }; +    static_assert(sizeof(IoctlGetSyncpoint) == 0x08, "IoctlGetSyncpoint has incorrect size"); + +    struct IoctlGetWaitbase { +        u32 unknown; // seems to be ignored? Nintendo added this +        u32 value; +    }; +    static_assert(sizeof(IoctlGetWaitbase) == 0x08, "IoctlGetWaitbase has incorrect size"); + +    struct IoctlMapBuffer { +        u32 unknown; +        u32 address_1; +        u32 address_2; +        INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure +    }; +    static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size"); + +    struct IoctlMapBufferEx { +        u32 unknown; +        u32 address_1; +        u32 address_2; +        INSERT_PADDING_BYTES(0x98); // TODO(DarkLordZach): RE this structure +    }; +    static_assert(sizeof(IoctlMapBufferEx) == 0xA4, "IoctlMapBufferEx has incorrect size"); + +    struct IoctlUnmapBufferEx { +        INSERT_PADDING_BYTES(0xA4); // TODO(DarkLordZach): RE this structure +    }; +    static_assert(sizeof(IoctlUnmapBufferEx) == 0xA4, "IoctlUnmapBufferEx has incorrect size");      u32_le nvmap_fd{};      u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output); +    u32 Submit(const std::vector<u8>& input, std::vector<u8>& output); +    u32 GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output); +    u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output); +    u32 MapBuffer(const std::vector<u8>& input, std::vector<u8>& output); +    u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output); +    u32 UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);  };  } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp index c695b8863..9da19ad56 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp @@ -22,6 +22,18 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve      switch (static_cast<IoctlCommand>(command.raw)) {      case IoctlCommand::IocSetNVMAPfdCommand:          return SetNVMAPfd(input, output); +    case IoctlCommand::IocSubmit: +        return Submit(input, output); +    case IoctlCommand::IocGetSyncpoint: +        return GetSyncpoint(input, output); +    case IoctlCommand::IocGetWaitbase: +        return GetWaitbase(input, output); +    case IoctlCommand::IocMapBuffer: +        return MapBuffer(input, output); +    case IoctlCommand::IocMapBufferEx: +        return MapBuffer(input, output); +    case IoctlCommand::IocUnmapBufferEx: +        return UnmapBufferEx(input, output);      }      UNIMPLEMENTED_MSG("Unimplemented ioctl"); @@ -30,11 +42,71 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve  u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {      IoctlSetNvmapFD params{}; -    std::memcpy(¶ms, input.data(), input.size()); +    std::memcpy(¶ms, input.data(), sizeof(IoctlSetNvmapFD));      LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);      nvmap_fd = params.nvmap_fd;      return 0;  } +u32 nvhost_vic::Submit(const std::vector<u8>& input, std::vector<u8>& output) { +    IoctlSubmit params{}; +    std::memcpy(¶ms, input.data(), sizeof(IoctlSubmit)); +    LOG_WARNING(Service_NVDRV, "(STUBBED) called"); + +    // Workaround for Luigi's Mansion 3, as nvhost_vic is not implemented for asynch GPU +    params.command_buffer = {}; + +    std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); +    return 0; +} + +u32 nvhost_vic::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) { +    IoctlGetSyncpoint params{}; +    std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint)); +    LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); +    params.value = 0; // Seems to be hard coded at 0 +    std::memcpy(output.data(), ¶ms, sizeof(IoctlGetSyncpoint)); +    return 0; +} + +u32 nvhost_vic::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) { +    IoctlGetWaitbase params{}; +    std::memcpy(¶ms, input.data(), sizeof(IoctlGetWaitbase)); +    LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); +    params.value = 0; // Seems to be hard coded at 0 +    std::memcpy(output.data(), ¶ms, sizeof(IoctlGetWaitbase)); +    return 0; +} + +u32 nvhost_vic::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) { +    IoctlMapBuffer params{}; +    std::memcpy(¶ms, input.data(), sizeof(IoctlMapBuffer)); +    LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2, +                params.address_1); +    params.address_1 = 0; +    params.address_2 = 0; +    std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBuffer)); +    return 0; +} + +u32 nvhost_vic::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { +    IoctlMapBufferEx params{}; +    std::memcpy(¶ms, input.data(), sizeof(IoctlMapBufferEx)); +    LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2, +                params.address_1); +    params.address_1 = 0; +    params.address_2 = 0; +    std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBufferEx)); +    return 0; +} + +u32 nvhost_vic::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { +    IoctlUnmapBufferEx params{}; +    std::memcpy(¶ms, input.data(), sizeof(IoctlUnmapBufferEx)); +    LOG_WARNING(Service_NVDRV, "(STUBBED) called"); +    std::memcpy(output.data(), ¶ms, sizeof(IoctlUnmapBufferEx)); +    return 0; +} +  } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h index bec32bea1..a7bb7bbd5 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h @@ -4,6 +4,7 @@  #pragma once +#include <array>  #include <vector>  #include "common/common_types.h"  #include "common/swap.h" @@ -23,6 +24,12 @@ public:  private:      enum class IoctlCommand : u32_le {          IocSetNVMAPfdCommand = 0x40044801, +        IocSubmit = 0xC0400001, +        IocGetSyncpoint = 0xC0080002, +        IocGetWaitbase = 0xC0080003, +        IocMapBuffer = 0xC01C0009, +        IocMapBufferEx = 0xC03C0009, +        IocUnmapBufferEx = 0xC03C000A,      };      struct IoctlSetNvmapFD { @@ -30,9 +37,65 @@ private:      };      static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size"); +    struct IoctlSubmitCommandBuffer { +        u32 id; +        u32 offset; +        u32 count; +    }; +    static_assert(sizeof(IoctlSubmitCommandBuffer) == 0xC, +                  "IoctlSubmitCommandBuffer is incorrect size"); + +    struct IoctlSubmit { +        u32 command_buffer_count; +        u32 relocations_count; +        u32 syncpt_count; +        u32 wait_count; +        std::array<IoctlSubmitCommandBuffer, 4> command_buffer; +    }; +    static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit is incorrect size"); + +    struct IoctlGetSyncpoint { +        u32 unknown; // seems to be ignored? Nintendo added this +        u32 value; +    }; +    static_assert(sizeof(IoctlGetSyncpoint) == 0x8, "IoctlGetSyncpoint is incorrect size"); + +    struct IoctlGetWaitbase { +        u32 unknown; // seems to be ignored? Nintendo added this +        u32 value; +    }; +    static_assert(sizeof(IoctlGetWaitbase) == 0x8, "IoctlGetWaitbase is incorrect size"); + +    struct IoctlMapBuffer { +        u32 unknown; +        u32 address_1; +        u32 address_2; +        INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure +    }; +    static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size"); + +    struct IoctlMapBufferEx { +        u32 unknown; +        u32 address_1; +        u32 address_2; +        INSERT_PADDING_BYTES(0x30); // TODO(DarkLordZach): RE this structure +    }; +    static_assert(sizeof(IoctlMapBufferEx) == 0x3C, "IoctlMapBufferEx is incorrect size"); + +    struct IoctlUnmapBufferEx { +        INSERT_PADDING_BYTES(0x3C); // TODO(DarkLordZach): RE this structure +    }; +    static_assert(sizeof(IoctlUnmapBufferEx) == 0x3C, "IoctlUnmapBufferEx is incorrect size"); +      u32_le nvmap_fd{};      u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output); +    u32 Submit(const std::vector<u8>& input, std::vector<u8>& output); +    u32 GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output); +    u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output); +    u32 MapBuffer(const std::vector<u8>& input, std::vector<u8>& output); +    u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output); +    u32 UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);  };  } // namespace Service::Nvidia::Devices  | 
