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); 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 */ /* Pipeline State */
void PipelineState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const { void PipelineState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const {
auto bindFunc{[&](auto &regs) { regs.DirtyBind(manager, handle); }}; auto bindFunc{[&](auto &regs) { regs.DirtyBind(manager, handle); }};
@ -555,7 +641,8 @@ namespace skyline::gpu::interconnect::maxwell3d {
: engine{manager, dirtyHandle, engine}, : engine{manager, dirtyHandle, engine},
colorRenderTargets{util::MergeInto<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount>(manager, engine.colorRenderTargetsRegisters)}, colorRenderTargets{util::MergeInto<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount>(manager, engine.colorRenderTargetsRegisters)},
depthRenderTarget{manager, engine.depthRenderTargetRegisters}, depthRenderTarget{manager, engine.depthRenderTargetRegisters},
rasterization{manager, engine.rasterizationRegisters} {} rasterization{manager, engine.rasterizationRegisters},
depthStencil{manager, engine.depthStencilRegisters} {}
void PipelineState::Flush(InterconnectContext &ctx, StateUpdateBuilder &builder) { void PipelineState::Flush(InterconnectContext &ctx, StateUpdateBuilder &builder) {
auto updateFunc{[&](auto &stateElem, auto &&... args) { stateElem.Update(ctx, args...); }}; auto updateFunc{[&](auto &stateElem, auto &&... args) { stateElem.Update(ctx, args...); }};
@ -563,9 +650,14 @@ namespace skyline::gpu::interconnect::maxwell3d {
updateFunc(depthRenderTarget); updateFunc(depthRenderTarget);
auto vertexState{directState.vertexInput.Build(ctx, engine->vertexInputRegisters)}; auto vertexState{directState.vertexInput.Build(ctx, engine->vertexInputRegisters)};
auto inputAssemblyState{directState.inputAssembly.Build()}; const auto &inputAssemblyState{directState.inputAssembly.Build()};
auto tessellationState{directState.tessellation.Build()}; const auto &tessellationState{directState.tessellation.Build()};
const auto &rasterizationState{rasterization.UpdateGet().rasterizationState}; 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(); 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 * @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; InputAssemblyState::EngineRegisters inputAssemblyRegisters;
TessellationState::EngineRegisters tessellationRegisters; TessellationState::EngineRegisters tessellationRegisters;
RasterizationState::EngineRegisters rasterizationRegisters; RasterizationState::EngineRegisters rasterizationRegisters;
DepthStencilState::EngineRegisters depthStencilRegisters;
void DirtyBind(DirtyManager &manager, dirty::Handle handle) const; 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; std::array<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount> colorRenderTargets;
dirty::ManualDirtyState<DepthRenderTargetState> depthRenderTarget; dirty::ManualDirtyState<DepthRenderTargetState> depthRenderTarget;
dirty::ManualDirtyState<RasterizationState> rasterization; dirty::ManualDirtyState<RasterizationState> rasterization;
dirty::ManualDirtyState<DepthStencilState> depthStencil;
public: public:
DirectPipelineState directState; DirectPipelineState directState;

View File

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

View File

@ -20,6 +20,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
.inputAssemblyRegisters = {*registers.primitiveRestartEnable}, .inputAssemblyRegisters = {*registers.primitiveRestartEnable},
.tessellationRegisters = {*registers.patchSize, *registers.tessellationParameters}, .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}, .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<0x4B9, u32> independentBlendEnable;
Register<0x4BA, u32> depthWriteEnable; Register<0x4BA, u32> depthWriteEnable;
Register<0x4BB, u32> alphaTestEnable; Register<0x4BB, u32> alphaTestEnable;
Register<0x4C3, type::CompareFunc> depthTestFunc; Register<0x4C3, type::CompareFunc> depthFunc;
Register<0x4C4, float> alphaTestRef; Register<0x4C4, float> alphaTestRef;
Register<0x4C5, type::CompareFunc> alphaTestFunc; Register<0x4C5, type::CompareFunc> alphaTestFunc;
Register<0x4C6, u32> drawTFBStride; Register<0x4C6, u32> drawTFBStride;
@ -222,7 +222,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
Register<0x4D8, std::array<u32, type::ColorTargetCount>> rtBlendEnable; Register<0x4D8, std::array<u32, type::ColorTargetCount>> rtBlendEnable;
Register<0x4E0, u32> stencilEnable; Register<0x4E0, u32> stencilTestEnable;
Register<0x4E1, type::StencilOps> stencilOps; Register<0x4E1, type::StencilOps> stencilOps;
Register<0x4E5, type::StencilValues> stencilValues; Register<0x4E5, type::StencilValues> stencilValues;
@ -334,7 +334,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
Register<0x652, type::PrimitiveTopologyControl> primitiveTopologyControl; Register<0x652, type::PrimitiveTopologyControl> primitiveTopologyControl;
Register<0x65C, type::PrimitiveTopology> primitiveTopology; Register<0x65C, type::PrimitiveTopology> primitiveTopology;
Register<0x66F, u32> depthBoundsEnable; Register<0x66F, u32> depthBoundsTestEnable;
struct ColorLogicOp { struct ColorLogicOp {
u32 enable; u32 enable;