mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-29 11:25:28 +03:00
Implement rasterization pipeline state
This commit is contained in:
parent
90cd6adb91
commit
690e96bce0
@ -476,6 +476,72 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
// maxwell3d::PipelineStage::TessellationEvaluation);
|
||||
}
|
||||
|
||||
/* Rasterizer State */
|
||||
void RasterizationState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const {
|
||||
manager.Bind(handle, rasterEnable, frontPolygonMode, backPolygonMode, viewportClipControl, oglCullEnable, oglFrontFace, oglCullFace, windowOrigin, provokingVertex, polyOffset);
|
||||
}
|
||||
|
||||
RasterizationState::RasterizationState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine) : engine{manager, dirtyHandle, engine} {}
|
||||
|
||||
static vk::PolygonMode ConvertPolygonMode(engine::PolygonMode mode) {
|
||||
switch (mode) {
|
||||
case engine::PolygonMode::Fill:
|
||||
return vk::PolygonMode::eFill;
|
||||
case engine::PolygonMode::Line:
|
||||
return vk::PolygonMode::eLine;
|
||||
case engine::PolygonMode::Point:
|
||||
return vk::PolygonMode::ePoint;
|
||||
}
|
||||
}
|
||||
|
||||
static vk::CullModeFlags ConvertCullMode(engine::CullFace cullMode) {
|
||||
switch (cullMode) {
|
||||
case engine::CullFace::Front:
|
||||
return vk::CullModeFlagBits::eFront;
|
||||
case engine::CullFace::Back:
|
||||
return vk::CullModeFlagBits::eBack;
|
||||
case engine::CullFace::FrontAndBack:
|
||||
return vk::CullModeFlagBits::eFrontAndBack;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ConvertDepthBiasEnable(engine::PolyOffset polyOffset, engine::PolygonMode polygonMode) {
|
||||
switch (polygonMode) {
|
||||
case engine::PolygonMode::Point:
|
||||
return polyOffset.pointEnable;
|
||||
case engine::PolygonMode::Line:
|
||||
return polyOffset.lineEnable;
|
||||
case engine::PolygonMode::Fill:
|
||||
return polyOffset.fillEnable;
|
||||
}
|
||||
}
|
||||
|
||||
static vk::ProvokingVertexModeEXT ConvertProvokingVertex(engine::ProvokingVertex::Value provokingVertex) {
|
||||
switch (provokingVertex) {
|
||||
case engine::ProvokingVertex::Value::First:
|
||||
return vk::ProvokingVertexModeEXT::eFirstVertex;
|
||||
case engine::ProvokingVertex::Value::Last:
|
||||
return vk::ProvokingVertexModeEXT::eLastVertex;
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizationState::Flush() {
|
||||
auto &rasterizationCreateInfo{rasterizationState.get<vk::PipelineRasterizationStateCreateInfo>()};
|
||||
rasterizationCreateInfo.rasterizerDiscardEnable = !engine->rasterEnable;
|
||||
rasterizationCreateInfo.polygonMode = ConvertPolygonMode(engine->frontPolygonMode);
|
||||
if (engine->backPolygonMode != engine->frontPolygonMode)
|
||||
Logger::Warn("Non-matching polygon modes!");
|
||||
|
||||
rasterizationCreateInfo.cullMode = engine->oglCullEnable ? ConvertCullMode(engine->oglCullFace) : vk::CullModeFlagBits::eNone;
|
||||
// UpdateRuntimeInformation(runtimeInfo.y_negate, enabled, maxwell3d::PipelineStage::Vertex, maxwell3d::PipelineStage::Fragment);
|
||||
|
||||
bool origFrontFaceClockwise{engine->oglFrontFace == engine::FrontFace::CW};
|
||||
rasterizationCreateInfo.frontFace = (engine->windowOrigin.flipY != origFrontFaceClockwise) ? vk::FrontFace::eClockwise : vk::FrontFace::eCounterClockwise;
|
||||
rasterizationCreateInfo.depthBiasEnable = ConvertDepthBiasEnable(engine->polyOffset, engine->frontPolygonMode);
|
||||
rasterizationState.get<vk::PipelineRasterizationProvokingVertexStateCreateInfoEXT>().provokingVertexMode = ConvertProvokingVertex(engine->provokingVertex.value);
|
||||
}
|
||||
|
||||
/* Pipeline State */
|
||||
void PipelineState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const {
|
||||
auto bindFunc{[&](auto ®s) { regs.DirtyBind(manager, handle); }};
|
||||
@ -488,7 +554,8 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
PipelineState::PipelineState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine)
|
||||
: engine{manager, dirtyHandle, engine},
|
||||
colorRenderTargets{util::MergeInto<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount>(manager, engine.colorRenderTargetsRegisters)},
|
||||
depthRenderTarget{manager, engine.depthRenderTargetRegisters} {}
|
||||
depthRenderTarget{manager, engine.depthRenderTargetRegisters},
|
||||
rasterization{manager, engine.rasterizationRegisters} {}
|
||||
|
||||
void PipelineState::Flush(InterconnectContext &ctx, StateUpdateBuilder &builder) {
|
||||
auto updateFunc{[&](auto &stateElem, auto &&... args) { stateElem.Update(ctx, args...); }};
|
||||
@ -497,7 +564,8 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
|
||||
auto vertexState{directState.vertexInput.Build(ctx, engine->vertexInputRegisters)};
|
||||
auto inputAssemblyState{directState.inputAssembly.Build()};
|
||||
auto tessellationState{directState.tessellationState.Build()};
|
||||
auto tessellationState{directState.tessellation.Build()};
|
||||
const auto &rasterizationState{rasterization.UpdateGet().rasterizationState};
|
||||
|
||||
}
|
||||
|
||||
|
@ -142,6 +142,34 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
TessellationState tessellation;
|
||||
};
|
||||
|
||||
class RasterizationState : dirty::ManualDirty {
|
||||
public:
|
||||
struct EngineRegisters {
|
||||
const u32 &rasterEnable;
|
||||
const engine::PolygonMode &frontPolygonMode;
|
||||
const engine::PolygonMode &backPolygonMode;
|
||||
const u32 &oglCullEnable;
|
||||
const engine::CullFace &oglCullFace;
|
||||
const engine::WindowOrigin &windowOrigin;
|
||||
const engine::FrontFace &oglFrontFace;
|
||||
const engine::ViewportClipControl &viewportClipControl;
|
||||
const engine::PolyOffset &polyOffset;
|
||||
const engine::ProvokingVertex &provokingVertex;
|
||||
|
||||
void DirtyBind(DirtyManager &manager, dirty::Handle handle) const;
|
||||
};
|
||||
|
||||
private:
|
||||
dirty::BoundSubresource<EngineRegisters> engine;
|
||||
|
||||
public:
|
||||
vk::StructureChain<vk::PipelineRasterizationStateCreateInfo, vk::PipelineRasterizationProvokingVertexStateCreateInfoEXT> rasterizationState;
|
||||
|
||||
RasterizationState(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
|
||||
*/
|
||||
@ -153,6 +181,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
VertexInputState::EngineRegisters vertexInputRegisters;
|
||||
InputAssemblyState::EngineRegisters inputAssemblyRegisters;
|
||||
TessellationState::EngineRegisters tessellationRegisters;
|
||||
RasterizationState::EngineRegisters rasterizationRegisters;
|
||||
|
||||
void DirtyBind(DirtyManager &manager, dirty::Handle handle) const;
|
||||
};
|
||||
@ -162,6 +191,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
|
||||
std::array<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount> colorRenderTargets;
|
||||
dirty::ManualDirtyState<DepthRenderTargetState> depthRenderTarget;
|
||||
dirty::ManualDirtyState<RasterizationState> rasterization;
|
||||
|
||||
public:
|
||||
DirectPipelineState directState;
|
||||
|
@ -351,6 +351,13 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
||||
Fill = 0x1B02, //!< Fill the area bounded by the vertices
|
||||
};
|
||||
|
||||
struct PolyOffset {
|
||||
u32 pointEnable;
|
||||
u32 lineEnable;
|
||||
u32 fillEnable;
|
||||
};
|
||||
static_assert(sizeof(PolyOffset) == (0x3 * sizeof(u32)));
|
||||
|
||||
/**
|
||||
* @brief A scissor which is used to reject all writes to non-masked regions
|
||||
* @note All coordinates are in screen-space as defined by the viewport
|
||||
@ -652,8 +659,8 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
||||
})
|
||||
|
||||
enum class FrontFace : u32 {
|
||||
Clockwise = 0x900,
|
||||
CounterClockwise = 0x901,
|
||||
CW = 0x900,
|
||||
CCW = 0x901,
|
||||
};
|
||||
|
||||
enum class CullFace : u32 {
|
||||
@ -662,18 +669,48 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
||||
FrontAndBack = 0x408,
|
||||
};
|
||||
|
||||
union ViewVolumeClipControl {
|
||||
union ViewportClipControl {
|
||||
u32 raw;
|
||||
enum class PixelZ : u8 {
|
||||
Clip = 0,
|
||||
Clamp = 1
|
||||
};
|
||||
|
||||
enum class GuardbandScale : u8 {
|
||||
Scale256,
|
||||
Scale1
|
||||
};
|
||||
|
||||
enum class GeometryClip : u8 {
|
||||
WZeroClip = 0,
|
||||
Passthru = 1,
|
||||
FrustrumXYClip = 2,
|
||||
FrustrumXYZClip = 3,
|
||||
WZeroClipNoZCull = 4,
|
||||
FrustrumZClip = 5,
|
||||
WZeroTriFillOrClip = 6
|
||||
};
|
||||
|
||||
enum class GuardbandZScale : u8 {
|
||||
SameAsXYGuardband = 0,
|
||||
Scale256 = 1,
|
||||
Scale1 = 2
|
||||
};
|
||||
|
||||
struct {
|
||||
bool forceDepthRangeZeroToOne : 1;
|
||||
u8 _unk0_ : 2;
|
||||
bool depthClampNear : 1;
|
||||
bool depthClampFar : 1;
|
||||
u8 _unk1_ : 6;
|
||||
bool depthClampDisable : 1;
|
||||
bool minZZeroMaxZOne : 1;
|
||||
GuardbandZScale guardbandZScale : 2;
|
||||
PixelZ pixelMinZ : 1;
|
||||
PixelZ pixelMaxZ : 1;
|
||||
u8 _pad1_ : 2;
|
||||
GuardbandScale geometryGuardbandScale : 1;
|
||||
u8 _pad2_ : 2;
|
||||
GuardbandScale linePointCullGuardbandScale : 1;
|
||||
GeometryClip geometryClip : 3;
|
||||
u32 _pad3_ : 18;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(ViewVolumeClipControl) == sizeof(u32));
|
||||
static_assert(sizeof(ViewportClipControl) == sizeof(u32));
|
||||
|
||||
union ColorWriteMask {
|
||||
u32 raw;
|
||||
@ -880,6 +917,15 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
||||
};
|
||||
static_assert(sizeof(SetProgramInfo) == (sizeof(u32) * 0x10));
|
||||
|
||||
struct ProvokingVertex {
|
||||
enum class Value : u8 {
|
||||
First = 0,
|
||||
Last = 1,
|
||||
} value : 1;
|
||||
u32 _pad_ : 31;
|
||||
};
|
||||
static_assert(sizeof(ProvokingVertex) == sizeof(u32));
|
||||
|
||||
struct ZtLayer {
|
||||
u16 offset;
|
||||
u16 _pad_;
|
||||
|
@ -19,6 +19,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
.vertexInputRegisters = {*registers.vertexStreams, *registers.vertexStreamInstance, *registers.vertexAttributes},
|
||||
.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},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
|
||||
Register<0xC8, type::TessellationParameters> tessellationParameters;
|
||||
|
||||
Register<0xDF, u32> rasterizerEnable;
|
||||
Register<0xDF, u32> rasterEnable;
|
||||
|
||||
Register<0xE0, std::array<type::StreamOutBuffer, type::StreamOutBufferCount>> streamOutBuffers;
|
||||
Register<0x1C0, std::array<type::TransformFeedbackBufferState, type::StreamOutBufferCount>> transformFeedbackBufferStates;
|
||||
@ -127,7 +127,6 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
|
||||
Register<0x35B, type::ClearRect> clearRect;
|
||||
|
||||
|
||||
Register<0x35D, u32> vertexArrayStart; //!< The first vertex to draw
|
||||
|
||||
struct DrawVertexArray {
|
||||
@ -142,11 +141,10 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
Register<0x364, float> zClearValue;
|
||||
Register<0x368, u32> stencilClearValue;
|
||||
|
||||
struct PolygonMode {
|
||||
type::PolygonMode front; // 0x36B
|
||||
type::PolygonMode back; // 0x36C
|
||||
};
|
||||
Register<0x36B, PolygonMode> polygonMode;
|
||||
Register<0x36B, type::PolygonMode> frontPolygonMode;
|
||||
Register<0x36C, type::PolygonMode> backPolygonMode;
|
||||
|
||||
Register<0x370, type::PolyOffset> polyOffset;
|
||||
|
||||
Register<0x373, u32> patchSize;
|
||||
|
||||
@ -310,7 +308,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
Register<0x591, u32> primitiveRestartEnable;
|
||||
Register<0x592, u32> primitiveRestartIndex;
|
||||
|
||||
Register<0x5A1, u32> provokingVertexIsLast;
|
||||
Register<0x5A1, type::ProvokingVertex> provokingVertex;
|
||||
|
||||
Register<0x5E7, type::ZtLayer> ztLayer;
|
||||
|
||||
@ -325,13 +323,13 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
|
||||
Register<0x620, std::array<type::VertexStreamInstance, type::VertexStreamCount>> vertexStreamInstance; //!< A per-VBO boolean denoting if the vertex input rate should be per vertex or per instance
|
||||
|
||||
Register<0x646, u32> cullFaceEnable;
|
||||
Register<0x647, type::FrontFace> frontFace;
|
||||
Register<0x648, type::CullFace> cullFace;
|
||||
Register<0x646, u32> oglCullEnable;
|
||||
Register<0x647, type::FrontFace> oglFrontFace;
|
||||
Register<0x648, type::CullFace> oglCullFace;
|
||||
|
||||
Register<0x649, u32> pixelCentreImage;
|
||||
Register<0x64B, u32> viewportScaleOffsetEnable;
|
||||
Register<0x64F, type::ViewVolumeClipControl> viewVolumeClipControl;
|
||||
Register<0x64F, type::ViewportClipControl> viewportClipControl;
|
||||
|
||||
Register<0x652, type::PrimitiveTopologyControl> primitiveTopologyControl;
|
||||
Register<0x65C, type::PrimitiveTopology> primitiveTopology;
|
||||
|
Loading…
Reference in New Issue
Block a user