Implement Vulkan-Supported Maxwell3D Primitive Topologies

Any primitive topologies that are directly supported by Vulkan were implemented but the rest were not and will be implemented with conversions as they are used by applications, they are:
* LineLoop
* QuadList
* QuadStrip
* Polygon
This commit is contained in:
PixelyIon 2021-11-17 16:58:03 +05:30
parent 138f884159
commit 38119e21d4
4 changed files with 90 additions and 3 deletions

View File

@ -930,7 +930,7 @@ namespace skyline::gpu::interconnect {
// @fmt:on
default:
throw exception("Unimplemented Vertex Buffer Format: {} | {}", maxwell3d::VertexAttribute::ToString(size), maxwell3d::VertexAttribute::ToString(type));
throw exception("Unimplemented Maxwell3D Vertex Buffer Format: {} | {}", maxwell3d::VertexAttribute::ToString(size), maxwell3d::VertexAttribute::ToString(type));
}
}
@ -940,5 +940,38 @@ namespace skyline::gpu::interconnect {
vkAttributes.format = ConvertVertexBufferFormat(attribute.type, attribute.elementSize);
vkAttributes.offset = attribute.offset;
}
/* Input Assembly */
private:
vk::PipelineInputAssemblyStateCreateInfo inputAssemblyState{};
public:
void SetPrimitiveTopology(maxwell3d::PrimitiveTopology topology) {
inputAssemblyState.topology = [topology]() {
switch (topology) {
// @fmt:off
case maxwell3d::PrimitiveTopology::PointList: return vk::PrimitiveTopology::ePointList;
case maxwell3d::PrimitiveTopology::LineList: return vk::PrimitiveTopology::eLineList;
case maxwell3d::PrimitiveTopology::LineListWithAdjacency: return vk::PrimitiveTopology::eLineListWithAdjacency;
case maxwell3d::PrimitiveTopology::LineStrip: return vk::PrimitiveTopology::eLineStrip;
case maxwell3d::PrimitiveTopology::LineStripWithAdjacency: return vk::PrimitiveTopology::eLineStripWithAdjacency;
case maxwell3d::PrimitiveTopology::TriangleList: return vk::PrimitiveTopology::eTriangleList;
case maxwell3d::PrimitiveTopology::TriangleListWithAdjacency: return vk::PrimitiveTopology::eTriangleListWithAdjacency;
case maxwell3d::PrimitiveTopology::TriangleStrip: return vk::PrimitiveTopology::eTriangleStrip;
case maxwell3d::PrimitiveTopology::TriangleStripWithAdjacency: return vk::PrimitiveTopology::eTriangleStripWithAdjacency;
case maxwell3d::PrimitiveTopology::TriangleFan: return vk::PrimitiveTopology::eTriangleFan;
case maxwell3d::PrimitiveTopology::PatchList: return vk::PrimitiveTopology::ePatchList;
// @fmt:on
default:
throw exception("Unimplemented Maxwell3D Primitive Topology: {}", maxwell3d::ToString(topology));
}
}();
}
};
}

View File

@ -428,6 +428,53 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
};
static_assert(sizeof(PointCoordReplace) == sizeof(u32));
enum class PrimitiveTopology : u16 {
PointList = 0,
LineList = 1,
LineLoop = 2,
LineStrip = 3,
TriangleList = 4,
TriangleStrip = 5,
TriangleFan = 6,
QuadList = 7,
QuadStrip = 8,
Polygon = 9,
LineListWithAdjacency = 10,
LineStripWithAdjacency = 11,
TriangleListWithAdjacency = 12,
TriangleStripWithAdjacency = 13,
PatchList = 14,
};
ENUM_STRING(PrimitiveTopology, {
ENUM_CASE(PointList);
ENUM_CASE(LineList);
ENUM_CASE(LineLoop);
ENUM_CASE(LineStrip);
ENUM_CASE(TriangleList);
ENUM_CASE(TriangleStrip);
ENUM_CASE(TriangleFan);
ENUM_CASE(QuadList);
ENUM_CASE(QuadStrip);
ENUM_CASE(Polygon);
ENUM_CASE(LineListWithAdjacency);
ENUM_CASE(LineStripWithAdjacency);
ENUM_CASE(TriangleListWithAdjacency);
ENUM_CASE(TriangleStripWithAdjacency);
ENUM_CASE(PatchList);
})
union VertexBeginGl {
u32 raw;
struct {
PrimitiveTopology topology;
u16 pad : 12;
bool instanceNext : 1;
bool instanceContinue : 1;
};
};
static_assert(sizeof(VertexBeginGl) == sizeof(u32));
enum class FrontFace : u32 {
Clockwise = 0x900,
CounterClockwise = 0x901,

View File

@ -393,6 +393,10 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
static_assert(type::StageCount == 6 && type::StageCount < BOOST_PP_LIMIT_REPEAT);
#undef SET_SHADER_ENABLE_CALLBACK
MAXWELL3D_CASE(vertexBeginGl, {
context.SetPrimitiveTopology(vertexBeginGl.topology);
})
default:
break;
}

View File

@ -202,6 +202,9 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
Register<0x581, type::PointCoordReplace> pointCoordReplace;
Register<0x582, type::Address> setProgramRegion;
Register<0x586, u32> vertexEndGl; //!< Method-only register with no real value, used after calling vertexBeginGl and draws are complete
Register<0x586, type::VertexBeginGl> vertexBeginGl; //!< Similar to glVertexBegin semantically, supplies a primitive topology for draws alongside instancing data
Register<0x5A1, u32> provokingVertexIsLast;
Register<0x61F, float> depthBiasClamp;