Implement tessellation pipeline state

This commit is contained in:
Billy Laws 2022-09-02 13:18:24 +01:00
parent 3649d4c779
commit 90cd6adb91
5 changed files with 109 additions and 13 deletions

View File

@ -434,6 +434,48 @@ namespace skyline::gpu::interconnect::maxwell3d {
inputAssemblyState.primitiveRestartEnable = enabled; inputAssemblyState.primitiveRestartEnable = enabled;
} }
/* Tessellation State */
void TessellationState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const {
manager.Bind(handle, patchControlPoints, tessellationParameters);
}
const vk::PipelineTessellationStateCreateInfo &TessellationState::Build() {
return tessellationState;
}
void TessellationState::SetPatchControlPoints(u32 patchControlPoints) {
tessellationState.patchControlPoints = patchControlPoints;
}
Shader::TessPrimitive ConvertShaderTessPrimitive(engine::TessellationParameters::DomainType domainType) {
switch (domainType) {
case engine::TessellationParameters::DomainType::Isoline:
return Shader::TessPrimitive::Isolines;
case engine::TessellationParameters::DomainType::Triangle:
return Shader::TessPrimitive::Triangles;
case engine::TessellationParameters::DomainType::Quad:
return Shader::TessPrimitive::Quads;
}
}
Shader::TessSpacing ConvertShaderTessSpacing(engine::TessellationParameters::Spacing spacing) {
switch (spacing) {
case engine::TessellationParameters::Spacing::Integer:
return Shader::TessSpacing::Equal;
case engine::TessellationParameters::Spacing::FractionalEven:
return Shader::TessSpacing::FractionalEven;
case engine::TessellationParameters::Spacing::FractionalOdd:
return Shader::TessSpacing::FractionalOdd;
}
}
void TessellationState::SetParameters(engine::TessellationParameters params) {
// UpdateRuntimeInformation(runtimeInfo.tess_primitive, ConvertShaderTessPrimitive(params.domainType), maxwell3d::PipelineStage::TessellationEvaluation);
// UpdateRuntimeInformation(runtimeInfo.tess_spacing, ConvertShaderTessSpacing(params.spacing), maxwell3d::PipelineStage::TessellationEvaluation);
// UpdateRuntimeInformation(runtimeInfo.tess_clockwise, params.outputPrimitive == engine::TessellationParameters::OutputPrimitives::TrianglesCW,
// maxwell3d::PipelineStage::TessellationEvaluation);
}
/* 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); }};
@ -455,6 +497,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
auto vertexState{directState.vertexInput.Build(ctx, engine->vertexInputRegisters)}; auto vertexState{directState.vertexInput.Build(ctx, engine->vertexInputRegisters)};
auto inputAssemblyState{directState.inputAssembly.Build()}; auto inputAssemblyState{directState.inputAssembly.Build()};
auto tessellationState{directState.tessellationState.Build()};
} }

View File

@ -114,12 +114,32 @@ namespace skyline::gpu::interconnect::maxwell3d {
void SetPrimitiveRestart(bool enable); void SetPrimitiveRestart(bool enable);
}; };
struct TessellationState {
private:
vk::PipelineTessellationStateCreateInfo tessellationState{};
public:
struct EngineRegisters {
const u32 &patchControlPoints;
const engine::TessellationParameters &tessellationParameters;
void DirtyBind(DirtyManager &manager, dirty::Handle handle) const;
};
const vk::PipelineTessellationStateCreateInfo &Build();
void SetPatchControlPoints(u32 controlPoints);
void SetParameters(engine::TessellationParameters parameters);
};
/** /**
* @brief Holds pipeline state that is directly written by the engine code, without using dirty tracking * @brief Holds pipeline state that is directly written by the engine code, without using dirty tracking
*/ */
struct DirectPipelineState { struct DirectPipelineState {
VertexInputState vertexInput; VertexInputState vertexInput;
InputAssemblyState inputAssembly; InputAssemblyState inputAssembly;
TessellationState tessellation;
}; };
/** /**
@ -132,6 +152,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
DepthRenderTargetState::EngineRegisters depthRenderTargetRegisters; DepthRenderTargetState::EngineRegisters depthRenderTargetRegisters;
VertexInputState::EngineRegisters vertexInputRegisters; VertexInputState::EngineRegisters vertexInputRegisters;
InputAssemblyState::EngineRegisters inputAssemblyRegisters; InputAssemblyState::EngineRegisters inputAssemblyRegisters;
TessellationState::EngineRegisters tessellationRegisters;
void DirtyBind(DirtyManager &manager, dirty::Handle handle) const; void DirtyBind(DirtyManager &manager, dirty::Handle handle) const;
}; };

View File

@ -1045,5 +1045,35 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
throw exception("Unsupported primitive topology 0x{:X}", static_cast<u16>(topology)); throw exception("Unsupported primitive topology 0x{:X}", static_cast<u16>(topology));
} }
} }
struct TessellationParameters {
enum class DomainType : u8 {
Isoline = 0,
Triangle = 1,
Quad = 2
};
enum class Spacing : u8 {
Integer = 0,
FractionalOdd = 1,
FractionalEven = 2
};
enum class OutputPrimitives : u8 {
Points = 0,
Lines = 1,
TrianglesCW = 2,
TrianglesCCW = 3
};
DomainType domainType : 2;
u8 _pad0_ : 2;
Spacing spacing : 2;
u8 _pad1_ : 2;
OutputPrimitives outputPrimitives : 2;
u32 _pad2_ : 22;
};
static_assert(sizeof(TessellationParameters) == sizeof(u32));
#pragma pack(pop) #pragma pack(pop)
} }

View File

@ -17,7 +17,8 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
.colorRenderTargetsRegisters = util::MergeInto<REGTYPE(ColorRenderTargetState), type::ColorTargetCount>(*registers.colorTargets), .colorRenderTargetsRegisters = util::MergeInto<REGTYPE(ColorRenderTargetState), type::ColorTargetCount>(*registers.colorTargets),
.depthRenderTargetRegisters = {*registers.ztSize, *registers.ztOffset, *registers.ztFormat, *registers.ztBlockSize, *registers.ztArrayPitch, *registers.ztSelect, *registers.ztLayer}, .depthRenderTargetRegisters = {*registers.ztSize, *registers.ztOffset, *registers.ztFormat, *registers.ztBlockSize, *registers.ztArrayPitch, *registers.ztSelect, *registers.ztLayer},
.vertexInputRegisters = {*registers.vertexStreams, *registers.vertexStreamInstance, *registers.vertexAttributes}, .vertexInputRegisters = {*registers.vertexStreams, *registers.vertexStreamInstance, *registers.vertexAttributes},
.inputAssemblyRegisters = {*registers.primitiveRestartEnable} .inputAssemblyRegisters = {*registers.primitiveRestartEnable},
.tessellationRegisters = {*registers.patchSize, *registers.tessellationParameters},
}; };
} }
@ -174,9 +175,20 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
static_assert(type::VertexAttributeCount == 32 && type::VertexAttributeCount < BOOST_PP_LIMIT_REPEAT); static_assert(type::VertexAttributeCount == 32 && type::VertexAttributeCount < BOOST_PP_LIMIT_REPEAT);
#undef VERTEX_ATTRIBUTE_CALLBACKS #undef VERTEX_ATTRIBUTE_CALLBACKS
ENGINE_CASE(primitiveRestartEnable, { ENGINE_CASE(primitiveRestartEnable, {
interconnect.directState.inputAssembly.SetPrimitiveRestart(primitiveRestartEnable != 0); interconnect.directState.inputAssembly.SetPrimitiveRestart(primitiveRestartEnable != 0);
}) })
ENGINE_CASE(tessellationParameters, {
interconnect.directState.tessellation.SetParameters(tessellationParameters);
})
ENGINE_CASE(patchSize, {
interconnect.directState.tessellation.SetPatchControlPoints(patchSize);
})
default: default:
break; break;
} }

View File

@ -113,17 +113,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
Register<0xB2, type::SyncpointAction> syncpointAction; Register<0xB2, type::SyncpointAction> syncpointAction;
union TessellationMode { Register<0xC8, type::TessellationParameters> tessellationParameters;
struct {
type::TessellationPrimitive primitive : 2;
u8 _pad0_ : 2;
type::TessellationSpacing spacing : 2;
u8 _pad1_ : 2;
type::TessellationWinding winding : 2;
};
u32 raw;
};
Register<0xC8, TessellationMode> tessellationMode;
Register<0xDF, u32> rasterizerEnable; Register<0xDF, u32> rasterizerEnable;
@ -158,7 +148,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
}; };
Register<0x36B, PolygonMode> polygonMode; Register<0x36B, PolygonMode> polygonMode;
Register<0x373, u32> tessellationPatchSize; Register<0x373, u32> patchSize;
Register<0x380, std::array<type::Scissor, type::ViewportCount>> scissors; Register<0x380, std::array<type::Scissor, type::ViewportCount>> scissors;