diff --git a/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h b/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h index 607ae665..72c9c64f 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h @@ -829,7 +829,7 @@ namespace skyline::gpu::interconnect { if (size == Size::e0 || type == Type::None) return vk::Format::eUndefined; - switch(size | type) { + switch (size | type) { // @fmt:off /* 8-bit components */ @@ -930,15 +930,48 @@ 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)); } } void SetVertexAttributeState(u32 index, maxwell3d::VertexAttribute attribute) { - auto& vkAttributes{vertexAttributes[index]}; + auto &vkAttributes{vertexAttributes[index]}; vkAttributes.binding = attribute.bufferId; 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)); + } + }(); + } }; } diff --git a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h index 4e3b07e6..734f3911 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h +++ b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h @@ -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, diff --git a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.cpp b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.cpp index d5b36064..c0592f54 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.cpp +++ b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.cpp @@ -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; } diff --git a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.h b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.h index c65ac30d..a940aba3 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.h +++ b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.h @@ -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;