Skip to content

Convert triangle fans from the effective primitive topology - #2851

Open
carbonimax wants to merge 2 commits into
KhronosGroup:mainfrom
carbonimax:fix-dynamic-topology-fans
Open

carbonimax wants to merge 2 commits into
KhronosGroup:mainfrom
carbonimax:fix-dynamic-topology-fans

Conversation

@carbonimax

Copy link
Copy Markdown

MoltenVK draws triangle fans by converting them to indexed triangles, but the draw paths decided whether to convert from the topology the pipeline was created with. With VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY, a pipeline created as a triangle list or strip drew a dynamic triangle fan as a triangle list, and a pipeline created as a triangle fan drew a dynamic triangle list or strip through the fan conversion.

The render state now keeps the Vulkan topology next to the Metal primitive type, which cannot tell a fan from a list, and the four draw paths read the effective topology from the encoder state. The pipeline accessor they used has no caller left and is removed.

Testing: a standalone reproducer (https://gist.github.com/carbonimax/6737e3169ba9cc2254e5343a5111934d) draws each topology of a class through one dynamic pipeline and compares the image and the vertex shader invocation count with one static pipeline per topology, in direct, indexed, indirect and indexed indirect forms, under Metal API and GPU validation. Before this change, the 8 triangle cases fail and the 4 line cases pass; after it, all 12 pass. Tested on Apple M4 Pro, macOS 27.2, on top of a63d486, with MoltenVK built with CMake (Debug, arm64) and MVK_USE_METAL_PRIVATE_API off. The change also builds with MVK_USE_METAL_PRIVATE_API on, but that configuration was not run on the GPU. Not tested on Intel Macs.

🤖 Generated with Claude Code

carbonimax and others added 2 commits October 9, 2026 12:58
The render state only kept the Metal primitive type, which cannot tell a
triangle fan from a triangle list. It now also keeps the Vulkan topology,
static from the pipeline or dynamic from vkCmdSetPrimitiveTopology, and the
encoder state reads the effective one through getPrimitiveTopology().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The draw paths decided whether to convert a triangle fan to triangles from
the topology the pipeline was created with, ignoring a primitive topology
set with vkCmdSetPrimitiveTopology. A pipeline created with another
triangle topology drew a dynamic triangle fan as a triangle list, and a
pipeline created as a triangle fan drew a dynamic triangle list or strip
through the fan conversion. The four draw paths now read the effective
topology from the encoder state, and the pipeline accessor they used,
left without callers, is removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@carbonimax
carbonimax force-pushed the fix-dynamic-topology-fans branch from aa9133c to 368e50d Compare October 9, 2026 12:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant