Skip to content

fix(agc): decode primitive type 3 as a line strip - #4584

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
xXPBSXx:fix/agc-line-strip-primitive
Oct 13, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
xXPBSXx:fix/agc-line-strip-primitive

Conversation

@xXPBSXx

@xXPBSXx xXPBSXx commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

What

DecodeState mapped VGT_PRIMITIVE_TYPE 1, 2, 4, 5, 6, 7, 9 and 17 and threw AGC graphics: unsupported primitive type 3 for 3, the line strip (V_008958_DI_PT_LINESTRIP 0x3 in Mesa's r600d.h, the same enum that gives 2 = line list and 4 = triangle list). Type 3 now decodes as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP.

RasterPrimitiveOf in State.cpp (the primitive class a pixel shader sees when it reads the ancillary word) maps the line strip to RasterPrimitive::Line as well, so a strip no longer falls to the triangle default (review of this PR).

The other places that depend on the topology already handled the strip class and needed no change:

  • Primitive restart: Draw.cpp, Pipeline.cpp and the draw precheck treat type 3 as a strip (restart allowed without VK_EXT_primitive_topology_list_restart), and Vulkan allows restart for LINE_STRIP.

  • ValidateProvokingVertex already accepts LINE_STRIP.

  • The conservative-rasterization and single-sample MSAA checks already name type 3 as lines and refuse it.

One change beside the case: the point and line depth bias enable (PA_SU_SC_MODE_CNTL bit 13) is rejected on point and line draws because Vulkan applies depth bias to polygons only (af9e60b). pointsOrLines in State.cpp now includes the line strip so the bit is still rejected there.

Tests (agc_driver_graphics):

  • LineStripTests: type 3 decodes to LINE_STRIP; with primitive restart enabled (user config register 0x24b) and reset index 0xffffffff (context register 0x103) the restart is kept and the draw precheck accepts an indexed draw.

  • The provoking-vertex loop now includes type 3.

  • The depth bias test refuses the point and line enable bit on type 3 like on type 2.

Without the State.cpp change the test fails with unsupported primitive type 3.

Tested

  • Windows 10, MinGW, agc_driver_graphics passes with the change and fails without it as above (checked before the last rebase). After the rebase onto main 2a5eca11c it passed in 8 of 10 runs; of the two failures I saw the message of one: host import of ... failed at vkAllocateMemory (-2) followed by write-watched arena contained no host exclusion to test, which is unrelated to line strips. I did not check whether the test fails the same way on plain main under load. tools/check_conventions.py --base upstream/main passes.

  • Branch rebased onto main c13dc7e6b, built there (Windows 10, MinGW, Release): agc_driver_graphics passes 10 of 10 runs with the change; with the RasterPrimitiveOf part taken out the test fails (a line strip draw did not get the line primitive class, 2 of 2 runs).

  • After the rebase onto main 0c3dc9ca2 (a conflict in tests/Graphics.cpp with the new aliasedBufferViewTests; both tests kept) the branch was built on that main and agc_driver_graphics passed 10 of 10 runs on Windows 10. Then rebased once more onto 37dd48308 without a conflict (not rebuilt).

  • Not tested: no game run, no Vulkan draw of a line strip. Record of Lodoss War -Deedlit in Wonder Labyrinth- (PPSA05347) stopped on unsupported primitive type 3 in two user runs (after about 270 s and about 73 s); whether it runs on past this stop is untested. The enum source is the older-generation r600d.h; I did not check the value against a GFX10 header.

Overlap: #4587 made the same case 3 change in State.cpp; it was closed in favour of this PR.

Checklist

  • Based on current main (last build on 0c3dc9ca2, later rebases not rebuilt); no other open PR makes the same change (feat(libSceAgcDriver): support primitive type 3 (line strip) #4587 was closed)

  • One topic per PR; follow-ups go in a new PR

  • No comments in code except technical debt

  • Unimplemented paths throw; no silent stubs added

  • No notes, investigation .md files or images added to the repository

  • New third-party code is a submodule built from source (none added)

  • Generic behaviour, not specific to one title

  • Depends on: none

  • Unblocks: none

  • AI-assisted: yes

AI-assisted (Claude Code).

🤖 Generated with Claude Code

@xXPBSXx

xXPBSXx commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor Author

Correction to my comment above (I overstated it): the test run of Record of Lodoss War -Deedlit in Wonder Labyrinth- (PPSA05347) with a local build of main 2a5eca11c + this PR (1858502b4) + #4491 reached the 300 s limit with no unsupported primitive type 3 in the log, but the player left the game standing in a dialog for most of the run, so it did not go through the new game and the later dialogs as I wrote. The earlier aborts happened after progressing through dialogs (about 73 s to 270 s), so this run does not show that the stop is gone. It only shows that sitting in the first dialog does not hit it. I will repeat the run while playing on and report the result here.

AI-assisted (Claude Code).

@kr4y4

kr4y4 commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

The agc_driver_graphics failure in the Tested section (write-watched arena contained no host exclusion to test) isn't from this change. That check depends on the process's address layout and fails in about 2.5 % of starts on main too. Details and a fix are in #4660.

Written with AI assistance.

@xXPBSXx

xXPBSXx commented Oct 12, 2026

Copy link
Copy Markdown
Contributor Author

Windows test of the LineStrip change (1858502b4): agc_driver_graphics (Vulkan, RTX 4080 SUPER, MinGW, -j2, nothing else running) passed 9 of 10 runs. The failing run logged [gpu] host import of 0x11226110000+0x20000 failed at vkAllocateMemory (-2); falling back to copies (-2 is VK_ERROR_OUT_OF_DEVICE_MEMORY).

Control on plain main 3e0e01f35 without this commit: 8 of 10 passed, and the two failing runs show the same vkAllocateMemory (-2) message. So the flakiness is present on main and not caused by this change. The sample is small and I did not investigate the cause of the -2. The LineStrip test itself never failed on its own in these runs.

AI-assisted (Claude Code).

@xXPBSXx

xXPBSXx commented Oct 12, 2026

Copy link
Copy Markdown
Contributor Author

Correction to the flake note above: the host import ... failed at vkAllocateMemory (-2) lines I quoted are not the cause of the agc_driver_graphics failure. The cause is the one in #4660: hostWriteWatchExclusionTests needs a host region inside the write-watched arena, and some process address layouts have none ("write-watched arena contained no host exclusion to test"). It also fails on plain main, independent of the line strip.

AI-assisted (Claude Code).

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 13, 2026
@xXPBSXx
xXPBSXx force-pushed the fix/agc-line-strip-primitive branch from 1858502 to a9df8fd Compare October 13, 2026 02:08
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 13, 2026
@oneandonlydean

Copy link
Copy Markdown
Collaborator

One place is missed: RasterPrimitiveOf in State.cpp maps only VK_PRIMITIVE_TOPOLOGY_LINE_LIST to RasterPrimitive::Line, so a line strip falls to the default and a pixel shader that reads the ancillary word gets the triangle class. Please add VK_PRIMITIVE_TOPOLOGY_LINE_STRIP there, with a check in LineStripTests.

#4587 is the duplicate; this is the one to keep.

DecodeState mapped points, lists, strips, fans, rect lists and patches
but threw "unsupported primitive type 3" for VGT_PRIMITIVE_TYPE 3, the
line strip (DI_PT_LINESTRIP in Mesa's r600d.h). Record of Lodoss War
(PPSA05347) stops on it after a few minutes.

Vulkan allows primitive restart for line strips without the list
restart extension, and the precheck, the pipeline and the provoking
vertex check already treat the strip class that way; only the decode
lacked the case. The point and line depth bias enable stays rejected on
line strips like on line lists, and a line strip gets the line primitive
class for a pixel shader that reads the ancillary word.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@xXPBSXx
xXPBSXx force-pushed the fix/agc-line-strip-primitive branch from a9df8fd to 67e7a30 Compare October 13, 2026 03:24
@xXPBSXx

xXPBSXx commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

Done: RasterPrimitiveOf maps VK_PRIMITIVE_TOPOLOGY_LINE_STRIP to RasterPrimitive::Line now, and LineStripTests checks it (the test fails without that part: a line strip draw did not get the line primitive class). The branch is one commit on main c13dc7e6b; agc_driver_graphics passes 10 of 10 on Windows there. Thanks for the pointer, and for choosing this over #4587.

AI-assisted (Claude Code).

@oneandonlydean oneandonlydean self-assigned this Oct 13, 2026
@oneandonlydean
oneandonlydean merged commit 02d4839 into boykopovar:main Oct 13, 2026
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc*

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants