mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-29 16:25:36 +03:00
Migrate Maxwell3D::Registers
to OffsetMember
Maxwell3D registers were primarily written with absolute offsets and ended up being fairly messy due to attempting to emulate this using struct relative positioning resulting in a lot of pointless padding members. This has now been improved by utilizing `OffsetMember` to directly use offsets resulting in much neater code.
This commit is contained in:
parent
69761389ff
commit
fbfad21f03
@ -29,6 +29,16 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
|||||||
MethodReplay = 3, //!< Replays older tracked writes for any new writes to registers, discarding the contents of the new write
|
MethodReplay = 3, //!< Replays older tracked writes for any new writes to registers, discarding the contents of the new write
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SyncpointAction {
|
||||||
|
u16 id : 12;
|
||||||
|
u8 _pad0_ : 4;
|
||||||
|
bool flushCache : 1;
|
||||||
|
u8 _pad1_ : 3;
|
||||||
|
bool increment : 1;
|
||||||
|
u16 _pad2_ : 11;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SyncpointAction) == sizeof(u32));
|
||||||
|
|
||||||
constexpr static size_t RenderTargetCount{8}; //!< Maximum amount of render targets that can be bound at once on Maxwell 3D
|
constexpr static size_t RenderTargetCount{8}; //!< Maximum amount of render targets that can be bound at once on Maxwell 3D
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -360,6 +370,14 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
|||||||
};
|
};
|
||||||
static_assert(sizeof(Blend) == (sizeof(u32) * 8));
|
static_assert(sizeof(Blend) == (sizeof(u32) * 8));
|
||||||
|
|
||||||
|
struct MultisampleControl {
|
||||||
|
bool alphaToCoverage : 1;
|
||||||
|
u8 _pad0_ : 3;
|
||||||
|
bool alphaToOne : 1;
|
||||||
|
u32 _pad1_ : 27;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(MultisampleControl) == sizeof(u32));
|
||||||
|
|
||||||
enum class StencilOp : u32 {
|
enum class StencilOp : u32 {
|
||||||
Keep = 1,
|
Keep = 1,
|
||||||
Zero = 2,
|
Zero = 2,
|
||||||
@ -371,6 +389,18 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
|||||||
DecrementAndWrap = 8,
|
DecrementAndWrap = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PointCoordReplace {
|
||||||
|
u8 _unk_ : 2;
|
||||||
|
enum class CoordOrigin : u8 {
|
||||||
|
LowerLeft = 0,
|
||||||
|
UpperLeft = 1,
|
||||||
|
};
|
||||||
|
CoordOrigin origin : 1;
|
||||||
|
u16 enable : 10;
|
||||||
|
u32 _pad_ : 19;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(PointCoordReplace) == sizeof(u32));
|
||||||
|
|
||||||
enum class FrontFace : u32 {
|
enum class FrontFace : u32 {
|
||||||
Clockwise = 0x900,
|
Clockwise = 0x900,
|
||||||
CounterClockwise = 0x901,
|
CounterClockwise = 0x901,
|
||||||
@ -495,10 +525,5 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
|||||||
};
|
};
|
||||||
static_assert(sizeof(SemaphoreInfo) == sizeof(u32));
|
static_assert(sizeof(SemaphoreInfo) == sizeof(u32));
|
||||||
|
|
||||||
enum class CoordOrigin : u8 {
|
|
||||||
LowerLeft = 0,
|
|
||||||
UpperLeft = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
}
|
}
|
||||||
|
@ -16,57 +16,57 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
|
|
||||||
registers.rasterizerEnable = true;
|
registers.rasterizerEnable = true;
|
||||||
|
|
||||||
for (auto &transform : registers.viewportTransforms) {
|
for (auto &transform : *registers.viewportTransforms) {
|
||||||
transform.swizzles.x = type::ViewportTransform::Swizzle::PositiveX;
|
transform.swizzles.x = type::ViewportTransform::Swizzle::PositiveX;
|
||||||
transform.swizzles.y = type::ViewportTransform::Swizzle::PositiveY;
|
transform.swizzles.y = type::ViewportTransform::Swizzle::PositiveY;
|
||||||
transform.swizzles.z = type::ViewportTransform::Swizzle::PositiveZ;
|
transform.swizzles.z = type::ViewportTransform::Swizzle::PositiveZ;
|
||||||
transform.swizzles.w = type::ViewportTransform::Swizzle::PositiveW;
|
transform.swizzles.w = type::ViewportTransform::Swizzle::PositiveW;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &viewport : registers.viewports) {
|
for (auto &viewport : *registers.viewports) {
|
||||||
viewport.depthRangeFar = 1.0f;
|
viewport.depthRangeFar = 1.0f;
|
||||||
viewport.depthRangeNear = 0.0f;
|
viewport.depthRangeNear = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
registers.polygonMode.front = type::PolygonMode::Fill;
|
registers.polygonMode->front = type::PolygonMode::Fill;
|
||||||
registers.polygonMode.back = type::PolygonMode::Fill;
|
registers.polygonMode->back = type::PolygonMode::Fill;
|
||||||
|
|
||||||
registers.stencilFront.failOp = registers.stencilFront.zFailOp = registers.stencilFront.zPassOp = type::StencilOp::Keep;
|
registers.stencilFront->failOp = registers.stencilFront->zFailOp = registers.stencilFront->zPassOp = type::StencilOp::Keep;
|
||||||
registers.stencilFront.compare.op = type::CompareOp::Always;
|
registers.stencilFront->compare.op = type::CompareOp::Always;
|
||||||
registers.stencilFront.compare.mask = 0xFFFFFFFF;
|
registers.stencilFront->compare.mask = 0xFFFFFFFF;
|
||||||
registers.stencilFront.writeMask = 0xFFFFFFFF;
|
registers.stencilFront->writeMask = 0xFFFFFFFF;
|
||||||
|
|
||||||
registers.stencilTwoSideEnable = true;
|
registers.stencilTwoSideEnable = true;
|
||||||
registers.stencilBack.failOp = registers.stencilBack.zFailOp = registers.stencilBack.zPassOp = type::StencilOp::Keep;
|
registers.stencilBack->failOp = registers.stencilBack->zFailOp = registers.stencilBack->zPassOp = type::StencilOp::Keep;
|
||||||
registers.stencilBack.compareOp = type::CompareOp::Always;
|
registers.stencilBack->compareOp = type::CompareOp::Always;
|
||||||
registers.stencilBackExtra.compareMask = 0xFFFFFFFF;
|
registers.stencilBackExtra->compareMask = 0xFFFFFFFF;
|
||||||
registers.stencilBackExtra.writeMask = 0xFFFFFFFF;
|
registers.stencilBackExtra->writeMask = 0xFFFFFFFF;
|
||||||
|
|
||||||
registers.rtSeparateFragData = true;
|
registers.rtSeparateFragData = true;
|
||||||
|
|
||||||
for (auto &attribute : registers.vertexAttributeState)
|
for (auto &attribute : *registers.vertexAttributeState)
|
||||||
attribute.fixed = true;
|
attribute.fixed = true;
|
||||||
|
|
||||||
registers.depthTestFunc = type::CompareOp::Always;
|
registers.depthTestFunc = type::CompareOp::Always;
|
||||||
|
|
||||||
registers.blend.colorOp = registers.blend.alphaOp = type::Blend::Op::Add;
|
registers.blendState->colorOp = registers.blendState->alphaOp = type::Blend::Op::Add;
|
||||||
registers.blend.colorSrcFactor = registers.blend.alphaSrcFactor = type::Blend::Factor::One;
|
registers.blendState->colorSrcFactor = registers.blendState->alphaSrcFactor = type::Blend::Factor::One;
|
||||||
registers.blend.colorDestFactor = registers.blend.alphaDestFactor = type::Blend::Factor::Zero;
|
registers.blendState->colorDestFactor = registers.blendState->alphaDestFactor = type::Blend::Factor::Zero;
|
||||||
|
|
||||||
registers.lineWidthSmooth = 1.0f;
|
registers.lineWidthSmooth = 1.0f;
|
||||||
registers.lineWidthAliased = 1.0f;
|
registers.lineWidthAliased = 1.0f;
|
||||||
|
|
||||||
registers.pointSpriteEnable = true;
|
registers.pointSpriteEnable = true;
|
||||||
registers.pointSpriteSize = 1.0f;
|
registers.pointSpriteSize = 1.0f;
|
||||||
registers.pointCoordReplace.enable = true;
|
registers.pointCoordReplace->enable = true;
|
||||||
|
|
||||||
registers.frontFace = type::FrontFace::CounterClockwise;
|
registers.frontFace = type::FrontFace::CounterClockwise;
|
||||||
registers.cullFace = type::CullFace::Back;
|
registers.cullFace = type::CullFace::Back;
|
||||||
|
|
||||||
for (auto &mask : registers.colorMask)
|
for (auto &mask : *registers.colorMask)
|
||||||
mask.r = mask.g = mask.b = mask.a = 1;
|
mask.r = mask.g = mask.b = mask.a = 1;
|
||||||
|
|
||||||
for (auto &blend : registers.independentBlend) {
|
for (auto &blend : *registers.independentBlend) {
|
||||||
blend.colorOp = blend.alphaOp = type::Blend::Op::Add;
|
blend.colorOp = blend.alphaOp = type::Blend::Op::Add;
|
||||||
blend.colorSrcFactor = blend.alphaSrcFactor = type::Blend::Factor::One;
|
blend.colorSrcFactor = blend.alphaSrcFactor = type::Blend::Factor::One;
|
||||||
blend.colorDestFactor = blend.alphaDestFactor = type::Blend::Factor::Zero;
|
blend.colorDestFactor = blend.alphaDestFactor = type::Blend::Factor::Zero;
|
||||||
@ -105,27 +105,31 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAXWELL3D_OFFSET(field) U32_OFFSET(Registers, field)
|
#define MAXWELL3D_OFFSET(field) (sizeof(typeof(Registers::field)) - sizeof(typeof(*Registers::field))) / sizeof(u32)
|
||||||
#define MAXWELL3D_STRUCT_OFFSET(field, member) U32_OFFSET(Registers, field) + U32_OFFSET(typeof(Registers::field), member)
|
#define MAXWELL3D_STRUCT_OFFSET(field, member) MAXWELL3D_OFFSET(field) + U32_OFFSET(typeof(*Registers::field), member)
|
||||||
#define MAXWELL3D_ARRAY_OFFSET(field, index) U32_OFFSET(Registers, field) + ((sizeof(typeof(Registers::field[0])) / sizeof(u32)) * index)
|
#define MAXWELL3D_ARRAY_OFFSET(field, index) MAXWELL3D_OFFSET(field) + ((sizeof(typeof(Registers::field[0])) / sizeof(u32)) * index)
|
||||||
#define MAXWELL3D_ARRAY_STRUCT_OFFSET(field, index, member) MAXWELL3D_ARRAY_OFFSET(field, index) + U32_OFFSET(typeof(Registers::field[0]), member)
|
#define MAXWELL3D_ARRAY_STRUCT_OFFSET(field, index, member) MAXWELL3D_ARRAY_OFFSET(field, index) + U32_OFFSET(typeof(Registers::field[0]), member)
|
||||||
#define MAXWELL3D_ARRAY_STRUCT_STRUCT_OFFSET(field, index, member, submember) MAXWELL3D_ARRAY_STRUCT_OFFSET(field, index, member) + U32_OFFSET(typeof(Registers::field[0].member), submember)
|
#define MAXWELL3D_ARRAY_STRUCT_STRUCT_OFFSET(field, index, member, submember) MAXWELL3D_ARRAY_STRUCT_OFFSET(field, index, member) + U32_OFFSET(typeof(Registers::field[0].member), submember)
|
||||||
|
|
||||||
|
#define MAXWELL3D_CASE(field, content) case MAXWELL3D_OFFSET(field): { \
|
||||||
|
auto field{util::BitCast<typeof(*registers.field)>(argument)}; \
|
||||||
|
content \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
#define MAXWELL3D_CASE_BASE(fieldName, fieldAccessor, offset, content) case offset: { \
|
#define MAXWELL3D_CASE_BASE(fieldName, fieldAccessor, offset, content) case offset: { \
|
||||||
auto fieldName{util::BitCast<typeof(registers.fieldAccessor)>(argument)}; \
|
auto fieldName{util::BitCast<typeof(registers.fieldAccessor)>(argument)}; \
|
||||||
content \
|
content \
|
||||||
return; \
|
return; \
|
||||||
}
|
}
|
||||||
#define MAXWELL3D_CASE(field, content) MAXWELL3D_CASE_BASE(field, field, MAXWELL3D_OFFSET(field), content)
|
#define MAXWELL3D_STRUCT_CASE(field, member, content) MAXWELL3D_CASE_BASE(member, field->member, MAXWELL3D_STRUCT_OFFSET(field, member), content)
|
||||||
#define MAXWELL3D_STRUCT_CASE(field, member, content) MAXWELL3D_CASE_BASE(member, field.member, MAXWELL3D_STRUCT_OFFSET(field, member), content)
|
|
||||||
#define MAXWELL3D_ARRAY_CASE(field, index, content) MAXWELL3D_CASE_BASE(field, field[index], MAXWELL3D_ARRAY_OFFSET(field, 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_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)
|
#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_OFFSET(mme.shadowRamControl)) {
|
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)
|
||||||
argument = shadowRegisters.raw[method];
|
argument = shadowRegisters.raw[method];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +139,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
if (!redundant) {
|
if (!redundant) {
|
||||||
switch (method) {
|
switch (method) {
|
||||||
MAXWELL3D_STRUCT_CASE(mme, shadowRamControl, {
|
MAXWELL3D_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) \
|
||||||
@ -220,43 +224,43 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
#undef SCISSOR_CALLBACKS
|
#undef SCISSOR_CALLBACKS
|
||||||
|
|
||||||
MAXWELL3D_CASE(renderTargetControl, {
|
MAXWELL3D_CASE(renderTargetControl, {
|
||||||
context.UpdateRenderTargetControl(registers.renderTargetControl);
|
context.UpdateRenderTargetControl(renderTargetControl);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (method) {
|
switch (method) {
|
||||||
MAXWELL3D_STRUCT_CASE(mme, instructionRamLoad, {
|
MAXWELL3D_STRUCT_CASE(mme, instructionRamLoad, {
|
||||||
if (registers.mme.instructionRamPointer >= macroCode.size())
|
if (registers.mme->instructionRamPointer >= macroCode.size())
|
||||||
throw exception("Macro memory is full!");
|
throw exception("Macro memory is full!");
|
||||||
|
|
||||||
macroCode[registers.mme.instructionRamPointer++] = instructionRamLoad;
|
macroCode[registers.mme->instructionRamPointer++] = instructionRamLoad;
|
||||||
|
|
||||||
// Wraparound writes
|
// Wraparound writes
|
||||||
registers.mme.instructionRamPointer %= macroCode.size();
|
registers.mme->instructionRamPointer %= macroCode.size();
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(mme, startAddressRamLoad, {
|
MAXWELL3D_STRUCT_CASE(mme, startAddressRamLoad, {
|
||||||
if (registers.mme.startAddressRamPointer >= macroPositions.size())
|
if (registers.mme->startAddressRamPointer >= macroPositions.size())
|
||||||
throw exception("Maximum amount of macros reached!");
|
throw exception("Maximum amount of macros reached!");
|
||||||
|
|
||||||
macroPositions[registers.mme.startAddressRamPointer++] = startAddressRamLoad;
|
macroPositions[registers.mme->startAddressRamPointer++] = startAddressRamLoad;
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(syncpointAction, {
|
MAXWELL3D_CASE(syncpointAction, {
|
||||||
state.logger->Debug("Increment syncpoint: {}", +syncpointAction.id);
|
state.logger->Debug("Increment syncpoint: {}", static_cast<u16>(syncpointAction.id));
|
||||||
channelCtx.executor.Execute();
|
channelCtx.executor.Execute();
|
||||||
state.soc->host1x.syncpoints.at(syncpointAction.id).Increment();
|
state.soc->host1x.syncpoints.at(syncpointAction.id).Increment();
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_CASE(clearBuffers, {
|
MAXWELL3D_CASE(clearBuffers, {
|
||||||
context.ClearBuffers(registers.clearBuffers);
|
context.ClearBuffers(clearBuffers);
|
||||||
})
|
})
|
||||||
|
|
||||||
MAXWELL3D_STRUCT_CASE(semaphore, info, {
|
MAXWELL3D_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);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case type::SemaphoreInfo::Op::Counter: {
|
case type::SemaphoreInfo::Op::Counter: {
|
||||||
@ -306,9 +310,9 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
u64 timestamp;
|
u64 timestamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (registers.semaphore.info.structureSize) {
|
switch (registers.semaphore->info.structureSize) {
|
||||||
case type::SemaphoreInfo::StructureSize::OneWord:
|
case type::SemaphoreInfo::StructureSize::OneWord:
|
||||||
channelCtx.asCtx->gmmu.Write<u32>(registers.semaphore.address.Pack(), static_cast<u32>(result));
|
channelCtx.asCtx->gmmu.Write<u32>(registers.semaphore->address.Pack(), static_cast<u32>(result));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case type::SemaphoreInfo::StructureSize::FourWords: {
|
case type::SemaphoreInfo::StructureSize::FourWords: {
|
||||||
@ -319,7 +323,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
i64 nsTime{util::GetTimeNs()};
|
i64 nsTime{util::GetTimeNs()};
|
||||||
i64 timestamp{(nsTime / NsToTickDenominator) * NsToTickNumerator + ((nsTime % NsToTickDenominator) * NsToTickNumerator) / NsToTickDenominator};
|
i64 timestamp{(nsTime / NsToTickDenominator) * NsToTickNumerator + ((nsTime % NsToTickDenominator) * NsToTickNumerator) / NsToTickDenominator};
|
||||||
|
|
||||||
channelCtx.asCtx->gmmu.Write<FourWordResult>(registers.semaphore.address.Pack(),
|
channelCtx.asCtx->gmmu.Write<FourWordResult>(registers.semaphore->address.Pack(),
|
||||||
FourWordResult{result, static_cast<u64>(timestamp)});
|
FourWordResult{result, static_cast<u64>(timestamp)});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -46,204 +46,163 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
union Registers {
|
union Registers {
|
||||||
std::array<u32, RegisterCount> raw;
|
std::array<u32, RegisterCount> raw;
|
||||||
|
|
||||||
struct {
|
template<size_t Offset, typename Type>
|
||||||
u32 _pad0_[0x40]; // 0x0
|
using Register = util::OffsetMember<Offset, Type, u32>;
|
||||||
u32 noOperation; // 0x40
|
|
||||||
u32 _pad1_[0x3]; // 0x41
|
|
||||||
u32 waitForIdle; // 0x44
|
|
||||||
|
|
||||||
struct {
|
Register<0x40, u32> noOperation;
|
||||||
u32 instructionRamPointer; // 0x45
|
Register<0x44, u32> waitForIdle;
|
||||||
u32 instructionRamLoad; // 0x46
|
|
||||||
u32 startAddressRamPointer; // 0x47
|
|
||||||
u32 startAddressRamLoad; // 0x48
|
|
||||||
type::MmeShadowRamControl shadowRamControl; // 0x49
|
|
||||||
} mme;
|
|
||||||
|
|
||||||
u32 _pad2_[0x68]; // 0x4A
|
struct MME {
|
||||||
|
u32 instructionRamPointer; // 0x45
|
||||||
struct {
|
u32 instructionRamLoad; // 0x46
|
||||||
u16 id : 12;
|
u32 startAddressRamPointer; // 0x47
|
||||||
u8 _pad0_ : 4;
|
u32 startAddressRamLoad; // 0x48
|
||||||
bool flushCache : 1;
|
type::MmeShadowRamControl shadowRamControl; // 0x49
|
||||||
u8 _pad1_ : 3;
|
|
||||||
bool increment : 1;
|
|
||||||
u16 _pad2_ : 11;
|
|
||||||
} syncpointAction; // 0xB2
|
|
||||||
|
|
||||||
u32 _pad3_[0x2C]; // 0xB3
|
|
||||||
u32 rasterizerEnable; // 0xDF
|
|
||||||
u32 _pad4_[0x120]; // 0xE0
|
|
||||||
std::array<type::RenderTarget, type::RenderTargetCount> renderTargets; // 0x200
|
|
||||||
std::array<type::ViewportTransform, type::ViewportCount> viewportTransforms; // 0x280
|
|
||||||
std::array<type::Viewport, type::ViewportCount> viewports; // 0x300
|
|
||||||
u32 _pad5_[0x20]; // 0x340
|
|
||||||
|
|
||||||
std::array<u32, 4> clearColorValue; // 0x360
|
|
||||||
u32 clearDepthValue; // 0x364
|
|
||||||
|
|
||||||
u32 _pad5_1_[0x6]; // 0x365
|
|
||||||
|
|
||||||
struct {
|
|
||||||
type::PolygonMode front; // 0x36B
|
|
||||||
type::PolygonMode back; // 0x36C
|
|
||||||
} polygonMode;
|
|
||||||
|
|
||||||
u32 _pad6_[0x13]; // 0x36D
|
|
||||||
std::array<type::Scissor, type::ViewportCount> scissors; // 0x380
|
|
||||||
u32 _pad6_1_[0x15]; // 0x3C0
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u32 compareRef; // 0x3D5
|
|
||||||
u32 writeMask; // 0x3D6
|
|
||||||
u32 compareMask; // 0x3D7
|
|
||||||
} stencilBackExtra;
|
|
||||||
|
|
||||||
u32 tiledCacheEnable; // 0x3D8
|
|
||||||
struct {
|
|
||||||
u16 width;
|
|
||||||
u16 height;
|
|
||||||
} tiledCacheSize; // 0x3D9
|
|
||||||
|
|
||||||
u32 _pad7_[0x11]; // 0x3DA
|
|
||||||
u32 rtSeparateFragData; // 0x3EB
|
|
||||||
u32 _pad8_[0x6C]; // 0x3EC
|
|
||||||
std::array<type::VertexAttribute, 0x20> vertexAttributeState; // 0x458
|
|
||||||
u32 _pad9_[0xF]; // 0x478
|
|
||||||
type::RenderTargetControl renderTargetControl; // 0x487
|
|
||||||
u32 _pad9_1_[0x3B]; // 0x488
|
|
||||||
type::CompareOp depthTestFunc; // 0x4C3
|
|
||||||
float alphaTestRef; // 0x4C4
|
|
||||||
type::CompareOp alphaTestFunc; // 0x4C5
|
|
||||||
u32 drawTFBStride; // 0x4C6
|
|
||||||
|
|
||||||
struct {
|
|
||||||
float r; // 0x4C7
|
|
||||||
float g; // 0x4C8
|
|
||||||
float b; // 0x4C9
|
|
||||||
float a; // 0x4CA
|
|
||||||
} blendConstant;
|
|
||||||
|
|
||||||
u32 _pad10_[0x4]; // 0x4CB
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u32 seperateAlpha; // 0x4CF
|
|
||||||
type::Blend::Op colorOp; // 0x4D0
|
|
||||||
type::Blend::Factor colorSrcFactor; // 0x4D1
|
|
||||||
type::Blend::Factor colorDestFactor; // 0x4D2
|
|
||||||
type::Blend::Op alphaOp; // 0x4D3
|
|
||||||
type::Blend::Factor alphaSrcFactor; // 0x4D4
|
|
||||||
u32 _pad_; // 0x4D5
|
|
||||||
type::Blend::Factor alphaDestFactor; // 0x4D6
|
|
||||||
|
|
||||||
u32 enableCommon; // 0x4D7
|
|
||||||
std::array<u32, 8> enable; // 0x4D8 For each render target
|
|
||||||
} blend;
|
|
||||||
|
|
||||||
u32 stencilEnable; // 0x4E0
|
|
||||||
|
|
||||||
struct {
|
|
||||||
type::StencilOp failOp; // 0x4E1
|
|
||||||
type::StencilOp zFailOp; // 0x4E2
|
|
||||||
type::StencilOp zPassOp; // 0x4E3
|
|
||||||
|
|
||||||
struct {
|
|
||||||
type::CompareOp op; // 0x4E4
|
|
||||||
i32 ref; // 0x4E5
|
|
||||||
u32 mask; // 0x4E6
|
|
||||||
} compare;
|
|
||||||
|
|
||||||
u32 writeMask; // 0x4E7
|
|
||||||
} stencilFront;
|
|
||||||
|
|
||||||
u32 _pad11_[0x4]; // 0x4E8
|
|
||||||
float lineWidthSmooth; // 0x4EC
|
|
||||||
float lineWidthAliased; // 0x4D
|
|
||||||
u32 _pad12_[0x1F]; // 0x4EE
|
|
||||||
u32 drawBaseVertex; // 0x50D
|
|
||||||
u32 drawBaseInstance; // 0x50E
|
|
||||||
u32 _pad13_[0x35]; // 0x50F
|
|
||||||
u32 clipDistanceEnable; // 0x544
|
|
||||||
u32 sampleCounterEnable; // 0x545
|
|
||||||
float pointSpriteSize; // 0x546
|
|
||||||
u32 zCullStatCountersEnable; // 0x547
|
|
||||||
u32 pointSpriteEnable; // 0x548
|
|
||||||
u32 _pad14_; // 0x549
|
|
||||||
u32 shaderExceptions; // 0x54A
|
|
||||||
u32 _pad15_[0x2]; // 0x54B
|
|
||||||
u32 multisampleEnable; // 0x54D
|
|
||||||
u32 depthTargetEnable; // 0x54E
|
|
||||||
|
|
||||||
struct {
|
|
||||||
bool alphaToCoverage : 1;
|
|
||||||
u8 _pad0_ : 3;
|
|
||||||
bool alphaToOne : 1;
|
|
||||||
u32 _pad1_ : 27;
|
|
||||||
} multisampleControl; // 0x54F
|
|
||||||
|
|
||||||
u32 _pad16_[0x7]; // 0x550
|
|
||||||
|
|
||||||
struct {
|
|
||||||
type::Address address; // 0x557
|
|
||||||
u32 maximumIndex; // 0x559
|
|
||||||
} texSamplerPool;
|
|
||||||
|
|
||||||
u32 _pad17_; // 0x55A
|
|
||||||
u32 polygonOffsetFactor; // 0x55B
|
|
||||||
u32 lineSmoothEnable; // 0x55C
|
|
||||||
|
|
||||||
struct {
|
|
||||||
type::Address address; // 0x55D
|
|
||||||
u32 maximumIndex; // 0x55F
|
|
||||||
} texHeaderPool;
|
|
||||||
|
|
||||||
u32 _pad18_[0x5]; // 0x560
|
|
||||||
|
|
||||||
u32 stencilTwoSideEnable; // 0x565
|
|
||||||
|
|
||||||
struct {
|
|
||||||
type::StencilOp failOp; // 0x566
|
|
||||||
type::StencilOp zFailOp; // 0x567
|
|
||||||
type::StencilOp zPassOp; // 0x568
|
|
||||||
type::CompareOp compareOp; // 0x569
|
|
||||||
} stencilBack;
|
|
||||||
|
|
||||||
u32 _pad19_[0x17]; // 0x56A
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u8 _unk_ : 2;
|
|
||||||
type::CoordOrigin origin : 1;
|
|
||||||
u16 enable : 10;
|
|
||||||
u32 _pad_ : 19;
|
|
||||||
} pointCoordReplace; // 0x581
|
|
||||||
|
|
||||||
u32 _pad20_[0xC4]; // 0x582
|
|
||||||
u32 cullFaceEnable; // 0x646
|
|
||||||
type::FrontFace frontFace; // 0x647
|
|
||||||
type::CullFace cullFace; // 0x648
|
|
||||||
u32 pixelCentreImage; // 0x649
|
|
||||||
u32 _pad21_; // 0x64A
|
|
||||||
u32 viewportTransformEnable; // 0x64B
|
|
||||||
u32 _pad22_[0x28]; // 0x64C
|
|
||||||
type::ClearBuffers clearBuffers; // 0x674
|
|
||||||
u32 _pad22_1_[0xB]; // 0x675
|
|
||||||
std::array<type::ColorWriteMask, type::RenderTargetCount> colorMask; // 0x680
|
|
||||||
u32 _pad23_[0x38]; // 0x688
|
|
||||||
|
|
||||||
struct {
|
|
||||||
type::Address address; // 0x6C0
|
|
||||||
u32 payload; // 0x6C2
|
|
||||||
type::SemaphoreInfo info; // 0x6C3
|
|
||||||
} semaphore;
|
|
||||||
|
|
||||||
u32 _pad24_[0xBC]; // 0x6C4
|
|
||||||
std::array<type::Blend, type::RenderTargetCount> independentBlend; // 0x780
|
|
||||||
u32 _pad25_[0x100]; // 0x7C0
|
|
||||||
u32 firmwareCall[0x20]; // 0x8C0
|
|
||||||
};
|
};
|
||||||
|
Register<0x45, MME> mme;
|
||||||
|
|
||||||
|
Register<0xB2, type::SyncpointAction> syncpointAction;
|
||||||
|
|
||||||
|
Register<0xDF, u32> rasterizerEnable;
|
||||||
|
Register<0x200, std::array<type::RenderTarget, type::RenderTargetCount>> renderTargets;
|
||||||
|
Register<0x280, std::array<type::ViewportTransform, type::ViewportCount>> viewportTransforms;
|
||||||
|
Register<0x300, std::array<type::Viewport, type::ViewportCount>> viewports;
|
||||||
|
|
||||||
|
Register<0x360, std::array<u32, 4>> clearColorValue;
|
||||||
|
Register<0x364, u32> clearDepthValue;
|
||||||
|
|
||||||
|
struct PolygonMode {
|
||||||
|
type::PolygonMode front; // 0x36B
|
||||||
|
type::PolygonMode back; // 0x36C
|
||||||
|
};
|
||||||
|
Register<0x36B, PolygonMode> polygonMode;
|
||||||
|
|
||||||
|
Register<0x380, std::array<type::Scissor, type::ViewportCount>> scissors;
|
||||||
|
|
||||||
|
struct StencilBackExtra {
|
||||||
|
u32 compareRef; // 0x3D5
|
||||||
|
u32 writeMask; // 0x3D6
|
||||||
|
u32 compareMask; // 0x3D7
|
||||||
|
};
|
||||||
|
Register<0x3D5, StencilBackExtra> stencilBackExtra;
|
||||||
|
|
||||||
|
Register<0x3D8, u32> tiledCacheEnable;
|
||||||
|
struct TiledCacheSize {
|
||||||
|
u16 width;
|
||||||
|
u16 height;
|
||||||
|
};
|
||||||
|
Register<0x3D9, TiledCacheSize> tiledCacheSize;
|
||||||
|
|
||||||
|
Register<0x3EB, u32> rtSeparateFragData;
|
||||||
|
Register<0x458, std::array<type::VertexAttribute, 0x20>> vertexAttributeState;
|
||||||
|
Register<0x487, type::RenderTargetControl> renderTargetControl;
|
||||||
|
Register<0x4C3, type::CompareOp> depthTestFunc;
|
||||||
|
Register<0x4C4, float> alphaTestRef;
|
||||||
|
Register<0x4C5, type::CompareOp> alphaTestFunc;
|
||||||
|
Register<0x4C6, u32> drawTFBStride;
|
||||||
|
|
||||||
|
struct BlendConstant {
|
||||||
|
float r; // 0x4C7
|
||||||
|
float g; // 0x4C8
|
||||||
|
float b; // 0x4C9
|
||||||
|
float a; // 0x4CA
|
||||||
|
};
|
||||||
|
Register<0x4C7, BlendConstant> blendConstant;
|
||||||
|
|
||||||
|
struct BlendState {
|
||||||
|
u32 seperateAlpha; // 0x4CF
|
||||||
|
type::Blend::Op colorOp; // 0x4D0
|
||||||
|
type::Blend::Factor colorSrcFactor; // 0x4D1
|
||||||
|
type::Blend::Factor colorDestFactor; // 0x4D2
|
||||||
|
type::Blend::Op alphaOp; // 0x4D3
|
||||||
|
type::Blend::Factor alphaSrcFactor; // 0x4D4
|
||||||
|
type::Blend::Factor alphaDestFactor; // 0x4D6
|
||||||
|
|
||||||
|
u32 enableCommon; // 0x4D7
|
||||||
|
std::array<u32, 8> enable; // 0x4D8 For each render target
|
||||||
|
};
|
||||||
|
Register<0x4CF, BlendState> blendState;
|
||||||
|
|
||||||
|
Register<0x4E0, u32> stencilEnable;
|
||||||
|
struct StencilFront {
|
||||||
|
type::StencilOp failOp; // 0x4E1
|
||||||
|
type::StencilOp zFailOp; // 0x4E2
|
||||||
|
type::StencilOp zPassOp; // 0x4E3
|
||||||
|
|
||||||
|
struct {
|
||||||
|
type::CompareOp op; // 0x4E4
|
||||||
|
i32 ref; // 0x4E5
|
||||||
|
u32 mask; // 0x4E6
|
||||||
|
} compare;
|
||||||
|
|
||||||
|
u32 writeMask; // 0x4E7
|
||||||
|
};
|
||||||
|
Register<0x4E1, StencilFront> stencilFront;
|
||||||
|
|
||||||
|
Register<0x4EC, float> lineWidthSmooth;
|
||||||
|
Register<0x4D, float> lineWidthAliased;
|
||||||
|
|
||||||
|
Register<0x50D, u32> drawBaseVertex;
|
||||||
|
Register<0x50E, u32> drawBaseInstance;
|
||||||
|
|
||||||
|
Register<0x544, u32> clipDistanceEnable;
|
||||||
|
Register<0x545, u32> sampleCounterEnable;
|
||||||
|
Register<0x546, float> pointSpriteSize;
|
||||||
|
Register<0x547, u32> zCullStatCountersEnable;
|
||||||
|
Register<0x548, u32> pointSpriteEnable;
|
||||||
|
Register<0x54A, u32> shaderExceptions;
|
||||||
|
Register<0x54D, u32> multisampleEnable;
|
||||||
|
Register<0x54E, u32> depthTargetEnable;
|
||||||
|
|
||||||
|
Register<0x54F, type::MultisampleControl> multisampleControl;
|
||||||
|
|
||||||
|
struct SamplerPool {
|
||||||
|
type::Address address; // 0x557
|
||||||
|
u32 maximumIndex; // 0x559
|
||||||
|
};
|
||||||
|
Register<0x557, SamplerPool> samplerPool;
|
||||||
|
|
||||||
|
Register<0x55B, u32> polygonOffsetFactor;
|
||||||
|
Register<0x55C, u32> lineSmoothEnable;
|
||||||
|
|
||||||
|
struct TexturePool {
|
||||||
|
type::Address address; // 0x55D
|
||||||
|
u32 maximumIndex; // 0x55F
|
||||||
|
};
|
||||||
|
Register<0x55D, TexturePool> texturePool;
|
||||||
|
|
||||||
|
|
||||||
|
Register<0x565, u32> stencilTwoSideEnable;
|
||||||
|
|
||||||
|
struct StencilBack {
|
||||||
|
type::StencilOp failOp; // 0x566
|
||||||
|
type::StencilOp zFailOp; // 0x567
|
||||||
|
type::StencilOp zPassOp; // 0x568
|
||||||
|
type::CompareOp compareOp; // 0x569
|
||||||
|
};
|
||||||
|
Register<0x566, StencilBack> stencilBack;
|
||||||
|
|
||||||
|
Register<0x581, type::PointCoordReplace> pointCoordReplace;
|
||||||
|
|
||||||
|
Register<0x646, u32> cullFaceEnable;
|
||||||
|
Register<0x647, type::FrontFace> frontFace;
|
||||||
|
Register<0x648, type::CullFace> cullFace;
|
||||||
|
Register<0x649, u32> pixelCentreImage;
|
||||||
|
Register<0x64B, u32> viewportTransformEnable;
|
||||||
|
Register<0x674, type::ClearBuffers> clearBuffers;
|
||||||
|
Register<0x680, std::array<type::ColorWriteMask, type::RenderTargetCount>> colorMask;
|
||||||
|
|
||||||
|
struct Semaphore {
|
||||||
|
type::Address address; // 0x6C0
|
||||||
|
u32 payload; // 0x6C2
|
||||||
|
type::SemaphoreInfo info; // 0x6C3
|
||||||
|
};
|
||||||
|
Register<0x6C0, Semaphore> semaphore;
|
||||||
|
|
||||||
|
Register<0x780, std::array<type::Blend, type::RenderTargetCount>> independentBlend;
|
||||||
|
Register<0x8C0, u32[0x20]> firmwareCall;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(Registers) == (RegisterCount * sizeof(u32)));
|
static_assert(sizeof(Registers) == (RegisterCount * sizeof(u32)));
|
||||||
static_assert(U32_OFFSET(Registers, firmwareCall) == 0x8C0);
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
Registers registers{};
|
Registers registers{};
|
||||||
|
Loading…
Reference in New Issue
Block a user