mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-06-18 00:28:45 +02:00
180 lines
5.5 KiB
C++
180 lines
5.5 KiB
C++
// SPDX-License-Identifier: MPL-2.0
|
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
|
|
|
#pragma once
|
|
|
|
#include "engine.h"
|
|
|
|
namespace skyline {
|
|
namespace constant {
|
|
constexpr u32 GpfifoRegisterCount{0x40}; //!< The number of GPFIFO registers
|
|
}
|
|
|
|
namespace gpu::engine {
|
|
/**
|
|
* @brief The GPFIFO engine handles managing macros and semaphores
|
|
* @url https://github.com/NVIDIA/open-gpu-doc/blob/ab27fc22db5de0d02a4cabe08e555663b62db4d4/manuals/volta/gv100/dev_pbdma.ref.txt
|
|
*/
|
|
class GPFIFO : public Engine {
|
|
private:
|
|
/**
|
|
* @url https://github.com/NVIDIA/open-gpu-doc/blob/ab27fc22db5de0d02a4cabe08e555663b62db4d4/classes/host/clb06f.h#L65
|
|
*/
|
|
#pragma pack(push, 1)
|
|
union Registers {
|
|
std::array<u32, constant::GpfifoRegisterCount> raw;
|
|
|
|
enum class SemaphoreOperation : u8 {
|
|
Acquire = 1,
|
|
Release = 2,
|
|
AcqGeq = 4,
|
|
AcqAnd = 8,
|
|
Reduction = 16,
|
|
};
|
|
|
|
enum class SemaphoreAcquireSwitch : u8 {
|
|
Disabled = 0,
|
|
Enabled = 1,
|
|
};
|
|
|
|
enum class SemaphoreReleaseWfi : u8 {
|
|
En = 0,
|
|
Dis = 1,
|
|
};
|
|
|
|
enum class SemaphoreReleaseSize : u8 {
|
|
SixteenBytes = 0,
|
|
FourBytes = 1,
|
|
};
|
|
|
|
enum class SemaphoreReduction : u8 {
|
|
Min = 0,
|
|
Max = 1,
|
|
Xor = 2,
|
|
And = 3,
|
|
Or = 4,
|
|
Add = 5,
|
|
Inc = 6,
|
|
Dec = 7,
|
|
};
|
|
|
|
enum class SemaphoreFormat : u8 {
|
|
Signed = 0,
|
|
Unsigned = 1,
|
|
};
|
|
|
|
enum class MemOpTlbInvalidatePdb : u8 {
|
|
One = 0,
|
|
All = 1,
|
|
};
|
|
|
|
enum class SyncpointOperation : u8 {
|
|
Wait = 0,
|
|
Incr = 1,
|
|
};
|
|
|
|
enum class SyncpointWaitSwitch : u8 {
|
|
Dis = 0,
|
|
En = 1,
|
|
};
|
|
|
|
enum class WfiScope : u8 {
|
|
CurrentScgType = 0,
|
|
All = 1,
|
|
};
|
|
|
|
enum class YieldOp : u8 {
|
|
Nop = 0,
|
|
PbdmaTimeslice = 1,
|
|
RunlistTimeslice = 2,
|
|
Tsg = 3,
|
|
};
|
|
|
|
struct {
|
|
struct {
|
|
u16 nvClass : 16;
|
|
u8 engine : 5;
|
|
u16 _pad_ : 11;
|
|
} setObject;
|
|
|
|
u32 illegal;
|
|
u32 nop;
|
|
u32 _pad0_;
|
|
|
|
struct {
|
|
struct {
|
|
u32 offsetUpper : 8;
|
|
u32 _pad0_ : 24;
|
|
};
|
|
|
|
struct {
|
|
u8 _pad1_ : 2;
|
|
u32 offsetLower : 30;
|
|
};
|
|
|
|
u32 payload;
|
|
|
|
struct {
|
|
SemaphoreOperation operation : 5;
|
|
u8 _pad2_ : 7;
|
|
SemaphoreAcquireSwitch acquireSwitch : 1;
|
|
u8 _pad3_ : 7;
|
|
SemaphoreReleaseWfi releaseWfi : 1;
|
|
u8 _pad4_ : 3;
|
|
SemaphoreReleaseSize releaseSize : 1;
|
|
u8 _pad5_ : 2;
|
|
SemaphoreReduction reduction : 4;
|
|
SemaphoreFormat format : 1;
|
|
};
|
|
} semaphore;
|
|
|
|
u32 nonStallInterrupt;
|
|
u32 fbFlush;
|
|
u32 _pad1_[2];
|
|
u32 memOpC;
|
|
u32 memOpD;
|
|
u32 _pad2_[6];
|
|
u32 setReference;
|
|
u32 _pad3_[7];
|
|
|
|
struct {
|
|
u32 payload;
|
|
|
|
struct {
|
|
SyncpointOperation operation : 1;
|
|
u8 _pad0_ : 3;
|
|
SyncpointWaitSwitch waitSwitch : 1;
|
|
u8 _pad1_ : 3;
|
|
u16 index : 12;
|
|
u16 _pad2_ : 12;
|
|
};
|
|
} syncpoint;
|
|
|
|
struct {
|
|
WfiScope scope : 1;
|
|
u32 _pad_ : 31;
|
|
} wfi;
|
|
|
|
u32 crcCheck;
|
|
|
|
struct {
|
|
YieldOp op : 2;
|
|
u32 _pad_ : 30;
|
|
} yield;
|
|
};
|
|
} registers{};
|
|
static_assert(sizeof(Registers) == (constant::GpfifoRegisterCount * sizeof(u32)));
|
|
#pragma pack(pop)
|
|
|
|
public:
|
|
GPFIFO(const DeviceState &state) : Engine(state) {}
|
|
|
|
void CallMethod(MethodParams params) override {
|
|
state.logger->Debug("Called method in GPFIFO: 0x{:X} args: 0x{:X}", params.method, params.argument);
|
|
|
|
registers.raw[params.method] = params.argument;
|
|
};
|
|
};
|
|
}
|
|
}
|