Implement Maxwell3D Depth/Stencil State

Implements the entirety of Maxwell3D Depth/Stencil state for both faces including compare/write masks and reference value. Maxwell3D register `stencilTwoSideEnable` is ignored as its behavior is unknown and could mean the same behavior for both stencils or the back facing stencil being disabled as a result of this it is unimplemented.
This commit is contained in:
PixelyIon 2022-01-13 02:27:43 +05:30
parent 9f5c3d8ecd
commit 6a6f51ea84
3 changed files with 244 additions and 8 deletions

View File

@ -2052,6 +2052,151 @@ namespace skyline::gpu::interconnect {
/* Depth */
vk::PipelineDepthStencilStateCreateInfo depthState{};
void SetDepthTestEnabled(bool enabled) {
depthState.depthTestEnable = enabled;
}
vk::CompareOp ConvertCompareOp(maxwell3d::CompareOp op) {
using MaxwellOp = maxwell3d::CompareOp;
using VkOp = vk::CompareOp;
switch (op) {
case MaxwellOp::Never:
case MaxwellOp::NeverGL:
return VkOp::eNever;
case MaxwellOp::Less:
case MaxwellOp::LessGL:
return VkOp::eLess;
case MaxwellOp::Equal:
case MaxwellOp::EqualGL:
return VkOp::eEqual;
case MaxwellOp::LessOrEqual:
case MaxwellOp::LessOrEqualGL:
return VkOp::eLessOrEqual;
case MaxwellOp::Greater:
case MaxwellOp::GreaterGL:
return VkOp::eGreater;
case MaxwellOp::NotEqual:
case MaxwellOp::NotEqualGL:
return VkOp::eNotEqual;
case MaxwellOp::GreaterOrEqual:
case MaxwellOp::GreaterOrEqualGL:
return VkOp::eGreaterOrEqual;
case MaxwellOp::Always:
case MaxwellOp::AlwaysGL:
return VkOp::eAlways;
}
}
void SetDepthTestFunction(maxwell3d::CompareOp function) {
depthState.depthCompareOp = ConvertCompareOp(function);
}
void SetDepthWriteEnabled(bool enabled) {
depthState.depthWriteEnable = enabled;
}
void SetDepthBoundsTestEnabled(bool enabled) {
depthState.depthBoundsTestEnable = enabled;
}
void SetMinDepthBounds(float min) {
depthState.minDepthBounds = min;
}
void SetMaxDepthBounds(float max) {
depthState.maxDepthBounds = max;
}
void SetStencilTestEnabled(bool enabled) {
depthState.stencilTestEnable = enabled;
}
vk::StencilOp ConvertStencilOp(maxwell3d::StencilOp op) {
using MaxwellOp = maxwell3d::StencilOp;
using VkOp = vk::StencilOp;
switch (op) {
case MaxwellOp::Keep:
return VkOp::eKeep;
case MaxwellOp::Zero:
return VkOp::eZero;
case MaxwellOp::Replace:
return VkOp::eReplace;
case MaxwellOp::IncrementAndClamp:
return VkOp::eIncrementAndClamp;
case MaxwellOp::DecrementAndClamp:
return VkOp::eDecrementAndClamp;
case MaxwellOp::Invert:
return VkOp::eInvert;
case MaxwellOp::IncrementAndWrap:
return VkOp::eIncrementAndWrap;
case MaxwellOp::DecrementAndWrap:
return VkOp::eDecrementAndWrap;
}
}
void SetStencilFrontFailOp(maxwell3d::StencilOp op) {
depthState.front.failOp = ConvertStencilOp(op);
}
void SetStencilBackFailOp(maxwell3d::StencilOp op) {
depthState.back.failOp = ConvertStencilOp(op);
}
void SetStencilFrontPassOp(maxwell3d::StencilOp op) {
depthState.front.passOp = ConvertStencilOp(op);
}
void SetStencilBackPassOp(maxwell3d::StencilOp op) {
depthState.back.passOp = ConvertStencilOp(op);
}
void SetStencilFrontDepthFailOp(maxwell3d::StencilOp op) {
depthState.front.depthFailOp = ConvertStencilOp(op);
}
void SetStencilBackDepthFailOp(maxwell3d::StencilOp op) {
depthState.back.depthFailOp = ConvertStencilOp(op);
}
void SetStencilFrontCompareOp(maxwell3d::CompareOp op) {
depthState.front.compareOp = ConvertCompareOp(op);
}
void SetStencilBackCompareOp(maxwell3d::CompareOp op) {
depthState.back.compareOp = ConvertCompareOp(op);
}
void SetStencilFrontCompareMask(u32 mask) {
depthState.front.compareMask = mask;
}
void SetStencilBackCompareMask(u32 mask) {
depthState.back.compareMask = mask;
}
void SetStencilFrontWriteMask(u32 mask) {
depthState.front.writeMask = mask;
}
void SetStencilBackWriteMask(u32 mask) {
depthState.back.writeMask = mask;
}
void SetStencilFrontReference(u32 reference) {
depthState.front.reference = reference;
}
void SetStencilBackReference(u32 reference) {
depthState.back.reference = reference;
}
/* Multisampling */
vk::PipelineMultisampleStateCreateInfo multisampleState{
.rasterizationSamples = vk::SampleCountFlagBits::e1,

View File

@ -234,6 +234,90 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
context.UpdateRenderTargetControl(renderTargetControl);
})
MAXWELL3D_CASE(depthTestEnable, {
context.SetDepthTestEnabled(depthTestEnable);
})
MAXWELL3D_CASE(depthTestFunc, {
context.SetDepthTestFunction(depthTestFunc);
})
MAXWELL3D_CASE(depthWriteEnable, {
context.SetDepthWriteEnabled(depthWriteEnable);
})
MAXWELL3D_CASE(depthBoundsEnable, {
context.SetDepthBoundsTestEnabled(depthBoundsEnable);
})
MAXWELL3D_CASE(depthBoundsNear, {
context.SetMinDepthBounds(depthBoundsNear);
})
MAXWELL3D_CASE(depthBoundsFar, {
context.SetMaxDepthBounds(depthBoundsFar);
})
MAXWELL3D_CASE(stencilEnable, {
context.SetStencilTestEnabled(stencilEnable);
})
MAXWELL3D_STRUCT_CASE(stencilFront, failOp, {
context.SetStencilFrontFailOp(failOp);
})
MAXWELL3D_STRUCT_CASE(stencilFront, zFailOp, {
context.SetStencilFrontDepthFailOp(zFailOp);
})
MAXWELL3D_STRUCT_CASE(stencilFront, passOp, {
context.SetStencilFrontPassOp(passOp);
})
MAXWELL3D_STRUCT_CASE(stencilFront, compareOp, {
context.SetStencilFrontCompareOp(compareOp);
})
MAXWELL3D_STRUCT_CASE(stencilFront, compareReference, {
context.SetStencilFrontReference(compareReference);
})
MAXWELL3D_STRUCT_CASE(stencilFront, compareMask, {
context.SetStencilFrontCompareMask(compareMask);
})
MAXWELL3D_STRUCT_CASE(stencilFront, writeMask, {
context.SetStencilFrontWriteMask(writeMask);
})
MAXWELL3D_STRUCT_CASE(stencilBack, failOp, {
context.SetStencilBackFailOp(failOp);
})
MAXWELL3D_STRUCT_CASE(stencilBack, zFailOp, {
context.SetStencilBackDepthFailOp(zFailOp);
})
MAXWELL3D_STRUCT_CASE(stencilBack, passOp, {
context.SetStencilBackPassOp(passOp);
})
MAXWELL3D_STRUCT_CASE(stencilBack, compareOp, {
context.SetStencilBackCompareOp(compareOp);
})
MAXWELL3D_STRUCT_CASE(stencilBackExtra, compareReference, {
context.SetStencilBackReference(compareReference);
})
MAXWELL3D_STRUCT_CASE(stencilBackExtra, compareMask, {
context.SetStencilBackCompareMask(compareMask);
})
MAXWELL3D_STRUCT_CASE(stencilBackExtra, writeMask, {
context.SetStencilBackWriteMask(writeMask);
})
MAXWELL3D_CASE(independentBlendEnable, {
context.SetIndependentBlendingEnabled(independentBlendEnable);
})

