mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-04 23:35:12 +01:00
Implement Maxwell3D Rasterizer State
Maxwell3D registers relevant to the Vulkan Rasterizer state have been implemented aside from certain features such as per-face polygon modes that cannot be implemented due to Vulkan limitations. A quirk was utilized to dynamically support the provoking vertex being the last vertex as opposed to the first as well.
This commit is contained in:
parent
8ef225a37d
commit
5ed26fef23
@ -26,6 +26,8 @@ namespace skyline::gpu::interconnect {
|
||||
public:
|
||||
GraphicsContext(GPU &gpu, soc::gm20b::ChannelContext &channelCtx, gpu::interconnect::CommandExecutor &executor) : gpu(gpu), channelCtx(channelCtx), executor(executor) {
|
||||
scissors.fill(DefaultScissor);
|
||||
if (!gpu.quirks.supportsLastProvokingVertex)
|
||||
rasterizerState.unlink<vk::PipelineRasterizationProvokingVertexStateCreateInfoEXT>();
|
||||
}
|
||||
|
||||
/* Render Targets + Render Target Control */
|
||||
@ -368,5 +370,110 @@ namespace skyline::gpu::interconnect {
|
||||
shader.offset = offset;
|
||||
shader.data = span<u8>{};
|
||||
}
|
||||
|
||||
/* Rasterizer State */
|
||||
private:
|
||||
vk::StructureChain<vk::PipelineRasterizationStateCreateInfo, vk::PipelineRasterizationProvokingVertexStateCreateInfoEXT> rasterizerState;
|
||||
bool cullFaceEnabled{};
|
||||
vk::CullModeFlags cullMode{}; //!< The current cull mode regardless of it being enabled or disabled
|
||||
vk::PipelineRasterizationProvokingVertexStateCreateInfoEXT provokingVertexState{};
|
||||
bool depthBiasPoint{}, depthBiasLine{}, depthBiasFill{};
|
||||
|
||||
public:
|
||||
void SetDepthClampEnabled(bool enabled) {
|
||||
rasterizerState.get<vk::PipelineRasterizationStateCreateInfo>().depthClampEnable = enabled;
|
||||
}
|
||||
|
||||
vk::PolygonMode ConvertPolygonMode(maxwell3d::PolygonMode mode) {
|
||||
switch (mode) {
|
||||
case maxwell3d::PolygonMode::Point:
|
||||
return vk::PolygonMode::ePoint;
|
||||
case maxwell3d::PolygonMode::Line:
|
||||
return vk::PolygonMode::eLine;
|
||||
case maxwell3d::PolygonMode::Fill:
|
||||
return vk::PolygonMode::eFill;
|
||||
}
|
||||
}
|
||||
|
||||
void SetPolygonModeFront(maxwell3d::PolygonMode mode) {
|
||||
rasterizerState.get<vk::PipelineRasterizationStateCreateInfo>().polygonMode = ConvertPolygonMode(mode);
|
||||
}
|
||||
|
||||
void SetPolygonModeBack(maxwell3d::PolygonMode mode) {
|
||||
auto frontPolygonMode{rasterizerState.get<vk::PipelineRasterizationStateCreateInfo>().polygonMode};
|
||||
auto backPolygonMode{ConvertPolygonMode(mode)};
|
||||
if (frontPolygonMode != backPolygonMode)
|
||||
Logger::Warn("Cannot set back-facing polygon mode ({}) different from front-facing polygon mode ({}) due to Vulkan constraints", vk::to_string(backPolygonMode), vk::to_string(frontPolygonMode));
|
||||
}
|
||||
|
||||
void SetCullFaceEnabled(bool enabled) {
|
||||
cullFaceEnabled = enabled;
|
||||
if (!enabled)
|
||||
rasterizerState.get<vk::PipelineRasterizationStateCreateInfo>().cullMode = {};
|
||||
}
|
||||
|
||||
void SetFrontFace(maxwell3d::FrontFace face) {
|
||||
rasterizerState.get<vk::PipelineRasterizationStateCreateInfo>().frontFace = [face]() {
|
||||
switch (face) {
|
||||
case maxwell3d::FrontFace::Clockwise:
|
||||
return vk::FrontFace::eClockwise;
|
||||
case maxwell3d::FrontFace::CounterClockwise:
|
||||
return vk::FrontFace::eCounterClockwise;
|
||||
}
|
||||
}();
|
||||
}
|
||||
|
||||
void SetCullFace(maxwell3d::CullFace face) {
|
||||
cullMode = [face]() -> vk::CullModeFlags {
|
||||
switch (face) {
|
||||
case maxwell3d::CullFace::Front:
|
||||
return vk::CullModeFlagBits::eFront;
|
||||
case maxwell3d::CullFace::Back:
|
||||
return vk::CullModeFlagBits::eBack;
|
||||
case maxwell3d::CullFace::FrontAndBack:
|
||||
return vk::CullModeFlagBits::eFrontAndBack;
|
||||
}
|
||||
}();
|
||||
if (cullFaceEnabled)
|
||||
rasterizerState.get<vk::PipelineRasterizationStateCreateInfo>().cullMode = cullMode;
|
||||
}
|
||||
|
||||
void SetProvokingVertex(bool isLast) {
|
||||
if (isLast) {
|
||||
if (!gpu.quirks.supportsLastProvokingVertex)
|
||||
Logger::Warn("Cannot set provoking vertex to last without host GPU support");
|
||||
rasterizerState.get<vk::PipelineRasterizationProvokingVertexStateCreateInfoEXT>().provokingVertexMode = vk::ProvokingVertexModeEXT::eLastVertex;
|
||||
} else {
|
||||
rasterizerState.get<vk::PipelineRasterizationProvokingVertexStateCreateInfoEXT>().provokingVertexMode = vk::ProvokingVertexModeEXT::eFirstVertex;
|
||||
}
|
||||
}
|
||||
|
||||
void SetLineWidth(float width) {
|
||||
rasterizerState.get<vk::PipelineRasterizationStateCreateInfo>().lineWidth = width;
|
||||
}
|
||||
|
||||
void SetDepthBiasPointEnabled(bool enabled) {
|
||||
depthBiasPoint = enabled;
|
||||
}
|
||||
|
||||
void SetDepthBiasLineEnabled(bool enabled) {
|
||||
depthBiasLine = enabled;
|
||||
}
|
||||
|
||||
void SetDepthBiasFillEnabled(bool enabled) {
|
||||
depthBiasFill = enabled;
|
||||
}
|
||||
|
||||
void SetDepthBiasConstantFactor(float factor) {
|
||||
rasterizerState.get<vk::PipelineRasterizationStateCreateInfo>().depthBiasConstantFactor = factor;
|
||||
}
|
||||
|
||||
void SetDepthBiasClamp(float clamp) {
|
||||
rasterizerState.get<vk::PipelineRasterizationStateCreateInfo>().depthBiasClamp = clamp;
|
||||
}
|
||||
|
||||
void SetDepthBiasSlopeFactor(float factor) {
|
||||
rasterizerState.get<vk::PipelineRasterizationStateCreateInfo>().depthBiasSlopeFactor = factor;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -412,6 +412,19 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
||||
FrontAndBack = 0x408,
|
||||
};
|
||||
|
||||
union ViewVolumeClipControl {
|
||||
u32 raw;
|
||||
struct {
|
||||
bool forceDepthRangeZeroToOne : 1;
|
||||
u8 _unk0_ : 2;
|
||||
bool depthClampNear : 1;
|
||||
bool depthClampFar : 1;
|
||||
u8 _unk1_ : 7;
|
||||
bool depthClampDisable : 1;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(ViewVolumeClipControl) == sizeof(u32));
|
||||
|
||||
union ColorWriteMask {
|
||||
u32 raw;
|
||||
|
||||
|
@ -208,6 +208,22 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
static_assert(4 < BOOST_PP_LIMIT_REPEAT);
|
||||
#undef COLOR_CLEAR_CALLBACKS
|
||||
|
||||
MAXWELL3D_STRUCT_CASE(polygonMode, front, {
|
||||
context.SetPolygonModeFront(front);
|
||||
})
|
||||
|
||||
MAXWELL3D_STRUCT_CASE(depthBiasEnable, point, {
|
||||
context.SetDepthBiasPointEnabled(point);
|
||||
})
|
||||
|
||||
MAXWELL3D_STRUCT_CASE(depthBiasEnable, line, {
|
||||
context.SetDepthBiasLineEnabled(line);
|
||||
})
|
||||
|
||||
MAXWELL3D_STRUCT_CASE(depthBiasEnable, fill, {
|
||||
context.SetDepthBiasFillEnabled(fill);
|
||||
})
|
||||
|
||||
#define SCISSOR_CALLBACKS(z, index, data) \
|
||||
MAXWELL3D_ARRAY_STRUCT_CASE(scissors, index, enable, { \
|
||||
context.SetScissor(index, enable ? registers.scissors[index] : std::optional<type::Scissor>{}); \
|
||||
@ -226,6 +242,61 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
MAXWELL3D_CASE(renderTargetControl, {
|
||||
context.UpdateRenderTargetControl(renderTargetControl);
|
||||
})
|
||||
|
||||
MAXWELL3D_CASE(lineWidthSmooth, {
|
||||
if (*registers.lineSmoothEnable)
|
||||
context.SetLineWidth(lineWidthSmooth);
|
||||
})
|
||||
|
||||
MAXWELL3D_CASE(lineWidthAliased, {
|
||||
if (!*registers.lineSmoothEnable)
|
||||
context.SetLineWidth(lineWidthAliased);
|
||||
})
|
||||
|
||||
MAXWELL3D_CASE(depthBiasFactor, {
|
||||
context.SetDepthBiasSlopeFactor(depthBiasFactor);
|
||||
})
|
||||
|
||||
MAXWELL3D_CASE(lineSmoothEnable, {
|
||||
context.SetLineWidth(lineSmoothEnable ? *registers.lineWidthSmooth : *registers.lineWidthAliased);
|
||||
})
|
||||
|
||||
MAXWELL3D_CASE(depthBiasUnits, {
|
||||
context.SetDepthBiasConstantFactor(depthBiasUnits / 2.0f);
|
||||
})
|
||||
|
||||
MAXWELL3D_STRUCT_CASE(setProgramRegion, high, {
|
||||
context.SetShaderBaseIovaHigh(high);
|
||||
})
|
||||
|
||||
MAXWELL3D_STRUCT_CASE(setProgramRegion, low, {
|
||||
context.SetShaderBaseIovaLow(low);
|
||||
})
|
||||
|
||||
MAXWELL3D_CASE(provokingVertexIsLast, {
|
||||
context.SetProvokingVertex(provokingVertexIsLast);
|
||||
})
|
||||
|
||||
MAXWELL3D_CASE(depthBiasClamp, {
|
||||
context.SetDepthBiasClamp(depthBiasClamp);
|
||||
})
|
||||
|
||||
MAXWELL3D_CASE(cullFaceEnable, {
|
||||
context.SetCullFaceEnabled(cullFaceEnable);
|
||||
})
|
||||
|
||||
MAXWELL3D_CASE(frontFace, {
|
||||
context.SetFrontFace(frontFace);
|
||||
})
|
||||
|
||||
MAXWELL3D_CASE(cullFace, {
|
||||
context.SetCullFace(cullFace);
|
||||
})
|
||||
|
||||
MAXWELL3D_CASE(viewVolumeClipControl, {
|
||||
context.SetDepthClampEnabled(!viewVolumeClipControl.depthClampDisable);
|
||||
})
|
||||
|
||||
#define SET_SHADER_ENABLE_CALLBACK(z, index, data) \
|
||||
MAXWELL3D_ARRAY_STRUCT_CASE(setProgram, index, info, { \
|
||||
context.SetShaderEnabled(info.stage, info.enable); \
|
||||
|
@ -79,6 +79,13 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
|
||||
Register<0x380, std::array<type::Scissor, type::ViewportCount>> scissors;
|
||||
|
||||
struct DepthBiasEnable {
|
||||
u32 point; // 0x370
|
||||
u32 line; // 0x371
|
||||
u32 fill; // 0x372
|
||||
};
|
||||
Register<0x370, DepthBiasEnable> depthBiasEnable;
|
||||
|
||||
struct StencilBackExtra {
|
||||
u32 compareRef; // 0x3D5
|
||||
u32 writeMask; // 0x3D6
|
||||
@ -162,7 +169,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
};
|
||||
Register<0x557, SamplerPool> samplerPool;
|
||||
|
||||
Register<0x55B, u32> polygonOffsetFactor;
|
||||
Register<0x55B, float> depthBiasFactor;
|
||||
Register<0x55C, u32> lineSmoothEnable;
|
||||
|
||||
struct TexturePool {
|
||||
@ -171,7 +178,6 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
};
|
||||
Register<0x55D, TexturePool> texturePool;
|
||||
|
||||
|
||||
Register<0x565, u32> stencilTwoSideEnable;
|
||||
|
||||
struct StencilBack {
|
||||
@ -182,16 +188,25 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
};
|
||||
Register<0x566, StencilBack> stencilBack;
|
||||
|
||||
Register<0x56F, float> depthBiasUnits;
|
||||
|
||||
Register<0x581, type::PointCoordReplace> pointCoordReplace;
|
||||
Register<0x582, type::Address> setProgramRegion;
|
||||
|
||||
Register<0x5A1, u32> provokingVertexIsLast;
|
||||
|
||||
Register<0x646, u32> cullFaceEnable;
|
||||
Register<0x647, type::FrontFace> frontFace;
|
||||
Register<0x648, type::CullFace> cullFace;
|
||||
|
||||
Register<0x649, u32> pixelCentreImage;
|
||||
Register<0x64B, u32> viewportTransformEnable;
|
||||
Register<0x674, type::ClearBuffers> clearBuffers;
|
||||
Register<0x680, std::array<type::ColorWriteMask, type::RenderTargetCount>> colorMask;
|
||||
|
||||
Register<0x61F, float> depthBiasClamp;
|
||||
Register<0x64F, type::ViewVolumeClipControl> viewVolumeClipControl;
|
||||
|
||||
struct Semaphore {
|
||||
type::Address address; // 0x6C0
|
||||
u32 payload; // 0x6C2
|
||||
|
Loading…
Reference in New Issue
Block a user