fix(vk): missing floor grass without mesh shaders: indirect task draws ran no mesh workgroups #1510
No reviewers
Labels
No labels
accessibility
autorelease: pending
autorelease: tagged
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
question
testing wanted
wontfix
No milestone
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Hookshot!1510
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/mesh-fallback-missing-floor-grass-indirect"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
On a GPU without mesh shaders, every
DrawMeshTasksIndirectdrew nothing. The floor grass in Link's house is one. This makes an indirect task draw's mesh stage run.Part of splitting up #1023.
Problem
DrawMeshTasksIndirectrecords no task count, because the count lives in GPU memory:nvn_native.czeroes the command. In the fallback, a task draw's mesh stage ranslots = groups × threadsworkgroups, and for an indirect drawgroupsis 0. So the mesh stage was never dispatched, the draw's vertex count was 0, and every indirect task draw drew nothing.Change
An indirect task draw takes every slot, as an indirect mesh draw without a task already does (
capacity × vertices per workgroup).Host code only; no translated program changes, so no re-translation.
Known limit: the record capacity is still 1024 slots, so a draw with more meshlets than that is cut off past them. The floor grass starts about 13,900. The records-allocator PR, which builds on this one, removes that limit.
Tests
tests/test_mesh_fallback.pychecks the slots and the vertex count. The check fails on main without this change.Tested on
Looks good. I traced
fallback_record: for an indirect task drawgroupsis 0, sogroups * threadsgave 0 slots, the mesh dispatch was skipped and the vertex count was 0. Usingcapacityis consistent with how an indirect mesh draw without a task already behaves. The task stage still runs throughvkCmdDispatchIndirecton the converted args. The payload clear now covers all slots, so slots the task doesn't reach stay unstarted and output nothing. If there are no converted args the task send returns false before any of this, so there is no new failure path. CI is green.Nit: the new test matches the exact source text (
d.indirect ? capacitywith the alignment spaces), so a clang-format reflow would break it. Fine to leave given the rest of that test works the same way.The 1024-slot cap for the floor grass is noted in the description and handled by the follow-up.
Tested main (
88b554e) + #1509, #1510, #1511, #1512, #1513 and #1581 on the GTX 1070, as asked in #1023. They merged cleanly.Setup: Linux, GTX 1070 8 GB / NVIDIA 580.178.04, i7-7700HQ, output 1920x1080 at 75%. This was a fresh game folder, so the first start had an empty pipeline cache (
precompile: 12421 programs, 0 graphics …), the same condition as my #1023 run. The session lasted 23 minutes.driver faulted, 0 failed fallback pipelines. The only failed programs are the 10 movie-upscaler networks, which are left out on purpose on this card.55d1da3fea1603d4). Here, under the same empty-cache condition:SLOW compileline at all, and55d1da3fea1603d4doesn't show up;fallback draw of … left out: its compute pipelines are still compiling. The draw is skipped instead of the frame waiting for it.MovieEventHandleThread … ran without a core after 251.0 ms, thenMediaExtractorWorker,VideoDecoderThread,longest 251.1 ms). No pipeline was compiling then (0 jobs queued). So it looks like the 4-core CPU, not the GPU. The log also had twoover the driver's video-memory allowance (7.3 of 7.2 GB)lines.I haven't done the second start on a filled cache yet. I'll add it here when I have.
Thanks, that's a thorough run, and good that you checked Link's house too. #1512 is doing what it's meant to. The four
left out: its compute pipelines are still compilinglines mean the draw was skipped instead of the frame waiting for it. There was also noSLOW compile, and the 101 s pipeline didn't come back.All of #1505–#1514 have been merged since your test, so plain main now has everything you tested except #1581, which I rebased today and is still open. For the filled-cache start, main plus #1581 would match what you tested.
On the two things you flagged: the movie-thread waits look like CPU contention to me too, since your log shows nothing compiling at that moment. The video-memory lines don't come from these PRs as far as I can tell. The slot count #1511 raised only sizes the slot map and the task payloads, not the 64 MB record area. Before #1511, the per-slot buffers took about 650 MB for the floor grass alone.