mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-23 05:19:18 +01:00
Implement the host side of host1x syncpoints
This will be extended in the future to support interfacing with the GPU.
This commit is contained in:
parent
3c5cc33a34
commit
8dc9a10324
@ -105,6 +105,7 @@ add_library(skyline SHARED
|
|||||||
${source_DIR}/skyline/services/nvdrv/devices/nvhost_ctrl.cpp
|
${source_DIR}/skyline/services/nvdrv/devices/nvhost_ctrl.cpp
|
||||||
${source_DIR}/skyline/services/nvdrv/devices/nvhost_channel.cpp
|
${source_DIR}/skyline/services/nvdrv/devices/nvhost_channel.cpp
|
||||||
${source_DIR}/skyline/services/nvdrv/devices/nvhost_as_gpu.cpp
|
${source_DIR}/skyline/services/nvdrv/devices/nvhost_as_gpu.cpp
|
||||||
|
${source_DIR}/skyline/services/nvdrv/devices/nvhost_syncpoint.cpp
|
||||||
${source_DIR}/skyline/services/hosbinder/IHOSBinderDriver.cpp
|
${source_DIR}/skyline/services/hosbinder/IHOSBinderDriver.cpp
|
||||||
${source_DIR}/skyline/services/visrv/IDisplayService.cpp
|
${source_DIR}/skyline/services/visrv/IDisplayService.cpp
|
||||||
${source_DIR}/skyline/services/visrv/IApplicationDisplayService.cpp
|
${source_DIR}/skyline/services/visrv/IApplicationDisplayService.cpp
|
||||||
|
@ -54,7 +54,7 @@ namespace skyline::service::nvdrv {
|
|||||||
return fdIndex++;
|
return fdIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
INvDrvServices::INvDrvServices(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, Service::nvdrv_INvDrvServices, "INvDrvServices", {
|
INvDrvServices::INvDrvServices(const DeviceState &state, ServiceManager &manager) : hostSyncpoint(state), BaseService(state, manager, Service::nvdrv_INvDrvServices, "INvDrvServices", {
|
||||||
{0x0, SFUNC(INvDrvServices::Open)},
|
{0x0, SFUNC(INvDrvServices::Open)},
|
||||||
{0x1, SFUNC(INvDrvServices::Ioctl)},
|
{0x1, SFUNC(INvDrvServices::Ioctl)},
|
||||||
{0x2, SFUNC(INvDrvServices::Close)},
|
{0x2, SFUNC(INvDrvServices::Close)},
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <kernel/types/KTransferMemory.h>
|
#include <kernel/types/KTransferMemory.h>
|
||||||
#include <gpu.h>
|
#include <gpu.h>
|
||||||
#include "devices/nvdevice.h"
|
#include "devices/nvdevice.h"
|
||||||
|
#include "devices/nvhost_syncpoint.h"
|
||||||
|
|
||||||
namespace skyline::service::nvdrv {
|
namespace skyline::service::nvdrv {
|
||||||
/**
|
/**
|
||||||
@ -43,6 +44,8 @@ namespace skyline::service::nvdrv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
NvHostSyncpoint hostSyncpoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns a particular device with a specific type
|
* @brief Returns a particular device with a specific type
|
||||||
* @tparam objectClass The class of the device to return
|
* @tparam objectClass The class of the device to return
|
||||||
|
25
app/src/main/cpp/skyline/services/nvdrv/devices/nvfence.h
Normal file
25
app/src/main/cpp/skyline/services/nvdrv/devices/nvfence.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include "nvhost_syncpoint.h"
|
||||||
|
|
||||||
|
namespace skyline::service::nvdrv::device {
|
||||||
|
/**
|
||||||
|
* @brief This holds information about a fence
|
||||||
|
*/
|
||||||
|
struct NvFence {
|
||||||
|
u32 id{};
|
||||||
|
u32 value{};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Synchronizes the fence's value with its underlying syncpoint
|
||||||
|
*/
|
||||||
|
static inline void UpdateValue(const NvHostSyncpoint &hostSyncpoint) {
|
||||||
|
//TODO: Implement this
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(sizeof(NvFence) == 0x8);
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
|
#include "nvhost_syncpoint.h"
|
||||||
|
|
||||||
|
namespace skyline::service::nvdrv {
|
||||||
|
NvHostSyncpoint::NvHostSyncpoint(const DeviceState &state) : state(state) {
|
||||||
|
constexpr u32 VBlank0SyncpointId{26};
|
||||||
|
constexpr u32 VBlank1SyncpointId{27};
|
||||||
|
|
||||||
|
// Reserve both vblank syncpoints as client managed since the userspace driver has direct access to them
|
||||||
|
ReserveSyncpoint(VBlank0SyncpointId, true);
|
||||||
|
ReserveSyncpoint(VBlank1SyncpointId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 NvHostSyncpoint::ReserveSyncpoint(u32 id, bool clientManaged) {
|
||||||
|
if (id >= constant::MaxHwSyncpointCount)
|
||||||
|
throw exception("Requested syncpoint ID is too high");
|
||||||
|
|
||||||
|
if (syncpoints.at(id).assigned)
|
||||||
|
throw exception("Requested syncpoint is in use");
|
||||||
|
|
||||||
|
syncpoints.at(id).assigned = true;
|
||||||
|
syncpoints.at(id).clientManaged = clientManaged;
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 NvHostSyncpoint::FindFreeSyncpoint() {
|
||||||
|
for (u32 i = 0; i < constant::MaxHwSyncpointCount; i++)
|
||||||
|
if (!syncpoints[i].assigned)
|
||||||
|
return i;
|
||||||
|
|
||||||
|
throw exception("Failed to find a free syncpoint!");
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 NvHostSyncpoint::AllocateSyncpoint(bool clientManaged) {
|
||||||
|
std::lock_guard lock(reservationLock);
|
||||||
|
return ReserveSyncpoint(FindFreeSyncpoint(), clientManaged);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NvHostSyncpoint::HasSyncpointExpired(u32 id, u32 threshold) {
|
||||||
|
const SyncpointInfo &syncpoint = syncpoints.at(id);
|
||||||
|
|
||||||
|
if (syncpoint.clientManaged)
|
||||||
|
return static_cast<i32>(syncpoint.counterMin - threshold) >= 0;
|
||||||
|
else
|
||||||
|
return (syncpoint.counterMax - threshold) >= (syncpoint.counterMin - threshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 NvHostSyncpoint::IncrementSyncpointMaxExt(u32 id, u32 amount) {
|
||||||
|
return syncpoints.at(id).counterMax += amount;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
namespace skyline {
|
||||||
|
namespace constant {
|
||||||
|
constexpr size_t MaxHwSyncpointCount = 192;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace service::nvdrv {
|
||||||
|
/**
|
||||||
|
* @todo Implement the GPU side of this
|
||||||
|
* @brief NvHostSyncpoint handles allocating and accessing host1x syncpoints
|
||||||
|
* @url https://http.download.nvidia.com/tegra-public-appnotes/host1x.html
|
||||||
|
* @url https://github.com/Jetson-TX1-AndroidTV/android_kernel_jetson_tx1_hdmi_primary/blob/jetson-tx1/drivers/video/tegra/host/nvhost_syncpt.c
|
||||||
|
*/
|
||||||
|
class NvHostSyncpoint {
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @brief This holds information about a single syncpoint
|
||||||
|
*/
|
||||||
|
struct SyncpointInfo {
|
||||||
|
std::atomic<u32> counterMin;
|
||||||
|
std::atomic<u32> counterMax;
|
||||||
|
bool clientManaged;
|
||||||
|
bool assigned;
|
||||||
|
};
|
||||||
|
|
||||||
|
const DeviceState &state;
|
||||||
|
std::array<SyncpointInfo, skyline::constant::MaxHwSyncpointCount> syncpoints{};
|
||||||
|
Mutex reservationLock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @note reservationLock should be locked when calling this
|
||||||
|
*/
|
||||||
|
u32 ReserveSyncpoint(u32 id, bool clientManaged);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The ID of the first free syncpoint
|
||||||
|
*/
|
||||||
|
u32 FindFreeSyncpoint();
|
||||||
|
|
||||||
|
public:
|
||||||
|
NvHostSyncpoint(const DeviceState &state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Finds a free syncpoint and reserves it
|
||||||
|
* @return The ID of the reserved syncpoint
|
||||||
|
*/
|
||||||
|
u32 AllocateSyncpoint(bool clientManaged);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @url https://github.com/Jetson-TX1-AndroidTV/android_kernel_jetson_tx1_hdmi_primary/blob/8f74a72394efb871cb3f886a3de2998cd7ff2990/drivers/gpu/host1x/syncpt.c#L259
|
||||||
|
*/
|
||||||
|
bool HasSyncpointExpired(u32 id, u32 threshold);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Atomically increments the maximum value of a syncpoint by the given amount
|
||||||
|
* @return The new value of the syncpoint
|
||||||
|
*/
|
||||||
|
u32 IncrementSyncpointMaxExt(u32 id, u32 amount);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user