Implement depth stencil pipeline state

This commit is contained in:
Billy Laws 2022-09-03 12:36:56 +01:00
parent 2484a2d6b5
commit cb11662ea5
5 changed files with 130 additions and 10 deletions

View File

@ -542,6 +542,92 @@ namespace skyline::gpu::interconnect::maxwell3d {
rasterizationState.get<vk::PipelineRasterizationProvokingVertexStateCreateInfoEXT>().provokingVertexMode = ConvertProvokingVertex(engine->provokingVertex.value);
}
/* Depth Stencil State */
void DepthStencilState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const {
manager.Bind(handle, depthTestEnable, depthWriteEnable, depthFunc, depthBoundsTestEnable, stencilTestEnable, twoSidedStencilTestEnable, stencilOps, stencilBack);
}
DepthStencilState::DepthStencilState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine) : engine{manager, dirtyHandle, engine} {}
static vk::CompareOp ConvertCompareFunc(engine::CompareFunc func) {
switch (func) {
case engine::CompareFunc::D3DNever:
case engine::CompareFunc::OglNever:
return vk::CompareOp::eNever;
case engine::CompareFunc::D3DLess:
case engine::CompareFunc::OglLess:
return vk::CompareOp::eLess;
case engine::CompareFunc::D3DEqual:
case engine::CompareFunc::OglEqual:
return vk::CompareOp::eEqual;
case engine::CompareFunc::D3DLessEqual:
case engine::CompareFunc::OglLEqual:
return vk::CompareOp::eLessOrEqual;
case engine::CompareFunc::D3DGreater:
case engine::CompareFunc::OglGreater:
return vk::CompareOp::eGreater;
case engine::CompareFunc::D3DNotEqual:
case engine::CompareFunc::OglNotEqual:
return vk::CompareOp::eNotEqual;
case engine::CompareFunc::D3DGreaterEqual:
case engine::CompareFunc::OglGEqual:
return vk::CompareOp::eGreaterOrEqual;
case engine::CompareFunc::D3DAlways:
case engine::CompareFunc::OglAlways:
return vk::CompareOp::eAlways;
}
}
static vk::StencilOp ConvertStencilOp(engine::StencilOps::Op op) {
switch (op) {
case engine::StencilOps::Op::OglZero:
case engine::StencilOps::Op::D3DZero:
return vk::StencilOp::eZero;
case engine::StencilOps::Op::D3DKeep:
case engine::StencilOps::Op::OglKeep:
return vk::StencilOp::eKeep;
case engine::StencilOps::Op::D3DReplace:
case engine::StencilOps::Op::OglReplace:
return vk::StencilOp::eReplace;
case engine::StencilOps::Op::D3DIncrSat:
case engine::StencilOps::Op::OglIncrSat:
return vk::StencilOp::eIncrementAndClamp;
case engine::StencilOps::Op::D3DDecrSat:
case engine::StencilOps::Op::OglDecrSat:
return vk::StencilOp::eDecrementAndClamp;
case engine::StencilOps::Op::D3DInvert:
case engine::StencilOps::Op::OglInvert:
return vk::StencilOp::eInvert;
case engine::StencilOps::Op::D3DIncr:
case engine::StencilOps::Op::OglIncr:
return vk::StencilOp::eIncrementAndWrap;
case engine::StencilOps::Op::D3DDecr:
case engine::StencilOps::Op::OglDecr:
return vk::StencilOp::eDecrementAndWrap;
}
}
static vk::StencilOpState ConvertStencilOpsState(engine::StencilOps ops) {
return {
.passOp = ConvertStencilOp(ops.zPass),
.depthFailOp = ConvertStencilOp(ops.zFail),
.failOp = ConvertStencilOp(ops.fail),
.compareOp = ConvertCompareFunc(ops.func),
};
}
void DepthStencilState::Flush() {
depthStencilState.depthTestEnable = engine->depthTestEnable;
depthStencilState.depthWriteEnable = engine->depthWriteEnable;
depthStencilState.depthCompareOp = ConvertCompareFunc(engine->depthFunc);
depthStencilState.depthBoundsTestEnable = engine->depthBoundsTestEnable;
depthStencilState.stencilTestEnable = engine->stencilTestEnable;
auto stencilBack{engine->twoSidedStencilTestEnable ? engine->stencilBack : engine->stencilOps};
depthStencilState.front = ConvertStencilOpsState(engine->stencilOps);
depthStencilState.back = ConvertStencilOpsState(stencilBack);
};
/* Pipeline State */
void PipelineState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const {
auto bindFunc{[&](auto &regs) { regs.DirtyBind(manager, handle); }};
@ -555,7 +641,8 @@ namespace skyline::gpu::interconnect::maxwell3d {
: engine{manager, dirtyHandle, engine},
colorRenderTargets{util::MergeInto<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount>(manager, engine.colorRenderTargetsRegisters)},
depthRenderTarget{manager, engine.depthRenderTargetRegisters},
rasterization{manager, engine.rasterizationRegisters} {}
rasterization{manager, engine.rasterizationRegisters},
depthStencil{manager, engine.depthStencilRegisters} {}
void PipelineState::Flush(InterconnectContext &ctx, StateUpdateBuilder &builder) {
auto updateFunc{[&](auto &stateElem, auto &&... args) { stateElem.Update(ctx, args...); }};
@ -563,9 +650,14 @@ namespace skyline::gpu::interconnect::maxwell3d {
updateFunc(depthRenderTarget);
auto vertexState{directState.vertexInput.Build(ctx, engine->vertexInputRegisters)};
auto inputAssemblyState{directState.inputAssembly.Build()};
auto tessellationState{directState.tessellation.Build()};
const auto &inputAssemblyState{directState.inputAssembly.Build()};
const auto &tessellationState{directState.tessellation.Build()};
const auto &rasterizationState{rasterization.UpdateGet().rasterizationState};
vk::PipelineMultisampleStateCreateInfo multisampleState{
.rasterizationSamples = vk::SampleCountFlagBits::e1
};
const auto &depthStencilState{depthStencil.UpdateGet().depthStencilState};
}

View File

@ -170,6 +170,32 @@ namespace skyline::gpu::interconnect::maxwell3d {
void Flush();
};
class DepthStencilState : dirty::ManualDirty {
public:
struct EngineRegisters {
const u32 &depthTestEnable;
const u32 &depthWriteEnable;
const engine::CompareFunc &depthFunc;
const u32 &depthBoundsTestEnable;
const u32 &stencilTestEnable;
const u32 &twoSidedStencilTestEnable;
const engine::StencilOps &stencilOps;
const engine::StencilOps &stencilBack;
void DirtyBind(DirtyManager &manager, dirty::Handle handle) const;
};
private:
dirty::BoundSubresource<EngineRegisters> engine;
public:
vk::PipelineDepthStencilStateCreateInfo depthStencilState;
DepthStencilState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine);
void Flush();
};
/**
* @brief Holds all GPU state for a pipeline, any changes to this will result in a pipeline cache lookup
*/
@ -182,6 +208,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
InputAssemblyState::EngineRegisters inputAssemblyRegisters;
TessellationState::EngineRegisters tessellationRegisters;
RasterizationState::EngineRegisters rasterizationRegisters;
DepthStencilState::EngineRegisters depthStencilRegisters;
void DirtyBind(DirtyManager &manager, dirty::Handle handle) const;
};
@ -192,6 +219,8 @@ namespace skyline::gpu::interconnect::maxwell3d {
std::array<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount> colorRenderTargets;
dirty::ManualDirtyState<DepthRenderTargetState> depthRenderTarget;
dirty::ManualDirtyState<RasterizationState> rasterization;
dirty::ManualDirtyState<DepthStencilState> depthStencil;
public:
DirectPipelineState directState;

View File

@ -549,8 +549,6 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
};
static_assert(sizeof(MultisampleControl) == sizeof(u32));
enum class CompareFunc : u32 {
D3DNever = 1,
D3DLess = 2,
@ -564,10 +562,10 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
OglNever = 0x200,
OglLess = 0x201,
OglEqual = 0x202,
OglLeEqual = 0x203,
OglLEqual = 0x203,
OglGreater = 0x204,
OglNotEqual = 0x205,
OglGequal = 0x206,
OglGEqual = 0x206,
OglAlways = 0x207,
};

View File

@ -20,6 +20,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
.inputAssemblyRegisters = {*registers.primitiveRestartEnable},
.tessellationRegisters = {*registers.patchSize, *registers.tessellationParameters},
.rasterizationRegisters = {*registers.rasterEnable, *registers.frontPolygonMode, *registers.backPolygonMode, *registers.oglCullEnable, *registers.oglCullFace, *registers.windowOrigin, *registers.oglFrontFace, *registers.viewportClipControl, *registers.polyOffset, *registers.provokingVertex},
.depthStencilRegisters = {*registers.depthTestEnable, *registers.depthWriteEnable, *registers.depthFunc, *registers.depthBoundsTestEnable, *registers.stencilTestEnable, *registers.twoSidedStencilTestEnable, *registers.stencilOps, *registers.stencilBack},
};
}

View File

@ -193,7 +193,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
Register<0x4B9, u32> independentBlendEnable;
Register<0x4BA, u32> depthWriteEnable;
Register<0x4BB, u32> alphaTestEnable;
Register<0x4C3, type::CompareFunc> depthTestFunc;
Register<0x4C3, type::CompareFunc> depthFunc;
Register<0x4C4, float> alphaTestRef;
Register<0x4C5, type::CompareFunc> alphaTestFunc;
Register<0x4C6, u32> drawTFBStride;
@ -222,7 +222,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
Register<0x4D8, std::array<u32, type::ColorTargetCount>> rtBlendEnable;
Register<0x4E0, u32> stencilEnable;
Register<0x4E0, u32> stencilTestEnable;
Register<0x4E1, type::StencilOps> stencilOps;
Register<0x4E5, type::StencilValues> stencilValues;
@ -334,7 +334,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
Register<0x652, type::PrimitiveTopologyControl> primitiveTopologyControl;
Register<0x65C, type::PrimitiveTopology> primitiveTopology;
Register<0x66F, u32> depthBoundsEnable;
Register<0x66F, u32> depthBoundsTestEnable;
struct ColorLogicOp {
u32 enable;