View File

@ -95,7 +95,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
Register<0x370, DepthBiasEnable> depthBiasEnable;
struct StencilBackExtra {
u32 compareRef; // 0x3D5
u32 compareReference; // 0x3D5
u32 writeMask; // 0x3D6
u32 compareMask; // 0x3D7
};
@ -109,6 +109,10 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
Register<0x3D9, TiledCacheSize> tiledCacheSize;
Register<0x3E4, u32> commonColorWriteMask; //!< If enabled, the color write masks for all RTs must be set to that of the first RT
Register<0x3E7, float> depthBoundsNear;
Register<0x3E8, float> depthBoundsFar;
Register<0x3EB, u32> rtSeparateFragData;
Register<0x3F8, type::Address> depthTargetAddress;
@ -117,13 +121,16 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
Register<0x3FC, u32> depthTargetLayerStride;
Register<0x458, std::array<type::VertexAttribute, type::VertexAttributeCount>> vertexAttributeState;
Register<0x487, type::RenderTargetControl> renderTargetControl;
Register<0x48A, u32> depthTargetWidth;
Register<0x48B, u32> depthTargetHeight;
Register<0x48C, type::RenderTargetArrayMode> depthTargetArrayMode;
Register<0x4B3, u32> depthTestEnable;
Register<0x4B9, u32> independentBlendEnable;
Register<0x4BA, u32> depthWriteEnable;
Register<0x4BB, u32> alphaTestEnable;
Register<0x4C3, type::CompareOp> depthTestFunc;
Register<0x4C4, float> alphaTestRef;
@ -158,13 +165,11 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
struct StencilFront {
type::StencilOp failOp; // 0x4E1
type::StencilOp zFailOp; // 0x4E2
type::StencilOp zPassOp; // 0x4E3
type::StencilOp passOp; // 0x4E3
struct {
type::CompareOp op; // 0x4E4
i32 ref; // 0x4E5
u32 mask; // 0x4E6
} compare;
type::CompareOp compareOp; // 0x4E4
u32 compareReference; // 0x4E5
u32 compareMask; // 0x4E6
u32 writeMask; // 0x4E7
};
@ -207,7 +212,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
struct StencilBack {
type::StencilOp failOp; // 0x566
type::StencilOp zFailOp; // 0x567
type::StencilOp zPassOp; // 0x568
type::StencilOp passOp; // 0x568
type::CompareOp compareOp; // 0x569
};
Register<0x566, StencilBack> stencilBack;
@ -239,6 +244,8 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
Register<0x64B, u32> viewportTransformEnable;
Register<0x64F, type::ViewVolumeClipControl> viewVolumeClipControl;
Register<0x66F, u32> depthBoundsEnable;
struct ColorLogicOp {
u32 enable;
type::ColorLogicOp type;