mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-05 07:25:08 +01:00
Unify engine related macros to avoid excessive code duplication
This commit is contained in:
parent
ae41ddf4f0
commit
82d2a9ab56
@ -6,65 +6,87 @@
|
|||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <soc/gm20b/macro/macro_state.h>
|
#include <soc/gm20b/macro/macro_state.h>
|
||||||
|
|
||||||
namespace skyline::soc::gm20b {
|
#define U32_OFFSET(regs, field) (offsetof(regs, field) / sizeof(u32))
|
||||||
#define U32_OFFSET(regs, field) (offsetof(regs, field) / sizeof(u32))
|
#define ENGINE_OFFSET(field) (sizeof(typeof(Registers::field)) - sizeof(std::remove_reference_t<decltype(*Registers::field)>)) / sizeof(u32)
|
||||||
|
#define ENGINE_STRUCT_OFFSET(field, member) ENGINE_OFFSET(field) + U32_OFFSET(std::remove_reference_t<decltype(*Registers::field)>, member)
|
||||||
|
#define ENGINE_STRUCT_STRUCT_OFFSET(field, member, submember) ENGINE_STRUCT_OFFSET(field, member) + U32_OFFSET(std::remove_reference_t<decltype(Registers::field->member)>, submember)
|
||||||
|
#define ENGINE_STRUCT_ARRAY_OFFSET(field, member, index) ENGINE_STRUCT_OFFSET(field, member) + ((sizeof(std::remove_reference_t<decltype(Registers::field->member[0])>) / sizeof(u32)) * index)
|
||||||
|
#define ENGINE_ARRAY_OFFSET(field, index) ENGINE_OFFSET(field) + ((sizeof(std::remove_reference_t<decltype(Registers::field[0])>) / sizeof(u32)) * index)
|
||||||
|
#define ENGINE_ARRAY_STRUCT_OFFSET(field, index, member) ENGINE_ARRAY_OFFSET(field, index) + U32_OFFSET(std::remove_reference_t<decltype(Registers::field[0])>, member)
|
||||||
|
#define ENGINE_ARRAY_STRUCT_STRUCT_OFFSET(field, index, member, submember) ENGINE_ARRAY_STRUCT_OFFSET(field, index, member) + U32_OFFSET(decltype(Registers::field[0].member), submember)
|
||||||
|
|
||||||
namespace engine {
|
#define ENGINE_CASE(field, content) case ENGINE_OFFSET(field): { \
|
||||||
/**
|
auto field{util::BitCast<std::remove_reference_t<decltype(*registers.field)>>(argument)}; \
|
||||||
* @brief A 40-bit GMMU virtual address with register-packing
|
content \
|
||||||
* @note The registers pack the address with big-endian ordering (but with 32 bit words)
|
return; \
|
||||||
*/
|
|
||||||
struct Address {
|
|
||||||
u32 high;
|
|
||||||
u32 low;
|
|
||||||
|
|
||||||
operator u64() {
|
|
||||||
return (static_cast<u64>(high) << 32) | low;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
static_assert(sizeof(Address) == sizeof(u64));
|
|
||||||
|
|
||||||
constexpr u32 EngineMethodsEnd = 0xE00; //!< All methods above this are passed to the MME on supported engines
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The MacroEngineBase interface provides an interface that can be used by engines to allow interfacing with the macro executer
|
|
||||||
*/
|
|
||||||
struct MacroEngineBase {
|
|
||||||
MacroState ¯oState;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
size_t index{std::numeric_limits<size_t>::max()};
|
|
||||||
std::vector<u32> arguments;
|
|
||||||
|
|
||||||
bool Valid() {
|
|
||||||
return index != std::numeric_limits<size_t>::max();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reset() {
|
|
||||||
index = std::numeric_limits<size_t>::max();
|
|
||||||
arguments.clear();
|
|
||||||
}
|
|
||||||
} macroInvocation{}; //!< Data for a macro that is pending execution
|
|
||||||
|
|
||||||
MacroEngineBase(MacroState ¯oState);
|
|
||||||
|
|
||||||
virtual ~MacroEngineBase() = default;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Calls an engine method with the given parameters
|
|
||||||
*/
|
|
||||||
virtual void CallMethodFromMacro(u32 method, u32 argument) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Reads the current value for the supplied method
|
|
||||||
*/
|
|
||||||
virtual u32 ReadMethodFromMacro(u32 method) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Handles a call to a method in the MME space
|
|
||||||
* @param macroMethodOffset The target offset from EngineMethodsEnd
|
|
||||||
*/
|
|
||||||
void HandleMacroCall(u32 macroMethodOffset, u32 value, bool lastCall);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
#define ENGINE_CASE_BASE(fieldName, fieldAccessor, offset, content) case offset: { \
|
||||||
|
auto fieldName{util::BitCast<std::remove_reference_t<decltype(registers.fieldAccessor)>>(argument)}; \
|
||||||
|
content \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
#define ENGINE_STRUCT_CASE(field, member, content) ENGINE_CASE_BASE(member, field->member, ENGINE_STRUCT_OFFSET(field, member), content)
|
||||||
|
#define ENGINE_STRUCT_STRUCT_CASE(field, member, submember, content) ENGINE_CASE_BASE(submember, field->member.submember, ENGINE_STRUCT_STRUCT_OFFSET(field, member, submember), content)
|
||||||
|
#define ENGINE_STRUCT_ARRAY_CASE(field, member, index, content) ENGINE_CASE_BASE(member, field->member[index], ENGINE_STRUCT_ARRAY_OFFSET(field, member, index), content)
|
||||||
|
#define ENGINE_ARRAY_CASE(field, index, content) ENGINE_CASE_BASE(field, field[index], ENGINE_ARRAY_OFFSET(field, index), content)
|
||||||
|
#define ENGINE_ARRAY_STRUCT_CASE(field, index, member, content) ENGINE_CASE_BASE(member, field[index].member, ENGINE_ARRAY_STRUCT_OFFSET(field, index, member), content)
|
||||||
|
#define ENGINE_ARRAY_STRUCT_STRUCT_CASE(field, index, member, submember, content) ENGINE_CASE_BASE(submember, field[index].member.submember, ENGINE_ARRAY_STRUCT_STRUCT_OFFSET(field, index, member, submember), content)
|
||||||
|
|
||||||
|
namespace skyline::soc::gm20b::engine {
|
||||||
|
/**
|
||||||
|
* @brief A 40-bit GMMU virtual address with register-packing
|
||||||
|
* @note The registers pack the address with big-endian ordering (but with 32 bit words)
|
||||||
|
*/
|
||||||
|
struct Address {
|
||||||
|
u32 high;
|
||||||
|
u32 low;
|
||||||
|
|
||||||
|
operator u64() {
|
||||||
|
return (static_cast<u64>(high) << 32) | low;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Address) == sizeof(u64));
|
||||||
|
|
||||||
|
constexpr u32 EngineMethodsEnd = 0xE00; //!< All methods above this are passed to the MME on supported engines
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The MacroEngineBase interface provides an interface that can be used by engines to allow interfacing with the macro executer
|
||||||
|
*/
|
||||||
|
struct MacroEngineBase {
|
||||||
|
MacroState ¯oState;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
size_t index{std::numeric_limits<size_t>::max()};
|
||||||
|
std::vector<u32> arguments;
|
||||||
|
|
||||||
|
bool Valid() {
|
||||||
|
return index != std::numeric_limits<size_t>::max();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset() {
|
||||||
|
index = std::numeric_limits<size_t>::max();
|
||||||
|
arguments.clear();
|
||||||
|
}
|
||||||
|
} macroInvocation{}; //!< Data for a macro that is pending execution
|
||||||
|
|
||||||
|
MacroEngineBase(MacroState ¯oState);
|
||||||
|
|
||||||
|
virtual ~MacroEngineBase() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Calls an engine method with the given parameters
|
||||||
|
*/
|
||||||
|
virtual void CallMethodFromMacro(u32 method, u32 argument) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads the current value for the supplied method
|
||||||
|
*/
|
||||||
|
virtual u32 ReadMethodFromMacro(u32 method) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Handles a call to a method in the MME space
|
||||||
|
* @param macroMethodOffset The target offset from EngineMethodsEnd
|
||||||
|
*/
|
||||||
|
void HandleMacroCall(u32 macroMethodOffset, u32 value, bool lastCall);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -13,36 +13,19 @@ namespace skyline::soc::gm20b::engine {
|
|||||||
|
|
||||||
registers.raw[method] = argument;
|
registers.raw[method] = argument;
|
||||||
|
|
||||||
#define GPFIFO_OFFSET(field) U32_OFFSET(Registers, field)
|
|
||||||
#define GPFIFO_STRUCT_OFFSET(field, member) GPFIFO_OFFSET(field) + U32_OFFSET(decltype(Registers::field), member)
|
|
||||||
|
|
||||||
#define GPFIFO_CASE_BASE(fieldName, fieldAccessor, offset, content) case offset: { \
|
|
||||||
auto fieldName{util::BitCast<decltype(registers.fieldAccessor)>(argument)}; \
|
|
||||||
content \
|
|
||||||
return; \
|
|
||||||
}
|
|
||||||
#define GPFIFO_CASE(field, content) GPFIFO_CASE_BASE(field, field, GPFIFO_OFFSET(field), content)
|
|
||||||
#define GPFIFO_STRUCT_CASE(field, member, content) GPFIFO_CASE_BASE(member, field.member, GPFIFO_STRUCT_OFFSET(field, member), content)
|
|
||||||
|
|
||||||
switch (method) {
|
switch (method) {
|
||||||
GPFIFO_STRUCT_CASE(syncpoint, action, {
|
ENGINE_STRUCT_CASE(syncpoint, action, {
|
||||||
if (action.operation == Registers::SyncpointOperation::Incr) {
|
if (action.operation == Registers::Syncpoint::Operation::Incr) {
|
||||||
Logger::Debug("Increment syncpoint: {}", +action.index);
|
Logger::Debug("Increment syncpoint: {}", +action.index);
|
||||||
channelCtx.executor.Execute();
|
channelCtx.executor.Execute();
|
||||||
syncpoints.at(action.index).Increment();
|
syncpoints.at(action.index).Increment();
|
||||||
} else if (action.operation == Registers::SyncpointOperation::Wait) {
|
} else if (action.operation == Registers::Syncpoint::Operation::Wait) {
|
||||||
Logger::Debug("Wait syncpoint: {}, thresh: {}", +action.index, registers.syncpoint.payload);
|
Logger::Debug("Wait syncpoint: {}, thresh: {}", +action.index, registers.syncpoint->payload);
|
||||||
|
|
||||||
// Wait forever for another channel to increment
|
// Wait forever for another channel to increment
|
||||||
syncpoints.at(action.index).Wait(registers.syncpoint.payload, std::chrono::steady_clock::duration::max());
|
syncpoints.at(action.index).Wait(registers.syncpoint->payload, std::chrono::steady_clock::duration::max());
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef GPFIFO_STRUCT_CASE
|
|
||||||
#undef GPFIFO_CASE
|
|
||||||
#undef GPFIFO_CASE_BASE
|
|
||||||
#undef GPFIFO_STRUCT_OFFSET
|
|
||||||
#undef GPFIFO_OFFSET
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -26,144 +26,153 @@ namespace skyline::soc::gm20b::engine {
|
|||||||
union Registers {
|
union Registers {
|
||||||
std::array<u32, RegisterCount> raw;
|
std::array<u32, RegisterCount> raw;
|
||||||
|
|
||||||
enum class SemaphoreOperation : u8 {
|
template<size_t Offset, typename Type>
|
||||||
Acquire = 1,
|
using Register = util::OffsetMember<Offset, Type, u32>;
|
||||||
Release = 2,
|
|
||||||
AcqGeq = 4,
|
struct SetObject {
|
||||||
AcqAnd = 8,
|
u16 nvClass : 16;
|
||||||
Reduction = 16,
|
u8 engine : 5;
|
||||||
|
u16 _pad_ : 11;
|
||||||
};
|
};
|
||||||
|
static_assert(sizeof(SetObject) == 0x4);
|
||||||
|
|
||||||
enum class SemaphoreAcquireSwitch : u8 {
|
Register<0x0, SetObject> setObject;
|
||||||
Disabled = 0,
|
|
||||||
Enabled = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class SemaphoreReleaseWfi : u8 {
|
Register<0x1, u32> illegal;
|
||||||
En = 0,
|
Register<0x1, u32> nop;
|
||||||
Dis = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class SemaphoreReleaseSize : u8 {
|
struct Semaphore {
|
||||||
SixteenBytes = 0,
|
enum class Operation : u8 {
|
||||||
FourBytes = 1,
|
Acquire = 1,
|
||||||
};
|
Release = 2,
|
||||||
|
AcqGeq = 4,
|
||||||
|
AcqAnd = 8,
|
||||||
|
Reduction = 16,
|
||||||
|
};
|
||||||
|
|
||||||
enum class SemaphoreReduction : u8 {
|
enum class AcquireSwitch : u8 {
|
||||||
Min = 0,
|
Disabled = 0,
|
||||||
Max = 1,
|
Enabled = 1,
|
||||||
Xor = 2,
|
};
|
||||||
And = 3,
|
|
||||||
Or = 4,
|
|
||||||
Add = 5,
|
|
||||||
Inc = 6,
|
|
||||||
Dec = 7,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class SemaphoreFormat : u8 {
|
enum class ReleaseWfi : u8 {
|
||||||
Signed = 0,
|
En = 0,
|
||||||
Unsigned = 1,
|
Dis = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class MemOpTlbInvalidatePdb : u8 {
|
enum class ReleaseSize : u8 {
|
||||||
One = 0,
|
SixteenBytes = 0,
|
||||||
All = 1,
|
FourBytes = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SyncpointOperation : u8 {
|
enum class Reduction : u8 {
|
||||||
Wait = 0,
|
Min = 0,
|
||||||
Incr = 1,
|
Max = 1,
|
||||||
};
|
Xor = 2,
|
||||||
|
And = 3,
|
||||||
|
Or = 4,
|
||||||
|
Add = 5,
|
||||||
|
Inc = 6,
|
||||||
|
Dec = 7,
|
||||||
|
};
|
||||||
|
|
||||||
enum class SyncpointWaitSwitch : u8 {
|
enum class Format : u8 {
|
||||||
Dis = 0,
|
Signed = 0,
|
||||||
En = 1,
|
Unsigned = 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; // 0x0
|
|
||||||
|
|
||||||
u32 illegal; // 0x1
|
|
||||||
u32 nop; // 0x2
|
|
||||||
u32 _pad0_; // 0x3
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct {
|
u32 offsetUpper : 8;
|
||||||
u32 offsetUpper : 8;
|
u32 _pad0_ : 24;
|
||||||
u32 _pad0_ : 24;
|
}; // 0x4
|
||||||
}; // 0x4
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u8 _pad1_ : 2;
|
|
||||||
u32 offsetLower : 30;
|
|
||||||
}; // 0x5
|
|
||||||
|
|
||||||
u32 payload; // 0x6
|
|
||||||
|
|
||||||
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;
|
|
||||||
}; // 0x7
|
|
||||||
} semaphore;
|
|
||||||
|
|
||||||
u32 nonStallInterrupt; // 0x8
|
|
||||||
u32 fbFlush; // 0x9
|
|
||||||
u32 _pad1_[2]; // 0xA
|
|
||||||
u32 memOpC; // 0xC
|
|
||||||
u32 memOpD; // 0xD
|
|
||||||
u32 _pad2_[6]; // 0xE
|
|
||||||
u32 setReference; // 0x14
|
|
||||||
u32 _pad3_[7]; // 0x15
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u32 payload; // 0x1C
|
u8 _pad1_ : 2;
|
||||||
|
u32 offsetLower : 30;
|
||||||
|
}; // 0x5
|
||||||
|
|
||||||
struct {
|
u32 payload; // 0x6
|
||||||
SyncpointOperation operation : 1;
|
|
||||||
u8 _pad0_ : 3;
|
|
||||||
SyncpointWaitSwitch waitSwitch : 1; //!< If the PBDMA unit can switch to a different timeslice group (TSG) while waiting on a syncpoint
|
|
||||||
u8 _pad1_ : 3;
|
|
||||||
u16 index : 12;
|
|
||||||
u16 _pad2_ : 12;
|
|
||||||
} action; // 0x1D
|
|
||||||
} syncpoint;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
WfiScope scope : 1;
|
Operation operation : 5;
|
||||||
u32 _pad_ : 31;
|
u8 _pad2_ : 7;
|
||||||
} wfi; // 0x1E
|
AcquireSwitch acquireSwitch : 1;
|
||||||
|
u8 _pad3_ : 7;
|
||||||
u32 crcCheck; // 0x1F
|
ReleaseWfi releaseWfi : 1;
|
||||||
|
u8 _pad4_ : 3;
|
||||||
struct {
|
ReleaseSize releaseSize : 1;
|
||||||
YieldOp op : 2;
|
u8 _pad5_ : 2;
|
||||||
u32 _pad_ : 30;
|
Reduction reduction : 4;
|
||||||
} yield; // 0x20
|
Format format : 1;
|
||||||
|
}; // 0x7
|
||||||
};
|
};
|
||||||
|
static_assert(sizeof(Semaphore) == 0x10);
|
||||||
|
|
||||||
|
Register<0x4, Semaphore> semaphore;
|
||||||
|
|
||||||
|
Register<0x8, u32> nonStallInterrupt;
|
||||||
|
Register<0x9, u32> fbFlush;
|
||||||
|
|
||||||
|
Register<0xC, u32> memOpC;
|
||||||
|
Register<0xD, u32> memOpD;
|
||||||
|
|
||||||
|
Register<0x14, u32> setReference;
|
||||||
|
|
||||||
|
struct Syncpoint {
|
||||||
|
enum class Operation : u8 {
|
||||||
|
Wait = 0,
|
||||||
|
Incr = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class WaitSwitch : u8 {
|
||||||
|
Dis = 0,
|
||||||
|
En = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
u32 payload; // 0x1C
|
||||||
|
|
||||||
|
struct {
|
||||||
|
Operation operation : 1;
|
||||||
|
u8 _pad0_ : 3;
|
||||||
|
WaitSwitch waitSwitch : 1; //!< If the PBDMA unit can switch to a different timeslice group (TSG) while waiting on a syncpoint
|
||||||
|
u8 _pad1_ : 3;
|
||||||
|
u16 index : 12;
|
||||||
|
u16 _pad2_ : 12;
|
||||||
|
} action; // 0x1D
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Syncpoint) == 0x8);
|
||||||
|
|
||||||
|
Register<0x1C, Syncpoint> syncpoint;
|
||||||
|
|
||||||
|
struct Wfi {
|
||||||
|
enum class Scope : u8 {
|
||||||
|
CurrentScgType = 0,
|
||||||
|
All = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
Scope scope : 1;
|
||||||
|
u32 _pad_ : 31;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Wfi) == 0x4);
|
||||||
|
|
||||||
|
Register<0x1E, Wfi> wfi;
|
||||||
|
|
||||||
|
Register<0x1F, u32> crcCheck;
|
||||||
|
|
||||||
|
struct Yield {
|
||||||
|
enum class Op : u8 {
|
||||||
|
Nop = 0,
|
||||||
|
PbdmaTimeslice = 1,
|
||||||
|
RunlistTimeslice = 2,
|
||||||
|
Tsg = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
Op op : 2;
|
||||||
|
u32 _pad_ : 30;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Yield) == 0x4);
|
||||||
|
|
||||||
|
Register<0x20, Yield> yield;
|
||||||
} registers{};
|
} registers{};
|
||||||
static_assert(sizeof(Registers) == (RegisterCount * sizeof(u32)));
|
static_assert(sizeof(Registers) == (RegisterCount * sizeof(u32)));
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
@ -55,19 +55,16 @@ namespace skyline::soc::gm20b::engine {
|
|||||||
HandleMethod(method, argument);
|
HandleMethod(method, argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INLINE2MEMORY_OFFSET(field) (sizeof(typeof(Registers::field)) - sizeof(std::remove_reference_t<decltype(*Registers::field)>)) / sizeof(u32)
|
|
||||||
#define INLINE2MEMORY_STRUCT_OFFSET(field, member) INLINE2MEMORY_OFFSET(field) + U32_OFFSET(std::remove_reference_t<decltype(*Registers::field)>, member)
|
|
||||||
|
|
||||||
void Inline2Memory::HandleMethod(u32 method, u32 argument) {
|
void Inline2Memory::HandleMethod(u32 method, u32 argument) {
|
||||||
registers.raw[method] = argument;
|
registers.raw[method] = argument;
|
||||||
|
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case INLINE2MEMORY_STRUCT_OFFSET(i2m, launchDma):
|
ENGINE_STRUCT_CASE(i2m, launchDma, {
|
||||||
backend.LaunchDma(*registers.i2m);
|
backend.LaunchDma(*registers.i2m);
|
||||||
return;
|
})
|
||||||
case INLINE2MEMORY_STRUCT_OFFSET(i2m, loadInlineData):
|
ENGINE_STRUCT_CASE(i2m, loadInlineData, {
|
||||||
backend.LoadInlineData(*registers.i2m, argument);
|
backend.LoadInlineData(*registers.i2m, argument);
|
||||||
return;
|
})
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -76,7 +73,7 @@ namespace skyline::soc::gm20b::engine {
|
|||||||
|
|
||||||
void Inline2Memory::CallMethodBatchNonInc(u32 method, span<u32> arguments) {
|
void Inline2Memory::CallMethodBatchNonInc(u32 method, span<u32> arguments) {
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case INLINE2MEMORY_STRUCT_OFFSET(i2m, loadInlineData):
|
case ENGINE_STRUCT_OFFSET(i2m, loadInlineData):
|
||||||
backend.LoadInlineData(*registers.i2m, arguments);
|
backend.LoadInlineData(*registers.i2m, arguments);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
@ -86,7 +83,4 @@ namespace skyline::soc::gm20b::engine {
|
|||||||
for (u32 argument : arguments)
|
for (u32 argument : arguments)
|
||||||
HandleMethod(method, argument);
|
HandleMethod(method, argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef INLINE2MEMORY_STRUCT_OFFSET
|
|
||||||
#undef INLINE2MEMORY_OFFSET
|
|
||||||
}
|
}
|
||||||
|
@ -16,34 +16,30 @@ namespace skyline::soc::gm20b::engine {
|
|||||||
HandleMethod(method, argument);
|
HandleMethod(method, argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define KEPLER_COMPUTE_OFFSET(field) (sizeof(typeof(Registers::field)) - sizeof(std::remove_reference_t<decltype(*Registers::field)>)) / sizeof(u32)
|
|
||||||
#define KEPLER_COMPUTE_STRUCT_OFFSET(field, member) KEPLER_COMPUTE_OFFSET(field) + U32_OFFSET(std::remove_reference_t<decltype(*Registers::field)>, member)
|
|
||||||
|
|
||||||
void KeplerCompute::HandleMethod(u32 method, u32 argument) {
|
void KeplerCompute::HandleMethod(u32 method, u32 argument) {
|
||||||
registers.raw[method] = argument;
|
registers.raw[method] = argument;
|
||||||
|
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case KEPLER_COMPUTE_STRUCT_OFFSET(i2m, launchDma):
|
ENGINE_STRUCT_CASE(i2m, launchDma, {
|
||||||
i2m.LaunchDma(*registers.i2m);
|
i2m.LaunchDma(*registers.i2m);
|
||||||
return;
|
})
|
||||||
case KEPLER_COMPUTE_STRUCT_OFFSET(i2m, loadInlineData):
|
ENGINE_STRUCT_CASE(i2m, loadInlineData, {
|
||||||
i2m.LoadInlineData(*registers.i2m, argument);
|
i2m.LoadInlineData(*registers.i2m, argument);
|
||||||
return;
|
})
|
||||||
case KEPLER_COMPUTE_OFFSET(sendSignalingPcasB):
|
ENGINE_CASE(sendSignalingPcasB, {
|
||||||
Logger::Warn("Attempted to execute compute kernel!");
|
Logger::Warn("Attempted to execute compute kernel!");
|
||||||
return;
|
})
|
||||||
case KEPLER_COMPUTE_STRUCT_OFFSET(reportSemaphore, action):
|
ENGINE_STRUCT_CASE(reportSemaphore, action, {
|
||||||
throw exception("Compute semaphores are unimplemented!");
|
throw exception("Compute semaphores are unimplemented!");
|
||||||
return;
|
})
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeplerCompute::CallMethodBatchNonInc(u32 method, span<u32> arguments) {
|
void KeplerCompute::CallMethodBatchNonInc(u32 method, span<u32> arguments) {
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case KEPLER_COMPUTE_STRUCT_OFFSET(i2m, loadInlineData):
|
case ENGINE_STRUCT_OFFSET(i2m, loadInlineData):
|
||||||
i2m.LoadInlineData(*registers.i2m, arguments);
|
i2m.LoadInlineData(*registers.i2m, arguments);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
@ -53,7 +49,4 @@ namespace skyline::soc::gm20b::engine {
|
|||||||
for (u32 argument : arguments)
|
for (u32 argument : arguments)
|
||||||
HandleMethod(method, argument);
|
HandleMethod(method, argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef KEPLER_COMPUTE_STRUCT_OFFSET
|
|
||||||
#undef KEPLER_COMPUTE_OFFSET
|
|
||||||
}
|
}
|
||||||
|
@ -30,33 +30,8 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
HandleMethod(method, argument);
|
HandleMethod(method, argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAXWELL3D_OFFSET(field) (sizeof(typeof(Registers::field)) - sizeof(std::remove_reference_t<decltype(*Registers::field)>)) / sizeof(u32)
|
|
||||||
#define MAXWELL3D_STRUCT_OFFSET(field, member) MAXWELL3D_OFFSET(field) + U32_OFFSET(std::remove_reference_t<decltype(*Registers::field)>, member)
|
|
||||||
#define MAXWELL3D_STRUCT_STRUCT_OFFSET(field, member, submember) MAXWELL3D_STRUCT_OFFSET(field, member) + U32_OFFSET(std::remove_reference_t<decltype(Registers::field->member)>, submember)
|
|
||||||
#define MAXWELL3D_STRUCT_ARRAY_OFFSET(field, member, index) MAXWELL3D_STRUCT_OFFSET(field, member) + ((sizeof(std::remove_reference_t<decltype(Registers::field->member[0])>) / sizeof(u32)) * index)
|
|
||||||
#define MAXWELL3D_ARRAY_OFFSET(field, index) MAXWELL3D_OFFSET(field) + ((sizeof(std::remove_reference_t<decltype(Registers::field[0])>) / sizeof(u32)) * index)
|
|
||||||
#define MAXWELL3D_ARRAY_STRUCT_OFFSET(field, index, member) MAXWELL3D_ARRAY_OFFSET(field, index) + U32_OFFSET(std::remove_reference_t<decltype(Registers::field[0])>, member)
|
|
||||||
#define MAXWELL3D_ARRAY_STRUCT_STRUCT_OFFSET(field, index, member, submember) MAXWELL3D_ARRAY_STRUCT_OFFSET(field, index, member) + U32_OFFSET(decltype(Registers::field[0].member), submember)
|
|
||||||
|
|
||||||
void Maxwell3D::HandleMethod(u32 method, u32 argument) {
|
void Maxwell3D::HandleMethod(u32 method, u32 argument) {
|
||||||
#define MAXWELL3D_CASE(field, content) case MAXWELL3D_OFFSET(field): { \
|
if (method != ENGINE_STRUCT_OFFSET(mme, shadowRamControl)) {
|
||||||
auto field{util::BitCast<std::remove_reference_t<decltype(*registers.field)>>(argument)}; \
|
|
||||||
content \
|
|
||||||
return; \
|
|
||||||
}
|
|
||||||
#define MAXWELL3D_CASE_BASE(fieldName, fieldAccessor, offset, content) case offset: { \
|
|
||||||
auto fieldName{util::BitCast<std::remove_reference_t<decltype(registers.fieldAccessor)>>(argument)}; \
|
|
||||||
content \
|
|
||||||
return; \
|
|
||||||
}
|
|
||||||
#define MAXWELL3D_STRUCT_CASE(field, member, content) MAXWELL3D_CASE_BASE(member, field->member, MAXWELL3D_STRUCT_OFFSET(field, member), content)
|
|
||||||
#define MAXWELL3D_STRUCT_STRUCT_CASE(field, member, submember, content) MAXWELL3D_CASE_BASE(submember, field->member.submember, MAXWELL3D_STRUCT_STRUCT_OFFSET(field, member, submember), content)
|
|
||||||
#define MAXWELL3D_STRUCT_ARRAY_CASE(field, member, index, content) MAXWELL3D_CASE_BASE(member, field->member[index], MAXWELL3D_STRUCT_ARRAY_OFFSET(field, member, index), content)
|
|
||||||
#define MAXWELL3D_ARRAY_CASE(field, index, content) MAXWELL3D_CASE_BASE(field, field[index], MAXWELL3D_ARRAY_OFFSET(field, index), content)
|
|
||||||
#define MAXWELL3D_ARRAY_STRUCT_CASE(field, index, member, content) MAXWELL3D_CASE_BASE(member, field[index].member, MAXWELL3D_ARRAY_STRUCT_OFFSET(field, index, member), content)
|
|
||||||
#define MAXWELL3D_ARRAY_STRUCT_STRUCT_CASE(field, index, member, submember, content) MAXWELL3D_CASE_BASE(submember, field[index].member.submember, MAXWELL3D_ARRAY_STRUCT_STRUCT_OFFSET(field, index, member, submember), content)
|
|
||||||
|
|
||||||
if (method != MAXWELL3D_STRUCT_OFFSET(mme, shadowRamControl)) {
|
|
||||||
if (shadowRegisters.mme->shadowRamControl == type::MmeShadowRamControl::MethodTrack || shadowRegisters.mme->shadowRamControl == type::MmeShadowRamControl::MethodTrackWithFilter)
|
if (shadowRegisters.mme->shadowRamControl == type::MmeShadowRamControl::MethodTrack || shadowRegisters.mme->shadowRamControl == type::MmeShadowRamControl::MethodTrackWithFilter)
|
||||||
shadowRegisters.raw[method] = argument;
|
shadowRegisters.raw[method] = argument;
|
||||||
else if (shadowRegisters.mme->shadowRamControl == type::MmeShadowRamControl::MethodReplay)
|
else if (shadowRegisters.mme->shadowRamControl == type::MmeShadowRamControl::MethodReplay)
|
||||||
@ -68,36 +43,36 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
|
|
||||||
if (!redundant) {
|
if (!redundant) {
|
||||||
switch (method) {
|
switch (method) {
|
||||||
MAXWELL3D_STRUCT_CASE(mme, shadowRamControl, {
|
ENGINE_STRUCT_CASE(mme, shadowRamControl, {
|
||||||
shadowRegisters.mme->shadowRamControl = shadowRamControl;
|
shadowRegisters.mme->shadowRamControl = shadowRamControl;
|
||||||
})
|
})
|
||||||
|
|
||||||
#define RENDER_TARGET_ARRAY(z, index, data) \
|
#define RENDER_TARGET_ARRAY(z, index, data) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_STRUCT_CASE(renderTargets, index, address, high, { \
|
ENGINE_ARRAY_STRUCT_STRUCT_CASE(renderTargets, index, address, high, { \
|
||||||
context.SetColorRenderTargetAddressHigh(index, high); \
|
context.SetColorRenderTargetAddressHigh(index, high); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_STRUCT_CASE(renderTargets, index, address, low, { \
|
ENGINE_ARRAY_STRUCT_STRUCT_CASE(renderTargets, index, address, low, { \
|
||||||
context.SetColorRenderTargetAddressLow(index, low); \
|
context.SetColorRenderTargetAddressLow(index, low); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(renderTargets, index, width, { \
|
ENGINE_ARRAY_STRUCT_CASE(renderTargets, index, width, { \
|
||||||
context.SetColorRenderTargetWidth(index, width); \
|
context.SetColorRenderTargetWidth(index, width); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(renderTargets, index, height, { \
|
ENGINE_ARRAY_STRUCT_CASE(renderTargets, index, height, { \
|
||||||
context.SetColorRenderTargetHeight(index, height); \
|
context.SetColorRenderTargetHeight(index, height); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(renderTargets, index, format, { \
|
ENGINE_ARRAY_STRUCT_CASE(renderTargets, index, format, { \
|
||||||
context.SetColorRenderTargetFormat(index, format); \
|
context.SetColorRenderTargetFormat(index, format); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(renderTargets, index, tileMode, { \
|
ENGINE_ARRAY_STRUCT_CASE(renderTargets, index, tileMode, { \
|
||||||
context.SetColorRenderTargetTileMode(index, tileMode); \
|
context.SetColorRenderTargetTileMode(index, tileMode); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(renderTargets, index, arrayMode, { \
|
ENGINE_ARRAY_STRUCT_CASE(renderTargets, index, arrayMode, { \
|
||||||
context.SetColorRenderTargetArrayMode(index, arrayMode); \
|
context.SetColorRenderTargetArrayMode(index, arrayMode); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(renderTargets, index, layerStrideLsr2, { \
|
ENGINE_ARRAY_STRUCT_CASE(renderTargets, index, layerStrideLsr2, { \
|
||||||
context.SetColorRenderTargetLayerStride(index, layerStrideLsr2); \
|
context.SetColorRenderTargetLayerStride(index, layerStrideLsr2); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(renderTargets, index, baseLayer, { \
|
ENGINE_ARRAY_STRUCT_CASE(renderTargets, index, baseLayer, { \
|
||||||
context.SetColorRenderTargetBaseLayer(index, baseLayer); \
|
context.SetColorRenderTargetBaseLayer(index, baseLayer); \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -105,54 +80,54 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
static_assert(type::RenderTargetCount == 8 && type::RenderTargetCount < BOOST_PP_LIMIT_REPEAT);
|
static_assert(type::RenderTargetCount == 8 && type::RenderTargetCount < BOOST_PP_LIMIT_REPEAT);
|
||||||
#undef RENDER_TARGET_ARRAY
|
#undef RENDER_TARGET_ARRAY
|
||||||
|
|
||||||
MAXWELL3D_CASE(depthTargetEnable, {
|
ENGINE_CASE(depthTargetEnable, {
|
||||||
context.SetDepthRenderTargetEnabled(depthTargetEnable);
|
context.SetDepthRenderTargetEnabled(depthTargetEnable);
|
||||||
})
|
})
|
||||||
MAXWELL3D_STRUCT_CASE(depthTargetAddress, high, {
|
ENGINE_STRUCT_CASE(depthTargetAddress, high, {
|
||||||
context.SetDepthRenderTargetAddressHigh(high);
|
context.SetDepthRenderTargetAddressHigh(high);
|
||||||
})
|
})
|
||||||
MAXWELL3D_STRUCT_CASE(depthTargetAddress, low, {
|
ENGINE_STRUCT_CASE(depthTargetAddress, low, {
|
||||||
context.SetDepthRenderTargetAddressLow(low);
|
context.SetDepthRenderTargetAddressLow(low);
|
||||||
})
|
})
|
||||||
MAXWELL3D_CASE(depthTargetFormat, {
|
ENGINE_CASE(depthTargetFormat, {
|
||||||
context.SetDepthRenderTargetFormat(depthTargetFormat);
|
context.SetDepthRenderTargetFormat(depthTargetFormat);
|
||||||
})
|
})
|
||||||
MAXWELL3D_CASE(depthTargetTileMode, {
|
ENGINE_CASE(depthTargetTileMode, {
|
||||||
context.SetDepthRenderTargetTileMode(depthTargetTileMode);
|
context.SetDepthRenderTargetTileMode(depthTargetTileMode);
|
||||||
})
|
})
|
||||||
MAXWELL3D_CASE(depthTargetLayerStride, {
|
ENGINE_CASE(depthTargetLayerStride, {
|
||||||
context.SetDepthRenderTargetLayerStride(depthTargetLayerStride);
|
context.SetDepthRenderTargetLayerStride(depthTargetLayerStride);
|
||||||
})
|
})
|
||||||
MAXWELL3D_CASE(depthTargetWidth, {
|
ENGINE_CASE(depthTargetWidth, {
|
||||||
context.SetDepthRenderTargetWidth(depthTargetWidth);
|
context.SetDepthRenderTargetWidth(depthTargetWidth);
|
||||||
})
|
})
|
||||||
MAXWELL3D_CASE(depthTargetHeight, {
|
ENGINE_CASE(depthTargetHeight, {
|
||||||
context.SetDepthRenderTargetHeight(depthTargetHeight);
|
context.SetDepthRenderTargetHeight(depthTargetHeight);
|
||||||
})
|
})
|
||||||
MAXWELL3D_CASE(depthTargetArrayMode, {
|
ENGINE_CASE(depthTargetArrayMode, {
|
||||||
context.SetDepthRenderTargetArrayMode(depthTargetArrayMode);
|
context.SetDepthRenderTargetArrayMode(depthTargetArrayMode);
|
||||||
})
|
})
|
||||||
|
|
||||||
#define VIEWPORT_TRANSFORM_CALLBACKS(_z, index, data) \
|
#define VIEWPORT_TRANSFORM_CALLBACKS(_z, index, data) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(viewportTransforms, index, scaleX, { \
|
ENGINE_ARRAY_STRUCT_CASE(viewportTransforms, index, scaleX, { \
|
||||||
context.SetViewportX(index, scaleX, registers.viewportTransforms[index].translateX); \
|
context.SetViewportX(index, scaleX, registers.viewportTransforms[index].translateX); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(viewportTransforms, index, translateX, { \
|
ENGINE_ARRAY_STRUCT_CASE(viewportTransforms, index, translateX, { \
|
||||||
context.SetViewportX(index, registers.viewportTransforms[index].scaleX, translateX); \
|
context.SetViewportX(index, registers.viewportTransforms[index].scaleX, translateX); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(viewportTransforms, index, scaleY, { \
|
ENGINE_ARRAY_STRUCT_CASE(viewportTransforms, index, scaleY, { \
|
||||||
context.SetViewportY(index, scaleY, registers.viewportTransforms[index].translateY); \
|
context.SetViewportY(index, scaleY, registers.viewportTransforms[index].translateY); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(viewportTransforms, index, translateY, { \
|
ENGINE_ARRAY_STRUCT_CASE(viewportTransforms, index, translateY, { \
|
||||||
context.SetViewportY(index, registers.viewportTransforms[index].scaleY, translateY); \
|
context.SetViewportY(index, registers.viewportTransforms[index].scaleY, translateY); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(viewportTransforms, index, scaleZ, { \
|
ENGINE_ARRAY_STRUCT_CASE(viewportTransforms, index, scaleZ, { \
|
||||||
context.SetViewportZ(index, scaleZ, registers.viewportTransforms[index].translateZ); \
|
context.SetViewportZ(index, scaleZ, registers.viewportTransforms[index].translateZ); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(viewportTransforms, index, translateZ, { \
|
ENGINE_ARRAY_STRUCT_CASE(viewportTransforms, index, translateZ, { \
|
||||||
context.SetViewportZ(index, registers.viewportTransforms[index].scaleZ, translateZ); \
|
context.SetViewportZ(index, registers.viewportTransforms[index].scaleZ, translateZ); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(viewportTransforms, index, swizzles, { \
|
ENGINE_ARRAY_STRUCT_CASE(viewportTransforms, index, swizzles, { \
|
||||||
context.SetViewportSwizzle(index, swizzles.x, swizzles.y, swizzles.z, swizzles.w); \
|
context.SetViewportSwizzle(index, swizzles.x, swizzles.y, swizzles.z, swizzles.w); \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -161,7 +136,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
#undef VIEWPORT_TRANSFORM_CALLBACKS
|
#undef VIEWPORT_TRANSFORM_CALLBACKS
|
||||||
|
|
||||||
#define COLOR_CLEAR_CALLBACKS(z, index, data) \
|
#define COLOR_CLEAR_CALLBACKS(z, index, data) \
|
||||||
MAXWELL3D_ARRAY_CASE(clearColorValue, index, { \
|
ENGINE_ARRAY_CASE(clearColorValue, index, { \
|
||||||
context.UpdateClearColorValue(index, clearColorValue); \
|
context.UpdateClearColorValue(index, clearColorValue); \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -169,38 +144,38 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
static_assert(4 < BOOST_PP_LIMIT_REPEAT);
|
static_assert(4 < BOOST_PP_LIMIT_REPEAT);
|
||||||
#undef COLOR_CLEAR_CALLBACKS
|
#undef COLOR_CLEAR_CALLBACKS
|
||||||
|
|
||||||
MAXWELL3D_CASE(clearDepthValue, {
|
ENGINE_CASE(clearDepthValue, {
|
||||||
context.UpdateClearDepthValue(clearDepthValue);
|
context.UpdateClearDepthValue(clearDepthValue);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(clearStencilValue, {
|
ENGINE_CASE(clearStencilValue, {
|
||||||
context.UpdateClearStencilValue(clearStencilValue);
|
context.UpdateClearStencilValue(clearStencilValue);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(polygonMode, front, {
|
ENGINE_STRUCT_CASE(polygonMode, front, {
|
||||||
context.SetPolygonModeFront(front);
|
context.SetPolygonModeFront(front);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(depthBiasEnable, point, {
|
ENGINE_STRUCT_CASE(depthBiasEnable, point, {
|
||||||
context.SetDepthBiasPointEnabled(point);
|
context.SetDepthBiasPointEnabled(point);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(depthBiasEnable, line, {
|
ENGINE_STRUCT_CASE(depthBiasEnable, line, {
|
||||||
context.SetDepthBiasLineEnabled(line);
|
context.SetDepthBiasLineEnabled(line);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(depthBiasEnable, fill, {
|
ENGINE_STRUCT_CASE(depthBiasEnable, fill, {
|
||||||
context.SetDepthBiasFillEnabled(fill);
|
context.SetDepthBiasFillEnabled(fill);
|
||||||
})
|
})
|
||||||
|
|
||||||
#define SCISSOR_CALLBACKS(z, index, data) \
|
#define SCISSOR_CALLBACKS(z, index, data) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(scissors, index, enable, { \
|
ENGINE_ARRAY_STRUCT_CASE(scissors, index, enable, { \
|
||||||
context.SetScissor(index, enable ? registers.scissors[index] : std::optional<type::Scissor>{}); \
|
context.SetScissor(index, enable ? registers.scissors[index] : std::optional<type::Scissor>{}); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(scissors, index, horizontal, { \
|
ENGINE_ARRAY_STRUCT_CASE(scissors, index, horizontal, { \
|
||||||
context.SetScissorHorizontal(index, horizontal); \
|
context.SetScissorHorizontal(index, horizontal); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(scissors, index, vertical, { \
|
ENGINE_ARRAY_STRUCT_CASE(scissors, index, vertical, { \
|
||||||
context.SetScissorVertical(index, vertical); \
|
context.SetScissorVertical(index, vertical); \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -208,7 +183,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
static_assert(type::ViewportCount == 16 && type::ViewportCount < BOOST_PP_LIMIT_REPEAT);
|
static_assert(type::ViewportCount == 16 && type::ViewportCount < BOOST_PP_LIMIT_REPEAT);
|
||||||
#undef SCISSOR_CALLBACKS
|
#undef SCISSOR_CALLBACKS
|
||||||
|
|
||||||
MAXWELL3D_CASE(commonColorWriteMask, {
|
ENGINE_CASE(commonColorWriteMask, {
|
||||||
if (commonColorWriteMask) {
|
if (commonColorWriteMask) {
|
||||||
auto colorWriteMask{registers.colorWriteMask[0]};
|
auto colorWriteMask{registers.colorWriteMask[0]};
|
||||||
for (u32 index{}; index != type::RenderTargetCount; index++)
|
for (u32 index{}; index != type::RenderTargetCount; index++)
|
||||||
@ -219,113 +194,113 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(renderTargetControl, {
|
ENGINE_CASE(renderTargetControl, {
|
||||||
context.UpdateRenderTargetControl(renderTargetControl);
|
context.UpdateRenderTargetControl(renderTargetControl);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(depthTestEnable, {
|
ENGINE_CASE(depthTestEnable, {
|
||||||
context.SetDepthTestEnabled(depthTestEnable);
|
context.SetDepthTestEnabled(depthTestEnable);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(depthTestFunc, {
|
ENGINE_CASE(depthTestFunc, {
|
||||||
context.SetDepthTestFunction(depthTestFunc);
|
context.SetDepthTestFunction(depthTestFunc);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(depthWriteEnable, {
|
ENGINE_CASE(depthWriteEnable, {
|
||||||
context.SetDepthWriteEnabled(depthWriteEnable);
|
context.SetDepthWriteEnabled(depthWriteEnable);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(depthBoundsEnable, {
|
ENGINE_CASE(depthBoundsEnable, {
|
||||||
context.SetDepthBoundsTestEnabled(depthBoundsEnable);
|
context.SetDepthBoundsTestEnabled(depthBoundsEnable);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(depthBoundsNear, {
|
ENGINE_CASE(depthBoundsNear, {
|
||||||
context.SetMinDepthBounds(depthBoundsNear);
|
context.SetMinDepthBounds(depthBoundsNear);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(depthBoundsFar, {
|
ENGINE_CASE(depthBoundsFar, {
|
||||||
context.SetMaxDepthBounds(depthBoundsFar);
|
context.SetMaxDepthBounds(depthBoundsFar);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(stencilEnable, {
|
ENGINE_CASE(stencilEnable, {
|
||||||
context.SetStencilTestEnabled(stencilEnable);
|
context.SetStencilTestEnabled(stencilEnable);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(stencilFront, failOp, {
|
ENGINE_STRUCT_CASE(stencilFront, failOp, {
|
||||||
context.SetStencilFrontFailOp(failOp);
|
context.SetStencilFrontFailOp(failOp);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(stencilFront, zFailOp, {
|
ENGINE_STRUCT_CASE(stencilFront, zFailOp, {
|
||||||
context.SetStencilFrontDepthFailOp(zFailOp);
|
context.SetStencilFrontDepthFailOp(zFailOp);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(stencilFront, passOp, {
|
ENGINE_STRUCT_CASE(stencilFront, passOp, {
|
||||||
context.SetStencilFrontPassOp(passOp);
|
context.SetStencilFrontPassOp(passOp);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(stencilFront, compareOp, {
|
ENGINE_STRUCT_CASE(stencilFront, compareOp, {
|
||||||
context.SetStencilFrontCompareOp(compareOp);
|
context.SetStencilFrontCompareOp(compareOp);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(stencilFront, compareReference, {
|
ENGINE_STRUCT_CASE(stencilFront, compareReference, {
|
||||||
context.SetStencilFrontReference(compareReference);
|
context.SetStencilFrontReference(compareReference);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(stencilFront, compareMask, {
|
ENGINE_STRUCT_CASE(stencilFront, compareMask, {
|
||||||
context.SetStencilFrontCompareMask(compareMask);
|
context.SetStencilFrontCompareMask(compareMask);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(stencilFront, writeMask, {
|
ENGINE_STRUCT_CASE(stencilFront, writeMask, {
|
||||||
context.SetStencilFrontWriteMask(writeMask);
|
context.SetStencilFrontWriteMask(writeMask);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(stencilTwoSideEnable, {
|
ENGINE_CASE(stencilTwoSideEnable, {
|
||||||
context.SetStencilTwoSideEnabled(stencilTwoSideEnable);
|
context.SetStencilTwoSideEnabled(stencilTwoSideEnable);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(stencilBack, failOp, {
|
ENGINE_STRUCT_CASE(stencilBack, failOp, {
|
||||||
context.SetStencilBackFailOp(failOp);
|
context.SetStencilBackFailOp(failOp);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(stencilBack, zFailOp, {
|
ENGINE_STRUCT_CASE(stencilBack, zFailOp, {
|
||||||
context.SetStencilBackDepthFailOp(zFailOp);
|
context.SetStencilBackDepthFailOp(zFailOp);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(stencilBack, passOp, {
|
ENGINE_STRUCT_CASE(stencilBack, passOp, {
|
||||||
context.SetStencilBackPassOp(passOp);
|
context.SetStencilBackPassOp(passOp);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(stencilBack, compareOp, {
|
ENGINE_STRUCT_CASE(stencilBack, compareOp, {
|
||||||
context.SetStencilBackCompareOp(compareOp);
|
context.SetStencilBackCompareOp(compareOp);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(stencilBackExtra, compareReference, {
|
ENGINE_STRUCT_CASE(stencilBackExtra, compareReference, {
|
||||||
context.SetStencilBackReference(compareReference);
|
context.SetStencilBackReference(compareReference);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(stencilBackExtra, compareMask, {
|
ENGINE_STRUCT_CASE(stencilBackExtra, compareMask, {
|
||||||
context.SetStencilBackCompareMask(compareMask);
|
context.SetStencilBackCompareMask(compareMask);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(stencilBackExtra, writeMask, {
|
ENGINE_STRUCT_CASE(stencilBackExtra, writeMask, {
|
||||||
context.SetStencilBackWriteMask(writeMask);
|
context.SetStencilBackWriteMask(writeMask);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(windowOriginMode, {
|
ENGINE_CASE(windowOriginMode, {
|
||||||
context.SetViewportOrigin(windowOriginMode.isOriginLowerLeft);
|
context.SetViewportOrigin(windowOriginMode.isOriginLowerLeft);
|
||||||
context.SetFrontFaceFlipEnabled(windowOriginMode.flipFrontFace);
|
context.SetFrontFaceFlipEnabled(windowOriginMode.flipFrontFace);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(independentBlendEnable, {
|
ENGINE_CASE(independentBlendEnable, {
|
||||||
context.SetIndependentBlendingEnabled(independentBlendEnable);
|
context.SetIndependentBlendingEnabled(independentBlendEnable);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(alphaTestEnable, {
|
ENGINE_CASE(alphaTestEnable, {
|
||||||
context.SetAlphaTestEnabled(alphaTestEnable);
|
context.SetAlphaTestEnabled(alphaTestEnable);
|
||||||
})
|
})
|
||||||
|
|
||||||
#define SET_COLOR_BLEND_CONSTANT_CALLBACK(z, index, data) \
|
#define SET_COLOR_BLEND_CONSTANT_CALLBACK(z, index, data) \
|
||||||
MAXWELL3D_ARRAY_CASE(blendConstant, index, { \
|
ENGINE_ARRAY_CASE(blendConstant, index, { \
|
||||||
context.SetColorBlendConstant(index, blendConstant); \
|
context.SetColorBlendConstant(index, blendConstant); \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -333,36 +308,36 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
static_assert(type::BlendColorChannelCount == 4 && type::BlendColorChannelCount < BOOST_PP_LIMIT_REPEAT);
|
static_assert(type::BlendColorChannelCount == 4 && type::BlendColorChannelCount < BOOST_PP_LIMIT_REPEAT);
|
||||||
#undef SET_COLOR_BLEND_CONSTANT_CALLBACK
|
#undef SET_COLOR_BLEND_CONSTANT_CALLBACK
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(blendStateCommon, colorOp, {
|
ENGINE_STRUCT_CASE(blendStateCommon, colorOp, {
|
||||||
context.SetColorBlendOp(colorOp);
|
context.SetColorBlendOp(colorOp);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(blendStateCommon, colorSrcFactor, {
|
ENGINE_STRUCT_CASE(blendStateCommon, colorSrcFactor, {
|
||||||
context.SetSrcColorBlendFactor(colorSrcFactor);
|
context.SetSrcColorBlendFactor(colorSrcFactor);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(blendStateCommon, colorDstFactor, {
|
ENGINE_STRUCT_CASE(blendStateCommon, colorDstFactor, {
|
||||||
context.SetDstColorBlendFactor(colorDstFactor);
|
context.SetDstColorBlendFactor(colorDstFactor);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(blendStateCommon, alphaOp, {
|
ENGINE_STRUCT_CASE(blendStateCommon, alphaOp, {
|
||||||
context.SetAlphaBlendOp(alphaOp);
|
context.SetAlphaBlendOp(alphaOp);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(blendStateCommon, alphaSrcFactor, {
|
ENGINE_STRUCT_CASE(blendStateCommon, alphaSrcFactor, {
|
||||||
context.SetSrcAlphaBlendFactor(alphaSrcFactor);
|
context.SetSrcAlphaBlendFactor(alphaSrcFactor);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(blendStateCommon, alphaDstFactor, {
|
ENGINE_STRUCT_CASE(blendStateCommon, alphaDstFactor, {
|
||||||
context.SetDstAlphaBlendFactor(alphaDstFactor);
|
context.SetDstAlphaBlendFactor(alphaDstFactor);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(blendStateCommon, enable, {
|
ENGINE_STRUCT_CASE(blendStateCommon, enable, {
|
||||||
context.SetColorBlendEnabled(enable);
|
context.SetColorBlendEnabled(enable);
|
||||||
})
|
})
|
||||||
|
|
||||||
#define SET_COLOR_BLEND_ENABLE_CALLBACK(z, index, data) \
|
#define SET_COLOR_BLEND_ENABLE_CALLBACK(z, index, data) \
|
||||||
MAXWELL3D_ARRAY_CASE(rtBlendEnable, index, { \
|
ENGINE_ARRAY_CASE(rtBlendEnable, index, { \
|
||||||
context.SetColorBlendEnabled(index, rtBlendEnable); \
|
context.SetColorBlendEnabled(index, rtBlendEnable); \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -370,58 +345,58 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
static_assert(type::RenderTargetCount == 8 && type::RenderTargetCount < BOOST_PP_LIMIT_REPEAT);
|
static_assert(type::RenderTargetCount == 8 && type::RenderTargetCount < BOOST_PP_LIMIT_REPEAT);
|
||||||
#undef SET_COLOR_BLEND_ENABLE_CALLBACK
|
#undef SET_COLOR_BLEND_ENABLE_CALLBACK
|
||||||
|
|
||||||
MAXWELL3D_CASE(lineWidthSmooth, {
|
ENGINE_CASE(lineWidthSmooth, {
|
||||||
if (*registers.lineSmoothEnable)
|
if (*registers.lineSmoothEnable)
|
||||||
context.SetLineWidth(lineWidthSmooth);
|
context.SetLineWidth(lineWidthSmooth);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(lineWidthAliased, {
|
ENGINE_CASE(lineWidthAliased, {
|
||||||
if (!*registers.lineSmoothEnable)
|
if (!*registers.lineSmoothEnable)
|
||||||
context.SetLineWidth(lineWidthAliased);
|
context.SetLineWidth(lineWidthAliased);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(depthBiasFactor, {
|
ENGINE_CASE(depthBiasFactor, {
|
||||||
context.SetDepthBiasSlopeFactor(depthBiasFactor);
|
context.SetDepthBiasSlopeFactor(depthBiasFactor);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(lineSmoothEnable, {
|
ENGINE_CASE(lineSmoothEnable, {
|
||||||
context.SetLineWidth(lineSmoothEnable ? *registers.lineWidthSmooth : *registers.lineWidthAliased);
|
context.SetLineWidth(lineSmoothEnable ? *registers.lineWidthSmooth : *registers.lineWidthAliased);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(depthBiasUnits, {
|
ENGINE_CASE(depthBiasUnits, {
|
||||||
context.SetDepthBiasConstantFactor(depthBiasUnits / 2.0f);
|
context.SetDepthBiasConstantFactor(depthBiasUnits / 2.0f);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(setProgramRegion, high, {
|
ENGINE_STRUCT_CASE(setProgramRegion, high, {
|
||||||
context.SetShaderBaseIovaHigh(high);
|
context.SetShaderBaseIovaHigh(high);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(setProgramRegion, low, {
|
ENGINE_STRUCT_CASE(setProgramRegion, low, {
|
||||||
context.SetShaderBaseIovaLow(low);
|
context.SetShaderBaseIovaLow(low);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(provokingVertexIsLast, {
|
ENGINE_CASE(provokingVertexIsLast, {
|
||||||
context.SetProvokingVertex(provokingVertexIsLast);
|
context.SetProvokingVertex(provokingVertexIsLast);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(depthBiasClamp, {
|
ENGINE_CASE(depthBiasClamp, {
|
||||||
context.SetDepthBiasClamp(depthBiasClamp);
|
context.SetDepthBiasClamp(depthBiasClamp);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(cullFaceEnable, {
|
ENGINE_CASE(cullFaceEnable, {
|
||||||
context.SetCullFaceEnabled(cullFaceEnable);
|
context.SetCullFaceEnabled(cullFaceEnable);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(frontFace, {
|
ENGINE_CASE(frontFace, {
|
||||||
context.SetFrontFace(frontFace);
|
context.SetFrontFace(frontFace);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(cullFace, {
|
ENGINE_CASE(cullFace, {
|
||||||
context.SetCullFace(cullFace);
|
context.SetCullFace(cullFace);
|
||||||
})
|
})
|
||||||
|
|
||||||
#define SET_COLOR_WRITE_MASK_CALLBACK(z, index, data) \
|
#define SET_COLOR_WRITE_MASK_CALLBACK(z, index, data) \
|
||||||
MAXWELL3D_ARRAY_CASE(colorWriteMask, index, { \
|
ENGINE_ARRAY_CASE(colorWriteMask, index, { \
|
||||||
if (*registers.commonColorWriteMask) \
|
if (*registers.commonColorWriteMask) \
|
||||||
if (index == 0) \
|
if (index == 0) \
|
||||||
for (u32 idx{}; idx != type::RenderTargetCount; idx++) \
|
for (u32 idx{}; idx != type::RenderTargetCount; idx++) \
|
||||||
@ -434,38 +409,38 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
static_assert(type::RenderTargetCount == 8 && type::RenderTargetCount < BOOST_PP_LIMIT_REPEAT);
|
static_assert(type::RenderTargetCount == 8 && type::RenderTargetCount < BOOST_PP_LIMIT_REPEAT);
|
||||||
#undef SET_COLOR_WRITE_MASK_CALLBACK
|
#undef SET_COLOR_WRITE_MASK_CALLBACK
|
||||||
|
|
||||||
MAXWELL3D_CASE(viewVolumeClipControl, {
|
ENGINE_CASE(viewVolumeClipControl, {
|
||||||
context.SetDepthClampEnabled(!viewVolumeClipControl.depthClampDisable);
|
context.SetDepthClampEnabled(!viewVolumeClipControl.depthClampDisable);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(colorLogicOp, enable, {
|
ENGINE_STRUCT_CASE(colorLogicOp, enable, {
|
||||||
context.SetBlendLogicOpEnable(enable);
|
context.SetBlendLogicOpEnable(enable);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(colorLogicOp, type, {
|
ENGINE_STRUCT_CASE(colorLogicOp, type, {
|
||||||
context.SetBlendLogicOpType(type);
|
context.SetBlendLogicOpType(type);
|
||||||
})
|
})
|
||||||
|
|
||||||
#define VERTEX_BUFFER_CALLBACKS(z, index, data) \
|
#define VERTEX_BUFFER_CALLBACKS(z, index, data) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(vertexBuffers, index, config, { \
|
ENGINE_ARRAY_STRUCT_CASE(vertexBuffers, index, config, { \
|
||||||
context.SetVertexBufferStride(index, config.stride); \
|
context.SetVertexBufferStride(index, config.stride); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_STRUCT_CASE(vertexBuffers, index, iova, high, { \
|
ENGINE_ARRAY_STRUCT_STRUCT_CASE(vertexBuffers, index, iova, high, { \
|
||||||
context.SetVertexBufferStartIovaHigh(index, high); \
|
context.SetVertexBufferStartIovaHigh(index, high); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_STRUCT_CASE(vertexBuffers, index, iova, low, { \
|
ENGINE_ARRAY_STRUCT_STRUCT_CASE(vertexBuffers, index, iova, low, { \
|
||||||
context.SetVertexBufferStartIovaLow(index, low); \
|
context.SetVertexBufferStartIovaLow(index, low); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(vertexBuffers, index, divisor, { \
|
ENGINE_ARRAY_STRUCT_CASE(vertexBuffers, index, divisor, { \
|
||||||
context.SetVertexBufferDivisor(index, divisor); \
|
context.SetVertexBufferDivisor(index, divisor); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_CASE(isVertexInputRatePerInstance, index, { \
|
ENGINE_ARRAY_CASE(isVertexInputRatePerInstance, index, { \
|
||||||
context.SetVertexBufferInputRate(index, isVertexInputRatePerInstance); \
|
context.SetVertexBufferInputRate(index, isVertexInputRatePerInstance); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(vertexBufferLimits, index, high, { \
|
ENGINE_ARRAY_STRUCT_CASE(vertexBufferLimits, index, high, { \
|
||||||
context.SetVertexBufferEndIovaHigh(index, high); \
|
context.SetVertexBufferEndIovaHigh(index, high); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(vertexBufferLimits, index, low, { \
|
ENGINE_ARRAY_STRUCT_CASE(vertexBufferLimits, index, low, { \
|
||||||
context.SetVertexBufferEndIovaLow(index, low); \
|
context.SetVertexBufferEndIovaLow(index, low); \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -474,7 +449,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
#undef VERTEX_BUFFER_CALLBACKS
|
#undef VERTEX_BUFFER_CALLBACKS
|
||||||
|
|
||||||
#define VERTEX_ATTRIBUTES_CALLBACKS(z, index, data) \
|
#define VERTEX_ATTRIBUTES_CALLBACKS(z, index, data) \
|
||||||
MAXWELL3D_ARRAY_CASE(vertexAttributeState, index, { \
|
ENGINE_ARRAY_CASE(vertexAttributeState, index, { \
|
||||||
context.SetVertexAttributeState(index, vertexAttributeState); \
|
context.SetVertexAttributeState(index, vertexAttributeState); \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -483,22 +458,22 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
#undef VERTEX_BUFFER_CALLBACKS
|
#undef VERTEX_BUFFER_CALLBACKS
|
||||||
|
|
||||||
#define SET_INDEPENDENT_COLOR_BLEND_CALLBACKS(z, index, data) \
|
#define SET_INDEPENDENT_COLOR_BLEND_CALLBACKS(z, index, data) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(independentBlend, index, colorOp, { \
|
ENGINE_ARRAY_STRUCT_CASE(independentBlend, index, colorOp, { \
|
||||||
context.SetColorBlendOp(index, colorOp); \
|
context.SetColorBlendOp(index, colorOp); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(independentBlend, index, colorSrcFactor, { \
|
ENGINE_ARRAY_STRUCT_CASE(independentBlend, index, colorSrcFactor, { \
|
||||||
context.SetSrcColorBlendFactor(index, colorSrcFactor); \
|
context.SetSrcColorBlendFactor(index, colorSrcFactor); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(independentBlend, index, colorDstFactor, { \
|
ENGINE_ARRAY_STRUCT_CASE(independentBlend, index, colorDstFactor, { \
|
||||||
context.SetDstColorBlendFactor(index, colorDstFactor); \
|
context.SetDstColorBlendFactor(index, colorDstFactor); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(independentBlend, index, alphaOp, { \
|
ENGINE_ARRAY_STRUCT_CASE(independentBlend, index, alphaOp, { \
|
||||||
context.SetAlphaBlendOp(index, alphaOp); \
|
context.SetAlphaBlendOp(index, alphaOp); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(independentBlend, index, alphaSrcFactor, { \
|
ENGINE_ARRAY_STRUCT_CASE(independentBlend, index, alphaSrcFactor, { \
|
||||||
context.SetSrcAlphaBlendFactor(index, alphaSrcFactor); \
|
context.SetSrcAlphaBlendFactor(index, alphaSrcFactor); \
|
||||||
}) \
|
}) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(independentBlend, index, alphaDstFactor, { \
|
ENGINE_ARRAY_STRUCT_CASE(independentBlend, index, alphaDstFactor, { \
|
||||||
context.SetDstAlphaBlendFactor(index, alphaDstFactor); \
|
context.SetDstAlphaBlendFactor(index, alphaDstFactor); \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -507,7 +482,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
#undef SET_COLOR_BLEND_ENABLE_CALLBACK
|
#undef SET_COLOR_BLEND_ENABLE_CALLBACK
|
||||||
|
|
||||||
#define SET_SHADER_ENABLE_CALLBACK(z, index, data) \
|
#define SET_SHADER_ENABLE_CALLBACK(z, index, data) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(setProgram, index, info, { \
|
ENGINE_ARRAY_STRUCT_CASE(setProgram, index, info, { \
|
||||||
context.SetShaderEnabled(info.stage, info.enable); \
|
context.SetShaderEnabled(info.stage, info.enable); \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -515,63 +490,63 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
static_assert(type::ShaderStageCount == 6 && type::ShaderStageCount < BOOST_PP_LIMIT_REPEAT);
|
static_assert(type::ShaderStageCount == 6 && type::ShaderStageCount < BOOST_PP_LIMIT_REPEAT);
|
||||||
#undef SET_SHADER_ENABLE_CALLBACK
|
#undef SET_SHADER_ENABLE_CALLBACK
|
||||||
|
|
||||||
MAXWELL3D_CASE(vertexBeginGl, {
|
ENGINE_CASE(vertexBeginGl, {
|
||||||
context.SetPrimitiveTopology(vertexBeginGl.topology);
|
context.SetPrimitiveTopology(vertexBeginGl.topology);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(constantBufferSelector, size, {
|
ENGINE_STRUCT_CASE(constantBufferSelector, size, {
|
||||||
context.SetConstantBufferSelectorSize(size);
|
context.SetConstantBufferSelectorSize(size);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_STRUCT_CASE(constantBufferSelector, address, high, {
|
ENGINE_STRUCT_STRUCT_CASE(constantBufferSelector, address, high, {
|
||||||
context.SetConstantBufferSelectorIovaHigh(high);
|
context.SetConstantBufferSelectorIovaHigh(high);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_STRUCT_CASE(constantBufferSelector, address, low, {
|
ENGINE_STRUCT_STRUCT_CASE(constantBufferSelector, address, low, {
|
||||||
context.SetConstantBufferSelectorIovaLow(low);
|
context.SetConstantBufferSelectorIovaLow(low);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_STRUCT_CASE(indexBuffer, start, high, {
|
ENGINE_STRUCT_STRUCT_CASE(indexBuffer, start, high, {
|
||||||
context.SetIndexBufferStartIovaHigh(high);
|
context.SetIndexBufferStartIovaHigh(high);
|
||||||
})
|
})
|
||||||
MAXWELL3D_STRUCT_STRUCT_CASE(indexBuffer, start, low, {
|
ENGINE_STRUCT_STRUCT_CASE(indexBuffer, start, low, {
|
||||||
context.SetIndexBufferStartIovaLow(low);
|
context.SetIndexBufferStartIovaLow(low);
|
||||||
})
|
})
|
||||||
MAXWELL3D_STRUCT_STRUCT_CASE(indexBuffer, limit, high, {
|
ENGINE_STRUCT_STRUCT_CASE(indexBuffer, limit, high, {
|
||||||
context.SetIndexBufferEndIovaHigh(high);
|
context.SetIndexBufferEndIovaHigh(high);
|
||||||
})
|
})
|
||||||
MAXWELL3D_STRUCT_STRUCT_CASE(indexBuffer, limit, low, {
|
ENGINE_STRUCT_STRUCT_CASE(indexBuffer, limit, low, {
|
||||||
context.SetIndexBufferEndIovaLow(low);
|
context.SetIndexBufferEndIovaLow(low);
|
||||||
})
|
})
|
||||||
MAXWELL3D_STRUCT_CASE(indexBuffer, format, {
|
ENGINE_STRUCT_CASE(indexBuffer, format, {
|
||||||
context.SetIndexBufferFormat(format);
|
context.SetIndexBufferFormat(format);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(bindlessTextureConstantBufferIndex, {
|
ENGINE_CASE(bindlessTextureConstantBufferIndex, {
|
||||||
context.SetBindlessTextureConstantBufferIndex(bindlessTextureConstantBufferIndex);
|
context.SetBindlessTextureConstantBufferIndex(bindlessTextureConstantBufferIndex);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_STRUCT_CASE(samplerPool, address, high, {
|
ENGINE_STRUCT_STRUCT_CASE(samplerPool, address, high, {
|
||||||
context.SetSamplerPoolIovaHigh(high);
|
context.SetSamplerPoolIovaHigh(high);
|
||||||
})
|
})
|
||||||
MAXWELL3D_STRUCT_STRUCT_CASE(samplerPool, address, low, {
|
ENGINE_STRUCT_STRUCT_CASE(samplerPool, address, low, {
|
||||||
context.SetSamplerPoolIovaLow(low);
|
context.SetSamplerPoolIovaLow(low);
|
||||||
})
|
})
|
||||||
MAXWELL3D_STRUCT_CASE(samplerPool, maximumIndex, {
|
ENGINE_STRUCT_CASE(samplerPool, maximumIndex, {
|
||||||
context.SetSamplerPoolMaximumIndex(maximumIndex);
|
context.SetSamplerPoolMaximumIndex(maximumIndex);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_STRUCT_CASE(texturePool, address, high, {
|
ENGINE_STRUCT_STRUCT_CASE(texturePool, address, high, {
|
||||||
context.SetTexturePoolIovaHigh(high);
|
context.SetTexturePoolIovaHigh(high);
|
||||||
})
|
})
|
||||||
MAXWELL3D_STRUCT_STRUCT_CASE(texturePool, address, low, {
|
ENGINE_STRUCT_STRUCT_CASE(texturePool, address, low, {
|
||||||
context.SetTexturePoolIovaLow(low);
|
context.SetTexturePoolIovaLow(low);
|
||||||
})
|
})
|
||||||
MAXWELL3D_STRUCT_CASE(texturePool, maximumIndex, {
|
ENGINE_STRUCT_CASE(texturePool, maximumIndex, {
|
||||||
context.SetTexturePoolMaximumIndex(maximumIndex);
|
context.SetTexturePoolMaximumIndex(maximumIndex);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(depthMode, {
|
ENGINE_CASE(depthMode, {
|
||||||
context.SetDepthMode(depthMode);
|
context.SetDepthMode(depthMode);
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -581,7 +556,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (method) {
|
switch (method) {
|
||||||
MAXWELL3D_STRUCT_CASE(mme, instructionRamLoad, {
|
ENGINE_STRUCT_CASE(mme, instructionRamLoad, {
|
||||||
if (registers.mme->instructionRamPointer >= macroState.macroCode.size())
|
if (registers.mme->instructionRamPointer >= macroState.macroCode.size())
|
||||||
throw exception("Macro memory is full!");
|
throw exception("Macro memory is full!");
|
||||||
|
|
||||||
@ -592,40 +567,40 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
registers.mme->instructionRamPointer %= macroState.macroCode.size();
|
registers.mme->instructionRamPointer %= macroState.macroCode.size();
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(mme, startAddressRamLoad, {
|
ENGINE_STRUCT_CASE(mme, startAddressRamLoad, {
|
||||||
if (registers.mme->startAddressRamPointer >= macroState.macroPositions.size())
|
if (registers.mme->startAddressRamPointer >= macroState.macroPositions.size())
|
||||||
throw exception("Maximum amount of macros reached!");
|
throw exception("Maximum amount of macros reached!");
|
||||||
|
|
||||||
macroState.macroPositions[registers.mme->startAddressRamPointer++] = startAddressRamLoad;
|
macroState.macroPositions[registers.mme->startAddressRamPointer++] = startAddressRamLoad;
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(i2m, launchDma, {
|
ENGINE_STRUCT_CASE(i2m, launchDma, {
|
||||||
i2m.LaunchDma(*registers.i2m);
|
i2m.LaunchDma(*registers.i2m);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(i2m, loadInlineData, {
|
ENGINE_STRUCT_CASE(i2m, loadInlineData, {
|
||||||
i2m.LoadInlineData(*registers.i2m, loadInlineData);
|
i2m.LoadInlineData(*registers.i2m, loadInlineData);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(syncpointAction, {
|
ENGINE_CASE(syncpointAction, {
|
||||||
Logger::Debug("Increment syncpoint: {}", static_cast<u16>(syncpointAction.id));
|
Logger::Debug("Increment syncpoint: {}", static_cast<u16>(syncpointAction.id));
|
||||||
channelCtx.executor.Execute();
|
channelCtx.executor.Execute();
|
||||||
syncpoints.at(syncpointAction.id).Increment();
|
syncpoints.at(syncpointAction.id).Increment();
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(clearBuffers, {
|
ENGINE_CASE(clearBuffers, {
|
||||||
context.ClearBuffers(clearBuffers);
|
context.ClearBuffers(clearBuffers);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(drawVertexCount, {
|
ENGINE_CASE(drawVertexCount, {
|
||||||
context.DrawVertex(drawVertexCount, *registers.drawVertexFirst);
|
context.DrawVertex(drawVertexCount, *registers.drawVertexFirst);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(drawIndexCount, {
|
ENGINE_CASE(drawIndexCount, {
|
||||||
context.DrawIndexed(drawIndexCount, *registers.drawIndexFirst, *registers.drawBaseVertex);
|
context.DrawIndexed(drawIndexCount, *registers.drawIndexFirst, *registers.drawBaseVertex);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(semaphore, info, {
|
ENGINE_STRUCT_CASE(semaphore, info, {
|
||||||
switch (info.op) {
|
switch (info.op) {
|
||||||
case type::SemaphoreInfo::Op::Release:
|
case type::SemaphoreInfo::Op::Release:
|
||||||
WriteSemaphoreResult(registers.semaphore->payload);
|
WriteSemaphoreResult(registers.semaphore->payload);
|
||||||
@ -651,7 +626,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
})
|
})
|
||||||
|
|
||||||
#define SHADER_CALLBACKS(z, index, data) \
|
#define SHADER_CALLBACKS(z, index, data) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(setProgram, index, offset, { \
|
ENGINE_ARRAY_STRUCT_CASE(setProgram, index, offset, { \
|
||||||
context.SetShaderOffset(static_cast<type::ShaderStage>(index), offset); \
|
context.SetShaderOffset(static_cast<type::ShaderStage>(index), offset); \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -660,7 +635,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
#undef SHADER_CALLBACKS
|
#undef SHADER_CALLBACKS
|
||||||
|
|
||||||
#define PIPELINE_CALLBACKS(z, idx, data) \
|
#define PIPELINE_CALLBACKS(z, idx, data) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(bind, idx, constantBuffer, { \
|
ENGINE_ARRAY_STRUCT_CASE(bind, idx, constantBuffer, { \
|
||||||
context.BindPipelineConstantBuffer(static_cast<type::PipelineStage>(idx), constantBuffer.valid, constantBuffer.index); \
|
context.BindPipelineConstantBuffer(static_cast<type::PipelineStage>(idx), constantBuffer.valid, constantBuffer.index); \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -668,12 +643,12 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
static_assert(type::PipelineStageCount == 5 && type::PipelineStageCount < BOOST_PP_LIMIT_REPEAT);
|
static_assert(type::PipelineStageCount == 5 && type::PipelineStageCount < BOOST_PP_LIMIT_REPEAT);
|
||||||
#undef PIPELINE_CALLBACKS
|
#undef PIPELINE_CALLBACKS
|
||||||
|
|
||||||
MAXWELL3D_ARRAY_CASE(firmwareCall, 4, {
|
ENGINE_ARRAY_CASE(firmwareCall, 4, {
|
||||||
registers.raw[0xD00] = 1;
|
registers.raw[0xD00] = 1;
|
||||||
})
|
})
|
||||||
|
|
||||||
#define CBUF_UPDATE_CALLBACKS(z, index, data_) \
|
#define CBUF_UPDATE_CALLBACKS(z, index, data_) \
|
||||||
MAXWELL3D_STRUCT_ARRAY_CASE(constantBufferUpdate, data, index, { \
|
ENGINE_STRUCT_ARRAY_CASE(constantBufferUpdate, data, index, { \
|
||||||
context.ConstantBufferUpdate(data, registers.constantBufferUpdate->offset); \
|
context.ConstantBufferUpdate(data, registers.constantBufferUpdate->offset); \
|
||||||
registers.constantBufferUpdate->offset += 4; \
|
registers.constantBufferUpdate->offset += 4; \
|
||||||
})
|
})
|
||||||
@ -684,19 +659,11 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef MAXWELL3D_CASE_BASE
|
|
||||||
#undef MAXWELL3D_CASE
|
|
||||||
#undef MAXWELL3D_STRUCT_CASE
|
|
||||||
#undef MAXWELL3D_STRUCT_ARRAY_CASE
|
|
||||||
#undef MAXWELL3D_ARRAY_CASE
|
|
||||||
#undef MAXWELL3D_ARRAY_STRUCT_CASE
|
|
||||||
#undef MAXWELL3D_ARRAY_STRUCT_STRUCT_CASE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Maxwell3D::CallMethodBatchNonInc(u32 method, span<u32> arguments) {
|
void Maxwell3D::CallMethodBatchNonInc(u32 method, span<u32> arguments) {
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case MAXWELL3D_STRUCT_OFFSET(i2m, loadInlineData):
|
case ENGINE_STRUCT_OFFSET(i2m, loadInlineData):
|
||||||
i2m.LoadInlineData(*registers.i2m, arguments);
|
i2m.LoadInlineData(*registers.i2m, arguments);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
@ -707,13 +674,6 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
HandleMethod(method, argument);
|
HandleMethod(method, argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef MAXWELL3D_OFFSET
|
|
||||||
#undef MAXWELL3D_STRUCT_OFFSET
|
|
||||||
#undef MAXWELL3D_STRUCT_ARRAY_OFFSET
|
|
||||||
#undef MAXWELL3D_ARRAY_OFFSET
|
|
||||||
#undef MAXWELL3D_ARRAY_STRUCT_OFFSET
|
|
||||||
#undef MAXWELL3D_ARRAY_STRUCT_STRUCT_OFFSET
|
|
||||||
|
|
||||||
void Maxwell3D::WriteSemaphoreResult(u64 result) {
|
void Maxwell3D::WriteSemaphoreResult(u64 result) {
|
||||||
struct FourWordResult {
|
struct FourWordResult {
|
||||||
u64 value;
|
u64 value;
|
||||||
|
@ -34,14 +34,12 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
void WriteSemaphoreResult(u64 result);
|
void WriteSemaphoreResult(u64 result);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static constexpr u32 RegisterCount{0xE00}; //!< The number of Maxwell 3D registers
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @url https://github.com/devkitPro/deko3d/blob/master/source/maxwell/engine_3d.def
|
* @url https://github.com/devkitPro/deko3d/blob/master/source/maxwell/engine_3d.def
|
||||||
*/
|
*/
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
union Registers {
|
union Registers {
|
||||||
std::array<u32, RegisterCount> raw;
|
std::array<u32, EngineMethodsEnd> raw;
|
||||||
|
|
||||||
template<size_t Offset, typename Type>
|
template<size_t Offset, typename Type>
|
||||||
using Register = util::OffsetMember<Offset, Type, u32>;
|
using Register = util::OffsetMember<Offset, Type, u32>;
|
||||||
@ -317,7 +315,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
|
|
||||||
Register<0x982, u32> bindlessTextureConstantBufferIndex; //!< The index of the constant buffer containing bindless texture descriptors
|
Register<0x982, u32> bindlessTextureConstantBufferIndex; //!< The index of the constant buffer containing bindless texture descriptors
|
||||||
};
|
};
|
||||||
static_assert(sizeof(Registers) == (RegisterCount * sizeof(u32)));
|
static_assert(sizeof(Registers) == (EngineMethodsEnd * sizeof(u32)));
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
Registers registers{};
|
Registers registers{};
|
||||||
|
Loading…
Reference in New Issue
Block a user